@cyber-dash-tech/revela 0.15.3 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -126,7 +126,7 @@ Export when needed, either manually or by asking the agent to export:
126
126
  /revela story open the read-only story workspace UI
127
127
  /revela make --deck make a deck from approved story state
128
128
  /revela make --brief [file.md] render executive brief from approved story
129
- /revela refine --deck open unified deck reading, inspection, and editing workspace
129
+ /revela review --deck open unified deck reading, insight, and comment workspace
130
130
  /revela export --deck pdf [file] export an HTML deck to PDF in the same directory
131
131
  /revela export --deck pptx [file] [--notes] export an HTML deck to editable PPTX
132
132
 
@@ -144,7 +144,7 @@ Export when needed, either manually or by asking the agent to export:
144
144
  /revela domain --rm <name> remove an installed domain
145
145
  ```
146
146
 
147
- Most `/revela` commands run locally with zero LLM cost. `/revela init`, `/revela research`, `/revela story`, `/revela make --deck`, `/revela design --new`, `/revela design --edit`, and `/revela export --deck pptx --notes` start AI-assisted workflows because they need to read or update project files. These workflow commands keep the visible chat message short and inject their detailed instructions through a one-shot system-prompt command intent. `/revela refine --deck` is the unified post-artifact workspace. It opens a local browser workspace with Edit and Inspect tabs that share the same Cmd/Ctrl-click element references. Edit sends targeted comments back into the current OpenCode session; Inspect sends grounded selection context to the current OpenCode session and renders localized Narrative Reading, Exploratory Reading, Source, and Purpose cards, has no chat box, and does not edit the deck. Deterministic preprocessing is kept as fallback context rather than the normal first UI. If a generated result omits newer reading cards, Refine keeps the deterministic Narrative Reading and Exploratory Reading cards instead of dropping context. Narrative Reading also shows artifact coverage for the selected canonical claim, including whether each recorded artifact contains the claim and whether coverage is current, stale, partial, or missing. Exploratory Reading is explicitly non-official and bounded to recorded claims, evidence, caveats, objections, risks, and artifact coverage. `/revela edit` and `/revela inspect` are no longer public commands; use `/revela refine --deck` instead.
147
+ Most `/revela` commands run locally with zero LLM cost. `/revela init`, `/revela research`, `/revela story`, `/revela make --deck`, `/revela design --new`, `/revela design --edit`, and `/revela export --deck pptx --notes` start AI-assisted workflows because they need to read or update project files. These workflow commands keep the visible chat message short and inject their detailed instructions through a one-shot system-prompt command intent. `/revela review --deck` is the unified post-artifact workspace. It opens a local browser workspace with Comment and Insight tabs that share the same Cmd/Ctrl-click element references. Comment sends targeted comments back into the current OpenCode session; Insight sends grounded selection context to the current OpenCode session and renders localized Narrative Reading, Exploratory Reading, Source, and Purpose cards, has no chat box, and does not edit the deck. Deterministic preprocessing is kept as fallback context rather than the normal first UI. If a generated result omits newer reading cards, Review keeps the deterministic Narrative Reading and Exploratory Reading cards instead of dropping context. Narrative Reading also shows artifact coverage for the selected canonical claim, including whether each recorded artifact contains the claim and whether coverage is current, stale, partial, or missing. Exploratory Reading is explicitly non-official and bounded to recorded claims, evidence, caveats, objections, risks, and artifact coverage. `/revela edit` and `/revela inspect` are no longer public commands; use `/revela review --deck` instead. `/revela refine --deck` remains a compatibility alias.
148
148
 
149
149
  ---
150
150
 
@@ -152,7 +152,7 @@ Most `/revela` commands run locally with zero LLM cost. `/revela init`, `/revela
152
152
 
153
153
  Explicit Revela workflow commands append one-shot command instructions to the current agent's system prompt and choose the needed prompt mode automatically.
154
154
 
155
- The default prompt is narrative-first: it follows `Init -> Research -> Story -> Make -> Refine -> Export` and focuses on audience belief shift, decision/action, thesis, claims, evidence boundaries, objections, risks, research gaps, and approval. Active design CSS, layout catalogs, component indexes, chart rules, and deck HTML skeletons are intentionally omitted until `/revela make --deck` switches the session into deck-render mode or `/revela design` starts explicit design work.
155
+ The default prompt is narrative-first: it follows `Init -> Research -> Story -> Make -> Review -> Export` and focuses on audience belief shift, decision/action, thesis, claims, evidence boundaries, objections, risks, research gaps, and approval. Active design CSS, layout catalogs, component indexes, chart rules, and deck HTML skeletons are intentionally omitted until `/revela make --deck` switches the session into deck-render mode or `/revela design` starts explicit design work.
156
156
 
157
157
  Deck-render mode is built from 2 layers:
158
158
 
@@ -195,8 +195,8 @@ Use Revela as a narrative-first artifact workflow:
195
195
  5. Run `/revela make --deck` to compile the approved narrative into deck slide specs and enter deck-render mode, or `/revela make --brief` to render an executive brief.
196
196
  6. Choose or confirm design only during deck handoff; `/revela make --deck` runs the deck/artifact gate after plan confirmation.
197
197
  7. Let the agent write the HTML deck under `decks/` only after the artifact gate is ready.
198
- 8. Use `/revela refine --deck` for visual comments, targeted revisions, read-only Narrative Reading, bounded Exploratory Reading, Source, and Purpose inspection, and claim-to-artifact coverage for selected deck elements.
199
- 9. Use `/revela refine --deck` for post-artifact changes; `/revela edit` and `/revela inspect` are no longer public commands.
198
+ 8. Use `/revela review --deck` for visual comments, targeted revisions, read-only Narrative Reading, bounded Exploratory Reading, Source, and Purpose insight, and claim-to-artifact coverage for selected deck elements.
199
+ 9. Use `/revela review --deck` for post-artifact changes; `/revela edit` and `/revela inspect` are no longer public commands.
200
200
  10. Export with `/revela export --deck pdf <file>` or `/revela export --deck pptx <file>`.
201
201
 
202
202
  `/revela story` opens the read-only story workspace UI for unclear audience, missing belief shift, missing decision/action, weak thesis, unsupported central claims, weak evidence, unsupported scope, unhandled objections, missing risk/assumption handling, stale approval, or missing approval. It does not review design/layout readiness or write the final deck.
@@ -561,10 +561,10 @@ A custom domain is a folder containing `INDUSTRY.md`.
561
561
  Use the unified refinement workspace for normal post-write review and revision:
562
562
 
563
563
  ```text
564
- /revela refine --deck
564
+ /revela review --deck
565
565
  ```
566
566
 
567
- `/revela refine --deck` opens the active HTML deck with two tabs. Use `Ctrl`/`Cmd` + click once to reference deck elements, then choose Edit for fast natural-language change comments or Inspect for read-only Narrative Reading, bounded Exploratory Reading, Source, Purpose, and artifact coverage review. Inspect does not mutate the deck; Edit remains the mutation path. This is the recommended entry for post-artifact reading, inspection, and editing.
567
+ `/revela review --deck` opens the active HTML deck with two tabs. Use `Ctrl`/`Cmd` + click once to reference deck elements, then choose Comment for fast natural-language change comments or Insight for read-only Narrative Reading, bounded Exploratory Reading, Source, Purpose, and artifact coverage review. Insight does not mutate the deck; Comment remains the mutation path. This is the recommended entry for post-artifact reading, insight, and commenting.
568
568
 
569
569
  Removed command:
570
570
 
@@ -572,29 +572,29 @@ Removed command:
572
572
  /revela edit
573
573
  ```
574
574
 
575
- `/revela edit` has been removed. Use `/revela refine --deck` for the unified reading, inspection, and editing workspace.
575
+ `/revela edit` has been removed. Use `/revela review --deck` for the unified reading, insight, and comment workspace.
576
576
 
577
- Use `Ctrl`/`Cmd` + click to reference deck elements, write a natural-language comment in the Edit tab, then send it back to OpenCode. Revela sends a structured edit prompt that includes the deck file, slide context, selected element metadata, and your comment.
577
+ Use `Ctrl`/`Cmd` + click to reference deck elements, write a natural-language comment in the Comment tab, then send it back to OpenCode. Revela sends a structured edit prompt that includes the deck file, slide context, selected element metadata, and your comment.
578
578
 
579
- LLM tool equivalent: `revela-edit` with no target. The tool remains a compatibility shim and opens Refine in Edit mode when you say things like “I want to edit the deck”.
579
+ LLM tool equivalent: `revela-edit` with no target. The tool remains a compatibility shim and opens Review in Comment mode when you say things like “I want to edit the deck”.
580
580
 
581
- For existing decks, `/revela refine --deck` prepares whatever minimal project context is needed so targeted edits can still use the normal safety checks.
581
+ For existing decks, `/revela review --deck` prepares whatever minimal project context is needed so targeted edits can still use the normal safety checks.
582
582
 
583
583
  ---
584
584
 
585
585
  ## Evidence Inspector
586
586
 
587
- Use `/revela refine --deck` for evidence inspection and narrative reading. Removed compatibility command:
587
+ Use `/revela review --deck` for evidence insight and narrative reading. Removed compatibility command:
588
588
 
589
589
  ```text
590
590
  /revela inspect
591
591
  ```
592
592
 
593
- `/revela inspect` no longer opens a separate inspector shell. Use `/revela refine --deck` and the Inspect tab. The Inspect tab shows Narrative Reading and Exploratory Reading cards alongside the fixed Source and Purpose cards. Narrative Reading preserves canonical claim ids, evidence binding ids, supported scope, unsupported scope, caveats, objections, risks, and artifact coverage when the selected element maps to canonical narrative state. Coverage shows whether the selected claim appears in recorded deck/brief/export artifacts and whether those artifacts are current, stale, partial, or missing against the current narrative hash. Exploratory Reading provides non-official objection prep, audience reframing boundaries, appendix leads, and meeting-prep cues from the same recorded context only. Use `Ctrl`/`Cmd` + click to reference deck elements, then click `Inspect Selection`. Selection is locked while the request is being processed.
593
+ `/revela inspect` no longer opens a separate inspector shell. Use `/revela review --deck` and the Insight tab. The Insight tab shows Narrative Reading and Exploratory Reading cards alongside the fixed Source and Purpose cards. Narrative Reading preserves canonical claim ids, evidence binding ids, supported scope, unsupported scope, caveats, objections, risks, and artifact coverage when the selected element maps to canonical narrative state. Coverage shows whether the selected claim appears in recorded deck/brief/export artifacts and whether those artifacts are current, stale, partial, or missing against the current narrative hash. Exploratory Reading provides non-official objection prep, audience reframing boundaries, appendix leads, and meeting-prep cues from the same recorded context only. Use `Ctrl`/`Cmd` + click to reference deck elements, then click `Get Insight`. Selection is locked while the request is being processed.
594
594
 
595
- The inspector is not chat and has no freeform prompt. It does not mutate `DECKS.json` or the deck HTML. It uses recorded slide specs, narrative state, and slide-level evidence trace as grounded context. Inspect is LLM-first in the UI: it shows a reading/loading state, then renders structured generated cards. Deterministic preprocessing remains internal fallback context and is shown only if generation fails or times out. The Inspect tab includes a fixed display-language selector; language changes affect card copy only and never alter claim ids, evidence ids, source paths, URLs, numbers, quotes, or canonical facts. When an older or partial generated result only returns Source/Purpose, Refine preserves the deterministic reading cards so generated inspection cannot silently remove claim, evidence-boundary, artifact-coverage, or exploratory context.
595
+ The insight surface is not chat and has no freeform prompt. It does not mutate `DECKS.json` or the deck HTML. It uses recorded slide specs, narrative state, and slide-level evidence trace as grounded context. Insight is LLM-first in the UI: it shows a reading/loading state, then renders structured generated cards. Deterministic preprocessing remains internal fallback context and is shown only if generation fails or times out. The Insight tab includes a fixed display-language selector; language changes affect card copy only and never alter claim ids, evidence ids, source paths, URLs, numbers, quotes, or canonical facts. When an older or partial generated result only returns Source/Purpose, Review preserves the deterministic reading cards so generated insight cannot silently remove claim, evidence-boundary, artifact-coverage, or exploratory context.
596
596
 
597
- Refine uses the active HTML deck render target recorded in workspace state. The deck HTML must satisfy Revela's slide identity contract: every `<section class="slide">` in the active artifact needs a positive 1-based `data-slide-index` matching the current slide specs. Invalid active artifacts are refused or reported before refine/export workflows trust them.
597
+ Review uses the active HTML deck render target recorded in workspace state. The deck HTML must satisfy Revela's slide identity contract: every `<section class="slide">` in the active artifact needs a positive 1-based `data-slide-index` matching the current slide specs. Invalid active artifacts are refused or reported before review/export workflows trust them.
598
598
 
599
599
  ---
600
600
 
package/README.zh-CN.md CHANGED
@@ -125,7 +125,7 @@ export { default } from "/absolute/path/to/revela/index.ts";
125
125
  /revela story 打开只读 story workspace UI
126
126
  /revela make --deck 从已批准 story 生成 deck
127
127
  /revela make --brief [file.md] 从已批准 story 渲染 executive brief
128
- /revela refine --deck 打开统一的 deck 阅读、检查和编辑 workspace
128
+ /revela review --deck 打开统一的 deck 阅读、洞察和评论 workspace
129
129
  /revela export --deck pdf [file] 将 HTML deck 导出为同目录 PDF
130
130
  /revela export --deck pptx [file] [--notes] 将 HTML deck 导出为可编辑 PPTX
131
131
 
@@ -143,7 +143,7 @@ export { default } from "/absolute/path/to/revela/index.ts";
143
143
  /revela domain --rm <name> 删除已安装 domain
144
144
  ```
145
145
 
146
- 大多数 `/revela` 命令都在本地执行,不消耗 LLM token。`/revela init`、`/revela research`、`/revela story`、`/revela make --deck`、`/revela design --new`、`/revela design --edit` 和 `/revela export --deck pptx --notes` 会启动 AI 辅助流程,因为它们需要读取或更新项目状态。这些 workflow command 只在可见聊天里显示短意图,详细内部说明通过一次性的 system-prompt command intent 注入。`/revela refine --deck` 是统一的 post-artifact workspace,会打开一个本地浏览器 workspace,里面有 EditInspect 两个 tab,并共享同一套 Cmd/Ctrl-click 元素引用。Edit 会把精准修改评论发回当前 OpenCode 会话;Inspect 会把 grounded selection context 发给当前 OpenCode 会话,并渲染本地化的 Narrative Reading、Exploratory Reading、Source、Purpose 卡片。确定性预处理保留为 fallback context,而不是默认先展示的 UI。如果生成结果缺少较新的 reading 卡片,Refine 会保留确定性 Narrative Reading 和 Exploratory Reading,而不是丢掉这些上下文。Narrative Reading 还会显示所选 canonical claim 的 artifact coverage,包括每个已记录 artifact 是否包含该 claim,以及 coverage 是 current、stale、partial 还是 missing。Exploratory Reading 明确是非官方阅读辅助,只能基于已记录 claim、evidence、caveat、objection、risk 和 artifact coverage。它没有聊天框,也不会修改 deck。`/revela edit` 和 `/revela inspect` 不再是公开命令;请使用 `/revela refine --deck`。
146
+ 大多数 `/revela` 命令都在本地执行,不消耗 LLM token。`/revela init`、`/revela research`、`/revela story`、`/revela make --deck`、`/revela design --new`、`/revela design --edit` 和 `/revela export --deck pptx --notes` 会启动 AI 辅助流程,因为它们需要读取或更新项目状态。这些 workflow command 只在可见聊天里显示短意图,详细内部说明通过一次性的 system-prompt command intent 注入。`/revela review --deck` 是统一的 post-artifact workspace,会打开一个本地浏览器 workspace,里面有 CommentInsight 两个 tab,并共享同一套 Cmd/Ctrl-click 元素引用。Comment 会把精准修改评论发回当前 OpenCode 会话;Insight 会把 grounded selection context 发给当前 OpenCode 会话,并渲染本地化的 Narrative Reading、Exploratory Reading、Source、Purpose 卡片。确定性预处理保留为 fallback context,而不是默认先展示的 UI。如果生成结果缺少较新的 reading 卡片,Review 会保留确定性 Narrative Reading 和 Exploratory Reading,而不是丢掉这些上下文。Narrative Reading 还会显示所选 canonical claim 的 artifact coverage,包括每个已记录 artifact 是否包含该 claim,以及 coverage 是 current、stale、partial 还是 missing。Exploratory Reading 明确是非官方阅读辅助,只能基于已记录 claim、evidence、caveat、objection、risk 和 artifact coverage。它没有聊天框,也不会修改 deck。`/revela edit` 和 `/revela inspect` 不再是公开命令;请使用 `/revela review --deck`。`/revela refine --deck` 仍作为兼容 alias 保留。
147
147
 
148
148
  ---
149
149
 
@@ -151,7 +151,7 @@ export { default } from "/absolute/path/to/revela/index.ts";
151
151
 
152
152
  显式 Revela workflow command 会把一次性 command instructions 追加到当前 agent 的 system prompt 中。你不需要先运行 ambient enable/disable;公开入口都在 `/revela` help 中列出。
153
153
 
154
- 默认 prompt 是 narrative-first:它遵循 `Init -> Research -> Story -> Make -> Refine -> Export`,关注受众信念变化、decision/action、thesis、claims、证据边界、objections、risks、research gaps 和 approval。Active design CSS、layout catalog、component index、chart rules 和 deck HTML skeleton 在 `/revela make --deck` 切换到 deck-render mode 或 `/revela design` 进入显式设计工作流前不会注入。
154
+ 默认 prompt 是 narrative-first:它遵循 `Init -> Research -> Story -> Make -> Review -> Export`,关注受众信念变化、decision/action、thesis、claims、证据边界、objections、risks、research gaps 和 approval。Active design CSS、layout catalog、component index、chart rules 和 deck HTML skeleton 在 `/revela make --deck` 切换到 deck-render mode 或 `/revela design` 进入显式设计工作流前不会注入。
155
155
 
156
156
  Deck-render mode 由 2 层组成:
157
157
 
@@ -193,8 +193,8 @@ Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace s
193
193
  5. 运行 `/revela make --deck`,把已批准 narrative 编译成 deck slide specs 并进入 deck-render mode,或运行 `/revela make --brief` 渲染 executive brief。
194
194
  6. 只在 deck handoff 阶段选择或确认 design;`/revela make --deck` 会在 deck plan 确认后运行 deck/artifact gate。
195
195
  7. 只有 artifact gate ready 后,才让 agent 把 HTML deck 写到 `decks/` 下。
196
- 8. 用 `/revela refine --deck` 对选中 deck 元素做可视化评论、精准修改、只读 Narrative Reading、有边界的 Exploratory Reading、Source、Purpose 检查,以及 claim-to-artifact coverage 查看。
197
- 9. post-artifact 修改统一使用 `/revela refine --deck`;`/revela edit` 和 `/revela inspect` 不再是公开命令。
196
+ 8. 用 `/revela review --deck` 对选中 deck 元素做可视化评论、精准修改、只读 Narrative Reading、有边界的 Exploratory Reading、Source、Purpose 洞察,以及 claim-to-artifact coverage 查看。
197
+ 9. post-artifact 修改统一使用 `/revela review --deck`;`/revela edit` 和 `/revela inspect` 不再是公开命令。
198
198
  10. 用 `/revela export --deck pdf <file>` 或 `/revela export --deck pptx <file>` 导出。
199
199
 
200
200
  普通聊天不需要 ambient command。需要 Revela 工作流时,直接运行对应的 `/revela ...` 显式命令。
@@ -527,10 +527,10 @@ Prompt 注入规则:
527
527
  正常的写后 review 和修改建议使用统一 refinement workspace:
528
528
 
529
529
  ```text
530
- /revela refine --deck
530
+ /revela review --deck
531
531
  ```
532
532
 
533
- `/revela refine --deck` 会打开 active HTML deck,并提供两个 tab。使用 `Ctrl`/`Cmd` + click 先引用 deck 元素,然后在 Edit 里快速写自然语言修改评论,或在 Inspect 里做只读 Narrative Reading、有边界的 Exploratory Reading、Source、Purpose 和 artifact coverage 检查。Inspect 不会修改 deck;真正的 mutation 仍然只走 Edit。这是 post-artifact 阅读、检查和编辑的推荐入口。
533
+ `/revela review --deck` 会打开 active HTML deck,并提供两个 tab。使用 `Ctrl`/`Cmd` + click 先引用 deck 元素,然后在 Comment 里快速写自然语言修改评论,或在 Insight 里做只读 Narrative Reading、有边界的 Exploratory Reading、Source、Purpose 和 artifact coverage 检查。Insight 不会修改 deck;真正的 mutation 仍然只走 Comment。这是 post-artifact 阅读、洞察和评论的推荐入口。
534
534
 
535
535
  已移除命令:
536
536
 
@@ -538,29 +538,29 @@ Prompt 注入规则:
538
538
  /revela edit
539
539
  ```
540
540
 
541
- `/revela edit` 已移除。请使用 `/revela refine --deck` 打开统一的阅读、检查和编辑 workspace。
541
+ `/revela edit` 已移除。请使用 `/revela review --deck` 打开统一的阅读、洞察和评论 workspace。
542
542
 
543
- 使用 `Ctrl`/`Cmd` + 点击 deck 元素来引用它们,在 Edit tab 写一段自然语言评论,然后发送回 OpenCode。Revela 会把 deck 文件、slide 上下文、选中元素 metadata 和你的评论整理成结构化 edit prompt。
543
+ 使用 `Ctrl`/`Cmd` + 点击 deck 元素来引用它们,在 Comment tab 写一段自然语言评论,然后发送回 OpenCode。Revela 会把 deck 文件、slide 上下文、选中元素 metadata 和你的评论整理成结构化 edit prompt。
544
544
 
545
- 对应的 LLM tool:`revela-edit`,不需要 target。这个 tool 仍作为兼容入口保留,当你说“我要编辑这个 deck”时,agent 会打开 RefineEdit mode。
545
+ 对应的 LLM tool:`revela-edit`,不需要 target。这个 tool 仍作为兼容入口保留,当你说“我要编辑这个 deck”时,agent 会打开 ReviewComment mode。
546
546
 
547
- 对于已有 HTML deck,`/revela refine --deck` 会自动准备必要的最小项目上下文,让后续精准修改仍然经过正常安全检查。
547
+ 对于已有 HTML deck,`/revela review --deck` 会自动准备必要的最小项目上下文,让后续精准修改仍然经过正常安全检查。
548
548
 
549
549
  ---
550
550
 
551
551
  ## Evidence Inspector
552
552
 
553
- 用 `/revela refine --deck` 做 evidence inspection 和 narrative reading。已移除的兼容命令:
553
+ 用 `/revela review --deck` 做 evidence insight 和 narrative reading。已移除的兼容命令:
554
554
 
555
555
  ```text
556
556
  /revela inspect
557
557
  ```
558
558
 
559
- `/revela inspect` 不再打开独立 inspector shell。请使用 `/revela refine --deck` 的 Inspect tab。Inspect tab 会在固定 Source 和 Purpose 卡片之外显示 Narrative Reading 和 Exploratory Reading 卡片。当选中元素能映射到 canonical narrative state 时,Narrative Reading 会保留 canonical claim id、evidence binding id、supported scope、unsupported scope、caveat、objection、risk 和 artifact coverage。Coverage 会显示所选 claim 是否出现在已记录的 deck/brief/export artifact 中,以及这些 artifact 相对当前 narrative hash 是 current、stale、partial 还是 missing。Exploratory Reading 提供非官方的 objection prep、audience reframing 边界、appendix leads 和 meeting-prep cues,并且只能使用同一份已记录 context。使用 `Ctrl`/`Cmd` + click 引用 deck 元素,然后点击 `Inspect Selection`。请求处理期间,deck 选择会被锁定。
559
+ `/revela inspect` 不再打开独立 inspector shell。请使用 `/revela review --deck` 的 Insight tab。Insight tab 会在固定 Source 和 Purpose 卡片之外显示 Narrative Reading 和 Exploratory Reading 卡片。当选中元素能映射到 canonical narrative state 时,Narrative Reading 会保留 canonical claim id、evidence binding id、supported scope、unsupported scope、caveat、objection、risk 和 artifact coverage。Coverage 会显示所选 claim 是否出现在已记录的 deck/brief/export artifact 中,以及这些 artifact 相对当前 narrative hash 是 current、stale、partial 还是 missing。Exploratory Reading 提供非官方的 objection prep、audience reframing 边界、appendix leads 和 meeting-prep cues,并且只能使用同一份已记录 context。使用 `Ctrl`/`Cmd` + click 引用 deck 元素,然后点击 `Get Insight`。请求处理期间,deck 选择会被锁定。
560
560
 
561
- Inspector 不是聊天,也没有自由输入框。它不会修改 `DECKS.json` 或 deck HTML。它使用已记录的 slide spec、narrative state 和 slide-level evidence trace 作为 grounded context。Inspect 的用户界面是 LLM-first:先显示 reading/loading 状态,再渲染结构化生成卡片。确定性预处理仍作为内部 fallback context,仅在生成失败或超时时显示。Inspect tab 提供固定 display-language 下拉选项;语言只影响卡片文案,不会改变 claim id、evidence id、source path、URL、数字、引用或 canonical facts。如果旧版或不完整的生成结果只返回 Source/Purpose,Refine 会保留确定性 reading 卡片,避免 generated inspection 静默移除 claim、evidence boundary、artifact coverage 或 exploratory context。
561
+ Insight 不是聊天,也没有自由输入框。它不会修改 `DECKS.json` 或 deck HTML。它使用已记录的 slide spec、narrative state 和 slide-level evidence trace 作为 grounded context。Insight 的用户界面是 LLM-first:先显示 reading/loading 状态,再渲染结构化生成卡片。确定性预处理仍作为内部 fallback context,仅在生成失败或超时时显示。Insight tab 提供固定 display-language 下拉选项;语言只影响卡片文案,不会改变 claim id、evidence id、source path、URL、数字、引用或 canonical facts。如果旧版或不完整的生成结果只返回 Source/Purpose,Review 会保留确定性 reading 卡片,避免 generated insight 静默移除 claim、evidence boundary、artifact coverage 或 exploratory context。
562
562
 
563
- Refine 会使用 workspace state 中记录的 active HTML deck render target。Deck HTML 必须满足 Revela 的 slide identity contract:active artifact 中每个 `<section class="slide">` 都需要有正数、1-based 的 `data-slide-index`,并且要匹配当前 slide specs。无效的 active artifact 会在 refine/export 工作流信任它之前被拒绝或报告。
563
+ Review 会使用 workspace state 中记录的 active HTML deck render target。Deck HTML 必须满足 Revela 的 slide identity contract:active artifact 中每个 `<section class="slide">` 都需要有正数、1-based 的 `data-slide-index`,并且要匹配当前 slide specs。无效的 active artifact 会在 review/export 工作流信任它之前被拒绝或报告。
564
564
 
565
565
  ---
566
566
 
@@ -3,5 +3,5 @@ export async function handleEdit(
3
3
  send: (text: string) => Promise<void>,
4
4
  ): Promise<void> {
5
5
  void options
6
- await send("`/revela edit` has been removed. Use `/revela refine --deck` for the unified reading, inspection, and editing workspace.")
6
+ await send("`/revela edit` has been removed. Use `/revela review --deck` and the Comment tab for the unified deck review workspace.")
7
7
  }
@@ -30,7 +30,7 @@ export async function handleHelp(
30
30
  `2. \`research\` — close evidence gaps and bind support\n` +
31
31
  `3. \`story\` — inspect audience, thesis, claims, evidence, risks, and approval\n` +
32
32
  `4. \`make\` — generate deck or brief from approved story state\n` +
33
- `5. \`refine\` — inspect and edit rendered deck artifacts\n` +
33
+ `5. \`review\` — comment on and inspect rendered deck artifacts\n` +
34
34
  `6. \`export\` — export deck artifacts to PDF or PPTX\n\n` +
35
35
  `---\n\n` +
36
36
  `**Commands**\n\n` +
@@ -40,7 +40,7 @@ export async function handleHelp(
40
40
  `\`/revela story [-l language]\` — open the read-only story workspace UI\n` +
41
41
  `\`/revela make --deck\` — make a deck from approved story state\n` +
42
42
  `\`/revela make --brief [file.md]\` — render executive brief from approved story\n` +
43
- `\`/revela refine --deck\` — open deck reading, inspection, and editing workspace\n` +
43
+ `\`/revela review --deck\` — open deck reading, insight, and comment workspace\n` +
44
44
  `\`/revela export --deck pdf [file.html]\` — export HTML deck to PDF\n` +
45
45
  `\`/revela export --deck pptx [file.html] [--notes]\` — export HTML deck to PPTX\n` +
46
46
  `\`/revela design\` — list installed designs\n` +
@@ -3,5 +3,5 @@ export async function handleInspect(
3
3
  send: (text: string) => Promise<void>,
4
4
  ): Promise<void> {
5
5
  void options
6
- await send("`/revela inspect` is no longer a public command. Use `/revela refine --deck` and the Inspect tab for grounded Source/Purpose/Narrative Reading.")
6
+ await send("`/revela inspect` is no longer a public command. Use `/revela review --deck` and the Insight tab for grounded Source/Purpose/Narrative Reading.")
7
7
  }
@@ -124,7 +124,13 @@ export function buildNarrativeViewPrompt(options: { workspaceRoot: string; langu
124
124
  })),
125
125
  relations: map.claimRelations.map((relation) => ({ id: relation.id, fromClaimId: relation.fromClaimId, toClaimId: relation.toClaimId, relation: relation.relation, rationale: relation.rationale, inferred: relation.inferred })),
126
126
  researchGaps: map.researchGaps.map((gap) => ({ id: gap.id, targetType: gap.targetType, targetId: gap.targetId, status: gap.status, priority: gap.priority, question: gap.question })),
127
- artifactCoverage: map.artifactCoverage.map((artifact) => ({ type: artifact.type, outputPath: artifact.outputPath, stale: artifact.stale, slideRefs: artifact.slideRefs.map((ref) => ({ claimId: ref.claimId, slideIndex: ref.slideIndex, role: ref.role, match: ref.match, location: ref.location })) })),
127
+ artifactCoverage: map.artifactCoverage.map((artifact) => ({ type: artifact.type, outputPath: artifact.outputPath, stale: artifact.stale, coverageStatus: artifact.coverageStatus, affectedClaimIds: artifact.affectedClaimIds, missingClaimIds: artifact.missingClaimIds, slideRefs: artifact.slideRefs.map((ref) => ({ claimId: ref.claimId, slideIndex: ref.slideIndex, role: ref.role, match: ref.match, location: ref.location })) })),
128
+ workbench: {
129
+ summary: map.workbench.summary,
130
+ filters: map.workbench.filters,
131
+ renderTargetAction: map.workbench.renderTargetAction,
132
+ artifactCoverage: map.workbench.artifactCoverage.map((item) => ({ type: item.type, outputPath: item.outputPath, coverageStatus: item.coverageStatus, affectedClaimIds: item.affectedClaimIds, missingClaimIds: item.missingClaimIds, statusNote: item.statusNote, recommendedNextCommand: item.recommendedNextCommand })),
133
+ },
128
134
  }
129
135
 
130
136
  return `Prepare the read-only Revela narrative UI display model.
@@ -141,11 +147,11 @@ Hard rules:
141
147
  - Do not invent new claims, evidence, relations, slide coverage, source paths, findings files, quotes, or caveats.
142
148
  - Preserve every claimId exactly.
143
149
  - Preserve every relation endpoint exactly: fromClaimId, toClaimId, relation.
144
- - You may only organize and localize display copy for the UI: pageTitle, summaryLine, section labels, claim card displayTitle, roleLabel, narrativeJob, evidenceSummary, riskOrGapSummary, relation displayLabel, and relation displayRationale.
150
+ - You may only organize and localize display copy for the UI: pageTitle, summaryLine, section labels including Story workbench labels, claim card displayTitle, roleLabel, narrativeJob, evidenceSummary, riskOrGapSummary, relation displayLabel, and relation displayRationale.
145
151
  - For inferred relations, do not provide relation displayLabel or displayRationale; inferred relations are unconfirmed order notes, not causal/support/dependency judgments.
146
152
  - relation displayRationale may only localize or clarify an existing canonical relation rationale. If relation.rationale is missing or the relation is inferred, do not provide displayRationale; the UI will show the missing or inferred status.
147
153
  - Keep source paths, findings files, claim IDs, narrative hash, and numbers unchanged.
148
- - Translate normal UI/display text into the target language request: pageTitle, summaryLine, labels, claim displayTitle, roleLabel, narrativeJob, evidenceSummary, riskOrGapSummary, relation displayLabel, and relation displayRationale.
154
+ - Translate normal UI/display text into the target language request: pageTitle, summaryLine, labels including workbench labels, claim displayTitle, roleLabel, narrativeJob, evidenceSummary, riskOrGapSummary, relation displayLabel, and relation displayRationale.
149
155
  - Do not translate claim IDs, relation endpoints, narrative hash, source paths, findings files, URLs, numbers, or quoted/source facts.
150
156
  - Use natural business and manufacturing terminology in the target language, not word-by-word machine translation.
151
157
  - If a fact is missing, describe it as missing instead of filling it in.
@@ -14,13 +14,13 @@ export async function handleRefine(
14
14
  })
15
15
 
16
16
  await send(
17
- `Opened Revela Refine for the active HTML deck.\n` +
17
+ `Opened Revela Review for the active HTML deck.\n` +
18
18
  `File: \`${result.deck.file}\`\n` +
19
19
  `${result.stateNote}\n` +
20
20
  `URL: ${result.url}\n\n` +
21
- `Use Ctrl/Cmd-click in the browser to reference deck elements. The Edit tab sends targeted change comments; the Inspect tab reviews the same selection with Source/Purpose cards and does not edit the deck.`
21
+ `Use Ctrl/Cmd-click in the browser to reference deck elements. The Comment tab sends targeted change comments; the Insight tab reviews the same selection with Source/Purpose cards and does not edit the deck.`
22
22
  )
23
23
  } catch (e: any) {
24
- await send(`**Refine failed:** ${e.message || String(e)}`)
24
+ await send(`**Review failed:** ${e.message || String(e)}`)
25
25
  }
26
26
  }
@@ -102,7 +102,7 @@ Workflow:
102
102
  11. Call \`revela-decks\` action \`review\` as the artifact gate. It computes \`writeReadiness\` and review snapshots for deck HTML writing. If it reports \`slide_plan_unconfirmed\`, stop and ask for explicit deck-plan confirmation.
103
103
  12. Write \`decks/*.html\` only if the deck/artifact gate is ready and all deck HTML contract requirements can be satisfied. Generate the artifact chapter by chapter instead of drafting all content slides in one broad pass. Keep the HTML file valid after every write, preserve already-written slides, and update one chapter's slide sections at a time.
104
104
  13. For each chapter, make every content slide carry a distinct claim, evidence item, comparison, risk, or action. If a chapter lacks enough substance for its allocated slides, merge weak slides or reduce the slide count instead of creating sparse filler.
105
- 14. After each HTML write, the system automatically runs artifact QA before opening Refine. If post-write artifact QA reports hard errors, fix them and let QA run again. Refine opens only after hard errors pass. Density warnings about thin claim/evidence substance should be reported and improved when useful, but they do not block Refine.
105
+ 14. After each HTML write, the system automatically runs artifact QA before opening Review. If post-write artifact QA reports hard errors, fix them and let QA run again. Review opens only after hard errors pass. Density warnings about thin claim/evidence substance should be reported and improved when useful, but they do not block Review.
106
106
 
107
107
  Deck plan report format:
108
108
  - Start with \`Deck plan: awaiting confirmation\` when a plan was compiled and has not yet been confirmed.
@@ -141,7 +141,7 @@ Report format before any HTML write after confirmation:
141
141
  - Include which user-confirmed plan, approved narrative hash, and deck review snapshot authorized the artifact work.
142
142
  - Include the chapter currently being generated and confirm already-written slides are being preserved.
143
143
  - If deck/artifact review is blocked, list blockers separately from narrative blockers.
144
- - After writing HTML, read the appended \`Artifact QA\` report from the tool output. If it failed, fix hard errors before considering the deck ready for Refine.
144
+ - After writing HTML, read the appended \`Artifact QA\` report from the tool output. If it failed, fix hard errors before considering the deck ready for Review.
145
145
 
146
146
  Rules:
147
147
  - \`compileDeckPlan\` is the canonical narrative-to-deck planning path. Do not manually invent slide specs to avoid it.
@@ -205,7 +205,7 @@ Workflow:
205
205
  8. For substantial decision decks, preserve a compact \`narrativeBrief\` through \`upsertDeck\` when the conversation or confirmed plan supports it. Do not invent stakeholder beliefs, objections, or risks; leave gaps visible if unknown.
206
206
  9. For substantial decision decks, launch the Task subagent with \`subagent_type: "revela-narrative-reviewer"\` after deck/slides are up to date. Ask it to read the current \`DECKS.json\`, run only its fixed rubric, use stable finding IDs, return \`Findings: none\` when all checks pass, and avoid optional pre-write improvements. Do not ask it to write state, call \`revela-decks review\`, or produce HTML.
207
207
  10. Call \`revela-decks\` action \`review\`. The tool computes and writes \`writeReadiness\` plus structured readiness issues for the current workspace deck.
208
- 11. Briefly report whether the deck is ready. If blocked, list the exact blockers returned by the tool. If warnings exist, list them after blockers as residual risks; separate evidence/source warnings from narrative warnings when possible. If the review result includes \`evidenceCandidates\`, add a separate \`Candidate evidence bindings\` section with candidateId, slide index/title, supported claim scope, sourceKind, findingsFile/sourcePath, quote/snippet, caveat, evidenceDraft summary, unsupportedScope, and recommendedRewrite. Tell the user they may explicitly ask to apply selected candidate IDs; do not apply them during review. If candidates are absent but \`evidenceCandidateSearch\` is present, briefly report searched file counts and the best near misses so the user can tell whether review failed to search or searched but did not find a bindable match. If the reviewer returned findings, include them in a separate \`Narrative reviewer notes\` section and label them advisory.
208
+ 11. Briefly report whether the deck is ready. If blocked, list the exact blockers returned by the tool. If warnings exist, list them after blockers as residual risks; separate evidence/source warnings from narrative warnings when possible. If the review result includes \`diagnostics\`, include a \`Plan and coverage diagnostics\` section with plan quality blockers/warnings, artifact \`coverageStatus\`, \`missingClaimIds\`, \`affectedClaimIds\`, stale reasons, and \`nextActions\`. If the review result includes \`evidenceCandidates\`, add a separate \`Candidate evidence bindings\` section with candidateId, slide index/title, supported claim scope, sourceKind, findingsFile/sourcePath, quote/snippet, caveat, evidenceDraft summary, unsupportedScope, and recommendedRewrite. Tell the user they may explicitly ask to apply selected candidate IDs; do not apply them during review. If candidates are absent but \`evidenceCandidateSearch\` is present, briefly report searched file counts and the best near misses so the user can tell whether review failed to search or searched but did not find a bindable match. If the reviewer returned findings, include them in a separate \`Narrative reviewer notes\` section and label them advisory.
209
209
 
210
210
  Minimum conditions for \`ready\`:
211
211
  - Topic, audience, slide count, language, and visual style/design are decided.
@@ -225,6 +225,7 @@ Report format:
225
225
  - Start with \`Ready: yes/no\`.
226
226
  - If blocked, list each blocker with slide index/title when the tool provides it, the issue type, and the suggested next action.
227
227
  - If warnings exist but the deck is otherwise ready, say the deck can be written but note the residual risks.
228
+ - Include coverage-driven make diagnostics when returned: whether the active deck artifact coverage is current/stale/partial/missing, which required claims are missing, which claims are affected, and the next command/action recommended by the tool.
228
229
  - Report \`narrative_gap\` warnings as story-structure risks such as weak so-what, missing risk/assumption handling, conclusion before support, missing audience framing, or abrupt transition.
229
230
  - Do not invent evidence or silently downgrade blockers. Use the tool result as authoritative.
230
231
  - Do not convert \`revela-narrative-reviewer\` advisory findings into tool readiness issues. Keep them separate from \`revela-decks review\` blockers and warnings, and preserve the reviewer's stable finding IDs when reporting them.
@@ -8,7 +8,7 @@ import {
8
8
  workspaceStatePath,
9
9
  writeWorkspaceState,
10
10
  } from "./workspace-state/repository"
11
- import { ensureActiveHtmlDeckRenderTarget } from "./workspace-state/render-targets"
11
+ import { activeHtmlDeckRenderTarget, ensureActiveHtmlDeckRenderTarget } from "./workspace-state/render-targets"
12
12
  import {
13
13
  activeReviewTargetId,
14
14
  appendReviewSnapshot,
@@ -19,6 +19,7 @@ import {
19
19
  import { WORKSPACE_STATE_FILE, type RenderTarget, type ReviewSnapshot, type WorkspaceAction } from "./workspace-state/types"
20
20
  import { normalizeCanonicalNarrativeState, normalizeNarrativeState } from "./narrative-state/normalize"
21
21
  import { computeNarrativeHash } from "./narrative-state/hash"
22
+ import { getArtifactClaimRefs } from "./narrative-state/queries"
22
23
  import type { NarrativeStateV1 } from "./narrative-state/types"
23
24
 
24
25
  export const DECKS_STATE_FILE = WORKSPACE_STATE_FILE
@@ -107,6 +108,13 @@ export interface DeckPlanReview {
107
108
  confirmedAt?: string
108
109
  confirmedBy?: "user"
109
110
  summary?: string
111
+ qualityChecks?: DeckPlanQualityCheck[]
112
+ }
113
+
114
+ export interface DeckPlanQualityCheck {
115
+ id: string
116
+ status: "pass" | "warning" | "blocker"
117
+ message: string
110
118
  }
111
119
 
112
120
  export interface NarrativeBrief {
@@ -206,6 +214,24 @@ export interface DeckStateReadinessResult {
206
214
  warnings: string[]
207
215
  issues: ReadinessIssue[]
208
216
  evidenceCandidates?: EvidenceBindingCandidate[]
217
+ diagnostics?: DeckReadinessDiagnostics
218
+ }
219
+
220
+ export interface DeckReadinessDiagnostics {
221
+ planQuality: DeckPlanQualityCheck[]
222
+ artifactCoverage?: ArtifactCoverageDiagnostic
223
+ nextActions: string[]
224
+ }
225
+
226
+ export interface ArtifactCoverageDiagnostic {
227
+ artifactId?: string
228
+ outputPath?: string
229
+ coverageStatus: "current" | "stale" | "partial" | "missing" | "unknown"
230
+ requiredClaimIds: string[]
231
+ coveredClaimIds: string[]
232
+ missingClaimIds: string[]
233
+ affectedClaimIds: string[]
234
+ staleReasons: string[]
209
235
  }
210
236
 
211
237
  export type ReadinessSeverity = "blocker" | "warning"
@@ -214,6 +240,8 @@ export type ReadinessIssueType =
214
240
  | "missing_required_input"
215
241
  | "missing_slide_spec"
216
242
  | "slide_plan_unconfirmed"
243
+ | "plan_quality"
244
+ | "artifact_coverage"
217
245
  | "research_not_ready"
218
246
  | "missing_evidence"
219
247
  | "weak_evidence"
@@ -444,6 +472,7 @@ export function confirmDeckPlan(state: DecksState, options: ConfirmDeckPlanOptio
444
472
  confirmedAt: options.now ?? new Date().toISOString(),
445
473
  confirmedBy: options.approvedBy ?? "user",
446
474
  summary: cleanOptionalText(options.note),
475
+ qualityChecks: pending?.qualityChecks,
447
476
  }
448
477
  deck.requiredInputs = { ...deck.requiredInputs, slidePlanConfirmed: true }
449
478
  deck.writeReadiness = { status: "blocked", blockers: [] }
@@ -579,7 +608,7 @@ export function reviewDeckState(state: DecksState, slug?: string, options: Revie
579
608
  }
580
609
  }
581
610
 
582
- const issues = computeDeckReadinessIssues(deck, normalized.workspace, {
611
+ const issues = computeDeckReadinessIssues(normalized, deck, {
583
612
  ...options,
584
613
  narrativeHash: options.narrativeHash ?? computeNarrativeHash(normalizeNarrativeState(normalized)),
585
614
  })
@@ -604,6 +633,7 @@ export function reviewDeckState(state: DecksState, slug?: string, options: Revie
604
633
  warnings,
605
634
  issues,
606
635
  evidenceCandidates,
636
+ diagnostics: deckReadinessDiagnostics(normalized, deck, issues),
607
637
  }
608
638
  appendReviewSnapshot(normalized, createReviewSnapshot(normalized, { slug: deck.slug, result, reviewedAt }))
609
639
  return {
@@ -639,7 +669,7 @@ export function evaluateDeckStateWriteReadiness(state: DecksState, filePath: str
639
669
  }
640
670
  }
641
671
 
642
- const issues = computeDeckReadinessIssues(deck, normalized.workspace, {
672
+ const issues = computeDeckReadinessIssues(normalized, deck, {
643
673
  narrativeHash: computeNarrativeHash(normalizeNarrativeState(normalized)),
644
674
  })
645
675
  const blockers = issues.filter((issue) => issue.severity === "blocker").map((issue) => issue.message)
@@ -715,6 +745,7 @@ export function evaluateDeckStateWriteReadiness(state: DecksState, filePath: str
715
745
  blockers,
716
746
  warnings,
717
747
  issues,
748
+ diagnostics: deckReadinessDiagnostics(normalized, deck, issues),
718
749
  }
719
750
  }
720
751
 
@@ -871,9 +902,23 @@ function normalizeDeckPlanReview(input: DeckPlanReview | undefined): DeckPlanRev
871
902
  confirmedAt: cleanOptionalText(input.confirmedAt),
872
903
  confirmedBy: input.confirmedBy === "user" ? "user" : undefined,
873
904
  summary: cleanOptionalText(input.summary),
905
+ qualityChecks: normalizeDeckPlanQualityChecks(input.qualityChecks),
874
906
  }
875
907
  }
876
908
 
909
+ function normalizeDeckPlanQualityChecks(input: DeckPlanQualityCheck[] | undefined): DeckPlanQualityCheck[] | undefined {
910
+ if (!Array.isArray(input)) return undefined
911
+ const checks = input.flatMap((item): DeckPlanQualityCheck[] => {
912
+ if (!item || typeof item !== "object") return []
913
+ const id = cleanOptionalText(item.id)
914
+ const message = cleanOptionalText(item.message)
915
+ if (!id || !message) return []
916
+ const status = item.status === "blocker" || item.status === "warning" ? item.status : "pass"
917
+ return [{ id, status, message }]
918
+ })
919
+ return checks.length > 0 ? checks : undefined
920
+ }
921
+
877
922
  function currentDeckKey(state: DecksState): string | undefined {
878
923
  if (state.activeDeck && state.decks[state.activeDeck]) return state.activeDeck
879
924
  const keys = Object.keys(state.decks)
@@ -887,8 +932,9 @@ function currentDeckBlocker(state: DecksState): string {
887
932
  return `${DECKS_STATE_FILE} contains multiple deck records and no activeDeck. Select one current deck explicitly or move extra decks to separate workspaces.`
888
933
  }
889
934
 
890
- function computeDeckReadinessIssues(deck: DeckSpec, workspace: DecksState["workspace"], options: ReviewDeckStateOptions = {}): ReadinessIssue[] {
935
+ function computeDeckReadinessIssues(state: DecksState, deck: DeckSpec, options: ReviewDeckStateOptions = {}): ReadinessIssue[] {
891
936
  const issues: ReadinessIssue[] = []
937
+ const workspace = state.workspace
892
938
  if (!deck.goal.trim()) issues.push(blockerIssue("missing_slide_spec", "Deck goal is missing", "Set the deck goal through revela-decks upsertDeck."))
893
939
  if (!isDeckHtmlPath(deck.outputPath)) {
894
940
  issues.push(blockerIssue(
@@ -919,6 +965,8 @@ function computeDeckReadinessIssues(deck: DeckSpec, workspace: DecksState["works
919
965
  ))
920
966
  }
921
967
  }
968
+ issues.push(...deckPlanQualityIssues(deck))
969
+ issues.push(...artifactCoverageIssues(state, deck))
922
970
  for (const slide of deck.slides) {
923
971
  const slideRef = { slideIndex: slide.index, slideTitle: slide.title }
924
972
  if (!slide.title.trim()) issues.push(blockerIssue("missing_slide_spec", `Slide ${slide.index} title is missing`, "Add a slide title to the slide spec.", slideRef))
@@ -985,6 +1033,96 @@ function computeDeckReadinessIssues(deck: DeckSpec, workspace: DecksState["works
985
1033
  return issues
986
1034
  }
987
1035
 
1036
+ function deckPlanQualityIssues(deck: DeckSpec): ReadinessIssue[] {
1037
+ const checks = deck.planReview?.qualityChecks ?? []
1038
+ return checks.flatMap((check): ReadinessIssue[] => {
1039
+ if (check.status === "pass") return []
1040
+ const suggestedAction = check.status === "blocker"
1041
+ ? "Re-run compileDeckPlan or revise the deck projection so the deterministic plan includes Cover, TOC, central claim coverage, compatible components, and Closing/Decision Ask before confirming or writing the deck."
1042
+ : "Keep the stated claim boundaries visible in the plan and rendered artifact; do not stretch partial evidence beyond the supported scope."
1043
+ return [{
1044
+ type: "plan_quality",
1045
+ severity: check.status,
1046
+ message: check.message,
1047
+ suggestedAction,
1048
+ }]
1049
+ })
1050
+ }
1051
+
1052
+ function artifactCoverageIssues(state: DecksState, deck: DeckSpec): ReadinessIssue[] {
1053
+ const coverage = artifactCoverageDiagnostic(state, deck)
1054
+ if (!coverage) return []
1055
+ const issues: ReadinessIssue[] = []
1056
+ if (coverage.missingClaimIds.length > 0) {
1057
+ issues.push(blockerIssue(
1058
+ "artifact_coverage",
1059
+ `Active deck plan is missing required narrative claims: ${coverage.missingClaimIds.join(", ")}`,
1060
+ "Re-run compileDeckPlan or revise the deck projection so every central or evidence-required claim appears in the planned slides before writing the deck.",
1061
+ ))
1062
+ }
1063
+ if (coverage.coverageStatus === "stale") {
1064
+ issues.push(blockerIssue(
1065
+ "artifact_coverage",
1066
+ `Active deck artifact coverage is stale: ${coverage.staleReasons.join("; ") || "narrative or render target changed"}`,
1067
+ "Re-run /revela make --deck so the deck plan and artifact coverage are regenerated from the current approved narrative state.",
1068
+ ))
1069
+ } else if (coverage.coverageStatus === "partial") {
1070
+ issues.push(warningIssue(
1071
+ "artifact_coverage",
1072
+ `Active deck artifact coverage is partial: ${coverage.affectedClaimIds.join(", ") || "some claims are not fully mapped"}`,
1073
+ "Keep the partial coverage visible in the make report and review the affected claims before exporting or presenting the deck.",
1074
+ ))
1075
+ }
1076
+ return issues
1077
+ }
1078
+
1079
+ function deckReadinessDiagnostics(state: DecksState, deck: DeckSpec, issues: ReadinessIssue[]): DeckReadinessDiagnostics {
1080
+ const planQuality = deck.planReview?.qualityChecks ?? []
1081
+ const artifactCoverage = artifactCoverageDiagnostic(state, deck)
1082
+ return {
1083
+ planQuality,
1084
+ ...(artifactCoverage ? { artifactCoverage } : {}),
1085
+ nextActions: readinessNextActions(issues, artifactCoverage),
1086
+ }
1087
+ }
1088
+
1089
+ function artifactCoverageDiagnostic(state: DecksState, deck: DeckSpec): ArtifactCoverageDiagnostic | undefined {
1090
+ const target = activeHtmlDeckRenderTarget(state)
1091
+ const artifact = getArtifactClaimRefs(state).find((item) => item.type === "html_deck" && normalizeDeckPath(item.outputPath ?? "") === normalizeDeckPath(deck.outputPath))
1092
+ const data = target?.data ?? {}
1093
+ const requiredClaimIds = stringArray(data.requiredClaimIds)
1094
+ const coveredClaimIds = stringArray(data.coveredClaimIds)
1095
+ const missingClaimIds = [...new Set([...(artifact?.missingClaimIds ?? []), ...stringArray(data.missingClaimIds)])].sort()
1096
+ const affectedClaimIds = [...new Set([...(artifact?.affectedClaimIds ?? []), ...missingClaimIds])].sort()
1097
+ const staleReasons = artifact?.staleReasons ?? []
1098
+ const coverageStatus = artifact?.coverageStatus ?? (target ? (missingClaimIds.length > 0 ? "missing" : "current") : "unknown")
1099
+ if (!target && !artifact && requiredClaimIds.length === 0 && coveredClaimIds.length === 0 && missingClaimIds.length === 0) return undefined
1100
+ return {
1101
+ artifactId: artifact?.artifactId ?? target?.id,
1102
+ outputPath: artifact?.outputPath ?? target?.outputPath ?? deck.outputPath,
1103
+ coverageStatus,
1104
+ requiredClaimIds: [...new Set([...(artifact?.claimIds ?? []), ...requiredClaimIds, ...missingClaimIds])].filter((id) => requiredClaimIds.length === 0 || requiredClaimIds.includes(id) || missingClaimIds.includes(id)).sort(),
1105
+ coveredClaimIds: [...new Set([...(artifact?.claimIds ?? []), ...coveredClaimIds])].filter((id) => missingClaimIds.length === 0 || !missingClaimIds.includes(id)).sort(),
1106
+ missingClaimIds,
1107
+ affectedClaimIds,
1108
+ staleReasons,
1109
+ }
1110
+ }
1111
+
1112
+ function readinessNextActions(issues: ReadinessIssue[], coverage?: ArtifactCoverageDiagnostic): string[] {
1113
+ const actions = issues
1114
+ .filter((issue) => issue.severity === "blocker" || issue.type === "plan_quality" || issue.type === "artifact_coverage")
1115
+ .map((issue) => issue.suggestedAction)
1116
+ if (coverage?.missingClaimIds.length) actions.unshift("Review missingClaimIds in artifactCoverage and recompile the deterministic deck plan before writing HTML.")
1117
+ if (coverage?.coverageStatus === "stale") actions.unshift("Regenerate the deck plan from the current narrative before writing or exporting artifacts.")
1118
+ return [...new Set(actions)].slice(0, 5)
1119
+ }
1120
+
1121
+ function stringArray(value: unknown): string[] {
1122
+ if (!Array.isArray(value)) return []
1123
+ return [...new Set(value.filter((item): item is string => typeof item === "string" && item.trim().length > 0).map((item) => item.trim()))].sort()
1124
+ }
1125
+
988
1126
  function findEvidenceBindingCandidates(deck: DeckSpec, slide: SlideSpec, claimText: string, options: ReviewDeckStateOptions): { candidates: EvidenceBindingCandidate[]; search?: EvidenceCandidateSearchDiagnostic } {
989
1127
  if (!options.workspaceRoot) return { candidates: [] }
990
1128
  const queryText = slideSearchText(slide)
@@ -84,7 +84,7 @@ function inferSlides(filePath: string): SlideSpec[] {
84
84
  evidence: [],
85
85
  visuals: [],
86
86
  status: "ready",
87
- notes: "Inferred automatically by /revela refine --deck preflight.",
87
+ notes: "Inferred automatically by /revela review --deck preflight.",
88
88
  }
89
89
  })
90
90
  }
@@ -12,7 +12,7 @@ export interface EditableDeck {
12
12
 
13
13
  export function resolveEditableDeck(workspaceRoot: string, input = ""): EditableDeck {
14
14
  if (input.trim()) {
15
- throw new Error("/revela refine --deck does not accept a target. It opens the active HTML deck or the only HTML deck in decks/.")
15
+ throw new Error("/revela review --deck does not accept a target. It opens the active HTML deck or the only HTML deck in decks/.")
16
16
  }
17
17
 
18
18
  if (hasDecksState(workspaceRoot)) {
@@ -484,7 +484,7 @@ export function renderInspectorShell(token: string): string {
484
484
  <aside>
485
485
  <div>
486
486
  <h1>Evidence Inspector</h1>
487
- <p class="hint">Cmd/Ctrl-click slide elements to attach them as references in /revela refine --deck. Then click <b>Inspect Selection</b>. This is not chat.</p>
487
+ <p class="hint">Cmd/Ctrl-click slide elements to attach them as references in /revela review --deck. Then click <b>Get Insight</b>. This is not chat.</p>
488
488
  </div>
489
489
  <div id="selection" class="selection">
490
490
  <strong>Selection</strong>
@@ -632,7 +632,7 @@ export function renderInspectorShell(token: string): string {
632
632
  if (bindAttempts >= 80) {
633
633
  clearInterval(bindTimer);
634
634
  bindTimer = 0;
635
- setBindingStatus('error', 'Selection binding timed out. Reopen /revela refine --deck or reload this page.');
635
+ setBindingStatus('error', 'Selection binding timed out. Reopen /revela review --deck or reload this page.');
636
636
  }
637
637
  }, 150);
638
638
  }