@cyber-dash-tech/revela 0.9.0 → 0.11.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 +54 -9
- package/README.zh-CN.md +54 -9
- package/designs/monet/DESIGN.md +9 -9
- package/designs/starter/DESIGN.md +8 -8
- package/designs/summit/DESIGN.md +9 -9
- package/lib/commands/help.ts +2 -0
- package/lib/commands/inspect.ts +23 -0
- package/lib/commands/pdf.ts +33 -5
- package/lib/commands/pptx.ts +14 -9
- package/lib/commands/refine.ts +26 -0
- package/lib/commands/review.ts +8 -2
- package/lib/deck-html/contract.ts +252 -0
- package/lib/decks-state.ts +574 -31
- package/lib/document-materials/extract.ts +20 -0
- package/lib/edit/resolve-deck.ts +13 -2
- package/lib/inspect/open.ts +63 -0
- package/lib/inspect/prompt.ts +32 -0
- package/lib/inspect/request.ts +70 -0
- package/lib/inspect/requests.ts +86 -0
- package/lib/inspect/server.ts +1063 -0
- package/lib/inspect/slide-index.ts +12 -0
- package/lib/inspection-context/compile.ts +346 -0
- package/lib/inspection-context/match.ts +169 -0
- package/lib/inspection-context/project.ts +263 -0
- package/lib/inspection-context/result.ts +160 -0
- package/lib/qa/export-gate.ts +8 -1
- package/lib/refine/open.ts +70 -0
- package/lib/refine/server.ts +1581 -0
- package/lib/workspace-state/actions.ts +71 -0
- package/lib/workspace-state/compat.ts +10 -0
- package/lib/workspace-state/evidence-status.ts +267 -0
- package/lib/workspace-state/graph.ts +426 -0
- package/lib/workspace-state/render-targets.ts +182 -0
- package/lib/workspace-state/rendered-artifacts.ts +43 -0
- package/lib/workspace-state/repository.ts +43 -0
- package/lib/workspace-state/research-attachments.ts +130 -0
- package/lib/workspace-state/review-snapshots.ts +127 -0
- package/lib/workspace-state/types.ts +119 -0
- package/package.json +1 -1
- package/plugin.ts +48 -1
- package/skill/SKILL.md +10 -5
- package/tools/decks.ts +61 -2
- package/tools/inspection-context.ts +22 -0
- package/tools/inspection-result.ts +63 -0
- package/tools/pdf.ts +9 -1
- package/tools/pptx.ts +10 -0
- package/tools/research-save.ts +15 -0
- package/tools/workspace-scan.ts +15 -0
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
**English** | [中文](README.zh-CN.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
|
-
Revela is an [OpenCode](https://opencode.ai) plugin
|
|
12
|
-
|
|
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
|
|
|
@@ -20,8 +20,10 @@ Enable it for the current session, assign a presentation task, and the agent can
|
|
|
20
20
|
- injects a presentation-specific system prompt into your current agent with `/revela enable`
|
|
21
21
|
- builds that prompt from 3 layers: core skill, active domain, active design
|
|
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
|
|
23
|
+
- keeps `DECKS.json` as the current workspace state engine for sources, research actions, findings, claims, evidence, narrative intent, render targets, and readiness
|
|
24
24
|
- checks for missing context, weak evidence, and incomplete structure before writing `decks/*.html`
|
|
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
|
|
@@ -140,7 +142,9 @@ Disable presentation mode when done:
|
|
|
140
142
|
/revela init prepare the workspace for a deck project
|
|
141
143
|
/revela review check whether context, structure, and evidence are ready
|
|
142
144
|
/revela remember <text> save an explicit user/workflow preference
|
|
145
|
+
/revela refine open unified Edit/Inspect refinement workspace
|
|
143
146
|
/revela edit open visual editor for the only deck in decks/
|
|
147
|
+
/revela inspect open Evidence Inspector for Cmd/Ctrl-click review
|
|
144
148
|
|
|
145
149
|
/revela designs list installed designs
|
|
146
150
|
/revela designs <name> activate a design
|
|
@@ -159,7 +163,7 @@ Disable presentation mode when done:
|
|
|
159
163
|
/revela pptx <file> export an HTML deck to editable PPTX in the same directory
|
|
160
164
|
```
|
|
161
165
|
|
|
162
|
-
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
|
|
166
|
+
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.
|
|
163
167
|
|
|
164
168
|
---
|
|
165
169
|
|
|
@@ -176,6 +180,22 @@ That prompt is built from 3 layers:
|
|
|
176
180
|
Persistent preferences live in `~/.config/revela/config.json`.
|
|
177
181
|
The enabled or disabled state is session-level only.
|
|
178
182
|
|
|
183
|
+
### Workspace State
|
|
184
|
+
|
|
185
|
+
`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.
|
|
186
|
+
|
|
187
|
+
The state records:
|
|
188
|
+
|
|
189
|
+
- workspace source materials and reusable extraction cache paths
|
|
190
|
+
- research plans, saved findings, and compact action provenance
|
|
191
|
+
- narrative intent, objections, risks, slide specs, claim candidates, and slide-level evidence trace
|
|
192
|
+
- render targets such as the active HTML deck plus derived PDF and PPTX artifacts
|
|
193
|
+
- review snapshots with input hashes so old readiness results become stale after meaningful state changes
|
|
194
|
+
|
|
195
|
+
0.11 keeps backward compatibility with existing root `DECKS.json` workspaces. Running `/revela init` or `/revela review` on an older project can normalize and refresh the new projection fields without requiring a manual migration, moving files, or replacing `DECKS.json` with a database.
|
|
196
|
+
|
|
197
|
+
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.
|
|
198
|
+
|
|
179
199
|
---
|
|
180
200
|
|
|
181
201
|
## Recommended Workflow
|
|
@@ -188,12 +208,13 @@ Use Revela as a guided deck-production mode:
|
|
|
188
208
|
4. Give the agent a clear deck task: audience, goal, language, number of slides, source requirements, and output path.
|
|
189
209
|
5. Use `/revela review` before writing if the deck needs research, citations, or a confirmed slide plan.
|
|
190
210
|
6. Let the agent write the HTML deck under `decks/`.
|
|
191
|
-
7. Use `/revela
|
|
192
|
-
8.
|
|
211
|
+
7. Use `/revela refine` for visual comments, targeted revisions, and optional Source/Purpose inspection of selected deck elements.
|
|
212
|
+
8. Use `/revela edit` or `/revela inspect` directly only if you need the older single-purpose shells.
|
|
213
|
+
9. Export with `/revela pdf <file>` or `/revela pptx <file>`.
|
|
193
214
|
|
|
194
215
|
`/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.
|
|
195
216
|
|
|
196
|
-
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.
|
|
217
|
+
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. In 0.11, review results are also saved as input-hashed snapshots; if sources, slide specs, evidence, narrative state, or the active render target changes afterward, the old review can no longer silently authorize a write.
|
|
197
218
|
|
|
198
219
|
To remember long-term preferences, use:
|
|
199
220
|
|
|
@@ -558,6 +579,14 @@ A custom domain is a folder containing `INDUSTRY.md`.
|
|
|
558
579
|
|
|
559
580
|
## Visual Editing
|
|
560
581
|
|
|
582
|
+
Use the unified refinement workspace for normal post-write review and revision:
|
|
583
|
+
|
|
584
|
+
```text
|
|
585
|
+
/revela refine
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
`/revela refine` opens the only HTML deck in `decks/` with two tabs. Use `Ctrl`/`Cmd` + click once to reference deck elements, then choose Edit for fast natural-language change comments or Inspect for read-only Source and Purpose review. Inspect does not mutate the deck; Edit remains the mutation path.
|
|
589
|
+
|
|
561
590
|
Open the visual editor for the only HTML deck in `decks/`:
|
|
562
591
|
|
|
563
592
|
```text
|
|
@@ -566,7 +595,7 @@ Open the visual editor for the only HTML deck in `decks/`:
|
|
|
566
595
|
|
|
567
596
|
`/revela edit` does not accept a target in Revela 0.8. If `decks/` contains exactly one `.html` file, Revela opens it. If `decks/` contains zero or multiple `.html` files, Revela asks you to generate a deck first or move extra decks to separate workspaces.
|
|
568
597
|
|
|
569
|
-
The
|
|
598
|
+
The older edit-only shell opens in your browser. Use `Ctrl`/`Cmd` + click to reference deck elements, write a natural-language comment, 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.
|
|
570
599
|
|
|
571
600
|
LLM tool equivalent: `revela-edit` with no target. This lets the agent open the same editor when you say things like “I want to edit the deck”.
|
|
572
601
|
|
|
@@ -574,6 +603,22 @@ For existing decks, `/revela edit` prepares whatever minimal project context is
|
|
|
574
603
|
|
|
575
604
|
---
|
|
576
605
|
|
|
606
|
+
## Evidence Inspector
|
|
607
|
+
|
|
608
|
+
Open the Evidence Inspector for the only HTML deck in `decks/`, or use the Inspect tab in `/revela refine`:
|
|
609
|
+
|
|
610
|
+
```text
|
|
611
|
+
/revela inspect
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
The inspector opens in your browser with the deck on the left and fixed cards on the right: Source and Purpose. Use `Ctrl`/`Cmd` + click to reference deck elements exactly like `/revela edit`, then click `Inspect Selection`. Selection is locked while the request is being processed.
|
|
615
|
+
|
|
616
|
+
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.
|
|
617
|
+
|
|
618
|
+
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.
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
577
622
|
## Export
|
|
578
623
|
|
|
579
624
|
PDF export:
|
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
|
-
Revela 是一个 [OpenCode](https://opencode.ai)
|
|
12
|
-
|
|
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
|
|
|
@@ -20,8 +20,10 @@ Revela 是一个 [OpenCode](https://opencode.ai) 插件,可以把你当前使
|
|
|
20
20
|
- 通过 `/revela enable` 向当前 agent 注入演示文稿专用 system prompt
|
|
21
21
|
- prompt 由 3 层组成:核心 skill、当前 domain、当前 design
|
|
22
22
|
- 支持工作区文档扫描,以及 `.pdf`、`.docx`、`.pptx`、`.xlsx` 的透明文本提取和嵌入素材缓存提取
|
|
23
|
-
-
|
|
23
|
+
- 将 `DECKS.json` 作为当前 workspace state engine,持续记录来源材料、调研动作、findings、claims、证据、叙事意图、render targets 和 readiness
|
|
24
24
|
- 写入 `decks/*.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
|
|
@@ -139,7 +141,9 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
|
|
|
139
141
|
/revela init 为当前 deck 项目准备工作区
|
|
140
142
|
/revela review 检查上下文、结构和证据是否 ready
|
|
141
143
|
/revela remember <text> 保存明确的用户/工作流偏好
|
|
144
|
+
/revela refine 打开统一的 Edit/Inspect refinement workspace
|
|
142
145
|
/revela edit 打开 decks/ 下唯一 deck 的可视化编辑器
|
|
146
|
+
/revela inspect 打开 Cmd/Ctrl-click 式 Evidence Inspector
|
|
143
147
|
|
|
144
148
|
/revela designs 列出已安装 design
|
|
145
149
|
/revela designs <name> 激活某个 design
|
|
@@ -158,7 +162,7 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
|
|
|
158
162
|
/revela pptx <file> 将 HTML deck 导出为同目录可编辑 PPTX
|
|
159
163
|
```
|
|
160
164
|
|
|
161
|
-
大多数 `/revela` 命令都在本地执行,不消耗 LLM token。`/revela init`、`/revela review`、`/revela remember`、`/revela designs-new` 和 `/revela designs-edit` 会启动 AI 辅助流程,因为它们需要读取或更新项目状态。`/revela
|
|
165
|
+
大多数 `/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。
|
|
162
166
|
|
|
163
167
|
---
|
|
164
168
|
|
|
@@ -175,6 +179,22 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
|
|
|
175
179
|
持久化配置保存在 `~/.config/revela/config.json`。
|
|
176
180
|
是否启用 Revela 则只在当前会话生效。
|
|
177
181
|
|
|
182
|
+
### Workspace State
|
|
183
|
+
|
|
184
|
+
`DECKS.json` 是 Revela 当前的 workspace state engine,也是兼容旧工作流的状态文件。它仍然保存在工作区根目录,也仍然可以理解为当前 deck 项目的状态入口,但 Revela 内部已经不再把它当成单纯的 deck checklist。
|
|
185
|
+
|
|
186
|
+
状态中会记录:
|
|
187
|
+
|
|
188
|
+
- 工作区来源材料和可复用的 extraction cache 路径
|
|
189
|
+
- 调研计划、已保存 findings,以及精简的 action provenance
|
|
190
|
+
- narrative intent、objections、risks、slide specs、claim candidates 和 slide-level evidence trace
|
|
191
|
+
- active HTML deck 以及派生 PDF、PPTX 等 render targets
|
|
192
|
+
- 带 input hash 的 review snapshots,使重要状态变化后旧的 readiness 自动变 stale
|
|
193
|
+
|
|
194
|
+
0.11 继续兼容已有的根目录 `DECKS.json` 工作区。对旧项目运行 `/revela init` 或 `/revela review` 时,可以安全 normalize 并刷新新的 projection 字段;用户不需要手动迁移、不需要移动文件,也不需要把 `DECKS.json` 换成数据库。
|
|
195
|
+
|
|
196
|
+
Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace state 渲染出来的目标之一。后续 briefs、appendix material、Evidence Inspector views、Q&A 和 interactive reading layers 都可以复用同一套来源/证据逻辑,而不是各自生成孤立内容。
|
|
197
|
+
|
|
178
198
|
---
|
|
179
199
|
|
|
180
200
|
## 推荐使用流程
|
|
@@ -187,12 +207,13 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
|
|
|
187
207
|
4. 给 agent 一个清楚的 deck 任务:受众、目标、语言、页数、来源要求和输出路径。
|
|
188
208
|
5. 如果 deck 需要调研、引用或已确认的 slide plan,写作前先运行 `/revela review`。
|
|
189
209
|
6. 让 agent 把 HTML deck 写到 `decks/` 下。
|
|
190
|
-
7. 用 `/revela
|
|
191
|
-
8.
|
|
210
|
+
7. 用 `/revela refine` 对选中 deck 元素做可视化评论、精准修改,以及可选的 Source/Purpose 检查。
|
|
211
|
+
8. 只有在需要旧的单一功能 shell 时,才单独使用 `/revela edit` 或 `/revela inspect`。
|
|
212
|
+
9. 用 `/revela pdf <file>` 或 `/revela pptx <file>` 导出。
|
|
192
213
|
|
|
193
214
|
`/revela review` 检查的是实际生产问题:受众是否清楚、是否缺来源材料、调研是否完成、关键 claim 是否有证据、source trace 是否太弱、页面结构是否完整、design/layout 信息是否齐全,以及轻量叙事问题,例如 so-what 不清晰、缺少风险/假设处理或转场突兀。它不会写最终 deck。
|
|
194
215
|
|
|
195
|
-
如果 Revela 阻止写入 deck,直接让 agent 运行 `/revela review`,根据报告补齐缺口后再写。这样可以避免在计划、证据或结构还不完整时覆盖真实 deck 文件。
|
|
216
|
+
如果 Revela 阻止写入 deck,直接让 agent 运行 `/revela review`,根据报告补齐缺口后再写。这样可以避免在计划、证据或结构还不完整时覆盖真实 deck 文件。0.11 还会把 review 结果保存为带 input hash 的 snapshot;如果之后来源材料、slide specs、证据、叙事状态或 active render target 发生变化,旧 review 不能继续默默授权写入。
|
|
196
217
|
|
|
197
218
|
记住长期偏好请使用:
|
|
198
219
|
|
|
@@ -523,6 +544,14 @@ Prompt 注入规则:
|
|
|
523
544
|
|
|
524
545
|
## 可视化编辑
|
|
525
546
|
|
|
547
|
+
正常的写后 review 和修改建议使用统一 refinement workspace:
|
|
548
|
+
|
|
549
|
+
```text
|
|
550
|
+
/revela refine
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
`/revela refine` 会打开 `decks/` 下唯一的 HTML deck,并提供两个 tab。使用 `Ctrl`/`Cmd` + click 先引用 deck 元素,然后在 Edit 里快速写自然语言修改评论,或在 Inspect 里做只读 Source 和 Purpose 检查。Inspect 不会修改 deck;真正的 mutation 仍然只走 Edit。
|
|
554
|
+
|
|
526
555
|
打开 `decks/` 下唯一 HTML deck 的可视化编辑器:
|
|
527
556
|
|
|
528
557
|
```text
|
|
@@ -531,7 +560,7 @@ Prompt 注入规则:
|
|
|
531
560
|
|
|
532
561
|
Revela 0.8 中 `/revela edit` 不接受 target。如果 `decks/` 下正好有一个 `.html` 文件,Revela 会打开它。如果 `decks/` 下没有 HTML 或有多个 HTML,Revela 会提示先生成 deck,或把多余 deck 移到独立 workspace。
|
|
533
562
|
|
|
534
|
-
|
|
563
|
+
旧的 edit-only shell 会在浏览器中打开。使用 `Ctrl`/`Cmd` + 点击 deck 元素来引用它们,写一段自然语言评论,然后发送回 OpenCode。Revela 会把 deck 文件、slide 上下文、选中元素 metadata 和你的评论整理成结构化 edit prompt。
|
|
535
564
|
|
|
536
565
|
对应的 LLM tool:`revela-edit`,不需要 target。因此当你说“我要编辑这个 deck”时,agent 也可以主动打开同一个编辑器。
|
|
537
566
|
|
|
@@ -539,6 +568,22 @@ Revela 0.8 中 `/revela edit` 不接受 target。如果 `decks/` 下正好有一
|
|
|
539
568
|
|
|
540
569
|
---
|
|
541
570
|
|
|
571
|
+
## Evidence Inspector
|
|
572
|
+
|
|
573
|
+
打开 `decks/` 下唯一 HTML deck 的 Evidence Inspector,或直接使用 `/revela refine` 里的 Inspect tab:
|
|
574
|
+
|
|
575
|
+
```text
|
|
576
|
+
/revela inspect
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Inspector 会在浏览器中打开,左侧是 deck,右侧是固定卡片:Source 和 Purpose。使用 `Ctrl`/`Cmd` + click 像 `/revela edit` 一样引用 deck 元素,然后点击 `Inspect Selection`。请求处理期间,deck 选择会被锁定。
|
|
580
|
+
|
|
581
|
+
Inspector 不是聊天,也没有自由输入框。它不会修改 `DECKS.json` 或 deck HTML。它使用已记录的 slide spec、narrative state 和 slide-level evidence trace 作为 grounded context。确定性预处理会立即显示;LLM judgment 随后 lazy 更新 Source 和 Purpose 卡片,不会强行生成编辑动作。
|
|
582
|
+
|
|
583
|
+
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 工作流信任它之前被拒绝或报告。
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
542
587
|
## 导出
|
|
543
588
|
|
|
544
589
|
PDF 导出:
|
package/designs/monet/DESIGN.md
CHANGED
|
@@ -193,10 +193,10 @@ Every generated presentation must use this exact HTML skeleton:
|
|
|
193
193
|
<style>/* all CSS here */</style>
|
|
194
194
|
</head>
|
|
195
195
|
<body>
|
|
196
|
-
<section class="slide cover-slide" slide-qa="false" data-index="
|
|
196
|
+
<section class="slide cover-slide" slide-qa="false" data-slide-index="1">
|
|
197
197
|
<div class="slide-canvas"> ... </div>
|
|
198
198
|
</section>
|
|
199
|
-
<section class="slide" slide-qa="true" data-index="
|
|
199
|
+
<section class="slide" slide-qa="true" data-slide-index="2">
|
|
200
200
|
<div class="slide-canvas"> ... </div>
|
|
201
201
|
</section>
|
|
202
202
|
<script>/* all JS here */</script>
|
|
@@ -507,7 +507,7 @@ These rules are mandatory for Monet.
|
|
|
507
507
|
|
|
508
508
|
### Layout Types
|
|
509
509
|
|
|
510
|
-
Each `<section class="slide">` must set `slide-qa="true"` or `slide-qa="false"`. Use the QA column to decide which value to write. Fetch any layout with the `revela-designs` tool (`action: "read"`, `layout: "<name>"`).
|
|
510
|
+
Each `<section class="slide">` must set `slide-qa="true"` or `slide-qa="false"`. It must also set `data-slide-index="N"`, where `N` is the 1-based `DECKS.json` `slides[].index` value. Use the QA column to decide which value to write. Fetch any layout with the `revela-designs` tool (`action: "read"`, `layout: "<name>"`).
|
|
511
511
|
|
|
512
512
|
<!-- @layout:fullbleed:start qa=false -->
|
|
513
513
|
#### Fullbleed
|
|
@@ -518,7 +518,7 @@ Structural intent:
|
|
|
518
518
|
- Single slot: place one `image-title` component directly inside `.page`. The component is self-contained — it manages its own image, blur, overlay, and text layers internally.
|
|
519
519
|
|
|
520
520
|
```html
|
|
521
|
-
<section class="slide" slide-qa="false" data-index="N">
|
|
521
|
+
<section class="slide" slide-qa="false" data-slide-index="N">
|
|
522
522
|
<div class="slide-canvas">
|
|
523
523
|
<div class="page" style="padding:0;">
|
|
524
524
|
|
|
@@ -550,7 +550,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
550
550
|
|
|
551
551
|
|
|
552
552
|
```html
|
|
553
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
553
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
554
554
|
<div class="slide-canvas">
|
|
555
555
|
<div class="page" style="padding:0;overflow:hidden;">
|
|
556
556
|
<div class="narrative-grid">
|
|
@@ -610,7 +610,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
610
610
|
|
|
611
611
|
|
|
612
612
|
```html
|
|
613
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
613
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
614
614
|
<div class="slide-canvas">
|
|
615
615
|
<div class="page" style="padding:0;overflow:hidden;">
|
|
616
616
|
<div class="narrative-grid narrative-grid--reverse">
|
|
@@ -649,7 +649,7 @@ Structural intent:
|
|
|
649
649
|
Every slot accepts 1 or more components. Add or remove child divs to control column count — 3 is the default, but 4 or 5 columns work equally well.
|
|
650
650
|
|
|
651
651
|
```html
|
|
652
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
652
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
653
653
|
<div class="slide-canvas">
|
|
654
654
|
<div class="page">
|
|
655
655
|
<div style="display:flex;flex-direction:column;gap:10px;margin-bottom:28px;max-width:520px;">
|
|
@@ -714,7 +714,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
714
714
|
|
|
715
715
|
|
|
716
716
|
```html
|
|
717
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
717
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
718
718
|
<div class="slide-canvas">
|
|
719
719
|
<div class="page" style="overflow:hidden;">
|
|
720
720
|
<div class="halves-grid" style="flex:1;min-height:0;">
|
|
@@ -768,7 +768,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
768
768
|
|
|
769
769
|
|
|
770
770
|
```html
|
|
771
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
771
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
772
772
|
<div class="slide-canvas">
|
|
773
773
|
<div class="page" style="padding:0;">
|
|
774
774
|
<div class="stacked-grid">
|
|
@@ -117,7 +117,7 @@ Every generated presentation must use this exact HTML skeleton:
|
|
|
117
117
|
<style>/* all CSS here */</style>
|
|
118
118
|
</head>
|
|
119
119
|
<body>
|
|
120
|
-
<section class="slide" slide-qa="false" data-index="
|
|
120
|
+
<section class="slide" slide-qa="false" data-slide-index="1">
|
|
121
121
|
<div class="slide-canvas"><div class="page">...</div></div>
|
|
122
122
|
</section>
|
|
123
123
|
<script>/* all JS here */</script>
|
|
@@ -246,7 +246,7 @@ new SlidePresentation();
|
|
|
246
246
|
|
|
247
247
|
### Layout Types
|
|
248
248
|
|
|
249
|
-
Each `<section class="slide">` must set `slide-qa="true"` or `slide-qa="false"`. Use the QA flag on each layout marker.
|
|
249
|
+
Each `<section class="slide">` must set `slide-qa="true"` or `slide-qa="false"`. Use the QA flag on each layout marker. It must also set `data-slide-index="N"`, where `N` is the 1-based `DECKS.json` `slides[].index` value.
|
|
250
250
|
|
|
251
251
|
<!-- @layout:fullbleed:start qa=false -->
|
|
252
252
|
#### Fullbleed
|
|
@@ -254,7 +254,7 @@ Each `<section class="slide">` must set `slide-qa="true"` or `slide-qa="false"`.
|
|
|
254
254
|
Full-page layout for a single dominant component such as `image-title`, a large `svg-motif`, or a sparse title field.
|
|
255
255
|
|
|
256
256
|
```html
|
|
257
|
-
<section class="slide" slide-qa="false" data-index="N">
|
|
257
|
+
<section class="slide" slide-qa="false" data-slide-index="N">
|
|
258
258
|
<div class="slide-canvas">
|
|
259
259
|
<div class="page" style="padding:0;">
|
|
260
260
|
<!-- [slot: content] — usually image-title, svg-motif, or a custom hero component -->
|
|
@@ -270,7 +270,7 @@ Full-page layout for a single dominant component such as `image-title`, a large
|
|
|
270
270
|
Asymmetric two-column layout. Use when one side needs more visual or reading weight.
|
|
271
271
|
|
|
272
272
|
```html
|
|
273
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
273
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
274
274
|
<div class="slide-canvas">
|
|
275
275
|
<div class="page" style="padding:0;">
|
|
276
276
|
<div class="narrative-grid">
|
|
@@ -295,7 +295,7 @@ Asymmetric two-column layout. Use when one side needs more visual or reading wei
|
|
|
295
295
|
Mirrored asymmetric two-column layout. Same structure as `narrative`, with the wider column on the right.
|
|
296
296
|
|
|
297
297
|
```html
|
|
298
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
298
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
299
299
|
<div class="slide-canvas">
|
|
300
300
|
<div class="page" style="padding:0;">
|
|
301
301
|
<div class="narrative-grid narrative-grid--reverse">
|
|
@@ -314,7 +314,7 @@ Mirrored asymmetric two-column layout. Same structure as `narrative`, with the w
|
|
|
314
314
|
Equal-column layout for parallel ideas, feature groups, proof points, or compact component showcases.
|
|
315
315
|
|
|
316
316
|
```html
|
|
317
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
317
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
318
318
|
<div class="slide-canvas">
|
|
319
319
|
<div class="page">
|
|
320
320
|
<div style="display:flex;flex-direction:column;gap:10px;margin-bottom:28px;max-width:620px;">
|
|
@@ -343,7 +343,7 @@ Equal-column layout for parallel ideas, feature groups, proof points, or compact
|
|
|
343
343
|
Symmetric two-column layout for direct comparison, paired evidence, or split workflows.
|
|
344
344
|
|
|
345
345
|
```html
|
|
346
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
346
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
347
347
|
<div class="slide-canvas">
|
|
348
348
|
<div class="page" style="padding:0;">
|
|
349
349
|
<div class="halves-grid">
|
|
@@ -367,7 +367,7 @@ Symmetric two-column layout for direct comparison, paired evidence, or split wor
|
|
|
367
367
|
Two-row layout for a compact header/summary above a larger evidence, chart, or flow area.
|
|
368
368
|
|
|
369
369
|
```html
|
|
370
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
370
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
371
371
|
<div class="slide-canvas">
|
|
372
372
|
<div class="page" style="padding:0;">
|
|
373
373
|
<div class="stacked-grid">
|
package/designs/summit/DESIGN.md
CHANGED
|
@@ -131,10 +131,10 @@ Every generated presentation must use this exact HTML skeleton:
|
|
|
131
131
|
<style>/* all CSS here */</style>
|
|
132
132
|
</head>
|
|
133
133
|
<body>
|
|
134
|
-
<section class="slide cover-slide" slide-qa="false" data-index="
|
|
134
|
+
<section class="slide cover-slide" slide-qa="false" data-slide-index="1">
|
|
135
135
|
<div class="slide-canvas"> ... </div>
|
|
136
136
|
</section>
|
|
137
|
-
<section class="slide" slide-qa="true" data-index="
|
|
137
|
+
<section class="slide" slide-qa="true" data-slide-index="2">
|
|
138
138
|
<div class="slide-canvas"> ... </div>
|
|
139
139
|
</section>
|
|
140
140
|
<script>/* all JS here */</script>
|
|
@@ -445,7 +445,7 @@ These rules are mandatory for Summit.
|
|
|
445
445
|
|
|
446
446
|
### Layout Types
|
|
447
447
|
|
|
448
|
-
Each `<section class="slide">` must set `slide-qa="true"` or `slide-qa="false"`. Use the QA column to decide which value to write. Fetch any layout with the `revela-designs` tool (`action: "read"`, `layout: "<name>"`).
|
|
448
|
+
Each `<section class="slide">` must set `slide-qa="true"` or `slide-qa="false"`. It must also set `data-slide-index="N"`, where `N` is the 1-based `DECKS.json` `slides[].index` value. Use the QA column to decide which value to write. Fetch any layout with the `revela-designs` tool (`action: "read"`, `layout: "<name>"`).
|
|
449
449
|
|
|
450
450
|
<!-- @layout:fullbleed:start qa=false -->
|
|
451
451
|
#### Fullbleed
|
|
@@ -456,7 +456,7 @@ Structural intent:
|
|
|
456
456
|
- Single slot: place one `image-title` component directly inside `.page`. The component is self-contained — it manages its own image, blur, overlay, and text layers internally.
|
|
457
457
|
|
|
458
458
|
```html
|
|
459
|
-
<section class="slide" slide-qa="false" data-index="N">
|
|
459
|
+
<section class="slide" slide-qa="false" data-slide-index="N">
|
|
460
460
|
<div class="slide-canvas">
|
|
461
461
|
<div class="page" style="padding:0;">
|
|
462
462
|
|
|
@@ -488,7 +488,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
488
488
|
|
|
489
489
|
|
|
490
490
|
```html
|
|
491
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
491
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
492
492
|
<div class="slide-canvas">
|
|
493
493
|
<div class="page" style="padding:0;overflow:hidden;">
|
|
494
494
|
<div class="narrative-grid">
|
|
@@ -548,7 +548,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
548
548
|
|
|
549
549
|
|
|
550
550
|
```html
|
|
551
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
551
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
552
552
|
<div class="slide-canvas">
|
|
553
553
|
<div class="page" style="padding:0;overflow:hidden;">
|
|
554
554
|
<div class="narrative-grid narrative-grid--reverse">
|
|
@@ -587,7 +587,7 @@ Structural intent:
|
|
|
587
587
|
Every slot accepts 1 or more components. Add or remove child divs to control column count — 3 is the default, but 4 or 5 columns work equally well.
|
|
588
588
|
|
|
589
589
|
```html
|
|
590
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
590
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
591
591
|
<div class="slide-canvas">
|
|
592
592
|
<div class="page">
|
|
593
593
|
<div style="display:flex;flex-direction:column;gap:10px;margin-bottom:28px;max-width:520px;">
|
|
@@ -652,7 +652,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
652
652
|
|
|
653
653
|
|
|
654
654
|
```html
|
|
655
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
655
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
656
656
|
<div class="slide-canvas">
|
|
657
657
|
<div class="page" style="overflow:hidden;">
|
|
658
658
|
<div class="halves-grid" style="flex:1;min-height:0;">
|
|
@@ -706,7 +706,7 @@ Every slot accepts 1 or more components. The LLM decides what each slot contains
|
|
|
706
706
|
|
|
707
707
|
|
|
708
708
|
```html
|
|
709
|
-
<section class="slide" slide-qa="true" data-index="N">
|
|
709
|
+
<section class="slide" slide-qa="true" data-slide-index="N">
|
|
710
710
|
<div class="slide-canvas">
|
|
711
711
|
<div class="page" style="padding:0;">
|
|
712
712
|
<div class="stacked-grid">
|
package/lib/commands/help.ts
CHANGED
|
@@ -28,7 +28,9 @@ export async function handleHelp(
|
|
|
28
28
|
`\`/revela disable\` — disable slide generation mode\n` +
|
|
29
29
|
`\`/revela init\` — initialize or refresh workspace DECKS.json\n` +
|
|
30
30
|
`\`/revela review\` — review current deck readiness before writing HTML\n` +
|
|
31
|
+
`\`/revela refine\` — open unified Edit/Inspect refinement workspace\n` +
|
|
31
32
|
`\`/revela edit\` — open visual editor for the only deck in decks/\n` +
|
|
33
|
+
`\`/revela inspect\` — open Evidence Inspector for click-to-inspect review\n` +
|
|
32
34
|
`\`/revela remember <text>\` — save an explicit preference to DECKS.json\n` +
|
|
33
35
|
`\`/revela designs\` — list installed designs\n` +
|
|
34
36
|
`\`/revela designs <name>\` — activate a design\n` +
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { openInspectDeck } from "../inspect/open"
|
|
2
|
+
|
|
3
|
+
export async function handleInspect(
|
|
4
|
+
options: { client: any; sessionID: string; workspaceRoot: string },
|
|
5
|
+
send: (text: string) => Promise<void>,
|
|
6
|
+
): Promise<void> {
|
|
7
|
+
try {
|
|
8
|
+
const result = openInspectDeck("", {
|
|
9
|
+
client: options.client,
|
|
10
|
+
sessionID: options.sessionID,
|
|
11
|
+
workspaceRoot: options.workspaceRoot,
|
|
12
|
+
})
|
|
13
|
+
await send(
|
|
14
|
+
`Opened Evidence Inspector for the active HTML deck.\n` +
|
|
15
|
+
`File: \`${result.deck.file}\`\n` +
|
|
16
|
+
`${result.stateNote}\n` +
|
|
17
|
+
`URL: ${result.url}\n\n` +
|
|
18
|
+
`Use Ctrl/Cmd-click in the browser to reference deck elements exactly like /revela edit, then click Inspect Selection. Deterministic Source/Purpose preprocessing appears first, followed by lazy LLM-generated cards. Selection is locked while the request is processed. There is no chat box or freeform prompt.`
|
|
19
|
+
)
|
|
20
|
+
} catch (e: any) {
|
|
21
|
+
await send(`**Inspect failed:** ${e.message || String(e)}`)
|
|
22
|
+
}
|
|
23
|
+
}
|
package/lib/commands/pdf.ts
CHANGED
|
@@ -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
|
-
|
|
22
|
+
const root = resolve(workspaceRoot)
|
|
23
|
+
const resolvedFile = resolvePdfDeckFile(root, filePath)
|
|
24
|
+
|
|
25
|
+
if (!resolvedFile) {
|
|
19
26
|
await send(
|
|
20
|
-
"**Usage:** `/revela pdf
|
|
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 =
|
|
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(
|
|
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
|
+
}
|