Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .claude/skills/consulting-deck-design/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,12 @@ several rounds, and each round's fix sometimes introduced a _new_ tell of a
different flavor. Treat "sounding human" as an ongoing discipline applied
while drafting, not a find-and-replace pass done at the end.

The general storyline, headline and Japanese wording rules live in the
distributable skill: `skill/references/story-document.md`,
`skill/references/writing-ja.md` and `skill/references/review.md` (run
`skill/scripts/deck-text.mjs --mode document` on the exported deck). This
section adds only what is specific to consulting-style exhibits.

### Numeric self-consistency is the single strongest signal

The #1 thing that got a deck flagged as AI-generated was a hard arithmetic
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,11 @@ and a next-actions table. Use labelled sample data where needed.

The [skill](skill/SKILL.md) creates a TSX project, starts the interactive preview,
checks the source and exports an editable PPTX. Ask for changes in the same
conversation; the preview updates as the agent edits TSX. You need Node.js 22.18+
conversation; the preview updates as the agent edits TSX. It plans the storyline for
either a talk or a deck people read and decide from, and checks the headlines and
Japanese wording before delivery ([talk](skill/references/story-talk.md),
[document](skill/references/story-document.md), [review](skill/references/review.md)).
You need Node.js 22.18+
and Git alongside Claude Code. See the
[authoring guide](https://office-kit.github.io/pptx/docs/authoring) for template
editing and manual setup. The bundled [core reference](skill/references/core-api.md)
Expand Down
62 changes: 62 additions & 0 deletions packages/dev/test/skill-deck-text.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { mkdtemp, writeFile, rm, symlink } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { buildDeck, initProject } from '../dist/index.mjs';

const execute = promisify(execFile);
const script = fileURLToPath(new URL('../../../skill/scripts/deck-text.mjs', import.meta.url));
const devModules = fileURLToPath(new URL('../node_modules', import.meta.url));

// The skill tells agents to name headlines "Headline" and run this script from the
// slide project; this keeps the documented workflow working end to end.
test('the skill deck-text script reads named headlines and flags wording', async (t) => {
const directory = await mkdtemp(join(tmpdir(), 'pptx-deck-text-test-'));
t.after(() => rm(directory, { recursive: true, force: true }));
const project = await initProject(join(directory, 'slides'));
await symlink(devModules, join(project, 'node_modules'), 'dir');
const deck = join(project, 'deck.tsx');
await writeFile(
deck,
`import { Presentation, Slide, Text } from '@office-kit/pptx-dsl';
export default (
<Presentation>
<Slide>
<Text name="Headline" x={1} y={0.5} width={10} height={1} size={32}>権限はどこで決まるの?</Text>
<Text x={1} y={2} width={10} height={1} size={60}>1</Text>
<Text x={1} y={3.5} width={10} height={1}>行レベルの権限が効く</Text>
</Slide>
<Slide notes="ここで RLS が効いてくる">
<Text name="Headline" x={1} y={0.5} width={10} height={1}>目次</Text>
<Text x={1} y={4} width={10} height={1}>値は有効期間つきで積む</Text>
<Text x={1} y={5} width={10} height={1}>DB 制約で守り切る</Text>
<Text x={1} y={2} width={10} height={1}>— 前提</Text>
</Slide>
</Presentation>
);
`,
);
const built = await buildDeck(deck);
await writeFile(join(project, 'deck.pptx'), built.bytes);

const { stdout } = await execute(process.execPath, [script, 'deck.pptx', '--mode', 'talk'], {
cwd: project,
});
assert.match(stdout, /^p01 権限はどこで決まるの?$/m);
assert.match(stdout, /^p02 目次$/m);
assert.match(stdout, /? 50%/);
assert.match(stdout, /^p01 \[効く\] 行レベルの権限が効く$/m);
assert.match(stdout, /^p02 \[dash\] — 前提$/m);
assert.match(stdout, /^p02 notes \[効く\] ここで RLS が効いてくる$/m);
assert.match(stdout, /^p02 \[intensifying 切る\] DB 制約で守り切る$/m);
assert.doesNotMatch(stdout, /有効期間/);

await assert.rejects(
execute(process.execPath, [script, 'deck.pptx', '--mode', 'slides'], { cwd: project }),
/Usage/,
);
});
33 changes: 30 additions & 3 deletions skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,28 @@ existing directory; reuse a presentation project or choose a new directory.
Read the generated `CLAUDE.md` before authoring. It is not necessarily loaded
automatically when Claude was started in the parent directory.

## Plan the story and the words

Decide which kind of deck this is before writing any slide text, including outline
drafts shown to the user:

- **Talk** (the default when a speaker presents it: conference talk, lightning talk,
lecture, all-hands). Read [the talk rules](references/story-talk.md).
- **Document** (read without the author, or used to reach a decision: report, proposal,
decision memo, board pack, handout). Read [the document rules](references/story-document.md).

If the brief does not make the kind clear, ask. For a Japanese deck, also read
[the Japanese wording rules](references/writing-ja.md). The two modes deliberately
disagree: a talk reveals its answer step by step and mixes headline forms; a document
states the answer first and makes every headline an assertion.

For a new deck, gather the user's real material first and agree a one-line-per-slide
storyline before building. Never invent figures, customers, quotes or anecdotes; ask,
or leave a visible `[要確認: …]`. Give each slide's headline `Text` the prop
`name="Headline"` so the checks can find it. When revising an existing deck, change
wording only where the reader gains something concrete, keep the speaker's voice, and
change structure only when asked.

## Author and revise

Read [the TSX reference](references/tsx.md) when first authoring or using unfamiliar
Expand Down Expand Up @@ -94,8 +116,10 @@ Saving TSX updates the preview. The user selects slides in the vertical thumbnai
strip, uses Fit/zoom, or chooses Present for presentation mode. Review affected slides
with available browser/image tools and fix problems in TSX. Keep this loop to
source edits and the running preview; do not run a separate export or restart
the server for each intermediate change. If visual inspection
is unavailable, state that limitation rather than claiming a visual check.
the server for each intermediate change. Without browser tools, render the exported
deck to images (for example `soffice --headless --convert-to pdf deck.pptx` and
`pdftoppm -r 80 -png deck.pdf page`) and inspect every page. If no visual inspection is
possible, state that limitation rather than claiming a visual check.

A failed build leaves the last successful preview visible with an error. Fix the
error before treating the visible slides or Download PPTX as current output.
Expand All @@ -111,7 +135,10 @@ npm run build
```

Type checking is separate from the live rebuild. Fix errors and review all slides,
including template slides retained in edit mode. The SVG preview is a rendering
including template slides retained in edit mode. Then review the words and the story
with [the review steps](references/review.md): run `scripts/deck-text.mjs` from this
skill's directory on `deck.pptx`, judge each flag, read the headline track, and for a
new deck or a substantial rewrite run one fresh-eye review by a separate agent. The SVG preview is a rendering
aid, not a guarantee of PowerPoint fidelity or animation/media playback.

Deliver the preview URL, the generated `deck.pptx` path and the editable project
Expand Down
99 changes: 99 additions & 0 deletions skill/references/review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Reviewing the words and the story

Run this after the deck builds and the visual check passes, before delivering a new deck
or a substantial rewrite. For a small edit, run step 1 on the affected slides only.

Detection is mechanical; judgement is yours. The model that wrote the deck cannot see its
own habits, so the checks list suspicions and a separate reviewer reads the deck cold.

## 1. Extract the text and the flags

From the slide project, after `npm run build`:

```sh
node <skill-directory>/scripts/deck-text.mjs deck.pptx --mode talk # or --mode document
node <skill-directory>/scripts/deck-text.mjs deck.pptx --full # every text and note
```

The script prints the headline track, mode-specific checks and wording flags. It finds a
headline by the shape name `Headline`, so give each slide's headline `Text` the prop
`name="Headline"`. Without it the script falls back to a title placeholder or the largest
text and marks the guess with `?`.

## 2. Judge every flag

For each flag, decide "fix" or "keep (reason)". Keep a short ledger while doing so.

- A flag inside a code sample, a quoted log or a product's official copy is kept.
- A flagged word that the project uses as a defined term is kept.
- Otherwise rewrite using [writing-ja.md](writing-ja.md) for Japanese wording, then rerun the
script to confirm the fix did not create a new flag.
- Do not rewrite in a new formula: replacing every 「〜ではなく」 with the same new pattern is
the same problem again.

## 3. Read the headline track

- **Talk**: read the headlines as the speaker's sequence of discoveries. Check that every
divider is answered by the next slide, nothing answers before it is asked, the mix of
forms is within reach of the reference ranges, and no pattern repeats three times in a
row ([story-talk.md](story-talk.md)).
- **Document**: read the headlines alone as one argument. Check that the answer comes first,
each headline is an assertion, peers share a form and nothing repeats
([story-document.md](story-document.md)).

Fix the storyline before polishing sentences; wording cannot rescue a missing step.

## 4. Check facts across pages

The mistakes readers and reviewers find first are not awkward words but pages that
contradict each other. The author misses them because each page was right when written.
List, in the ledger:

- every quantity that appears on more than one page (counts of paths, layers, types; percentages;
dates), with each page's value. One quantity has one value, and a headline count matches
the items drawn on that slide;
- every mechanism explained on more than one page (where a check runs, what a marker is,
what a store holds), with each page's wording. They must describe the same thing; if the
design changed over time, say which version each page shows;
- every claim on the closing or summary slide, with the body page that supports it. A
summary that says "no manual steps" while body pages describe manual ones is a
contradiction, not a simplification;
- the central terms, with every variant used for each.

Resolve each conflict from the source material. When the source does not settle it, weaken
the claim and ask the user; do not pick the version that reads better.

## 5. Fresh-eye review

Give the exported deck to a new agent that shares none of your context: do not mention how
the deck was made, the skill, the modes or what you were proud of. Replace `{FILE}`, `{N}`
and `{KIND}` (「登壇で話すための資料」 or 「読んで判断するための資料」) and pass this prompt:

```text
あなたはプレゼン資料のレビュアーです。{KIND}({N} ページ)を読み、作った本人には見えない
破綻を指摘してください。どう作られたかは知らされません。

ファイル {FILE} を最後まで読み、全ページを順に確認してください。一部だけ読んで推測しない
こと。発表者ノートがあれば、話す内容として参照してかまいません。

1. 日本語の言い回し: 日本語話者が読んで引っかかる表現をすべて挙げる。不自然な語尾、口語と
文語の混在、主語や述語が抜けた圧縮語、そろっていない箇条書きの語尾、長い連体修飾、
定義のない略語や造語、同じ概念の表記ゆれ、AI が書いたように感じる言い回し。
2. 論理展開: 見出しだけを上から読み、話が飛ぶ・戻る・同じことを二度言う・前提なしに結論が
出る箇所を挙げる。
3. 破綻: 見出しの数と本文の数の食い違い、見出しと図の結論の食い違い、裏づけのない評価語
(十分・問題ない・限定的)、既出ページの焼き直し、冒頭の予告と本編のずれ、同じ量が
ページごとに違う値、同じ仕組みの説明がページごとに違う箇所、まとめのページと本編の
矛盾、数値の出所の欠落。

各指摘は「ページ番号・該当箇所の引用・何が問題か・言い換え案」で書く。最後に、直すべき順に
上位 5 件を挙げる。盛らずに書くこと。無傷の資料はないので、欠点を最低 3 つ挙げること。
```

Tabulate the findings (page, finding verbatim, type, adopt / reject / hold, action or
reason). Decide each one; do not apply all of them. Show the user any finding that would
change meaning or structure and let them decide. Apply the adopted ones, rebuild, rerun
steps 1–4 and the visual check.

One round is the default. Report the number of findings, adopted changes and remaining
concerns in three lines, and ask before running another round.
40 changes: 40 additions & 0 deletions skill/references/sources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Sources and licences

The storytelling and wording guidance in this skill adapts, translates and condenses rules
from the projects below. Each file was rewritten for office-kit; none is copied verbatim.
Measured figures (headline mix, seconds per slide) are the original authors' data.

| Used in | Source | Licence |
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| story-talk.md | [minorun365/minorun-marp-skill](https://github.com/minorun365/minorun-marp-skill) `skills/slide-story` (commit c6b20bb) | Apache-2.0 |
| story-talk.md, writing-ja.md | [minorun365/my-claude-code-settings](https://github.com/minorun365/my-claude-code-settings) `claude/skills/writing-guide` (commit 3bab8cd) | MIT, © 2026 Minoru Onda |
| story-document.md | [tyroneross/pyramid-principle](https://github.com/tyroneross/pyramid-principle) `pyramid-presentation`, `pyramid-principle-core` (commit d1343aa) | Apache-2.0 |
| story-document.md, writing-ja.md, review.md, deck-text.mjs | [carnot-tech/consulting-pptx-skill](https://github.com/carnot-tech/consulting-pptx-skill) `references/slide-rules.md`, `ai-smell-lexicon.md`, `content-review-prompt.md` (commit f50edac) | MIT, © 2026 Carnot AI Inc. |
| story-document.md, writing-ja.md, review.md | [coji/natural-japanese](https://github.com/coji/natural-japanese) `writing-constitution.md`, `forbidden-patterns.md`, `translationese.md`, `doctypes/slide.md` (commit 9a78a42) | MIT, © 2026 coji |

Changes made for this skill: translated between English and Japanese, merged overlapping
rules, removed rules specific to Marp, HTML output, book publishing and the original
authors' brand design, split the rules into talk and document modes, and reimplemented
the text checks in JavaScript against `@office-kit/pptx`.

The MIT-licensed sources are provided under this notice:

> Permission is hereby granted, free of charge, to any person obtaining a copy of this
> software and associated documentation files (the "Software"), to deal in the Software
> without restriction, including without limitation the rights to use, copy, modify, merge,
> publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
> to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or
> substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
> INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
> PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
> FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
> OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> DEALINGS IN THE SOFTWARE.

The Apache-2.0 sources are used under the
[Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0); the changes are
listed above.
Loading
Loading