@cyber-dash-tech/revela 0.10.0 → 0.12.0

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.
Files changed (44) hide show
  1. package/README.md +54 -28
  2. package/README.zh-CN.md +54 -28
  3. package/lib/commands/designs.ts +2 -2
  4. package/lib/commands/domains.ts +2 -2
  5. package/lib/commands/enable.ts +19 -19
  6. package/lib/commands/help.ts +5 -3
  7. package/lib/commands/init.ts +30 -19
  8. package/lib/commands/inspect.ts +1 -1
  9. package/lib/commands/pdf.ts +33 -5
  10. package/lib/commands/pptx.ts +14 -9
  11. package/lib/commands/refine.ts +1 -1
  12. package/lib/commands/review.ts +115 -1
  13. package/lib/deck-html/contract.ts +252 -0
  14. package/lib/decks-state.ts +111 -28
  15. package/lib/document-materials/extract.ts +20 -0
  16. package/lib/edit/resolve-deck.ts +13 -2
  17. package/lib/inspect/open.ts +3 -1
  18. package/lib/narrative-state/hash.ts +52 -0
  19. package/lib/narrative-state/normalize.ts +307 -0
  20. package/lib/narrative-state/project-compat.ts +14 -0
  21. package/lib/narrative-state/readiness.ts +289 -0
  22. package/lib/narrative-state/render-plan.ts +207 -0
  23. package/lib/narrative-state/types.ts +139 -0
  24. package/lib/prompt-builder.ts +59 -26
  25. package/lib/qa/export-gate.ts +8 -1
  26. package/lib/refine/open.ts +3 -1
  27. package/lib/workspace-state/actions.ts +71 -0
  28. package/lib/workspace-state/compat.ts +10 -0
  29. package/lib/workspace-state/evidence-status.ts +267 -0
  30. package/lib/workspace-state/graph.ts +544 -0
  31. package/lib/workspace-state/render-targets.ts +182 -0
  32. package/lib/workspace-state/rendered-artifacts.ts +43 -0
  33. package/lib/workspace-state/repository.ts +43 -0
  34. package/lib/workspace-state/research-attachments.ts +130 -0
  35. package/lib/workspace-state/review-snapshots.ts +127 -0
  36. package/lib/workspace-state/types.ts +122 -0
  37. package/package.json +1 -1
  38. package/plugin.ts +53 -3
  39. package/skill/NARRATIVE_SKILL.md +64 -0
  40. package/tools/decks.ts +233 -6
  41. package/tools/pdf.ts +9 -1
  42. package/tools/pptx.ts +10 -0
  43. package/tools/research-save.ts +15 -0
  44. package/tools/workspace-scan.ts +29 -1
package/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  **English** | [中文](README.zh-CN.md)
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/@cyber-dash-tech/revela)](https://www.npmjs.com/package/@cyber-dash-tech/revela) [![license](https://img.shields.io/npm/l/@cyber-dash-tech/revela)](LICENSE) [![tests](https://img.shields.io/badge/tests-178%20passing-brightgreen)](tests/) [![OpenCode plugin](https://img.shields.io/badge/OpenCode-plugin-blue)](https://opencode.ai) [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.0-orange)](https://bun.sh)
5
+ [![npm version](https://img.shields.io/npm/v/@cyber-dash-tech/revela)](https://www.npmjs.com/package/@cyber-dash-tech/revela) [![license](https://img.shields.io/npm/l/@cyber-dash-tech/revela)](LICENSE) [![tests](https://img.shields.io/badge/tests-324%20passing-brightgreen)](tests/) [![OpenCode plugin](https://img.shields.io/badge/OpenCode-plugin-blue)](https://opencode.ai) [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.0-orange)](https://bun.sh)
6
6
 
7
7
  <p align="center">
8
8
  <img src="assets/img/logo.png" alt="Revela" width="800" />
9
9
  </p>
10
10
 
11
- Revela is an [OpenCode](https://opencode.ai) plugin that turns your current agent into an HTML slide deck generator.
12
- Enable it for the current session, assign a presentation task, and the agent can research, structure, write, QA, and export a deck.
11
+ Revela is an [OpenCode](https://opencode.ai) plugin for building trusted narrative artifacts from workspace sources, research, evidence, and user intent.
12
+ Its first render target is still the HTML slide deck: enable Revela for the current session, assign a presentation task, and the agent can research, structure, write, QA, inspect, refine, and export a deck.
13
13
 
14
14
  **[Live Demo — The AI Power Shift](https://cyber-dash-tech.github.io/revela/assets/html/ai-power-shift.html)**
15
15
 
@@ -17,11 +17,13 @@ Enable it for the current session, assign a presentation task, and the agent can
17
17
 
18
18
  ## What It Does
19
19
 
20
- - injects a presentation-specific system prompt into your current agent with `/revela enable`
21
- - builds that prompt from 3 layers: core skill, active domain, active design
20
+ - injects a narrative-first system prompt into your current agent with `/revela enable`
21
+ - switches into deck-render prompt mode only when you explicitly start `/revela deck`
22
22
  - supports workspace document discovery, transparent text extraction for `.pdf`, `.docx`, `.pptx`, and `.xlsx`, and cached embedded-material extraction for those formats
23
- - keeps track of deck context, slide structure, sources, and readiness across the current workspace
24
- - checks for missing context, weak evidence, and incomplete structure before writing `decks/*.html`
23
+ - keeps `DECKS.json` as the current workspace state engine for sources, research actions, findings, claims, evidence, narrative intent, render targets, and readiness
24
+ - reviews narrative readiness before artifact rendering, then separately gates deck HTML writes through deck/artifact readiness
25
+ - records review snapshots so stale readiness cannot silently authorize new deck HTML after important state changes
26
+ - treats HTML decks, PDF, and PPTX as render targets from shared workspace state rather than isolated output files
25
27
  - runs fast design compliance checks whenever the agent writes, patches, or edits `decks/*.html`
26
28
  - opens a visual comment editor for existing decks so users can Ctrl/Cmd-click elements and send precise edit requests back to OpenCode
27
29
  - exports finished decks to PDF and editable PPTX
@@ -103,16 +105,17 @@ Optionally switch design or domain:
103
105
  /revela domains deeptech-investment
104
106
  ```
105
107
 
106
- Then give the agent a deck task:
108
+ Then shape or review the narrative. When the narrative is ready and approved, start deck handoff:
107
109
 
108
110
  ```text
109
- Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main market drivers, use the active design faithfully, and save the result to decks/humanoid-robotics.html.
111
+ /revela review
112
+ /revela deck
110
113
  ```
111
114
 
112
- If the task depends on sources, research, or a confirmed slide plan, you can ask Revela to review whether the deck has enough context, structure, and evidence before writing:
115
+ If you need to check only the deck/artifact gate before HTML writing, use:
113
116
 
114
117
  ```text
115
- /revela review
118
+ /revela deck --review
116
119
  ```
117
120
 
118
121
  Export when needed, either manually or by asking the agent to export:
@@ -134,11 +137,13 @@ Disable presentation mode when done:
134
137
 
135
138
  ```text
136
139
  /revela show status and help
137
- /revela enable enable presentation mode for this session
138
- /revela disable disable presentation mode
140
+ /revela enable enable narrative/artifact mode for this session
141
+ /revela disable disable Revela mode
139
142
 
140
- /revela init prepare the workspace for a deck project
141
- /revela review check whether context, structure, and evidence are ready
143
+ /revela init initialize or refresh narrative workspace state
144
+ /revela review review narrative readiness and approval state
145
+ /revela deck start deck handoff from approved narrative
146
+ /revela deck --review review deck/artifact readiness before writing HTML
142
147
  /revela remember <text> save an explicit user/workflow preference
143
148
  /revela refine open unified Edit/Inspect refinement workspace
144
149
  /revela edit open visual editor for the only deck in decks/
@@ -161,7 +166,7 @@ Disable presentation mode when done:
161
166
  /revela pptx <file> export an HTML deck to editable PPTX in the same directory
162
167
  ```
163
168
 
164
- Most `/revela` commands run locally with zero LLM cost. `/revela init`, `/revela review`, `/revela remember`, `/revela designs-new`, and `/revela designs-edit` start AI-assisted workflows because they need to read or update project files. `/revela refine` 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 renders deterministic Source/Purpose preprocessing first before lazy LLM-generated cards arrive, has no chat box, and does not edit the deck.
169
+ Most `/revela` commands run locally with zero LLM cost. `/revela init`, `/revela review`, `/revela deck`, `/revela remember`, `/revela designs-new`, and `/revela designs-edit` start AI-assisted workflows because they need to read or update project files. `/revela refine` 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 renders deterministic Source/Purpose preprocessing first before lazy LLM-generated cards arrive, has no chat box, and does not edit the deck.
165
170
 
166
171
  ---
167
172
 
@@ -169,34 +174,53 @@ Most `/revela` commands run locally with zero LLM cost. `/revela init`, `/revela
169
174
 
170
175
  When Revela is enabled, it appends a generated prompt to the current agent's system prompt.
171
176
 
172
- That prompt is built from 3 layers:
177
+ The default prompt is narrative-first: it focuses on audience belief shift, decision/action, thesis, claims, evidence boundaries, objections, risks, and approval. Active design CSS, layout catalogs, component indexes, chart rules, and deck HTML skeletons are intentionally omitted until `/revela deck` switches the session into deck-render mode.
178
+
179
+ Deck-render mode is built from 3 layers:
173
180
 
174
- 1. `skill/SKILL.md` - the core slide-generation workflow
181
+ 1. `skill/SKILL.md` - the core deck-render workflow
175
182
  2. active domain - domain-specific report structure and terminology
176
183
  3. active design - visual system, layouts, components, and chart rules
177
184
 
178
185
  Persistent preferences live in `~/.config/revela/config.json`.
179
186
  The enabled or disabled state is session-level only.
180
187
 
188
+ ### Workspace State
189
+
190
+ `DECKS.json` is Revela's workspace state engine and compatibility file. It is still stored at the workspace root and remains readable as the current deck project state, but internally Revela now treats it as a lightweight persistence layer for more than a deck checklist.
191
+
192
+ The state records:
193
+
194
+ - workspace source materials and reusable extraction cache paths
195
+ - research plans, saved findings, and compact action provenance
196
+ - canonical narrative state, approvals, objections, risks, slide specs, claim candidates, and evidence trace
197
+ - render targets such as the active HTML deck plus derived PDF and PPTX artifacts
198
+ - review snapshots with input hashes so old readiness results become stale after meaningful state changes
199
+
200
+ Existing root `DECKS.json` workspaces remain compatible. Running `/revela init` or `/revela review` on an older project can normalize canonical narrative state and refresh projection fields without requiring a manual migration, moving files, or replacing `DECKS.json` with a database. `writeReadiness.status: "ready"` is deck/artifact readiness only; it is never narrative approval.
201
+
202
+ Decks remain the primary authored artifact, but they are now treated as render targets from the same workspace state that can later support briefs, appendix material, Evidence Inspector views, Q&A, and interactive reading layers without duplicating source/evidence logic.
203
+
181
204
  ---
182
205
 
183
206
  ## Recommended Workflow
184
207
 
185
- Use Revela as a guided deck-production mode:
208
+ Use Revela as a narrative-first artifact workflow:
186
209
 
187
210
  1. Enable Revela with `/revela enable`.
188
211
  2. Run `/revela init` when starting in a new project or when the workspace has changed significantly.
189
- 3. Choose a design or domain if the default style is not right.
190
- 4. Give the agent a clear deck task: audience, goal, language, number of slides, source requirements, and output path.
191
- 5. Use `/revela review` before writing if the deck needs research, citations, or a confirmed slide plan.
192
- 6. Let the agent write the HTML deck under `decks/`.
193
- 7. Use `/revela refine` for visual comments, targeted revisions, and optional Source/Purpose inspection of selected deck elements.
194
- 8. Use `/revela edit` or `/revela inspect` directly only if you need the older single-purpose shells.
195
- 9. Export with `/revela pdf <file>` or `/revela pptx <file>`.
212
+ 3. Use `/revela review` to check narrative readiness: audience, belief shift, decision/action, thesis, central claims, evidence, objections, risks, and approval state.
213
+ 4. Approve the narrative or request revisions. If you intentionally render before full strategic approval, record an explicit render override.
214
+ 5. Run `/revela deck` to compile the approved narrative into deck slide specs and enter deck-render mode.
215
+ 6. Choose or confirm design only during deck handoff, then run the deck/artifact gate with `/revela deck --review` or the handoff workflow.
216
+ 7. Let the agent write the HTML deck under `decks/` only after the artifact gate is ready.
217
+ 8. Use `/revela refine` for visual comments, targeted revisions, and optional Source/Purpose inspection of selected deck elements.
218
+ 9. Use `/revela edit` or `/revela inspect` directly only if you need the older single-purpose shells.
219
+ 10. Export with `/revela pdf <file>` or `/revela pptx <file>`.
196
220
 
197
- `/revela review` checks for practical readiness problems: unclear audience, missing source material, unfinished research, unsupported claims, weak source trace, incomplete slide structure, missing design/layout information, or lightweight narrative issues such as weak so-what, missing risk/assumption handling, and abrupt transitions. It does not write the final deck.
221
+ `/revela review` checks narrative readiness: 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 and does not write the final deck.
198
222
 
199
- If Revela blocks a deck write, ask the agent to run `/revela review`, resolve the reported gaps, and try again. This protects the deck file from being overwritten before the plan, evidence, and structure are ready.
223
+ If Revela blocks a deck write, ask the agent to run `/revela deck --review`, resolve the reported artifact gaps, and try again. This protects the deck file from being overwritten before the slide specs, evidence projection, design/layout readiness, review snapshot, and deck HTML contract are ready.
200
224
 
201
225
  To remember long-term preferences, use:
202
226
 
@@ -597,6 +621,8 @@ The inspector opens in your browser with the deck on the left and fixed cards on
597
621
 
598
622
  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. Deterministic preprocessing appears immediately; lazy LLM judgment then refines the Source and Purpose cards without inventing edits.
599
623
 
624
+ Inspection and refinement use 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 inspect/refine/export workflows trust them.
625
+
600
626
  ---
601
627
 
602
628
  ## Export
package/README.zh-CN.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  [English](README.md) | **中文**
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/@cyber-dash-tech/revela)](https://www.npmjs.com/package/@cyber-dash-tech/revela) [![license](https://img.shields.io/npm/l/@cyber-dash-tech/revela)](LICENSE) [![tests](https://img.shields.io/badge/tests-178%20passing-brightgreen)](tests/) [![OpenCode plugin](https://img.shields.io/badge/OpenCode-plugin-blue)](https://opencode.ai) [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.0-orange)](https://bun.sh)
5
+ [![npm version](https://img.shields.io/npm/v/@cyber-dash-tech/revela)](https://www.npmjs.com/package/@cyber-dash-tech/revela) [![license](https://img.shields.io/npm/l/@cyber-dash-tech/revela)](LICENSE) [![tests](https://img.shields.io/badge/tests-324%20passing-brightgreen)](tests/) [![OpenCode plugin](https://img.shields.io/badge/OpenCode-plugin-blue)](https://opencode.ai) [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.0-orange)](https://bun.sh)
6
6
 
7
7
  <p align="center">
8
8
  <img src="assets/img/logo.png" alt="Revela" width="800" />
9
9
  </p>
10
10
 
11
- Revela 是一个 [OpenCode](https://opencode.ai) 插件,可以把你当前使用的 agent 变成 HTML 幻灯片生成器。
12
- 在当前会话中启用之后,agent 可以完成调研、结构设计、HTML 写作、QA 和导出。
11
+ Revela 是一个 [OpenCode](https://opencode.ai) 插件,用来把工作区来源材料、调研、证据和用户意图转成可信的叙事型沟通 artifact。
12
+ 它的第一个 render target 仍然是 HTML slide deck:在当前会话中启用之后,agent 可以完成调研、结构设计、HTML 写作、QA、检查、refine 和导出。
13
13
 
14
14
  **[在线演示 — AI 权力转移](https://cyber-dash-tech.github.io/revela/assets/html/ai-power-shift.html)**
15
15
 
@@ -17,11 +17,13 @@ Revela 是一个 [OpenCode](https://opencode.ai) 插件,可以把你当前使
17
17
 
18
18
  ## 它能做什么
19
19
 
20
- - 通过 `/revela enable` 向当前 agent 注入演示文稿专用 system prompt
21
- - prompt 3 层组成:核心 skill、当前 domain、当前 design
20
+ - 通过 `/revela enable` 向当前 agent 注入 narrative-first system prompt
21
+ - 只有在显式运行 `/revela deck` 时,才切换到 deck-render prompt mode
22
22
  - 支持工作区文档扫描,以及 `.pdf`、`.docx`、`.pptx`、`.xlsx` 的透明文本提取和嵌入素材缓存提取
23
- - 在当前工作区持续跟踪 deck 背景、页面结构、来源材料和 readiness
24
- - 写入 `decks/*.html` 前检查是否缺上下文、证据或结构
23
+ - `DECKS.json` 作为当前 workspace state engine,持续记录来源材料、调研动作、findings、claims、证据、叙事意图、render targets 和 readiness
24
+ - 先检查 narrative readiness,再用独立 deck/artifact gate 保护 deck HTML 写入
25
+ - 记录 review snapshots,避免重要状态变化后旧的 ready 结果继续默默授权写入 deck HTML
26
+ - 把 HTML deck、PDF 和 PPTX 视为来自同一 workspace state 的 render targets,而不是互相孤立的输出文件
25
27
  - agent 每次写入、patch 或 edit `decks/*.html` 时自动执行快速 design compliance 检查
26
28
  - 为已有 deck 打开可视化评论编辑器,用户可以 Ctrl/Cmd + 点击元素,并把精确修改意见发回 OpenCode
27
29
  - 支持导出成 PDF 和可编辑 PPTX
@@ -102,16 +104,17 @@ export { default } from "/absolute/path/to/revela/index.ts";
102
104
  /revela domains deeptech-investment
103
105
  ```
104
106
 
105
- 然后直接给 agent 一个 deck 任务:
107
+ 然后先打磨或检查叙事。叙事 ready 并获得批准后,再进入 deck handoff:
106
108
 
107
109
  ```text
108
- Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main market drivers, use the active design faithfully, and save the result to decks/humanoid-robotics.html.
110
+ /revela review
111
+ /revela deck
109
112
  ```
110
113
 
111
- 如果任务依赖来源材料、调研或已确认的 slide plan,可以先让 Revela 检查上下文、结构和证据是否足够:
114
+ 如果只需要检查写 HTML 前的 deck/artifact gate,使用:
112
115
 
113
116
  ```text
114
- /revela review
117
+ /revela deck --review
115
118
  ```
116
119
 
117
120
  需要导出时,可以手动调用,也可以让 agent 直接导出:
@@ -133,11 +136,13 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
133
136
 
134
137
  ```text
135
138
  /revela 显示当前状态与帮助
136
- /revela enable 为当前会话启用演示文稿模式
137
- /revela disable 关闭演示文稿模式
139
+ /revela enable 为当前会话启用 narrative/artifact 模式
140
+ /revela disable 关闭 Revela 模式
138
141
 
139
- /revela init 为当前 deck 项目准备工作区
140
- /revela review 检查上下文、结构和证据是否 ready
142
+ /revela init 初始化或刷新 narrative workspace state
143
+ /revela review 检查 narrative readiness 和 approval state
144
+ /revela deck 从已批准 narrative 开始 deck handoff
145
+ /revela deck --review 写 HTML 前检查 deck/artifact readiness
141
146
  /revela remember <text> 保存明确的用户/工作流偏好
142
147
  /revela refine 打开统一的 Edit/Inspect refinement workspace
143
148
  /revela edit 打开 decks/ 下唯一 deck 的可视化编辑器
@@ -160,7 +165,7 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
160
165
  /revela pptx <file> 将 HTML deck 导出为同目录可编辑 PPTX
161
166
  ```
162
167
 
163
- 大多数 `/revela` 命令都在本地执行,不消耗 LLM token。`/revela init`、`/revela review`、`/revela remember`、`/revela designs-new` 和 `/revela designs-edit` 会启动 AI 辅助流程,因为它们需要读取或更新项目状态。`/revela refine` 会打开一个本地浏览器 workspace,里面有 Edit 和 Inspect 两个 tab,并共享同一套 Cmd/Ctrl-click 元素引用。Edit 会把精准修改评论发回当前 OpenCode 会话;Inspect 会先渲染确定性 Source/Purpose 预处理结果,再 lazy 显示 LLM 生成的卡片。它没有聊天框,也不会修改 deck。
168
+ 大多数 `/revela` 命令都在本地执行,不消耗 LLM token。`/revela init`、`/revela review`、`/revela deck`、`/revela remember`、`/revela designs-new` 和 `/revela designs-edit` 会启动 AI 辅助流程,因为它们需要读取或更新项目状态。`/revela refine` 会打开一个本地浏览器 workspace,里面有 Edit 和 Inspect 两个 tab,并共享同一套 Cmd/Ctrl-click 元素引用。Edit 会把精准修改评论发回当前 OpenCode 会话;Inspect 会先渲染确定性 Source/Purpose 预处理结果,再 lazy 显示 LLM 生成的卡片。它没有聊天框,也不会修改 deck。
164
169
 
165
170
  ---
166
171
 
@@ -168,34 +173,53 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
168
173
 
169
174
  启用 Revela 后,它会把一份动态生成的 prompt 追加到当前 agent 的 system prompt 中。
170
175
 
171
- 这份 prompt 3 层组成:
176
+ 默认 prompt narrative-first:它关注受众信念变化、decision/action、thesis、claims、证据边界、objections、risks 和 approval。Active design CSS、layout catalog、component index、chart rules 和 deck HTML skeleton 在 `/revela deck` 切换到 deck-render mode 前不会注入。
177
+
178
+ Deck-render mode 由 3 层组成:
172
179
 
173
- 1. `skill/SKILL.md` - 核心幻灯片生成流程
180
+ 1. `skill/SKILL.md` - 核心 deck-render 流程
174
181
  2. 当前 active domain - 行业结构与术语
175
182
  3. 当前 active design - 视觉系统、layout、component 和图表规则
176
183
 
177
184
  持久化配置保存在 `~/.config/revela/config.json`。
178
185
  是否启用 Revela 则只在当前会话生效。
179
186
 
187
+ ### Workspace State
188
+
189
+ `DECKS.json` 是 Revela 当前的 workspace state engine,也是兼容旧工作流的状态文件。它仍然保存在工作区根目录,也仍然可以理解为当前 deck 项目的状态入口,但 Revela 内部已经不再把它当成单纯的 deck checklist。
190
+
191
+ 状态中会记录:
192
+
193
+ - 工作区来源材料和可复用的 extraction cache 路径
194
+ - 调研计划、已保存 findings,以及精简的 action provenance
195
+ - canonical narrative state、approvals、objections、risks、slide specs、claim candidates 和 evidence trace
196
+ - active HTML deck 以及派生 PDF、PPTX 等 render targets
197
+ - 带 input hash 的 review snapshots,使重要状态变化后旧的 readiness 自动变 stale
198
+
199
+ 已有的根目录 `DECKS.json` 工作区继续兼容。对旧项目运行 `/revela init` 或 `/revela review` 时,可以安全 normalize canonical narrative state 并刷新 projection 字段;用户不需要手动迁移、不需要移动文件,也不需要把 `DECKS.json` 换成数据库。`writeReadiness.status: "ready"` 只代表 deck/artifact readiness,永远不等于 narrative approval。
200
+
201
+ Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace state 渲染出来的目标之一。后续 briefs、appendix material、Evidence Inspector views、Q&A 和 interactive reading layers 都可以复用同一套来源/证据逻辑,而不是各自生成孤立内容。
202
+
180
203
  ---
181
204
 
182
205
  ## 推荐使用流程
183
206
 
184
- 把 Revela 当成一个有检查环节的 deck 生产模式:
207
+ 把 Revela 当成 narrative-first artifact workflow:
185
208
 
186
209
  1. 用 `/revela enable` 启用 Revela。
187
210
  2. 新项目或工作区明显变化时,运行 `/revela init`。
188
- 3. 如果默认风格不合适,先选择 design domain
189
- 4. agent 一个清楚的 deck 任务:受众、目标、语言、页数、来源要求和输出路径。
190
- 5. 如果 deck 需要调研、引用或已确认的 slide plan,写作前先运行 `/revela review`。
191
- 6. agent HTML deck 写到 `decks/` 下。
192
- 7. `/revela refine` 对选中 deck 元素做可视化评论、精准修改,以及可选的 Source/Purpose 检查。
193
- 8. 只有在需要旧的单一功能 shell 时,才单独使用 `/revela edit` `/revela inspect`。
194
- 9. `/revela pdf <file>` 或 `/revela pptx <file>` 导出。
211
+ 3. `/revela review` 检查 narrative readiness:受众、信念变化、decision/action、thesis、central claims、证据、objections、risks 和 approval state
212
+ 4. 批准 narrative 或要求修改。如果需要在完整战略批准前渲染,必须记录 explicit render override。
213
+ 5. 运行 `/revela deck`,把已批准 narrative 编译成 deck slide specs,并进入 deck-render mode。
214
+ 6. 只在 deck handoff 阶段选择或确认 design,然后通过 handoff workflow 或 `/revela deck --review` 运行 deck/artifact gate。
215
+ 7. 只有 artifact gate ready 后,才让 agent 把 HTML deck 写到 `decks/` 下。
216
+ 8. `/revela refine` 对选中 deck 元素做可视化评论、精准修改,以及可选的 Source/Purpose 检查。
217
+ 9. 只有在需要旧的单一功能 shell 时,才单独使用 `/revela edit` 或 `/revela inspect`。
218
+ 10. 用 `/revela pdf <file>` 或 `/revela pptx <file>` 导出。
195
219
 
196
- `/revela review` 检查的是实际生产问题:受众是否清楚、是否缺来源材料、调研是否完成、关键 claim 是否有证据、source trace 是否太弱、页面结构是否完整、design/layout 信息是否齐全,以及轻量叙事问题,例如 so-what 不清晰、缺少风险/假设处理或转场突兀。它不会写最终 deck。
220
+ `/revela review` 检查的是 narrative readiness:受众不清、缺信念变化、缺 decision/action、thesis 弱、central claims 无证据、evidence 弱、unsupported scope、objection 未处理、缺风险/假设处理、approval stale 或缺 approval。它不检查 design/layout readiness,也不会写最终 deck。
197
221
 
198
- 如果 Revela 阻止写入 deck,直接让 agent 运行 `/revela review`,根据报告补齐缺口后再写。这样可以避免在计划、证据或结构还不完整时覆盖真实 deck 文件。
222
+ 如果 Revela 阻止写入 deck,直接让 agent 运行 `/revela deck --review`,根据报告补齐 artifact 缺口后再写。这样可以避免在 slide specs、evidence projection、design/layout readiness、review snapshot 和 deck HTML contract 还不完整时覆盖真实 deck 文件。
199
223
 
200
224
  记住长期偏好请使用:
201
225
 
@@ -562,6 +586,8 @@ Inspector 会在浏览器中打开,左侧是 deck,右侧是固定卡片:So
562
586
 
563
587
  Inspector 不是聊天,也没有自由输入框。它不会修改 `DECKS.json` 或 deck HTML。它使用已记录的 slide spec、narrative state 和 slide-level evidence trace 作为 grounded context。确定性预处理会立即显示;LLM judgment 随后 lazy 更新 Source 和 Purpose 卡片,不会强行生成编辑动作。
564
588
 
589
+ Inspect 和 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 会在 inspect/refine/export 工作流信任它之前被拒绝或报告。
590
+
565
591
  ---
566
592
 
567
593
  ## 导出
@@ -35,8 +35,8 @@ export async function handleDesignsActivate(
35
35
  ): Promise<void> {
36
36
  try {
37
37
  activateDesign(name)
38
- buildPrompt()
39
- await send(`**Design activated:** \`${name}\`\nPrompt rebuilt. The new visual style will apply to the next message.`)
38
+ buildPrompt({ mode: "narrative" })
39
+ await send(`**Design activated:** \`${name}\`\nNarrative prompt rebuilt. The design will apply when \`/revela deck\` enters deck-render mode.`)
40
40
  } catch (e: any) {
41
41
  await send(`**Error:** ${e.message}`)
42
42
  }
@@ -35,8 +35,8 @@ export async function handleDomainsActivate(
35
35
  ): Promise<void> {
36
36
  try {
37
37
  activateDomain(name)
38
- buildPrompt()
39
- await send(`**Domain activated:** \`${name}\`\nPrompt rebuilt. The new domain context will apply to the next message.`)
38
+ buildPrompt({ mode: "narrative" })
39
+ await send(`**Domain activated:** \`${name}\`\nNarrative prompt rebuilt. Domain reasoning applies now; deck-specific render guidance applies during \`/revela deck\`.`)
40
40
  } catch (e: any) {
41
41
  await send(`**Error:** ${e.message}`)
42
42
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * lib/commands/enable.ts
3
3
  *
4
- * Handler for `/revela enable` — activates slide generation mode.
4
+ * Handler for `/revela enable` — activates Revela narrative/artifact mode.
5
5
  */
6
6
 
7
7
  import { existsSync } from "fs"
@@ -19,30 +19,30 @@ export async function handleEnable(
19
19
  const design = activeDesign()
20
20
  const domain = activeDomain()
21
21
 
22
- // Health check: ensure the active prompt file exists.
23
- // If startup failed (e.g. SKILL.md missing), rebuild now so the user gets a working session.
22
+ // Always rebuild narrative mode on enable. A prior `/revela deck` handoff may
23
+ // have intentionally switched the active prompt to deck-render mode.
24
24
  if (!existsSync(ACTIVE_PROMPT_FILE)) {
25
25
  log.warn("active prompt file missing on enable — rebuilding", { promptFile: ACTIVE_PROMPT_FILE })
26
- try {
27
- buildPrompt()
28
- log.info("prompt rebuilt on enable", { design, domain, promptFile: ACTIVE_PROMPT_FILE })
29
- } catch (e) {
30
- log.error("prompt rebuild failed on enable", { error: e instanceof Error ? e.message : String(e) })
31
- await send(
32
- `**Revela enabled (with warnings).** Slide generation mode is active, ` +
33
- `but the prompt file could not be built. ` +
34
- `Try \`/revela disable\` then \`/revela enable\` again, or check that the package is correctly installed.\n\n` +
35
- `Design: \`${design}\` · Domain: \`${domain}\``
36
- )
37
- return
38
- }
26
+ }
27
+ try {
28
+ buildPrompt({ mode: "narrative" })
29
+ log.info("narrative prompt rebuilt on enable", { design, domain, promptFile: ACTIVE_PROMPT_FILE })
30
+ } catch (e) {
31
+ log.error("prompt rebuild failed on enable", { error: e instanceof Error ? e.message : String(e) })
32
+ await send(
33
+ `**Revela enabled (with warnings).** Narrative/artifact mode is active, ` +
34
+ `but the prompt file could not be built. ` +
35
+ `Try \`/revela disable\` then \`/revela enable\` again, or check that the package is correctly installed.\n\n` +
36
+ `Design: \`${design}\` · Domain: \`${domain}\``
37
+ )
38
+ return
39
39
  }
40
40
 
41
41
  log.info("revela enabled", { design, domain })
42
42
  await send(
43
- `**Revela enabled.** Slide generation mode is now active.\n` +
43
+ `**Revela enabled.** Narrative/artifact mode is now active.\n` +
44
44
  `Design: \`${design}\` · Domain: \`${domain}\`\n\n` +
45
- `The three-layer slide generation prompt will be injected into every message. ` +
46
- `Describe your presentation to get started.`
45
+ `The narrative-first prompt will be injected into every message. ` +
46
+ `Use \`/revela deck\` when you are ready to enter deck-render mode.`
47
47
  )
48
48
  }
@@ -24,10 +24,12 @@ export async function handleHelp(
24
24
  `🟠 **Domain:** \`${domain}\`\n\n` +
25
25
  `---\n\n` +
26
26
  `**Commands**\n\n` +
27
- `\`/revela enable\` — enable slide generation mode\n` +
28
- `\`/revela disable\` — disable slide generation mode\n` +
27
+ `\`/revela enable\` — enable Revela narrative/artifact mode\n` +
28
+ `\`/revela disable\` — disable Revela mode\n` +
29
29
  `\`/revela init\` — initialize or refresh workspace DECKS.json\n` +
30
- `\`/revela review\` — review current deck readiness before writing HTML\n` +
30
+ `\`/revela review\` — review narrative readiness and approval state\n` +
31
+ `\`/revela deck\` — start deck handoff from approved narrative\n` +
32
+ `\`/revela deck --review\` — review deck/artifact readiness before writing HTML\n` +
31
33
  `\`/revela refine\` — open unified Edit/Inspect refinement workspace\n` +
32
34
  `\`/revela edit\` — open visual editor for the only deck in decks/\n` +
33
35
  `\`/revela inspect\` — open Evidence Inspector for click-to-inspect review\n` +
@@ -9,17 +9,17 @@ export function buildInitPrompt({
9
9
  }): string {
10
10
  const mode = exists
11
11
  ? `A ${DECKS_STATE_FILE} file already exists. Read it first through the revela-decks tool and update it conservatively.`
12
- : `No ${DECKS_STATE_FILE} file exists yet. Create it through the revela-decks tool.`
12
+ : `No ${DECKS_STATE_FILE} file exists yet. Create it through the revela-decks tool only when there is enough stable workspace or narrative context.`
13
13
 
14
- return `Initialize Revela workspace state and deck workboard.
14
+ return `Initialize Revela narrative workspace state.
15
15
 
16
16
  Goal:
17
- - Build or update ${DECKS_STATE_FILE}, the workspace-level machine-readable state file for slide deck work.
17
+ - Build or update ${DECKS_STATE_FILE}, the workspace-level machine-readable state file for Revela narrative and artifact work.
18
18
  - Use the \`revela-decks\` tool for state updates. Do not write or patch ${DECKS_STATE_FILE} directly.
19
- - Capture stable project context, professional/domain context, topic, audience, available source materials, the current deck artifact, slide specs, and open questions for future sessions.
20
- - Do not treat initialization as permission to write a slide deck; the current deck must pass a later readiness review.
21
- - ${DECKS_STATE_FILE} is the source of truth for the single current workspace deck.
22
- - \`slides\` is the only slide-plan source of truth. Do not track or infer a separate slide count field.
19
+ - Capture stable narrative context first: primary audience, belief before, belief after, decision/action, thesis, central claims, evidence availability, objections, risks, available source materials, existing artifact history, and open questions.
20
+ - Do not treat initialization as permission to write a deck. Narrative readiness is reviewed later by \`/revela review\`; deck/artifact readiness is reviewed by \`/revela deck --review\`.
21
+ - Do not require slide count, visual style, design selection, output path, layout choices, or component choices during narrative initialization unless the user explicitly asks to render a deck now.
22
+ - ${DECKS_STATE_FILE} is the compatibility workspace-state file. Deck specs are render-target projections, not the center of initialization.
23
23
 
24
24
  Current state:
25
25
  - ${mode}
@@ -35,30 +35,41 @@ Workspace boundary rules:
35
35
 
36
36
  Workflow:
37
37
  1. Use the \`revela-workspace-scan\` tool to inspect document and data files in the workspace. Start with no \`path\` and \`max_depth: 2\`.
38
- 2. Separately search for existing deck outputs and deck history, especially:
38
+ 2. Separately search for existing artifact history, especially:
39
39
  - \`decks/**/*.html\`
40
40
  - \`slides/**/*.html\`
41
41
  - \`presentations/**/*.html\`
42
42
  - \`decks/**/*.pdf\`
43
43
  - \`slides/**/*.pdf\`
44
- Run these searches only inside the current workspace root. These are generated/output decks, not necessarily source materials. If \`decks/\` contains exactly one HTML file, treat it as the current deck artifact. If \`decks/\` contains multiple HTML files, stop and ask the user to move extra decks to separate workspaces before adopting one.
44
+ Run these searches only inside the current workspace root. These are generated/output artifacts, not necessarily source materials. If \`decks/\` contains exactly one HTML file, record it as existing artifact history and possible current deck artifact. If \`decks/\` contains multiple HTML files, do not guess which one is canonical; ask the user which artifact belongs to this workspace or whether extra decks should move to separate workspaces.
45
45
  3. Register or refresh source material records by passing the scan result's \`sourceMaterial\` objects to \`revela-decks\` action \`init\`. Preserve unchanged existing records; the tool will upsert by path and fingerprint.
46
- 4. Select the files that look most relevant for future slide decks. Prioritize source decks, PDFs, Word docs, spreadsheets, CSVs, Markdown, text notes, and relevant existing generated decks.
47
- 5. Do not automatically extract every PDF/PPTX/DOCX/XLSX during init. Call \`revela-extract-document-materials\` only for selected files that are clearly needed to form conservative workspace memory, or when the user explicitly asked to analyze the material now.
46
+ 4. Select the files that look most relevant for understanding the narrative problem. Prioritize source decks, PDFs, Word docs, spreadsheets, CSVs, Markdown, text notes, and relevant existing generated artifacts.
47
+ 5. Do not automatically extract every PDF/PPTX/DOCX/XLSX during init. Call \`revela-extract-document-materials\` only for selected files that are clearly needed to form conservative narrative memory, or when the user explicitly asked to analyze the material now.
48
48
  6. Before extracting or deeply reading a selected document, check \`DECKS.json.workspace.sourceMaterials\`. If the same path has the same fingerprint and valid extraction paths, reuse those paths instead of repeating extraction.
49
- 7. Read only the materials needed to form a conservative workspace memory. Do not exhaustively read every file if the workspace is large.
50
- 8. If this conversation or the workspace contains a concrete deck task or an existing deck artifact, call \`revela-decks\` with action \`upsertDeck\` and later \`upsertSlides\` for explicit deck information. Do not pass or ask for a deck key; the tool uses the workspace folder name internally. Do not mark readiness ready during init.
51
- 9. When adopting an existing HTML deck, analyze the artifact and create one conservative \`SlideSpec\` per identifiable slide/page. Record only visible source notes or explicit source information as evidence; do not infer original evidence that is not present in the artifact.
52
- 10. When a read or extracted source material clearly supports a specific slide claim, you may attach compact evidence fields such as \`sourcePath\`, \`location\`, \`extractedTextPath\`, or \`extractedManifestPath\`. Attach extraction cache paths only when they support that specific claim, not to every slide by default.
53
- 11. Treat \`workspace.sourceMaterials\` as a reusable candidate index, not proof by itself. A source material record alone is not slide evidence.
54
- 12. Report what was initialized or updated and list any open questions.
49
+ 7. Read only the materials needed to form conservative narrative memory. Do not exhaustively read every file if the workspace is large.
50
+ 8. If enough information is available, preserve canonical narrative intent through \`revela-decks\` action \`upsertNarrative\`: audience intent, decision intent, thesis, central claims, explicit evidence bindings where known, objections, and risks. This does not require deck rendering inputs.
51
+ 9. If the workspace has explicit slide/deck information, existing HTML, or a user-requested deck task, you may also call \`upsertDeck\` and \`upsertSlides\` for explicit deck information. The tool projects canonical narrative state back to compatibility \`narrativeBrief\` when a deck record exists. Do not pass or ask for a deck key; the tool uses the workspace folder name internally. Do not mark deck readiness ready during init.
52
+ 10. When adopting an existing HTML deck, analyze the artifact and create one conservative \`SlideSpec\` per identifiable slide/page only if the artifact is clearly the current workspace artifact. Record only visible source notes or explicit source information as evidence; do not infer original evidence that is not present in the artifact.
53
+ 11. When a read or extracted source material clearly supports a specific narrative or slide claim, preserve compact evidence trace such as \`sourcePath\`, \`location\`, \`extractedTextPath\`, or \`extractedManifestPath\`. Attach extraction cache paths only when they support that specific claim, not to every claim or slide by default.
54
+ 12. Treat \`workspace.sourceMaterials\` as a reusable candidate index, not proof by itself. A source material record alone is not narrative evidence or slide evidence.
55
+ 13. Report what was initialized or updated and list the smallest open narrative questions needed to proceed.
56
+
57
+ Narrative questions to ask only when missing:
58
+ - Who is the primary audience?
59
+ - What do they believe before this communication?
60
+ - What should they believe after it?
61
+ - What decision or action is required?
62
+ - What is the working thesis or recommendation?
63
+ - Which central claims support the thesis?
64
+ - Which sources or findings support those claims?
65
+ - What objections, risks, assumptions, or caveats could break the argument?
55
66
 
56
67
  Memory rules:
57
- - Only write facts supported by workspace files into ${DECKS_STATE_FILE} workspace state, source materials, deck memory, and open questions.
68
+ - Only write facts supported by workspace files or explicit user statements into ${DECKS_STATE_FILE} workspace state, source materials, narrative compatibility fields, deck memory, and open questions.
58
69
  - Only write user preferences if the user explicitly stated that Revela should remember them.
59
70
  - Do not infer personal preferences from one-off requests.
60
71
  - Do not store secrets, credentials, API keys, tokens, account details, or sensitive personal information.
61
- - Do not mark writeReadiness as ready during init unless the current deck has already passed an explicit \`revela-decks\` review.
72
+ - Do not mark narrative approval, render override, or writeReadiness as ready during init.
62
73
  - Treat this workspace as a single deck project. If the user wants another deck, guide them to create another workspace/folder rather than adding a second deck record.
63
74
  - If new evidence conflicts with existing memory, preserve both briefly and add an Open Question instead of silently overwriting.
64
75
 
@@ -11,7 +11,7 @@ export async function handleInspect(
11
11
  workspaceRoot: options.workspaceRoot,
12
12
  })
13
13
  await send(
14
- `Opened Evidence Inspector for the only deck in \`decks/\`.\n` +
14
+ `Opened Evidence Inspector for the active HTML deck.\n` +
15
15
  `File: \`${result.deck.file}\`\n` +
16
16
  `${result.stateNote}\n` +
17
17
  `URL: ${result.url}\n\n` +
@@ -8,28 +8,41 @@
8
8
  */
9
9
 
10
10
  import { resolve } from "path"
11
+ import { hasDecksState, readDecksState } from "../decks-state"
11
12
  import { exportToPdf } from "../pdf/export"
12
13
  import { assertExportQAPassed } from "../qa/export-gate"
14
+ import { recordRenderedArtifact, workspaceRelative } from "../workspace-state/rendered-artifacts"
15
+ import { resolveActiveHtmlDeckPath } from "../workspace-state/render-targets"
13
16
 
14
17
  export async function handlePdf(
15
18
  filePath: string,
16
19
  send: (text: string) => Promise<void>,
20
+ workspaceRoot = process.cwd(),
17
21
  ): Promise<void> {
18
- if (!filePath) {
22
+ const root = resolve(workspaceRoot)
23
+ const resolvedFile = resolvePdfDeckFile(root, filePath)
24
+
25
+ if (!resolvedFile) {
19
26
  await send(
20
- "**Usage:** `/revela pdf <file_path>`\n\n" +
27
+ "**Usage:** `/revela pdf [file_path]`\n\n" +
21
28
  "Example: `/revela pdf decks/my-deck.html`"
22
29
  )
23
30
  return
24
31
  }
25
32
 
26
- const abs = resolve(filePath)
33
+ const abs = resolvedFile.absoluteFile
27
34
  await send(`Running pre-export QA for \`${abs}\`...`)
28
35
 
29
36
  try {
30
- await assertExportQAPassed(abs)
37
+ await assertExportQAPassed(abs, { workspaceRoot: root })
31
38
  await send(`Exporting \`${abs}\` to PDF...`)
32
- const result = await exportToPdf(filePath)
39
+ const result = await exportToPdf(abs)
40
+ recordRenderedArtifact(root, {
41
+ sourceHtmlPath: resolvedFile.file,
42
+ outputPath: result.outputPath,
43
+ type: "pdf",
44
+ actor: "revela-pdf",
45
+ })
33
46
  const secs = (result.durationMs / 1000).toFixed(1)
34
47
  await send(
35
48
  `**PDF exported successfully**\n\n` +
@@ -42,3 +55,18 @@ export async function handlePdf(
42
55
  await send(`**PDF export failed**\n\n\`\`\`\n${msg}\n\`\`\``)
43
56
  }
44
57
  }
58
+
59
+ function resolvePdfDeckFile(workspaceRoot: string, filePath: string): { file: string; absoluteFile: string } | undefined {
60
+ const explicit = filePath.trim()
61
+ if (explicit) {
62
+ const absoluteFile = resolve(workspaceRoot, explicit)
63
+ return { file: workspaceRelative(workspaceRoot, absoluteFile), absoluteFile }
64
+ }
65
+
66
+ if (!hasDecksState(workspaceRoot)) return undefined
67
+ const state = readDecksState(workspaceRoot)
68
+ const activePath = resolveActiveHtmlDeckPath(state)
69
+ if (!activePath) return undefined
70
+ const absoluteFile = resolve(workspaceRoot, activePath)
71
+ return { file: workspaceRelative(workspaceRoot, absoluteFile), absoluteFile }
72
+ }