@cyber-dash-tech/revela 0.15.3 → 0.15.4
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 +15 -15
- package/README.zh-CN.md +15 -15
- package/lib/commands/edit.ts +1 -1
- package/lib/commands/help.ts +2 -2
- package/lib/commands/inspect.ts +1 -1
- package/lib/commands/refine.ts +3 -3
- package/lib/commands/review.ts +2 -2
- package/lib/edit/deck-state.ts +1 -1
- package/lib/edit/resolve-deck.ts +1 -1
- package/lib/inspect/server.ts +2 -2
- package/lib/refine/server.ts +50 -33
- package/package.json +1 -1
- package/plugin.ts +10 -1
- package/skill/NARRATIVE_SKILL.md +5 -5
- package/skill/SKILL.md +2 -2
- package/tools/edit.ts +6 -6
- package/tools/inspection-result.ts +1 -1
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
|
|
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
|
|
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 ->
|
|
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
|
|
199
|
-
9. Use `/revela
|
|
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
|
|
564
|
+
/revela review --deck
|
|
565
565
|
```
|
|
566
566
|
|
|
567
|
-
`/revela
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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,里面有 Comment 和 Insight 两个 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 ->
|
|
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
|
|
197
|
-
9. post-artifact 修改统一使用 `/revela
|
|
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
|
|
530
|
+
/revela review --deck
|
|
531
531
|
```
|
|
532
532
|
|
|
533
|
-
`/revela
|
|
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
|
|
541
|
+
`/revela edit` 已移除。请使用 `/revela review --deck` 打开统一的阅读、洞察和评论 workspace。
|
|
542
542
|
|
|
543
|
-
使用 `Ctrl`/`Cmd` + 点击 deck 元素来引用它们,在
|
|
543
|
+
使用 `Ctrl`/`Cmd` + 点击 deck 元素来引用它们,在 Comment tab 写一段自然语言评论,然后发送回 OpenCode。Revela 会把 deck 文件、slide 上下文、选中元素 metadata 和你的评论整理成结构化 edit prompt。
|
|
544
544
|
|
|
545
|
-
对应的 LLM tool:`revela-edit`,不需要 target。这个 tool 仍作为兼容入口保留,当你说“我要编辑这个 deck”时,agent 会打开
|
|
545
|
+
对应的 LLM tool:`revela-edit`,不需要 target。这个 tool 仍作为兼容入口保留,当你说“我要编辑这个 deck”时,agent 会打开 Review 的 Comment mode。
|
|
546
546
|
|
|
547
|
-
对于已有 HTML deck,`/revela
|
|
547
|
+
对于已有 HTML deck,`/revela review --deck` 会自动准备必要的最小项目上下文,让后续精准修改仍然经过正常安全检查。
|
|
548
548
|
|
|
549
549
|
---
|
|
550
550
|
|
|
551
551
|
## Evidence Inspector
|
|
552
552
|
|
|
553
|
-
用 `/revela
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
package/lib/commands/edit.ts
CHANGED
|
@@ -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
|
|
6
|
+
await send("`/revela edit` has been removed. Use `/revela review --deck` and the Comment tab for the unified deck review workspace.")
|
|
7
7
|
}
|
package/lib/commands/help.ts
CHANGED
|
@@ -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. \`
|
|
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
|
|
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` +
|
package/lib/commands/inspect.ts
CHANGED
|
@@ -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
|
|
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
|
}
|
package/lib/commands/refine.ts
CHANGED
|
@@ -14,13 +14,13 @@ export async function handleRefine(
|
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
await send(
|
|
17
|
-
`Opened Revela
|
|
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
|
|
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(`**
|
|
24
|
+
await send(`**Review failed:** ${e.message || String(e)}`)
|
|
25
25
|
}
|
|
26
26
|
}
|
package/lib/commands/review.ts
CHANGED
|
@@ -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
|
|
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
|
|
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.
|
package/lib/edit/deck-state.ts
CHANGED
|
@@ -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
|
|
87
|
+
notes: "Inferred automatically by /revela review --deck preflight.",
|
|
88
88
|
}
|
|
89
89
|
})
|
|
90
90
|
}
|
package/lib/edit/resolve-deck.ts
CHANGED
|
@@ -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
|
|
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)) {
|
package/lib/inspect/server.ts
CHANGED
|
@@ -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
|
|
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
|
|
635
|
+
setBindingStatus('error', 'Selection binding timed out. Reopen /revela review --deck or reload this page.');
|
|
636
636
|
}
|
|
637
637
|
}, 150);
|
|
638
638
|
}
|
package/lib/refine/server.ts
CHANGED
|
@@ -247,7 +247,7 @@ async function handleAssetSave(req: Request, session: EditSession): Promise<Resp
|
|
|
247
247
|
id: body?.id || candidate.candidateId,
|
|
248
248
|
type: "image",
|
|
249
249
|
purpose,
|
|
250
|
-
brief: body?.brief || `Saved from ${candidate.provider} for
|
|
250
|
+
brief: body?.brief || `Saved from ${candidate.provider} for Review asset placement.`,
|
|
251
251
|
status: "success",
|
|
252
252
|
sourceUrl: candidate.imageUrl,
|
|
253
253
|
alt: body?.alt || candidate.alt || candidate.title,
|
|
@@ -652,7 +652,7 @@ function handleInspectResult(requestId: string | null, session: EditSession): Re
|
|
|
652
652
|
session.lastActiveAt = Date.now()
|
|
653
653
|
scheduleIdleStop()
|
|
654
654
|
if (request.status === "completed") return jsonResponse({ ok: true, requestId, status: request.status, deckVersion: request.deckVersion, result: request.result })
|
|
655
|
-
if (request.status === "failed" || request.status === "expired") return jsonResponse({ ok: true, requestId, status: request.status, deckVersion: request.deckVersion, error: request.error || "
|
|
655
|
+
if (request.status === "failed" || request.status === "expired") return jsonResponse({ ok: true, requestId, status: request.status, deckVersion: request.deckVersion, error: request.error || "Insight failed" })
|
|
656
656
|
return jsonResponse({ ok: true, requestId, status: request.status, deckVersion: request.deckVersion })
|
|
657
657
|
}
|
|
658
658
|
|
|
@@ -764,7 +764,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
764
764
|
<head>
|
|
765
765
|
<meta charset="utf-8" />
|
|
766
766
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
767
|
-
<title>Revela
|
|
767
|
+
<title>Revela Review</title>
|
|
768
768
|
<style>
|
|
769
769
|
:root { color-scheme: light; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
|
|
770
770
|
* { box-sizing: border-box; }
|
|
@@ -783,15 +783,16 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
783
783
|
.deck-nav button:hover:not(:disabled) { background: rgba(255,255,255,.22); }
|
|
784
784
|
.deck-nav button:disabled { opacity: .38; }
|
|
785
785
|
.deck-nav-status { min-width: 76px; color: #e2e8f0; font-size: 12px; font-weight: 900; text-align: center; font-variant-numeric: tabular-nums; }
|
|
786
|
-
aside { position: relative; display: flex; flex-direction: column; gap: 16px; padding: 20px; background: linear-gradient(180deg, #fbfaf7 0%, #f2eee6 100%); overflow: auto; border-left: 1px solid #d8d2c6; }
|
|
786
|
+
aside { position: relative; display: flex; flex-direction: column; gap: 16px; padding: 20px; background: linear-gradient(180deg, #fbfaf7 0%, #f2eee6 100%); overflow: auto; border-left: 1px solid #d8d2c6; font-family: Garamond, "Iowan Old Style", Georgia, serif; }
|
|
787
|
+
aside button, aside input, aside select, aside textarea, aside .comment-editor { font-family: inherit; }
|
|
787
788
|
h1 { margin: 0; font-size: 18px; line-height: 1.2; letter-spacing: -.01em; color: #0f172a; }
|
|
788
789
|
.wordmark { font-family: Garamond, "Iowan Old Style", Georgia, serif; font-size: 21px; letter-spacing: .08em; font-weight: 600; }
|
|
789
|
-
.hint { margin: 0; color: #756f66; font-size: 13px; line-height: 1.5; }
|
|
790
790
|
.panel { display: flex; flex-direction: column; gap: 10px; }
|
|
791
|
-
.tabs { display:
|
|
792
|
-
.tab { padding:
|
|
793
|
-
.tab
|
|
794
|
-
.tab
|
|
791
|
+
.tabs { display: flex; gap: 2px; padding: 0 0 0 8px; border-bottom: 1px solid #d8d2c6; background: transparent; }
|
|
792
|
+
.tab { width: auto; min-width: 112px; padding: 10px 18px; border: 1px solid transparent; border-bottom: 0; border-radius: 13px 13px 0 0; background: transparent; color: #5f594f; box-shadow: none; font-weight: 900; }
|
|
793
|
+
.tab:hover:not(:disabled) { background: rgba(255,253,248,.58); }
|
|
794
|
+
.tab.active { position: relative; top: 1px; background: #fbfaf7; border-color: #d8d2c6; color: #111827; box-shadow: 0 -7px 16px rgba(31,41,51,.05); }
|
|
795
|
+
.tab-panel { display: none; flex-direction: column; gap: 12px; padding-top: 12px; }
|
|
795
796
|
.tab-panel.active { display: flex; }
|
|
796
797
|
.sr-only { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0,0,0,0) !important; white-space: nowrap !important; border: 0 !important; }
|
|
797
798
|
.selection-summary { padding: 10px 12px; border: 1px solid #d8d2c6; border-radius: 14px; background: #fbfaf7; color: #3f3a33; font-size: 13px; line-height: 1.45; box-shadow: 0 8px 22px rgba(31,41,51,.05); }
|
|
@@ -885,20 +886,19 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
885
886
|
<div id="resizeHandle" class="resize-handle" role="separator" aria-label="Resize editor panel" aria-orientation="vertical" title="Drag to resize editor. Double-click to reset."></div>
|
|
886
887
|
<aside>
|
|
887
888
|
<div>
|
|
888
|
-
<h1><span class="wordmark">REVELA</span>
|
|
889
|
-
<p class="hint">Select refs, describe the change, then send. Use Inspect only when you need source or purpose context.</p>
|
|
889
|
+
<h1><span class="wordmark">REVELA</span> Review</h1>
|
|
890
890
|
</div>
|
|
891
891
|
<div id="selectionSummary" class="selection-summary sr-only" aria-live="polite"><strong>Selection</strong><span>No references selected.</span><div id="selectionChips" class="selection-chips"></div></div>
|
|
892
|
-
<div class="tabs" role="tablist" aria-label="
|
|
893
|
-
<button id="editTab" class="tab" type="button" role="tab">
|
|
894
|
-
<button id="inspectTab" class="tab" type="button" role="tab">
|
|
892
|
+
<div class="tabs" role="tablist" aria-label="Review mode">
|
|
893
|
+
<button id="editTab" class="tab" type="button" role="tab">Comment</button>
|
|
894
|
+
<button id="inspectTab" class="tab" type="button" role="tab">Insight</button>
|
|
895
895
|
</div>
|
|
896
896
|
<div id="editPanel" class="tab-panel">
|
|
897
897
|
<div class="panel">
|
|
898
898
|
<div class="label">Describe the change</div>
|
|
899
899
|
<div id="comment" class="comment-editor" contenteditable="true" role="textbox" aria-multiline="true" data-placeholder="Cmd/Ctrl-click slide elements to add @refs, then describe the exact edit."></div>
|
|
900
900
|
</div>
|
|
901
|
-
<div class="edit-assets" aria-label="
|
|
901
|
+
<div class="edit-assets" aria-label="Comment assets">
|
|
902
902
|
<div class="panel">
|
|
903
903
|
<div class="asset-tools"><div class="label">Local Assets</div><button id="assetSearchToggle" class="asset-search-toggle" type="button" aria-expanded="false" aria-controls="assetSearchView" title="Search assets">+</button></div>
|
|
904
904
|
<div id="editSavedAssets" class="asset-grid"><p class="asset-empty">No local assets yet. Click + to search assets.</p></div>
|
|
@@ -909,20 +909,20 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
909
909
|
</div>
|
|
910
910
|
<div id="inspectPanel" class="tab-panel">
|
|
911
911
|
<div class="panel">
|
|
912
|
-
<label class="label" for="inspectComment">
|
|
912
|
+
<label class="label" for="inspectComment">Insight comment</label>
|
|
913
913
|
<div id="inspectComment" class="comment-editor" contenteditable="true" role="textbox" aria-multiline="true" data-placeholder="Cmd/Ctrl-click slide elements to add @refs, then ask about purpose or source."></div>
|
|
914
914
|
</div>
|
|
915
915
|
<div class="inspect-actions">
|
|
916
916
|
<div class="inspect-options"><label for="inspectLanguage">Display Language</label><select id="inspectLanguage" class="inspect-select"><option>Auto</option><option>English</option><option>简体中文</option><option>繁體中文</option><option>日本語</option><option>Deutsch</option><option>Français</option><option>Español</option><option>Português</option><option>Arabic</option></select></div>
|
|
917
|
-
<button id="inspectButton" disabled>
|
|
917
|
+
<button id="inspectButton" disabled>Get Insight</button>
|
|
918
918
|
<div id="inspectStale"></div>
|
|
919
919
|
</div>
|
|
920
|
-
<div id="inspectCards" class="inspect-cards"><div class="inspect-empty">Select a deck element to create an @ref, optionally ask a question, then
|
|
920
|
+
<div id="inspectCards" class="inspect-cards"><div class="inspect-empty">Select a deck element to create an @ref, optionally ask a question, then get insight. This does not edit the deck.</div></div>
|
|
921
921
|
</div>
|
|
922
922
|
<div id="assetSearchView" class="asset-search-view" aria-hidden="true">
|
|
923
923
|
<div class="asset-search-head">
|
|
924
924
|
<button id="assetSearchBack" class="asset-back" type="button">← Back</button>
|
|
925
|
-
<div class="asset-search-title"><h2>Search Assets</h2><span>Save images to Local Assets, then use them from
|
|
925
|
+
<div class="asset-search-title"><h2>Search Assets</h2><span>Save images to Local Assets, then use them from Comment.</span></div>
|
|
926
926
|
</div>
|
|
927
927
|
<div class="panel">
|
|
928
928
|
<div class="asset-search"><input id="assetQuery" type="search" placeholder="Company logo, product photo, portrait..." /><select id="assetPurpose"><option value="logo" selected>logo</option><option value="illustration">photo</option><option value="hero">hero</option><option value="portrait">portrait</option><option value="screenshot">screenshot</option></select></div>
|
|
@@ -1072,7 +1072,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
1072
1072
|
restoreEditorWidth();
|
|
1073
1073
|
bindEvents();
|
|
1074
1074
|
setMode(state.mode);
|
|
1075
|
-
setStatus('
|
|
1075
|
+
setStatus('Review ready. Ctrl/Cmd + click deck elements to reference them.');
|
|
1076
1076
|
initFrame();
|
|
1077
1077
|
loadSavedAssets();
|
|
1078
1078
|
startDeckVersionPolling();
|
|
@@ -1116,6 +1116,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
1116
1116
|
els.inspectComment.addEventListener('mouseup', saveCommentRange);
|
|
1117
1117
|
document.addEventListener('selectionchange', saveCommentRange);
|
|
1118
1118
|
els.hitbox.addEventListener('pointermove', onHover);
|
|
1119
|
+
els.hitbox.addEventListener('pointerleave', clearHoverSilently);
|
|
1119
1120
|
els.hitbox.addEventListener('pointerdown', onPointerDown);
|
|
1120
1121
|
els.hitbox.addEventListener('click', onClick);
|
|
1121
1122
|
els.hitbox.addEventListener('contextmenu', (event) => {
|
|
@@ -1263,7 +1264,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
1263
1264
|
state.pendingRefreshMessage = false;
|
|
1264
1265
|
setStatus('Deck updated. Preview refreshed. Element references were cleared.');
|
|
1265
1266
|
} else {
|
|
1266
|
-
setStatus(slides.length > 0 ? '
|
|
1267
|
+
setStatus(slides.length > 0 ? 'Review ready. Found ' + slides.length + ' slides. Ctrl/Cmd + click to reference elements.' : 'Review ready, but no .slide elements were found. Ctrl/Cmd + click to reference elements.');
|
|
1267
1268
|
}
|
|
1268
1269
|
} catch (error) {
|
|
1269
1270
|
reportError(error);
|
|
@@ -1336,9 +1337,11 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
1336
1337
|
} catch {}
|
|
1337
1338
|
}
|
|
1338
1339
|
if (!handled) applyFallbackDeckNavigation(win, doc, slides, clamped);
|
|
1340
|
+
const changed = clamped !== state.deckSlideIndex;
|
|
1339
1341
|
state.deckSlideIndex = clamped;
|
|
1340
1342
|
updateDeckNavControls();
|
|
1341
|
-
|
|
1343
|
+
if (changed) clearHoverSilently();
|
|
1344
|
+
else renderHoverOutline(state.hoverEl);
|
|
1342
1345
|
renderReferenceOutlines();
|
|
1343
1346
|
} catch (error) {
|
|
1344
1347
|
reportError(error);
|
|
@@ -1415,6 +1418,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
1415
1418
|
initFrame();
|
|
1416
1419
|
const target = selectable(targetFromPointer(event));
|
|
1417
1420
|
if (!target || isReferenced(target)) {
|
|
1421
|
+
state.hoverEl = null;
|
|
1418
1422
|
renderHoverOutline(null);
|
|
1419
1423
|
return;
|
|
1420
1424
|
}
|
|
@@ -1829,7 +1833,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
1829
1833
|
renderReferenceOutlines();
|
|
1830
1834
|
updateSendState();
|
|
1831
1835
|
renderSelectionSummary();
|
|
1832
|
-
resetInspectCards('References ready. Open
|
|
1836
|
+
resetInspectCards('References ready. Open Insight and click Get Insight for concise Purpose and Source context.');
|
|
1833
1837
|
setStatus('Inserted @' + label + '. ' + state.references.length + ' reference' + (state.references.length === 1 ? '' : 's') + ' will be sent.');
|
|
1834
1838
|
}
|
|
1835
1839
|
|
|
@@ -1997,14 +2001,27 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
1997
2001
|
function renderReferenceOutlines() {
|
|
1998
2002
|
const doc = els.frame.contentDocument;
|
|
1999
2003
|
if (!doc || doc.location.href === 'about:blank') return;
|
|
2004
|
+
const slides = getSlides(doc);
|
|
2005
|
+
const currentSlide = slides[state.deckSlideIndex];
|
|
2006
|
+
const explicitSlideIndex = Number(currentSlide?.getAttribute('data-slide-index'));
|
|
2007
|
+
const currentSlideIndex = Number.isFinite(explicitSlideIndex) && explicitSlideIndex > 0 ? explicitSlideIndex : state.deckSlideIndex + 1;
|
|
2000
2008
|
while (state.referenceOutlines.length < state.references.length) state.referenceOutlines.push(createOutline(doc, '#7aa6d8', 'rgba(122,166,216,.18)'));
|
|
2001
2009
|
state.referenceOutlines.forEach((outline, index) => {
|
|
2002
2010
|
const reference = state.references[index];
|
|
2003
2011
|
setOutlineColor(outline, reference?.color);
|
|
2012
|
+
if (!reference || reference.payload?.slideIndex !== currentSlideIndex) {
|
|
2013
|
+
renderBox(outline, null);
|
|
2014
|
+
return;
|
|
2015
|
+
}
|
|
2004
2016
|
renderBox(outline, reference?.target);
|
|
2005
2017
|
});
|
|
2006
2018
|
}
|
|
2007
2019
|
|
|
2020
|
+
function clearHoverSilently() {
|
|
2021
|
+
state.hoverEl = null;
|
|
2022
|
+
if (state.hoverOutline) state.hoverOutline.style.display = 'none';
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2008
2025
|
function clearHover() {
|
|
2009
2026
|
state.hoverEl = null;
|
|
2010
2027
|
setStatus('Hover cleared. Existing references are kept.');
|
|
@@ -2015,8 +2032,8 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
2015
2032
|
if (state.sendingEdit) setButtonLoading(els.send, true, 'Sending...');
|
|
2016
2033
|
else setButtonLoading(els.send, false, '<svg class="send-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94L14.7 6.3z"/></svg><span>Apply Fix</span>', true);
|
|
2017
2034
|
els.send.disabled = state.sendingEdit || !getCommentText().trim();
|
|
2018
|
-
if (state.inspecting) setButtonLoading(els.inspectButton, true, '
|
|
2019
|
-
else setButtonLoading(els.inspectButton, false, '
|
|
2035
|
+
if (state.inspecting) setButtonLoading(els.inspectButton, true, 'Getting insight...');
|
|
2036
|
+
else setButtonLoading(els.inspectButton, false, 'Get Insight');
|
|
2020
2037
|
els.inspectButton.disabled = state.inspecting || state.references.length === 0;
|
|
2021
2038
|
}
|
|
2022
2039
|
|
|
@@ -2077,7 +2094,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
2077
2094
|
body: JSON.stringify({ snapshot, deckVersion: state.deckVersion, language: state.inspectLanguage, comment }),
|
|
2078
2095
|
});
|
|
2079
2096
|
const body = await res.json().catch(() => ({}));
|
|
2080
|
-
if (!res.ok || !body.ok) throw new Error(body.error || '
|
|
2097
|
+
if (!res.ok || !body.ok) throw new Error(body.error || 'Insight failed');
|
|
2081
2098
|
state.deckVersion = body.deckVersion || state.deckVersion;
|
|
2082
2099
|
state.activeInspectRequestId = body.requestId;
|
|
2083
2100
|
state.inspectFallback = body.preprocess || null;
|
|
@@ -2086,7 +2103,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
2086
2103
|
} catch (error) {
|
|
2087
2104
|
if (state.inspectFallback) {
|
|
2088
2105
|
renderInspectResult(state.inspectFallback, 'Deterministic fallback');
|
|
2089
|
-
els.inspectCards.insertAdjacentHTML('afterbegin', '<div class="inspect-warning">Generated
|
|
2106
|
+
els.inspectCards.insertAdjacentHTML('afterbegin', '<div class="inspect-warning">Generated insight failed or timed out. Showing deterministic fallback context only.</div>');
|
|
2090
2107
|
} else {
|
|
2091
2108
|
resetInspectCards(error && error.message ? error.message : String(error));
|
|
2092
2109
|
}
|
|
@@ -2101,15 +2118,15 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
2101
2118
|
await delay(900);
|
|
2102
2119
|
const res = await fetch('/api/inspect-result?token=' + encodeURIComponent(token) + '&requestId=' + encodeURIComponent(requestId));
|
|
2103
2120
|
const body = await res.json().catch(() => ({}));
|
|
2104
|
-
if (!res.ok || !body.ok) throw new Error(body.error || '
|
|
2121
|
+
if (!res.ok || !body.ok) throw new Error(body.error || 'Insight result failed');
|
|
2105
2122
|
if (body.status === 'completed') {
|
|
2106
2123
|
state.deckVersion = body.deckVersion || state.deckVersion;
|
|
2107
2124
|
renderInspectResult(body.result, 'Generated');
|
|
2108
2125
|
return;
|
|
2109
2126
|
}
|
|
2110
|
-
if (body.status === 'failed' || body.status === 'expired') throw new Error(body.error || '
|
|
2127
|
+
if (body.status === 'failed' || body.status === 'expired') throw new Error(body.error || 'Insight failed');
|
|
2111
2128
|
}
|
|
2112
|
-
throw new Error('
|
|
2129
|
+
throw new Error('Insight timed out while waiting for OpenCode result');
|
|
2113
2130
|
}
|
|
2114
2131
|
|
|
2115
2132
|
function collectReferenceSnapshot() {
|
|
@@ -2136,10 +2153,10 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
2136
2153
|
}
|
|
2137
2154
|
|
|
2138
2155
|
function renderInspectResult(result, phase) {
|
|
2139
|
-
if (result.stale?.stale) els.inspectStale.innerHTML = '<div class="inspect-stale">' + escapeHtml(result.stale.reason || '
|
|
2156
|
+
if (result.stale?.stale) els.inspectStale.innerHTML = '<div class="inspect-stale">' + escapeHtml(result.stale.reason || 'Insight may be stale.') + '</div>';
|
|
2140
2157
|
else els.inspectStale.innerHTML = '';
|
|
2141
2158
|
els.inspectCards.innerHTML = [
|
|
2142
|
-
'<div class="status">' + escapeHtml(phase || '
|
|
2159
|
+
'<div class="status">' + escapeHtml(phase || 'Insight') + '</div>',
|
|
2143
2160
|
renderInspectCard('Purpose', result.cards.purpose.status, result.cards.purpose.rationale, renderPurpose(result.cards.purpose)),
|
|
2144
2161
|
renderInspectCard('Source', result.cards.source.status, result.cards.source.rationale, renderSource(result.cards.source)),
|
|
2145
2162
|
].join('');
|
|
@@ -2303,7 +2320,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
|
|
|
2303
2320
|
removeAssetChip();
|
|
2304
2321
|
}
|
|
2305
2322
|
renderSelectionSummary();
|
|
2306
|
-
resetInspectCards('Select a deck element to create an @ref, optionally ask a question, then
|
|
2323
|
+
resetInspectCards('Select a deck element to create an @ref, optionally ask a question, then get insight. This does not edit the deck.');
|
|
2307
2324
|
}
|
|
2308
2325
|
|
|
2309
2326
|
function getCommentText(editor) {
|
package/package.json
CHANGED
package/plugin.ts
CHANGED
|
@@ -341,11 +341,20 @@ const server: Plugin = (async (pluginCtx) => {
|
|
|
341
341
|
await send("Usage: `/revela make --deck` or `/revela make --brief [workspace-relative-output.md]`.")
|
|
342
342
|
throw new Error("__REVELA_MAKE_USAGE_HANDLED__")
|
|
343
343
|
}
|
|
344
|
+
if (sub === "review") {
|
|
345
|
+
if (param !== "--deck") {
|
|
346
|
+
await send("Usage: `/revela review --deck`.")
|
|
347
|
+
throw new Error("__REVELA_REVIEW_USAGE_HANDLED__")
|
|
348
|
+
}
|
|
349
|
+
await handleRefine({ client, sessionID, workspaceRoot }, send)
|
|
350
|
+
throw new Error("__REVELA_REVIEW_HANDLED__")
|
|
351
|
+
}
|
|
344
352
|
if (sub === "refine") {
|
|
345
353
|
if (param !== "--deck") {
|
|
346
|
-
await send("Usage: `/revela
|
|
354
|
+
await send("Usage: `/revela review --deck`.")
|
|
347
355
|
throw new Error("__REVELA_REFINE_USAGE_HANDLED__")
|
|
348
356
|
}
|
|
357
|
+
await send("`/revela refine --deck` is deprecated. Use `/revela review --deck`.")
|
|
349
358
|
await handleRefine({ client, sessionID, workspaceRoot }, send)
|
|
350
359
|
throw new Error("__REVELA_REFINE_HANDLED__")
|
|
351
360
|
}
|
package/skill/NARRATIVE_SKILL.md
CHANGED
|
@@ -20,7 +20,7 @@ Use the same phase semantics whether the user invokes a slash command or asks in
|
|
|
20
20
|
- `Research` runs closed loops to fill open story gaps, bind supported findings into canonical evidence, narrow overbroad claims/relations, and reduce caveats without crossing evidence boundaries.
|
|
21
21
|
- `Story` opens the read-only story workspace UI for inspecting claim flow, evidence strength, unsupported scope, caveats, objections, risks, research gaps, approval state, and affected artifacts.
|
|
22
22
|
- `Make` renders an artifact from approved or explicitly overridden narrative state. Supported 0.15 targets are deck and executive brief.
|
|
23
|
-
- `
|
|
23
|
+
- `Review` is the post-artifact workspace for reading, insight, and targeted commenting. Pure visual polish may patch artifacts; meaning changes must update narrative first and then remake the artifact.
|
|
24
24
|
|
|
25
25
|
Public command surface:
|
|
26
26
|
|
|
@@ -29,7 +29,7 @@ Public command surface:
|
|
|
29
29
|
- `/revela story`
|
|
30
30
|
- `/revela make --deck`
|
|
31
31
|
- `/revela make --brief`
|
|
32
|
-
- `/revela
|
|
32
|
+
- `/revela review --deck`
|
|
33
33
|
- `/revela export --deck pdf`
|
|
34
34
|
- `/revela export --deck pptx`
|
|
35
35
|
- `/revela design`
|
|
@@ -115,14 +115,14 @@ For `/revela make --brief`, render the executive brief from canonical narrative
|
|
|
115
115
|
|
|
116
116
|
If story readiness, approval, evidence, or artifact blockers remain, report the blocker and suggest `/revela story`, `/revela research`, or a targeted user answer. Do not bypass with invented state.
|
|
117
117
|
|
|
118
|
-
##
|
|
118
|
+
## Review Rules
|
|
119
119
|
|
|
120
|
-
Use `/revela
|
|
120
|
+
Use `/revela review --deck` for post-artifact reading, insight, and commenting.
|
|
121
121
|
|
|
122
122
|
- Reading should explain source, support strength, caveat, unsupported scope, narrative purpose, related risks/objections, research gaps, and artifact coverage.
|
|
123
123
|
- Pure artifact polish may stay artifact-level: layout, typography, spacing, crop, visual hierarchy, export mechanics, and deck contract fixes.
|
|
124
124
|
- Meaning-changing edits must update canonical narrative first, then run story readiness/approval or explicit override, then remake affected artifacts.
|
|
125
|
-
- `/revela edit` and `/revela inspect` have been removed from the public surface; use `/revela
|
|
125
|
+
- `/revela edit` and `/revela inspect` have been removed from the public surface; use `/revela review --deck`.
|
|
126
126
|
|
|
127
127
|
## Design Surface
|
|
128
128
|
|
package/skill/SKILL.md
CHANGED
|
@@ -182,7 +182,7 @@ Required contract:
|
|
|
182
182
|
- All JS methods must be fully implemented. No empty stubs and no TODO comments.
|
|
183
183
|
- Do not add deck-local editing JavaScript, `contenteditable`, `editable` classes,
|
|
184
184
|
or `window.getEditedHTML()` implementations. Post-artifact editing belongs in
|
|
185
|
-
`/revela
|
|
185
|
+
`/revela review --deck`.
|
|
186
186
|
|
|
187
187
|
Example slide identity:
|
|
188
188
|
|
|
@@ -283,4 +283,4 @@ instructions, secrets, or unverified claims.
|
|
|
283
283
|
- Avoid text overflow, clipping, element overflow, unintended overlap, and page
|
|
284
284
|
scrollbars.
|
|
285
285
|
- Artifact QA hard errors must be fixed before opening or reporting the deck as
|
|
286
|
-
ready for
|
|
286
|
+
ready for Review.
|
package/tools/edit.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* tools/edit.ts
|
|
3
3
|
*
|
|
4
|
-
* revela-edit — Compatibility tool that opens Revela
|
|
4
|
+
* revela-edit — Compatibility tool that opens Revela Review in Comment mode.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { tool } from "@opencode-ai/plugin"
|
|
@@ -10,11 +10,11 @@ import { openRefineDeck } from "../lib/refine/open"
|
|
|
10
10
|
export function createEditTool(options: { client: any; workspaceRoot: string; openBrowser?: boolean }) {
|
|
11
11
|
return tool({
|
|
12
12
|
description:
|
|
13
|
-
"Open Revela
|
|
13
|
+
"Open Revela Review in Comment mode for an existing slide deck. " +
|
|
14
14
|
"Use this when the user asks to edit, revise, annotate, or visually comment on a deck, " +
|
|
15
15
|
"including when they reference the current deck. " +
|
|
16
|
-
"This is a compatibility tool for the older edit-only workflow; the user-facing entry is /revela
|
|
17
|
-
"It opens a local browser workspace where the user can Ctrl/Cmd-click deck elements, use the
|
|
16
|
+
"This is a compatibility tool for the older edit-only workflow; the user-facing entry is /revela review --deck. " +
|
|
17
|
+
"It opens a local browser workspace where the user can Ctrl/Cmd-click deck elements, use the Comment tab, " +
|
|
18
18
|
"and send precise edit requests back to the current OpenCode session.",
|
|
19
19
|
args: {},
|
|
20
20
|
async execute(_args, context: any) {
|
|
@@ -43,8 +43,8 @@ export function createEditTool(options: { client: any; workspaceRoot: string; op
|
|
|
43
43
|
url: result.url,
|
|
44
44
|
mode: result.mode,
|
|
45
45
|
message:
|
|
46
|
-
`${result.stateNote} Opened Revela
|
|
47
|
-
"Ask the user to use Ctrl/Cmd-click in the browser to reference elements, then use the
|
|
46
|
+
`${result.stateNote} Opened Revela Review in Comment mode. ` +
|
|
47
|
+
"Ask the user to use Ctrl/Cmd-click in the browser to reference elements, then use the Comment tab to send comments.",
|
|
48
48
|
}, null, 2)
|
|
49
49
|
} catch (error) {
|
|
50
50
|
return JSON.stringify({
|
|
@@ -15,7 +15,7 @@ const evidenceSourceItemSchema = tool.schema.object({
|
|
|
15
15
|
|
|
16
16
|
export default tool({
|
|
17
17
|
description:
|
|
18
|
-
"Submit the final structured Evidence Inspector result for a pending /revela
|
|
18
|
+
"Submit the final structured Evidence Inspector result for a pending /revela review --deck Insight request. " +
|
|
19
19
|
"Use only when responding to an inspection prompt. This updates the local browser inspector; it does not mutate DECKS.json or deck files.",
|
|
20
20
|
args: {
|
|
21
21
|
requestId: tool.schema.string().describe("Pending inspection request id from the inspection prompt."),
|