@cyber-dash-tech/revela 0.13.0 → 0.15.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.
- package/README.md +75 -55
- package/README.zh-CN.md +75 -55
- package/lib/command-intent.ts +59 -0
- package/lib/commands/brief.ts +1 -1
- package/lib/commands/designs.ts +1 -1
- package/lib/commands/domains.ts +1 -1
- package/lib/commands/edit.ts +7 -5
- package/lib/commands/enable.ts +6 -6
- package/lib/commands/help.ts +19 -10
- package/lib/commands/init.ts +1 -1
- package/lib/commands/inspect.ts +7 -5
- package/lib/commands/research.ts +66 -0
- package/lib/commands/review.ts +3 -3
- package/lib/decks-state.ts +5 -5
- package/lib/inspect/prompt.ts +15 -2
- package/lib/inspect/requests.ts +21 -2
- package/lib/inspection-context/compile.ts +71 -5
- package/lib/inspection-context/match.ts +71 -1
- package/lib/inspection-context/project.ts +116 -13
- package/lib/inspection-context/result.ts +183 -0
- package/lib/narrative-state/queries.ts +1 -0
- package/lib/refine/server.ts +91 -13
- package/package.json +1 -1
- package/plugin.ts +252 -53
- package/skill/NARRATIVE_SKILL.md +103 -25
- package/skill/SKILL.md +1 -1
- package/tools/edit.ts +10 -8
- package/tools/inspection-result.ts +37 -0
package/README.zh-CN.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | **中文**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@cyber-dash-tech/revela) [](LICENSE) [](https://www.npmjs.com/package/@cyber-dash-tech/revela) [](LICENSE) [](tests/) [](https://opencode.ai) [](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
11
|
Revela 是一个 [OpenCode](https://opencode.ai) 插件,用来把工作区来源材料、调研、证据和用户意图转成可信的叙事型沟通 artifact。
|
|
12
|
-
它的第一个 render target 仍然是 HTML slide deck
|
|
12
|
+
它的第一个 render target 仍然是 HTML slide deck:启动 Revela workflow command 之后,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,8 +17,8 @@ Revela 是一个 [OpenCode](https://opencode.ai) 插件,用来把工作区来
|
|
|
17
17
|
|
|
18
18
|
## 它能做什么
|
|
19
19
|
|
|
20
|
-
-
|
|
21
|
-
- 只有在显式运行 `/revela deck` 时,才切换到 deck-render prompt mode
|
|
20
|
+
- 为 `/revela init`、`/revela story`、`/revela make deck` 等显式命令注入一次性 workflow instructions
|
|
21
|
+
- 只有在显式运行 `/revela make deck` 时,才切换到 deck-render prompt mode
|
|
22
22
|
- 支持工作区文档扫描,以及 `.pdf`、`.docx`、`.pptx`、`.xlsx` 的透明文本提取和嵌入素材缓存提取
|
|
23
23
|
- 将 `DECKS.json` 作为当前 workspace state engine,持续记录来源材料、调研动作、findings、claims、证据、叙事意图、render targets 和 readiness
|
|
24
24
|
- 先检查 narrative readiness,再用独立 deck/artifact gate 保护 deck HTML 写入
|
|
@@ -84,12 +84,6 @@ export { default } from "/absolute/path/to/revela/index.ts";
|
|
|
84
84
|
|
|
85
85
|
## 快速开始
|
|
86
86
|
|
|
87
|
-
先在当前会话中启用 Revela:
|
|
88
|
-
|
|
89
|
-
```text
|
|
90
|
-
/revela enable
|
|
91
|
-
```
|
|
92
|
-
|
|
93
87
|
在新项目里可以先准备工作区:
|
|
94
88
|
|
|
95
89
|
```text
|
|
@@ -99,22 +93,23 @@ export { default } from "/absolute/path/to/revela/index.ts";
|
|
|
99
93
|
如有需要,先切换 design 或 domain:
|
|
100
94
|
|
|
101
95
|
```text
|
|
102
|
-
/revela
|
|
103
|
-
/revela
|
|
96
|
+
/revela design
|
|
97
|
+
/revela design use summit
|
|
104
98
|
/revela domains deeptech-investment
|
|
105
99
|
```
|
|
106
100
|
|
|
107
|
-
|
|
101
|
+
然后先打磨、调研或检查 story。叙事 ready 并获得批准后,再生成 deck:
|
|
108
102
|
|
|
109
103
|
```text
|
|
110
|
-
/revela
|
|
111
|
-
/revela
|
|
104
|
+
/revela story
|
|
105
|
+
/revela research
|
|
106
|
+
/revela make deck
|
|
112
107
|
```
|
|
113
108
|
|
|
114
109
|
如果只需要检查写 HTML 前的 deck/artifact gate,使用:
|
|
115
110
|
|
|
116
111
|
```text
|
|
117
|
-
/revela deck --review
|
|
112
|
+
/revela make deck --review
|
|
118
113
|
```
|
|
119
114
|
|
|
120
115
|
需要导出时,可以手动调用,也可以让 agent 直接导出:
|
|
@@ -124,7 +119,13 @@ export { default } from "/absolute/path/to/revela/index.ts";
|
|
|
124
119
|
/revela pptx decks/humanoid-robotics.html
|
|
125
120
|
```
|
|
126
121
|
|
|
127
|
-
|
|
122
|
+
如果希望普通聊天消息在显式命令之间也保持 Revela narrative mode,可以启用可选 ambient mode:
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
/revela enable
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
完成后关闭 ambient mode:
|
|
128
129
|
|
|
129
130
|
```text
|
|
130
131
|
/revela disable
|
|
@@ -136,18 +137,32 @@ export { default } from "/absolute/path/to/revela/index.ts";
|
|
|
136
137
|
|
|
137
138
|
```text
|
|
138
139
|
/revela 显示当前状态与帮助
|
|
139
|
-
/revela enable
|
|
140
|
-
/revela disable 关闭 Revela
|
|
140
|
+
/revela enable 可选:让普通聊天保持 ambient narrative mode
|
|
141
|
+
/revela disable 关闭 ambient Revela mode
|
|
141
142
|
|
|
142
143
|
/revela init 初始化或刷新 narrative workspace state
|
|
143
|
-
/revela
|
|
144
|
-
/revela
|
|
145
|
-
/revela deck
|
|
144
|
+
/revela research 调研、绑定证据,并减少 story gaps/caveats
|
|
145
|
+
/revela story 打开只读 story workspace UI
|
|
146
|
+
/revela make deck 从已批准 story 生成 deck
|
|
147
|
+
/revela make deck --review 写 HTML 前检查 deck/artifact readiness
|
|
148
|
+
/revela make brief [file.md] 从已批准 story 渲染 executive brief
|
|
146
149
|
/revela remember <text> 保存明确的用户/工作流偏好
|
|
147
|
-
/revela refine
|
|
148
|
-
/revela edit
|
|
149
|
-
/revela inspect
|
|
150
|
-
|
|
150
|
+
/revela refine 打开统一的阅读、检查和编辑 workspace
|
|
151
|
+
/revela edit deprecated,兼容到 /revela refine Edit mode
|
|
152
|
+
/revela inspect deprecated,兼容到 /revela refine Inspect mode
|
|
153
|
+
|
|
154
|
+
/revela review legacy story readiness report
|
|
155
|
+
/revela narrative 兼容别名,等同 /revela story
|
|
156
|
+
/revela deck 兼容别名,等同 /revela make deck
|
|
157
|
+
/revela brief [file.md] 兼容别名,等同 /revela make brief
|
|
158
|
+
|
|
159
|
+
/revela design 列出已安装 design
|
|
160
|
+
/revela design use <name> 激活某个 design
|
|
161
|
+
/revela design new <name> 通过 AI 创建一个自定义 design
|
|
162
|
+
/revela design edit <name> 通过 AI 调整已有自定义 design
|
|
163
|
+
/revela design preview [name] 在浏览器中打开 design preview
|
|
164
|
+
/revela design add <source> 从 URL、本地路径或 github:user/repo 安装 design
|
|
165
|
+
/revela design rm <name> 删除已安装 design
|
|
151
166
|
/revela designs 列出已安装 design
|
|
152
167
|
/revela designs <name> 激活某个 design
|
|
153
168
|
/revela designs-new <name> 通过 AI 创建一个自定义 design
|
|
@@ -165,15 +180,15 @@ export { default } from "/absolute/path/to/revela/index.ts";
|
|
|
165
180
|
/revela pptx <file> 将 HTML deck 导出为同目录可编辑 PPTX
|
|
166
181
|
```
|
|
167
182
|
|
|
168
|
-
大多数 `/revela` 命令都在本地执行,不消耗 LLM token。`/revela init`、`/revela review`、`/revela deck`、`/revela remember`、`/revela
|
|
183
|
+
大多数 `/revela` 命令都在本地执行,不消耗 LLM token。`/revela init`、`/revela research`、`/revela story`、`/revela review`、`/revela make deck`、`/revela remember`、`/revela design new` 和 `/revela design edit` 会启动 AI 辅助流程,因为它们需要读取或更新项目状态。这些 workflow command 只在可见聊天里显示短意图,详细内部说明通过一次性的 system-prompt command intent 注入。`/revela refine` 是统一的 post-artifact workspace,会打开一个本地浏览器 workspace,里面有 Edit 和 Inspect 两个 tab,并共享同一套 Cmd/Ctrl-click 元素引用。Edit 会把精准修改评论发回当前 OpenCode 会话;Inspect 会把 grounded selection context 发给当前 OpenCode 会话,并渲染本地化的 Narrative Reading、Exploratory Reading、Source、Purpose 卡片。确定性预处理保留为 fallback context,而不是默认先展示的 UI。如果生成结果缺少较新的 reading 卡片,Refine 会保留确定性 Narrative Reading 和 Exploratory Reading,而不是丢掉这些上下文。Narrative Reading 还会显示所选 canonical claim 的 artifact coverage,包括每个已记录 artifact 是否包含该 claim,以及 coverage 是 current、stale、partial 还是 missing。Exploratory Reading 明确是非官方阅读辅助,只能基于已记录 claim、evidence、caveat、objection、risk 和 artifact coverage。它没有聊天框,也不会修改 deck。`/revela edit` 和 `/revela inspect` 只作为 deprecated 兼容入口保留。
|
|
169
184
|
|
|
170
185
|
---
|
|
171
186
|
|
|
172
187
|
## 工作原理
|
|
173
188
|
|
|
174
|
-
|
|
189
|
+
显式 Revela workflow command 会把一次性 command instructions 追加到当前 agent 的 system prompt 中。`/revela enable` 是可选 ambient mode,用于让显式命令之间的普通聊天也保持 Revela narrative mode。
|
|
175
190
|
|
|
176
|
-
默认 prompt 是 narrative-first
|
|
191
|
+
默认 prompt 是 narrative-first:它遵循 `Init -> Research -> Story -> Make -> Refine`,关注受众信念变化、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` 进入显式设计工作流前不会注入。
|
|
177
192
|
|
|
178
193
|
Deck-render mode 由 3 层组成:
|
|
179
194
|
|
|
@@ -182,7 +197,7 @@ Deck-render mode 由 3 层组成:
|
|
|
182
197
|
3. 当前 active design - 视觉系统、layout、component 和图表规则
|
|
183
198
|
|
|
184
199
|
持久化配置保存在 `~/.config/revela/config.json`。
|
|
185
|
-
|
|
200
|
+
ambient enable/disable 状态只在当前会话生效。
|
|
186
201
|
|
|
187
202
|
### Workspace State
|
|
188
203
|
|
|
@@ -206,20 +221,22 @@ Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace s
|
|
|
206
221
|
|
|
207
222
|
把 Revela 当成 narrative-first artifact workflow:
|
|
208
223
|
|
|
209
|
-
1.
|
|
210
|
-
2.
|
|
211
|
-
3. 用 `/revela
|
|
224
|
+
1. 新项目或工作区明显变化时,运行 `/revela init`。
|
|
225
|
+
2. 如果 story gaps 或 unsupported central claims 需要外部证据,用 `/revela research` 定向调研;它应循环执行 research、证据绑定、claim/relation 收窄和 re-review,直到公开调研无法继续改善状态。
|
|
226
|
+
3. 用 `/revela story` 打开 story workspace UI,查看 claim flow、证据、caveats、research gaps、approval state 和 artifact coverage。
|
|
212
227
|
4. 批准 narrative 或要求修改。如果需要在完整战略批准前渲染,必须记录 explicit render override。
|
|
213
|
-
5. 运行 `/revela deck`,把已批准 narrative 编译成 deck slide specs
|
|
214
|
-
6. 只在 deck handoff 阶段选择或确认 design,然后通过 handoff workflow 或 `/revela deck --review` 运行 deck/artifact gate。
|
|
228
|
+
5. 运行 `/revela make deck`,把已批准 narrative 编译成 deck slide specs 并进入 deck-render mode,或运行 `/revela make brief` 渲染 executive brief。
|
|
229
|
+
6. 只在 deck handoff 阶段选择或确认 design,然后通过 handoff workflow 或 `/revela make deck --review` 运行 deck/artifact gate。
|
|
215
230
|
7. 只有 artifact gate ready 后,才让 agent 把 HTML deck 写到 `decks/` 下。
|
|
216
|
-
8. 用 `/revela refine` 对选中 deck
|
|
217
|
-
9.
|
|
231
|
+
8. 用 `/revela refine` 对选中 deck 元素做可视化评论、精准修改、只读 Narrative Reading、有边界的 Exploratory Reading、Source、Purpose 检查,以及 claim-to-artifact coverage 查看。
|
|
232
|
+
9. 只有旧脚本或旧习惯需要时,才使用 `/revela edit` 或 `/revela inspect`;两者都会打开对应模式的 `/revela refine`。
|
|
218
233
|
10. 用 `/revela pdf <file>` 或 `/revela pptx <file>` 导出。
|
|
219
234
|
|
|
220
|
-
`/revela
|
|
235
|
+
只有当你希望普通聊天消息,而不只是显式 `/revela ...` 命令,也保持 Revela narrative mode 时,才需要使用 `/revela enable`。
|
|
236
|
+
|
|
237
|
+
`/revela story` 打开只读 story workspace UI。`/revela review` 生成 legacy readiness report,用于检查受众不清、缺信念变化、缺 decision/action、thesis 弱、central claims 无证据、evidence 弱、unsupported scope、objection 未处理、缺风险/假设处理、approval stale 或缺 approval。两者都不检查 design/layout readiness,也不会写最终 deck。
|
|
221
238
|
|
|
222
|
-
如果 Revela 阻止写入 deck,直接让 agent 运行 `/revela deck --review`,根据报告补齐 artifact 缺口后再写。这样可以避免在 slide specs、evidence projection、design/layout readiness、review snapshot 和 deck HTML contract 还不完整时覆盖真实 deck 文件。
|
|
239
|
+
如果 Revela 阻止写入 deck,直接让 agent 运行 `/revela make deck --review`,根据报告补齐 artifact 缺口后再写。这样可以避免在 slide specs、evidence projection、design/layout readiness、review snapshot 和 deck HTML contract 还不完整时覆盖真实 deck 文件。
|
|
223
240
|
|
|
224
241
|
记住长期偏好请使用:
|
|
225
242
|
|
|
@@ -233,7 +250,7 @@ Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace s
|
|
|
233
250
|
|
|
234
251
|
## 调研与文件摄取
|
|
235
252
|
|
|
236
|
-
|
|
253
|
+
在 Revela workflow 中,agent 可以使用:
|
|
237
254
|
|
|
238
255
|
- `revela-workspace-scan` 扫描工作区中的 PDF、Office 文件、CSV、Markdown 和文本文件
|
|
239
256
|
- `revela-research` 子代理做定向网页调研
|
|
@@ -245,7 +262,7 @@ Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace s
|
|
|
245
262
|
支持提取文本的入口:
|
|
246
263
|
|
|
247
264
|
- 在对话里 `@` 引用或直接粘贴文件
|
|
248
|
-
-
|
|
265
|
+
- 在 Revela workflow 或 ambient mode 中通过 `read` 工具访问文件
|
|
249
266
|
|
|
250
267
|
支持提取的文件类型:
|
|
251
268
|
|
|
@@ -279,7 +296,7 @@ Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace s
|
|
|
279
296
|
|
|
280
297
|
## Designs 与 Domains
|
|
281
298
|
|
|
282
|
-
用 `/revela
|
|
299
|
+
用 `/revela design` 和 `/revela domains` 查看你当前环境里实际安装的内容。旧的 `/revela designs*` 命令仍作为兼容别名保留。
|
|
283
300
|
|
|
284
301
|
仓库内置的 domains:
|
|
285
302
|
|
|
@@ -307,6 +324,7 @@ Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace s
|
|
|
307
324
|
|
|
308
325
|
```text
|
|
309
326
|
/revela designs-new my-design
|
|
327
|
+
/revela design new my-design
|
|
310
328
|
```
|
|
311
329
|
|
|
312
330
|
Agent 会先询问你的审美参考,整理设计 brief 并等待确认,然后把 `DESIGN.md` 和 `preview.html` 保存到本地 Revela designs 目录。对 AI 生成的 design,`preview.html` 是必需验收面:它必须包含 cover 和 closing 页,并且必须展示所有 `@component:*`,否则 `revela-designs-author` 不会接受这个包。默认结构底座是内部中性 `starter` design,它不会出现在普通 design 列表中。只有当你明确想从 `summit` 或 `monet` 的具体风格派生时,才建议使用 `--base summit` 或 `--base monet`。
|
|
@@ -315,6 +333,7 @@ Agent 会先询问你的审美参考,整理设计 brief 并等待确认,然
|
|
|
315
333
|
|
|
316
334
|
```text
|
|
317
335
|
/revela designs-edit my-design
|
|
336
|
+
/revela design edit my-design
|
|
318
337
|
```
|
|
319
338
|
|
|
320
339
|
Agent 会询问你想修改什么,读取当前 design,整理 edit brief 并等待确认,然后通过受控 authoring tool 覆盖保存本地 design 包。
|
|
@@ -323,6 +342,7 @@ Agent 会询问你想修改什么,读取当前 design,整理 edit brief 并
|
|
|
323
342
|
|
|
324
343
|
```text
|
|
325
344
|
/revela designs-preview my-design
|
|
345
|
+
/revela design preview my-design
|
|
326
346
|
```
|
|
327
347
|
|
|
328
348
|
省略 name 时会打开当前 active design 的 preview。如果该 design 没有 `preview.html`,Revela 会提示没有可用 preview。
|
|
@@ -340,7 +360,7 @@ my-design/
|
|
|
340
360
|
```yaml
|
|
341
361
|
---
|
|
342
362
|
name: my-design
|
|
343
|
-
description: 在 /revela
|
|
363
|
+
description: 在 /revela design 中显示的简短说明
|
|
344
364
|
author: you
|
|
345
365
|
version: 1.0.0
|
|
346
366
|
---
|
|
@@ -529,9 +549,9 @@ Prompt 注入规则:
|
|
|
529
549
|
安装自定义 design:
|
|
530
550
|
|
|
531
551
|
```text
|
|
532
|
-
/revela
|
|
533
|
-
/revela
|
|
534
|
-
/revela
|
|
552
|
+
/revela design add github:your-org/your-design
|
|
553
|
+
/revela design add https://example.com/my-design.zip
|
|
554
|
+
/revela design add ./path/to/local/design-folder
|
|
535
555
|
```
|
|
536
556
|
|
|
537
557
|
---
|
|
@@ -556,19 +576,19 @@ Prompt 注入规则:
|
|
|
556
576
|
/revela refine
|
|
557
577
|
```
|
|
558
578
|
|
|
559
|
-
`/revela refine` 会打开
|
|
579
|
+
`/revela refine` 会打开 active HTML deck,并提供两个 tab。使用 `Ctrl`/`Cmd` + click 先引用 deck 元素,然后在 Edit 里快速写自然语言修改评论,或在 Inspect 里做只读 Narrative Reading、有边界的 Exploratory Reading、Source、Purpose 和 artifact coverage 检查。Inspect 不会修改 deck;真正的 mutation 仍然只走 Edit。这是 post-artifact 阅读、检查和编辑的推荐入口。
|
|
560
580
|
|
|
561
|
-
|
|
581
|
+
Deprecated 兼容命令:
|
|
562
582
|
|
|
563
583
|
```text
|
|
564
584
|
/revela edit
|
|
565
585
|
```
|
|
566
586
|
|
|
567
|
-
|
|
587
|
+
`/revela edit` 不再打开独立的 edit-only shell。它会打开 `/revela refine` 的 Edit mode,用于兼容旧脚本和旧使用习惯。
|
|
568
588
|
|
|
569
|
-
|
|
589
|
+
使用 `Ctrl`/`Cmd` + 点击 deck 元素来引用它们,在 Edit tab 写一段自然语言评论,然后发送回 OpenCode。Revela 会把 deck 文件、slide 上下文、选中元素 metadata 和你的评论整理成结构化 edit prompt。
|
|
570
590
|
|
|
571
|
-
对应的 LLM tool:`revela-edit`,不需要 target
|
|
591
|
+
对应的 LLM tool:`revela-edit`,不需要 target。这个 tool 也是兼容入口,当你说“我要编辑这个 deck”时,agent 会打开 Refine 的 Edit mode。
|
|
572
592
|
|
|
573
593
|
对于已有 HTML deck,`/revela edit` 会自动准备必要的最小项目上下文,让后续精准修改仍然经过正常安全检查。
|
|
574
594
|
|
|
@@ -576,17 +596,17 @@ Revela 0.8 中 `/revela edit` 不接受 target。如果 `decks/` 下正好有一
|
|
|
576
596
|
|
|
577
597
|
## Evidence Inspector
|
|
578
598
|
|
|
579
|
-
|
|
599
|
+
用 `/revela refine` 做 evidence inspection 和 narrative reading。Deprecated 兼容命令:
|
|
580
600
|
|
|
581
601
|
```text
|
|
582
602
|
/revela inspect
|
|
583
603
|
```
|
|
584
604
|
|
|
585
|
-
|
|
605
|
+
`/revela inspect` 不再打开独立 inspector shell。它会打开 `/revela refine` 的 Inspect mode。Inspect tab 会在固定 Source 和 Purpose 卡片之外显示 Narrative Reading 和 Exploratory Reading 卡片。当选中元素能映射到 canonical narrative state 时,Narrative Reading 会保留 canonical claim id、evidence binding id、supported scope、unsupported scope、caveat、objection、risk 和 artifact coverage。Coverage 会显示所选 claim 是否出现在已记录的 deck/brief/export artifact 中,以及这些 artifact 相对当前 narrative hash 是 current、stale、partial 还是 missing。Exploratory Reading 提供非官方的 objection prep、audience reframing 边界、appendix leads 和 meeting-prep cues,并且只能使用同一份已记录 context。使用 `Ctrl`/`Cmd` + click 引用 deck 元素,然后点击 `Inspect Selection`。请求处理期间,deck 选择会被锁定。
|
|
586
606
|
|
|
587
|
-
Inspector 不是聊天,也没有自由输入框。它不会修改 `DECKS.json` 或 deck HTML。它使用已记录的 slide spec、narrative state 和 slide-level evidence trace 作为 grounded context
|
|
607
|
+
Inspector 不是聊天,也没有自由输入框。它不会修改 `DECKS.json` 或 deck HTML。它使用已记录的 slide spec、narrative state 和 slide-level evidence trace 作为 grounded context。Inspect 的用户界面是 LLM-first:先显示 reading/loading 状态,再渲染结构化生成卡片。确定性预处理仍作为内部 fallback context,仅在生成失败或超时时显示。Inspect tab 提供固定 display-language 下拉选项;语言只影响卡片文案,不会改变 claim id、evidence id、source path、URL、数字、引用或 canonical facts。如果旧版或不完整的生成结果只返回 Source/Purpose,Refine 会保留确定性 reading 卡片,避免 generated inspection 静默移除 claim、evidence boundary、artifact coverage 或 exploratory context。
|
|
588
608
|
|
|
589
|
-
|
|
609
|
+
Refine 会使用 workspace state 中记录的 active HTML deck render target。Deck HTML 必须满足 Revela 的 slide identity contract:active artifact 中每个 `<section class="slide">` 都需要有正数、1-based 的 `data-slide-index`,并且要匹配当前 slide specs。无效的 active artifact 会在 refine/export 工作流信任它之前被拒绝或报告。
|
|
590
610
|
|
|
591
611
|
---
|
|
592
612
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { PromptMode } from "./prompt-builder"
|
|
2
|
+
|
|
3
|
+
export interface PendingCommandIntent {
|
|
4
|
+
sessionID: string
|
|
5
|
+
name: string
|
|
6
|
+
mode: PromptMode
|
|
7
|
+
visibleText: string
|
|
8
|
+
hiddenPrompt: string
|
|
9
|
+
createdAt: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const pendingCommandIntents = new Map<string, PendingCommandIntent>()
|
|
13
|
+
|
|
14
|
+
export function setPendingCommandIntent(intent: Omit<PendingCommandIntent, "createdAt"> & { createdAt?: number }): PendingCommandIntent {
|
|
15
|
+
const normalized: PendingCommandIntent = {
|
|
16
|
+
...intent,
|
|
17
|
+
createdAt: intent.createdAt ?? Date.now(),
|
|
18
|
+
}
|
|
19
|
+
pendingCommandIntents.set(normalized.sessionID, normalized)
|
|
20
|
+
return normalized
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function peekPendingCommandIntent(sessionID: string): PendingCommandIntent | undefined {
|
|
24
|
+
if (!sessionID) return undefined
|
|
25
|
+
return pendingCommandIntents.get(sessionID)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function takePendingCommandIntent(sessionID: string): PendingCommandIntent | undefined {
|
|
29
|
+
if (!sessionID) return undefined
|
|
30
|
+
const intent = pendingCommandIntents.get(sessionID)
|
|
31
|
+
if (intent) pendingCommandIntents.delete(sessionID)
|
|
32
|
+
return intent
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function clearPendingCommandIntent(sessionID: string): void {
|
|
36
|
+
if (!sessionID) return
|
|
37
|
+
pendingCommandIntents.delete(sessionID)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function clearAllPendingCommandIntents(): void {
|
|
41
|
+
pendingCommandIntents.clear()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function formatCommandIntentSystemBlock(intent: PendingCommandIntent): string {
|
|
45
|
+
return [
|
|
46
|
+
"<revela-command-intent>",
|
|
47
|
+
`User invoked: /revela ${intent.name}`,
|
|
48
|
+
`Prompt mode: ${intent.mode}`,
|
|
49
|
+
"Visible user intent:",
|
|
50
|
+
intent.visibleText,
|
|
51
|
+
"",
|
|
52
|
+
"Execute the hidden workflow instructions below with the available Revela tools.",
|
|
53
|
+
"Do not persist this command block as workspace memory or user preference.",
|
|
54
|
+
"",
|
|
55
|
+
"Hidden workflow instructions:",
|
|
56
|
+
intent.hiddenPrompt,
|
|
57
|
+
"</revela-command-intent>",
|
|
58
|
+
].join("\n")
|
|
59
|
+
}
|
package/lib/commands/brief.ts
CHANGED
|
@@ -34,7 +34,7 @@ export async function handleBrief(
|
|
|
34
34
|
await send(
|
|
35
35
|
`**Executive brief not rendered**\n\n${result.reason}\n\n` +
|
|
36
36
|
(result.narrativeHash ? `Narrative hash: \`${result.narrativeHash}\`\n\n` : "") +
|
|
37
|
-
"Run `/revela
|
|
37
|
+
"Run `/revela story` and approve the current narrative, or record an explicit render override before retrying."
|
|
38
38
|
)
|
|
39
39
|
return
|
|
40
40
|
}
|
package/lib/commands/designs.ts
CHANGED
|
@@ -36,7 +36,7 @@ export async function handleDesignsActivate(
|
|
|
36
36
|
try {
|
|
37
37
|
activateDesign(name)
|
|
38
38
|
buildPrompt({ mode: "narrative" })
|
|
39
|
-
await send(`**Design activated:** \`${name}\`\nNarrative prompt rebuilt. The design will apply when \`/revela deck\` enters deck-render mode.`)
|
|
39
|
+
await send(`**Design activated:** \`${name}\`\nNarrative prompt rebuilt. The design will apply when \`/revela make deck\` enters deck-render mode.`)
|
|
40
40
|
} catch (e: any) {
|
|
41
41
|
await send(`**Error:** ${e.message}`)
|
|
42
42
|
}
|
package/lib/commands/domains.ts
CHANGED
|
@@ -36,7 +36,7 @@ export async function handleDomainsActivate(
|
|
|
36
36
|
try {
|
|
37
37
|
activateDomain(name)
|
|
38
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\`.`)
|
|
39
|
+
await send(`**Domain activated:** \`${name}\`\nNarrative prompt rebuilt. Domain reasoning applies now; deck-specific render guidance applies during \`/revela make deck\`.`)
|
|
40
40
|
} catch (e: any) {
|
|
41
41
|
await send(`**Error:** ${e.message}`)
|
|
42
42
|
}
|
package/lib/commands/edit.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { openRefineDeck } from "../refine/open"
|
|
2
2
|
|
|
3
3
|
export async function handleEdit(
|
|
4
|
-
options: { client: any; sessionID: string; workspaceRoot: string },
|
|
4
|
+
options: { client: any; sessionID: string; workspaceRoot: string; openBrowser?: boolean },
|
|
5
5
|
send: (text: string) => Promise<void>,
|
|
6
6
|
): Promise<void> {
|
|
7
7
|
try {
|
|
8
|
-
const result =
|
|
8
|
+
const result = openRefineDeck("", {
|
|
9
9
|
client: options.client,
|
|
10
10
|
sessionID: options.sessionID,
|
|
11
11
|
workspaceRoot: options.workspaceRoot,
|
|
12
|
+
mode: "edit",
|
|
13
|
+
openBrowser: options.openBrowser,
|
|
12
14
|
})
|
|
13
15
|
|
|
14
16
|
await send(
|
|
15
|
-
|
|
17
|
+
`\`/revela edit\` is deprecated. Opened \`/revela refine\` in Edit mode for the active HTML deck.\n` +
|
|
16
18
|
`File: \`${result.deck.file}\`\n` +
|
|
17
19
|
`${result.stateNote}\n` +
|
|
18
20
|
`URL: ${result.url}\n\n` +
|
|
19
|
-
`Use Ctrl/Cmd
|
|
21
|
+
`Use \`/revela refine\` directly going forward. Use Ctrl/Cmd-click in the browser to reference elements, then use the Edit tab to send targeted change comments.`
|
|
20
22
|
)
|
|
21
23
|
} catch (e: any) {
|
|
22
24
|
await send(`**Edit failed:** ${e.message || String(e)}`)
|
package/lib/commands/enable.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* lib/commands/enable.ts
|
|
3
3
|
*
|
|
4
|
-
* Handler for `/revela enable` — activates Revela narrative
|
|
4
|
+
* Handler for `/revela enable` — activates Revela ambient narrative mode.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { existsSync } from "fs"
|
|
@@ -19,7 +19,7 @@ export async function handleEnable(
|
|
|
19
19
|
const design = activeDesign()
|
|
20
20
|
const domain = activeDomain()
|
|
21
21
|
|
|
22
|
-
// Always rebuild narrative mode on enable. A prior `/revela deck` handoff may
|
|
22
|
+
// Always rebuild narrative mode on enable. A prior `/revela make deck` handoff may
|
|
23
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 })
|
|
@@ -30,7 +30,7 @@ export async function handleEnable(
|
|
|
30
30
|
} catch (e) {
|
|
31
31
|
log.error("prompt rebuild failed on enable", { error: e instanceof Error ? e.message : String(e) })
|
|
32
32
|
await send(
|
|
33
|
-
`**Revela enabled (with warnings).** Narrative
|
|
33
|
+
`**Revela ambient mode enabled (with warnings).** Narrative mode is active for normal chat, ` +
|
|
34
34
|
`but the prompt file could not be built. ` +
|
|
35
35
|
`Try \`/revela disable\` then \`/revela enable\` again, or check that the package is correctly installed.\n\n` +
|
|
36
36
|
`Design: \`${design}\` · Domain: \`${domain}\``
|
|
@@ -40,9 +40,9 @@ export async function handleEnable(
|
|
|
40
40
|
|
|
41
41
|
log.info("revela enabled", { design, domain })
|
|
42
42
|
await send(
|
|
43
|
-
`**Revela enabled.**
|
|
43
|
+
`**Revela ambient mode enabled.** Normal chat will stay in Revela narrative mode.\n` +
|
|
44
44
|
`Design: \`${design}\` · Domain: \`${domain}\`\n\n` +
|
|
45
|
-
`
|
|
46
|
-
`Use \`/revela
|
|
45
|
+
`Explicit workflow commands like \`/revela init\`, \`/revela story\`, and \`/revela make deck\` work without enabling first. ` +
|
|
46
|
+
`Use \`/revela disable\` to return normal chat to plain OpenCode mode.`
|
|
47
47
|
)
|
|
48
48
|
}
|
package/lib/commands/help.ts
CHANGED
|
@@ -24,18 +24,27 @@ export async function handleHelp(
|
|
|
24
24
|
`🟠 **Domain:** \`${domain}\`\n\n` +
|
|
25
25
|
`---\n\n` +
|
|
26
26
|
`**Commands**\n\n` +
|
|
27
|
-
`\`/revela enable\` —
|
|
28
|
-
`\`/revela disable\` — disable Revela mode\n` +
|
|
27
|
+
`\`/revela enable\` — optional ambient narrative mode for normal chat\n` +
|
|
28
|
+
`\`/revela disable\` — disable ambient Revela mode\n` +
|
|
29
29
|
`\`/revela init\` — initialize or refresh workspace DECKS.json\n` +
|
|
30
|
-
`\`/revela
|
|
31
|
-
`\`/revela
|
|
32
|
-
`\`/revela
|
|
33
|
-
`\`/revela
|
|
34
|
-
`\`/revela deck
|
|
35
|
-
`\`/revela
|
|
36
|
-
`\`/revela
|
|
37
|
-
`\`/revela
|
|
30
|
+
`\`/revela research\` — research, bind evidence, and reduce story gaps\n` +
|
|
31
|
+
`\`/revela story\` — open the read-only story workspace UI\n` +
|
|
32
|
+
`\`/revela review\` — legacy readiness report for story state\n` +
|
|
33
|
+
`\`/revela narrative\` — compatibility alias for /revela story\n` +
|
|
34
|
+
`\`/revela make deck\` — make a deck from approved story state\n` +
|
|
35
|
+
`\`/revela make deck --review\` — review deck/artifact readiness before writing HTML\n` +
|
|
36
|
+
`\`/revela make brief [file.md]\` — render executive brief from approved story\n` +
|
|
37
|
+
`\`/revela deck\` — compatibility alias for /revela make deck\n` +
|
|
38
|
+
`\`/revela brief [file.md]\` — compatibility alias for /revela make brief\n` +
|
|
39
|
+
`\`/revela refine\` — open unified reading, inspection, and editing workspace\n` +
|
|
40
|
+
`\`/revela edit\` — deprecated compatibility shim to /revela refine Edit\n` +
|
|
41
|
+
`\`/revela inspect\` — deprecated compatibility shim to /revela refine Inspect\n` +
|
|
38
42
|
`\`/revela remember <text>\` — save an explicit preference to DECKS.json\n` +
|
|
43
|
+
`\`/revela design\` — list installed designs\n` +
|
|
44
|
+
`\`/revela design use <name>\` — activate a design\n` +
|
|
45
|
+
`\`/revela design new <name>\` — create a custom design with AI\n` +
|
|
46
|
+
`\`/revela design edit <name>\` — refine an existing custom design with AI\n` +
|
|
47
|
+
`\`/revela design preview [name]\` — open a design preview in browser\n` +
|
|
39
48
|
`\`/revela designs\` — list installed designs\n` +
|
|
40
49
|
`\`/revela designs <name>\` — activate a design\n` +
|
|
41
50
|
`\`/revela designs-new <name>\` — create a new custom design with AI\n` +
|
package/lib/commands/init.ts
CHANGED
|
@@ -17,7 +17,7 @@ Goal:
|
|
|
17
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
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
|
|
20
|
+
- Do not treat initialization as permission to write a deck. Narrative readiness is reviewed later by \`/revela story\`; deck/artifact readiness is reviewed by \`/revela make deck --review\`.
|
|
21
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
22
|
- ${DECKS_STATE_FILE} is the compatibility workspace-state file. Deck specs are render-target projections, not the center of initialization.
|
|
23
23
|
|
package/lib/commands/inspect.ts
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { openRefineDeck } from "../refine/open"
|
|
2
2
|
|
|
3
3
|
export async function handleInspect(
|
|
4
|
-
options: { client: any; sessionID: string; workspaceRoot: string },
|
|
4
|
+
options: { client: any; sessionID: string; workspaceRoot: string; openBrowser?: boolean },
|
|
5
5
|
send: (text: string) => Promise<void>,
|
|
6
6
|
): Promise<void> {
|
|
7
7
|
try {
|
|
8
|
-
const result =
|
|
8
|
+
const result = openRefineDeck("", {
|
|
9
9
|
client: options.client,
|
|
10
10
|
sessionID: options.sessionID,
|
|
11
11
|
workspaceRoot: options.workspaceRoot,
|
|
12
|
+
mode: "inspect",
|
|
13
|
+
openBrowser: options.openBrowser,
|
|
12
14
|
})
|
|
13
15
|
await send(
|
|
14
|
-
|
|
16
|
+
`\`/revela inspect\` is deprecated. Opened \`/revela refine\` in Inspect mode for the active HTML deck.\n` +
|
|
15
17
|
`File: \`${result.deck.file}\`\n` +
|
|
16
18
|
`${result.stateNote}\n` +
|
|
17
19
|
`URL: ${result.url}\n\n` +
|
|
18
|
-
`Use Ctrl/Cmd-click in the browser to reference deck elements
|
|
20
|
+
`Use \`/revela refine\` directly going forward. Use Ctrl/Cmd-click in the browser to reference deck elements, then use the Inspect tab for read-only Source/Purpose review. There is no chat box or freeform prompt.`
|
|
19
21
|
)
|
|
20
22
|
} catch (e: any) {
|
|
21
23
|
await send(`**Inspect failed:** ${e.message || String(e)}`)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { DECKS_STATE_FILE } from "../decks-state"
|
|
2
|
+
|
|
3
|
+
export function buildResearchPrompt({
|
|
4
|
+
exists,
|
|
5
|
+
workspaceRoot,
|
|
6
|
+
}: {
|
|
7
|
+
exists: boolean
|
|
8
|
+
workspaceRoot?: string
|
|
9
|
+
}): string {
|
|
10
|
+
const state = exists
|
|
11
|
+
? `${DECKS_STATE_FILE} exists. Read it through the revela-decks tool before researching.`
|
|
12
|
+
: `${DECKS_STATE_FILE} does not exist yet. Do not start broad internet research; initialize the workspace first with /revela init unless the user supplied a specific research question in chat.`
|
|
13
|
+
|
|
14
|
+
return `Run Revela closed-loop research.
|
|
15
|
+
|
|
16
|
+
Goal:
|
|
17
|
+
- Reduce open gaps, unsupported scope, weak evidence, unattached findings, and overextended relation rationale for the current story.
|
|
18
|
+
- Drive research from canonical narrative gaps: unsupported central claims, objections, risks, decision questions, explicit researchGaps, and claim_chain_gap warnings.
|
|
19
|
+
- Treat /revela research as authorization to bind clearly supported findings into canonical evidence without asking for item-by-item user confirmation.
|
|
20
|
+
- Preserve evidence boundaries: eliminate caveats only when evidence or narrower wording actually resolves them; otherwise keep precise caveats visible.
|
|
21
|
+
- Do not write decks, briefs, or design artifacts during research.
|
|
22
|
+
|
|
23
|
+
Current state:
|
|
24
|
+
- ${state}
|
|
25
|
+
${workspaceRoot ? `- Current workspace root: \`${workspaceRoot}\`` : ""}
|
|
26
|
+
|
|
27
|
+
Closed-loop workflow:
|
|
28
|
+
1. Call \`revela-decks\` action \`read\`, then \`reviewNarrative\`.
|
|
29
|
+
2. If current research gaps are missing or stale, call \`deriveResearchGaps\` when useful. Do not invent gaps that are not tied to a claim, objection, risk, decision, or narrative issue.
|
|
30
|
+
3. Run up to 3 research loops unless the stop conditions below are met earlier.
|
|
31
|
+
4. At the start of each loop, choose the highest-value 2-3 targets: open/in-progress high-priority gaps, unattached saved findings, unsupported central claims, weak evidence, high-priority objections/risks, and claim_chain_gap relations. Prefer targets that can improve readiness or materially reduce caveats. Do not repeat searches for claims already strongly supported.
|
|
32
|
+
5. If a target already has saved findings, prioritize binding/narrowing before doing more external search.
|
|
33
|
+
6. For targets needing external evidence, mark matching gaps \`in_progress\` with \`revela-decks updateResearchGap\`, then delegate search to the \`revela-research\` subagent. Ask it for source URLs, quotes/snippets, dates or locations when available, caveats, remaining gaps, and a \`## Recommended evidence bindings\` section with claimId, quote, source, supportScope, unsupportedScope, caveat, and strength. Save findings with \`revela-research-save\` under \`researches/{topic}/{axis}.md\` using \`## Data\`, \`## Cases\`, \`## Images\`, and \`## Gaps\` sections as applicable.
|
|
34
|
+
7. After findings are saved or existing findings are selected, read or inspect the findings file. Attach it with \`revela-decks attachResearchFindings\` when it maps to an existing research axis.
|
|
35
|
+
8. Automatically bind evidence when all binding criteria are met. Use \`revela-decks applyEvidenceCandidates\` for concrete candidate ids when available, or \`upsertNarrative\` to preserve canonical evidence bindings with exact source, URL/path, quote/snippet, support scope, unsupported scope, caveat, and strength.
|
|
36
|
+
9. Binding criteria: claimId exists; quote/snippet is traceable to the source and is not invented; source URL or workspace source path is present; supportScope and unsupportedScope are explicit; strength is strong or useful partial; caveat is preserved; binding does not expand the claim beyond the evidence.
|
|
37
|
+
10. If a claim or relation is broader than the evidence, narrow the claim text, supportedScope, unsupportedScope, or relation rationale through \`upsertNarrative\` only when the narrower wording preserves the user's strategic meaning and source boundaries. Do not silently change the decision ask, central recommendation, or approval meaning.
|
|
38
|
+
11. Update matching gaps after binding: use \`evidence_bound\` when canonical evidence was added, \`closed\` when the gap is resolved or non-researchable, \`findings_saved\` only when findings exist but binding criteria are not met, and \`open\` with notes when more external research is still warranted.
|
|
39
|
+
12. Re-run \`reviewNarrative\` after each loop. Compare against the previous loop: fewer open gaps, fewer unattached findings, stronger evidence, narrower unsupported scope, or clearer internal-data caveats should count as progress.
|
|
40
|
+
|
|
41
|
+
Stop conditions:
|
|
42
|
+
- No open externally researchable gaps remain.
|
|
43
|
+
- All useful saved findings have been attached or evidence-bound.
|
|
44
|
+
- A full loop produces no new bindable evidence, narrower wording, or gap status improvement.
|
|
45
|
+
- Remaining gaps require internal user/company data, confidential sources, or strategic judgment.
|
|
46
|
+
- 3 loops have completed.
|
|
47
|
+
|
|
48
|
+
Report format:
|
|
49
|
+
- Start with \`Research loop completed after <n> round(s).\`
|
|
50
|
+
- List bound evidence by claim id and count.
|
|
51
|
+
- List gaps closed or moved to evidence_bound.
|
|
52
|
+
- List claims or relations narrowed, with the remaining unsupported scope.
|
|
53
|
+
- List remaining caveats only as one of: \`internal_data_needed\`, \`not_publicly_researchable\`, \`source_quality_limit\`, or \`still_open\`.
|
|
54
|
+
- If no binding happened, say why binding criteria failed and what exact source type is needed next.
|
|
55
|
+
- End with the next smallest story action, not a generic request for user confirmation.
|
|
56
|
+
|
|
57
|
+
Rules:
|
|
58
|
+
- Do not use primary-agent broad websearch. Use the \`revela-research\` subagent for external search.
|
|
59
|
+
- Do not invent quotes, source paths, URLs, page references, locations, or caveats.
|
|
60
|
+
- Do not treat \`researches/**/*.md\` as canonical evidence until attached or evidence-bound, but do not stop at findings_saved when binding criteria are met.
|
|
61
|
+
- Do not mutate canonical claims merely to fit a source; narrow only to preserve evidence boundaries and avoid overstated claims.
|
|
62
|
+
- Do not ask the user to approve each evidence binding. Ask only when binding would change strategic meaning, downgrade a central claim, rely on suspicious sources, or require narrative approval.
|
|
63
|
+
- Do not store secrets, credentials, tokens, or sensitive personal information.
|
|
64
|
+
|
|
65
|
+
Start now by reading ${DECKS_STATE_FILE} through \`revela-decks\`, reviewing current readiness, and running the first research/binding loop.`
|
|
66
|
+
}
|