@cyber-dash-tech/revela 0.7.8 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/README.zh-CN.md +14 -14
- package/designs/starter/DESIGN.md +118 -14
- package/designs/starter/preview.html +48 -12
- package/lib/agents/research-prompt.ts +4 -4
- package/lib/commands/designs-new.ts +14 -0
- package/lib/commands/edit.ts +3 -6
- package/lib/commands/help.ts +2 -2
- package/lib/commands/init.ts +6 -5
- package/lib/commands/review.ts +5 -8
- package/lib/decks-state.ts +58 -12
- package/lib/design/designs.ts +20 -0
- package/lib/edit/deck-state.ts +8 -2
- package/lib/edit/open.ts +31 -3
- package/lib/edit/resolve-deck.ts +20 -75
- package/lib/edit/server.ts +196 -54
- package/package.json +1 -1
- package/plugin.ts +37 -3
- package/skill/SKILL.md +31 -26
- package/tools/decks.ts +13 -11
- package/tools/edit.ts +6 -10
- package/tools/media-batch-save.ts +1 -1
- package/tools/media-save.ts +1 -1
- package/tools/research-images-list.ts +1 -1
- package/tools/research-save.ts +10 -10
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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" />
|
|
@@ -112,7 +112,7 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
|
|
|
112
112
|
Before the agent writes `decks/humanoid-robotics.html`, it must update `DECKS.json` through the `revela-decks` tool with the active deck, confirmed slide specs, layouts, components, and computed `writeReadiness.status: ready`. You can ask for an explicit readiness check at any time:
|
|
113
113
|
|
|
114
114
|
```text
|
|
115
|
-
/revela review
|
|
115
|
+
/revela review
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
Export when needed, either manually or by asking the agent to export:
|
|
@@ -138,9 +138,9 @@ Disable presentation mode when done:
|
|
|
138
138
|
/revela disable disable presentation mode
|
|
139
139
|
|
|
140
140
|
/revela init initialize or refresh workspace DECKS.json
|
|
141
|
-
/revela review
|
|
141
|
+
/revela review review current deck readiness before writing HTML
|
|
142
142
|
/revela remember <text> save an explicit user/workflow preference
|
|
143
|
-
/revela edit
|
|
143
|
+
/revela edit open visual editor for the only deck in decks/
|
|
144
144
|
|
|
145
145
|
/revela designs list installed designs
|
|
146
146
|
/revela designs <name> activate a design
|
|
@@ -185,7 +185,7 @@ Revela uses a workspace-root `DECKS.json` file for cross-session continuity and
|
|
|
185
185
|
It has two jobs:
|
|
186
186
|
|
|
187
187
|
- workspace memory: stable project context, source materials, explicit user preferences, deck history, and open questions
|
|
188
|
-
- active deck spec: current deck
|
|
188
|
+
- active deck spec: current deck output path, prerequisites, research plan, per-slide content, layouts, components, evidence, visuals, blockers, and write readiness
|
|
189
189
|
|
|
190
190
|
`DECKS.json` is the source of truth for workspace memory and deck readiness.
|
|
191
191
|
|
|
@@ -198,7 +198,7 @@ Create or refresh it with:
|
|
|
198
198
|
Review the current deck state with:
|
|
199
199
|
|
|
200
200
|
```text
|
|
201
|
-
/revela review
|
|
201
|
+
/revela review
|
|
202
202
|
```
|
|
203
203
|
|
|
204
204
|
`/revela review` does not write the final HTML deck. It reads and updates `DECKS.json` through the `revela-decks` tool, checks what is missing, and sets `writeReadiness.status` to `ready` only when the deck is ready to generate.
|
|
@@ -351,7 +351,7 @@ You can ask Revela to create a new local design interactively:
|
|
|
351
351
|
/revela designs-new my-design
|
|
352
352
|
```
|
|
353
353
|
|
|
354
|
-
The agent will interview you for visual references, summarize a design brief for confirmation, then save `DESIGN.md` and `preview.html` into your local Revela designs directory. The default structural base is an internal neutral `starter` design, which is hidden from the normal design list. Use `--base summit` or `--base monet` only when you want to derive from those specific styles.
|
|
354
|
+
The agent will interview you for visual references, summarize a design brief for confirmation, then save `DESIGN.md` and `preview.html` into your local Revela designs directory. For AI-authored designs, `preview.html` is required: it must include cover and closing slides, and it must showcase every `@component:*` before `revela-designs-author` will accept the package. The default structural base is an internal neutral `starter` design, which is hidden from the normal design list. Use `--base summit` or `--base monet` only when you want to derive from those specific styles.
|
|
355
355
|
|
|
356
356
|
Refine an existing local design:
|
|
357
357
|
|
|
@@ -374,7 +374,7 @@ Recommended structure:
|
|
|
374
374
|
```text
|
|
375
375
|
my-design/
|
|
376
376
|
├── DESIGN.md
|
|
377
|
-
└── preview.html
|
|
377
|
+
└── preview.html required for AI-authored designs
|
|
378
378
|
```
|
|
379
379
|
|
|
380
380
|
`DESIGN.md` starts with frontmatter metadata:
|
|
@@ -565,7 +565,9 @@ If a design has no markers, Revela falls back to injecting the full `DESIGN.md`
|
|
|
565
565
|
- Put the non-negotiable rules in `foundation` and `rules`; do not hide essential constraints only inside one layout
|
|
566
566
|
- Keep layout names semantically meaningful; they become the vocabulary the model sees in the layout index
|
|
567
567
|
- If your design defines a custom CSS class, document that class inside `DESIGN.md`; QA checks can flag classes not present in the design vocabulary
|
|
568
|
-
-
|
|
568
|
+
- For AI-authored designs, `preview.html` must include `<section class="slide" data-slide-role="cover">` and `<section class="slide" data-slide-role="closing">`
|
|
569
|
+
- For AI-authored designs, `preview.html` must visibly showcase every `@component:*` and mark each sample with `data-preview-component="<component-name>"`; otherwise `revela-designs-author create/validate` will fail
|
|
570
|
+
- When the design supports chart styling, include a 3x3 ECharts gallery with at least 9 chart examples in `preview.html`; this is a quality requirement for the agent workflow, not a hard validation blocker
|
|
569
571
|
|
|
570
572
|
Install a custom design:
|
|
571
573
|
|
|
@@ -591,19 +593,17 @@ A custom domain is a folder containing `INDUSTRY.md`.
|
|
|
591
593
|
|
|
592
594
|
## Visual Editing
|
|
593
595
|
|
|
594
|
-
Open the visual editor for the
|
|
596
|
+
Open the visual editor for the only HTML deck in `decks/`:
|
|
595
597
|
|
|
596
598
|
```text
|
|
597
599
|
/revela edit
|
|
598
|
-
/revela edit my-deck
|
|
599
|
-
/revela edit decks/my-deck.html
|
|
600
600
|
```
|
|
601
601
|
|
|
602
|
-
|
|
602
|
+
`/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.
|
|
603
603
|
|
|
604
604
|
The editor 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.
|
|
605
605
|
|
|
606
|
-
LLM tool equivalent: `revela-edit` with
|
|
606
|
+
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”.
|
|
607
607
|
|
|
608
608
|
`/revela edit` prepares minimal `DECKS.json` state for the existing HTML deck if needed, so the normal deck write gate can still protect `decks/*.html` while allowing targeted edits.
|
|
609
609
|
|
package/README.zh-CN.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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" />
|
|
@@ -111,7 +111,7 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
|
|
|
111
111
|
在 agent 写入 `decks/humanoid-robotics.html` 之前,它必须通过 `revela-decks` 工具更新 `DECKS.json`:记录 active deck、已确认的逐页规格、layout、component,并由工具计算出 `writeReadiness.status: ready`。你也可以随时显式触发 readiness 检查:
|
|
112
112
|
|
|
113
113
|
```text
|
|
114
|
-
/revela review
|
|
114
|
+
/revela review
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
需要导出时,可以手动调用,也可以让 agent 直接导出:
|
|
@@ -137,9 +137,9 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
|
|
|
137
137
|
/revela disable 关闭演示文稿模式
|
|
138
138
|
|
|
139
139
|
/revela init 初始化或刷新工作区 DECKS.json
|
|
140
|
-
/revela review
|
|
140
|
+
/revela review 写 HTML 前检查当前 deck readiness
|
|
141
141
|
/revela remember <text> 保存明确的用户/工作流偏好
|
|
142
|
-
/revela edit
|
|
142
|
+
/revela edit 打开 decks/ 下唯一 deck 的可视化编辑器
|
|
143
143
|
|
|
144
144
|
/revela designs 列出已安装 design
|
|
145
145
|
/revela designs <name> 激活某个 design
|
|
@@ -184,7 +184,7 @@ Revela 使用工作区根目录的 `DECKS.json` 做跨会话记忆和 deck 生
|
|
|
184
184
|
它有两个职责:
|
|
185
185
|
|
|
186
186
|
- 工作区记忆:稳定项目背景、源材料、明确用户偏好、历史 deck 和开放问题
|
|
187
|
-
- active deck 规格:当前 deck
|
|
187
|
+
- active deck 规格:当前 deck 输出路径、前置条件、research plan、逐页内容、layout、component、证据、视觉需求、blocker 和 write readiness
|
|
188
188
|
|
|
189
189
|
`DECKS.json` 是工作区记忆和 deck readiness 的 source of truth。
|
|
190
190
|
|
|
@@ -197,7 +197,7 @@ Revela 使用工作区根目录的 `DECKS.json` 做跨会话记忆和 deck 生
|
|
|
197
197
|
检查当前 deck 状态:
|
|
198
198
|
|
|
199
199
|
```text
|
|
200
|
-
/revela review
|
|
200
|
+
/revela review
|
|
201
201
|
```
|
|
202
202
|
|
|
203
203
|
`/revela review` 不会写最终 HTML deck。它通过 `revela-decks` 工具读取并更新 `DECKS.json`,检查缺失项,并且只有在 deck 真的可以生成时才把 `writeReadiness.status` 设为 `ready`。
|
|
@@ -317,7 +317,7 @@ Revela 使用工作区根目录的 `DECKS.json` 做跨会话记忆和 deck 生
|
|
|
317
317
|
/revela designs-new my-design
|
|
318
318
|
```
|
|
319
319
|
|
|
320
|
-
Agent 会先询问你的审美参考,整理设计 brief 并等待确认,然后把 `DESIGN.md` 和 `preview.html` 保存到本地 Revela designs
|
|
320
|
+
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`。
|
|
321
321
|
|
|
322
322
|
调整已有本地 design:
|
|
323
323
|
|
|
@@ -340,7 +340,7 @@ Agent 会询问你想修改什么,读取当前 design,整理 edit brief 并
|
|
|
340
340
|
```text
|
|
341
341
|
my-design/
|
|
342
342
|
├── DESIGN.md
|
|
343
|
-
└── preview.html
|
|
343
|
+
└── preview.html AI 生成 design 必需
|
|
344
344
|
```
|
|
345
345
|
|
|
346
346
|
`DESIGN.md` 顶部使用 frontmatter:
|
|
@@ -530,7 +530,9 @@ Prompt 注入规则:
|
|
|
530
530
|
- 把不可妥协的规则放进 `foundation` 和 `rules`,不要只藏在某个 layout 里
|
|
531
531
|
- layout 名称尽量语义化,因为模型在 layout index 里首先看到的就是这些名字
|
|
532
532
|
- 如果定义了自定义 CSS class,记得在 `DESIGN.md` 里写出来;QA 会检查 design 词汇表之外的新 class
|
|
533
|
-
-
|
|
533
|
+
- AI 生成的 design 必须在 `preview.html` 中包含 `<section class="slide" data-slide-role="cover">` 和 `<section class="slide" data-slide-role="closing">`
|
|
534
|
+
- AI 生成的 design 必须在 `preview.html` 中可视化展示每个 `@component:*`,并用 `data-preview-component="<component-name>"` 标记;否则 `revela-designs-author create/validate` 会失败
|
|
535
|
+
- 如果 design 支持图表样式,`preview.html` 应包含 3x3 ECharts 九宫格,至少展示 9 个 chart 示例;这是 agent 工作流的质量要求,不是硬校验 blocker
|
|
534
536
|
|
|
535
537
|
安装自定义 design:
|
|
536
538
|
|
|
@@ -556,19 +558,17 @@ Prompt 注入规则:
|
|
|
556
558
|
|
|
557
559
|
## 可视化编辑
|
|
558
560
|
|
|
559
|
-
|
|
561
|
+
打开 `decks/` 下唯一 HTML deck 的可视化编辑器:
|
|
560
562
|
|
|
561
563
|
```text
|
|
562
564
|
/revela edit
|
|
563
|
-
/revela edit my-deck
|
|
564
|
-
/revela edit decks/my-deck.html
|
|
565
565
|
```
|
|
566
566
|
|
|
567
|
-
|
|
567
|
+
Revela 0.8 中 `/revela edit` 不接受 target。如果 `decks/` 下正好有一个 `.html` 文件,Revela 会打开它。如果 `decks/` 下没有 HTML 或有多个 HTML,Revela 会提示先生成 deck,或把多余 deck 移到独立 workspace。
|
|
568
568
|
|
|
569
569
|
编辑器会在浏览器中打开。使用 `Ctrl`/`Cmd` + 点击 deck 元素来引用它们,写一段自然语言评论,然后发送回 OpenCode。Revela 会把 deck 文件、slide 上下文、选中元素 metadata 和你的评论整理成结构化 edit prompt。
|
|
570
570
|
|
|
571
|
-
对应的 LLM tool:`revela-edit
|
|
571
|
+
对应的 LLM tool:`revela-edit`,不需要 target。因此当你说“我要编辑这个 deck”时,agent 也可以主动打开同一个编辑器。
|
|
572
572
|
|
|
573
573
|
如果已有 HTML deck 缺少 `DECKS.json` 状态,`/revela edit` 会自动准备最小 deck state,让正常的 `decks/*.html` 写入门禁仍然生效,同时允许后续精准修改。
|
|
574
574
|
|
|
@@ -692,35 +692,139 @@ Small page number utility.
|
|
|
692
692
|
<!-- @component:timeline-journey-horizontal:start -->
|
|
693
693
|
#### Timeline Journey Horizontal (.timeline-journey-horizontal)
|
|
694
694
|
|
|
695
|
-
Horizontal
|
|
695
|
+
Horizontal milestone journey with a central axis line. Nodes sit on the axis; a dashed vertical stem leads to a tip dot, with date, title, and description text alongside. Alternate nodes above and below the axis for rhythm. Suitable for 4-8 milestones across a chronological arc, transformation story, roadmap, or multi-year programme recap.
|
|
696
696
|
|
|
697
697
|
```html
|
|
698
|
-
<div class="timeline-journey-horizontal"
|
|
698
|
+
<div class="timeline-journey-horizontal" data-preview-component="timeline-journey-horizontal">
|
|
699
|
+
<div class="tjh-axis"></div>
|
|
700
|
+
|
|
701
|
+
<!-- Up node: label, tip-dot, stem, axis-dot. Content grows upward. -->
|
|
702
|
+
<div class="tjh-item tjh-item--up" style="left:12%; --tjh-item-color:var(--accent-primary);">
|
|
703
|
+
<div class="tjh-label">
|
|
704
|
+
<span class="tjh-date">Q1</span>
|
|
705
|
+
<span class="tjh-title">Baseline</span>
|
|
706
|
+
<span class="tjh-text">Map current signals and establish the reference state.</span>
|
|
707
|
+
</div>
|
|
708
|
+
<div class="tjh-tip-dot"></div>
|
|
709
|
+
<div class="tjh-stem"></div>
|
|
710
|
+
<div class="tjh-axis-dot"></div>
|
|
711
|
+
</div>
|
|
712
|
+
|
|
713
|
+
<!-- Down node: axis-dot, stem, tip-dot, label. Content grows downward. -->
|
|
714
|
+
<div class="tjh-item tjh-item--down" style="left:34%; --tjh-item-color:var(--accent-secondary);">
|
|
715
|
+
<div class="tjh-axis-dot"></div>
|
|
716
|
+
<div class="tjh-stem"></div>
|
|
717
|
+
<div class="tjh-tip-dot"></div>
|
|
718
|
+
<div class="tjh-label">
|
|
719
|
+
<span class="tjh-date">Q2</span>
|
|
720
|
+
<span class="tjh-title">Prototype</span>
|
|
721
|
+
<span class="tjh-text">Convert the plan into visible experiments.</span>
|
|
722
|
+
</div>
|
|
723
|
+
</div>
|
|
724
|
+
</div>
|
|
699
725
|
```
|
|
700
726
|
|
|
701
727
|
```css
|
|
702
|
-
.timeline-journey-horizontal {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
728
|
+
.timeline-journey-horizontal {
|
|
729
|
+
--tjh-node: 12px;
|
|
730
|
+
--tjh-stem-h: 76px;
|
|
731
|
+
--tjh-col: calc(100% / 6);
|
|
732
|
+
position: relative;
|
|
733
|
+
width: 100%;
|
|
734
|
+
height: 340px;
|
|
735
|
+
}
|
|
736
|
+
.tjh-axis { position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: var(--line-strong); transform: translateY(-50%); }
|
|
737
|
+
.tjh-item { position: absolute; display: flex; flex-direction: column; align-items: center; width: var(--tjh-col); transform: translateX(-50%); }
|
|
738
|
+
.tjh-item--up { bottom: 50%; }
|
|
739
|
+
.tjh-item--down { top: 50%; }
|
|
740
|
+
.tjh-axis-dot, .tjh-tip-dot { width: var(--tjh-node); height: var(--tjh-node); border-radius: 999px; background: var(--tjh-item-color, var(--accent-primary)); flex-shrink: 0; }
|
|
741
|
+
.tjh-item--up .tjh-axis-dot { margin-bottom: calc(-1 * var(--tjh-node) / 2); }
|
|
742
|
+
.tjh-item--down .tjh-axis-dot { margin-top: calc(-1 * var(--tjh-node) / 2); }
|
|
743
|
+
.tjh-stem { width: 1px; height: var(--tjh-stem-h); background-image: repeating-linear-gradient(to bottom, var(--line-strong) 0 4px, transparent 4px 8px); flex-shrink: 0; }
|
|
744
|
+
.tjh-label { display: flex; flex-direction: column; gap: 4px; width: 100%; padding: 0 6px; }
|
|
745
|
+
.tjh-item--up .tjh-label { margin-bottom: 8px; }
|
|
746
|
+
.tjh-item--down .tjh-label { margin-top: 8px; }
|
|
747
|
+
.tjh-date { font-size: var(--font-size-meta); font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--tjh-item-color, var(--accent-primary)); line-height: 1.3; white-space: nowrap; }
|
|
748
|
+
.tjh-title { font-size: 18px; font-weight: 700; line-height: 1.15; color: var(--text-primary); }
|
|
749
|
+
.tjh-text { font-size: 15px; line-height: 1.45; color: var(--text-secondary); }
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
Rules:
|
|
753
|
+
- Position nodes with `left: X%` inline style. For N nodes, space them at `(100 / (N + 1)) * k %` or manually distribute to show real time gaps.
|
|
754
|
+
- Each node may set `--tjh-item-color` inline. Prefer existing neutral theme tokens such as `--accent-primary`, `--accent-secondary`, `--accent-danger`, or a derived local accent.
|
|
755
|
+
- Up node DOM order is `label -> tip-dot -> stem -> axis-dot`; down node DOM order is `axis-dot -> stem -> tip-dot -> label`.
|
|
756
|
+
- Keep `.tjh-text` short, usually 1-2 lines. The column width limits wrapping naturally.
|
|
757
|
+
- Alternate up/down nodes for visual rhythm unless clustering intentionally communicates a phase.
|
|
758
|
+
- Adjust `--tjh-col`, `--tjh-stem-h`, and component `height` for fewer or longer milestones.
|
|
707
759
|
<!-- @component:timeline-journey-horizontal:end -->
|
|
708
760
|
|
|
709
761
|
<!-- @component:timeline-journey-vertical:start -->
|
|
710
762
|
#### Timeline Journey Vertical (.timeline-journey-vertical)
|
|
711
763
|
|
|
712
|
-
Vertical
|
|
764
|
+
Vertical milestone journey with a central axis line. Nodes sit on the axis; a horizontal dashed stem leads to a tip dot, with date, title, and description text alongside. Alternate nodes left and right of the axis for rhythm. Suitable for 3-8 milestones in a full-height slot.
|
|
713
765
|
|
|
714
766
|
```html
|
|
715
|
-
<div class="timeline-journey-vertical"
|
|
767
|
+
<div class="timeline-journey-vertical" data-preview-component="timeline-journey-vertical">
|
|
768
|
+
<div class="tjv-axis"></div>
|
|
769
|
+
|
|
770
|
+
<!-- Left node: DOM order stays axis-dot, stem, tip-dot, label. CSS reverses the row. -->
|
|
771
|
+
<div class="tjv-item tjv-item--left" style="top:18%; --tjv-item-color:var(--accent-primary);">
|
|
772
|
+
<div class="tjv-axis-dot"></div>
|
|
773
|
+
<div class="tjv-stem"></div>
|
|
774
|
+
<div class="tjv-tip-dot"></div>
|
|
775
|
+
<div class="tjv-label">
|
|
776
|
+
<span class="tjv-date">Discover</span>
|
|
777
|
+
<span class="tjv-title">Signal scan</span>
|
|
778
|
+
<span class="tjv-text">Collect inputs and identify the high-confidence path.</span>
|
|
779
|
+
</div>
|
|
780
|
+
</div>
|
|
781
|
+
|
|
782
|
+
<!-- Right node: same DOM order, standard row direction. -->
|
|
783
|
+
<div class="tjv-item tjv-item--right" style="top:42%; --tjv-item-color:var(--accent-secondary);">
|
|
784
|
+
<div class="tjv-axis-dot"></div>
|
|
785
|
+
<div class="tjv-stem"></div>
|
|
786
|
+
<div class="tjv-tip-dot"></div>
|
|
787
|
+
<div class="tjv-label">
|
|
788
|
+
<span class="tjv-date">Build</span>
|
|
789
|
+
<span class="tjv-title">Visible proof</span>
|
|
790
|
+
<span class="tjv-text">Create the first proof points and refine the operating model.</span>
|
|
791
|
+
</div>
|
|
792
|
+
</div>
|
|
793
|
+
</div>
|
|
716
794
|
```
|
|
717
795
|
|
|
718
796
|
```css
|
|
719
|
-
.timeline-journey-vertical {
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
797
|
+
.timeline-journey-vertical {
|
|
798
|
+
--tjv-node: 12px;
|
|
799
|
+
--tjv-stem-w: 76px;
|
|
800
|
+
position: relative;
|
|
801
|
+
width: 100%;
|
|
802
|
+
height: 100%;
|
|
803
|
+
}
|
|
804
|
+
.tjv-axis { position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--line-strong); transform: translateX(-50%); }
|
|
805
|
+
.tjv-item { position: absolute; display: flex; align-items: center; height: 78px; transform: translateY(-50%); }
|
|
806
|
+
.tjv-item--left { right: 50%; flex-direction: row-reverse; }
|
|
807
|
+
.tjv-item--right { left: 50%; flex-direction: row; }
|
|
808
|
+
.tjv-axis-dot { width: var(--tjv-node); height: var(--tjv-node); border-radius: 999px; background: var(--tjv-item-color, var(--accent-primary)); flex-shrink: 0; position: relative; z-index: 1; }
|
|
809
|
+
.tjv-item--left .tjv-axis-dot { margin-right: calc(-1 * var(--tjv-node) / 2); }
|
|
810
|
+
.tjv-item--right .tjv-axis-dot { margin-left: calc(-1 * var(--tjv-node) / 2); }
|
|
811
|
+
.tjv-tip-dot { width: 8px; height: 8px; border-radius: 999px; background: var(--tjv-item-color, var(--accent-primary)); flex-shrink: 0; }
|
|
812
|
+
.tjv-stem { width: var(--tjv-stem-w); height: 1px; background-image: repeating-linear-gradient(to right, var(--line-strong) 0 4px, transparent 4px 8px); flex-shrink: 0; }
|
|
813
|
+
.tjv-label { display: flex; flex-direction: column; gap: 4px; }
|
|
814
|
+
.tjv-item--left .tjv-label { text-align: right; align-items: flex-end; padding-right: 18px; max-width: 440px; }
|
|
815
|
+
.tjv-item--right .tjv-label { text-align: left; align-items: flex-start; padding-left: 18px; max-width: 440px; }
|
|
816
|
+
.tjv-date { font-size: var(--font-size-meta); font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--tjv-item-color, var(--accent-primary)); line-height: 1.3; white-space: nowrap; }
|
|
817
|
+
.tjv-title { font-size: 18px; font-weight: 700; line-height: 1.15; color: var(--text-primary); }
|
|
818
|
+
.tjv-text { font-size: 15px; line-height: 1.45; color: var(--text-secondary); max-width: 360px; }
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
Rules:
|
|
822
|
+
- DOM order is identical for left and right nodes: `axis-dot -> stem -> tip-dot -> label`. Direction is controlled by CSS (`row-reverse` for left, `row` for right).
|
|
823
|
+
- Position each node with `top: Y%` inline style. For N nodes, distribute evenly with `(100 / (N + 1)) * k %` or manually to reflect time proportions.
|
|
824
|
+
- Each node may set `--tjv-item-color` inline. Prefer current theme tokens rather than hard-coded project colors.
|
|
825
|
+
- Alternate left and right nodes for rhythm. Avoid consecutive same-side nodes unless the story needs clustering.
|
|
826
|
+
- The parent container must have a defined height. Use `height: 100%` inside a layout slot, or set an explicit height when standalone.
|
|
827
|
+
- Keep `.tjv-text` to 2-3 lines. Longer labels shift the perceived center away from the axis dot.
|
|
724
828
|
<!-- @component:timeline-journey-vertical:end -->
|
|
725
829
|
|
|
726
830
|
<!-- @component:svg-motif:start -->
|
|
@@ -140,13 +140,37 @@
|
|
|
140
140
|
.brand-watermark strong { font-weight: 800; color: var(--text-secondary); }
|
|
141
141
|
.page-number { position: absolute; right: 34px; bottom: 26px; z-index: 10; font-size: 12px; letter-spacing: 0.14em; color: var(--text-muted); }
|
|
142
142
|
.page-number--light { color: rgba(248,250,252,0.72); }
|
|
143
|
-
.timeline-journey-horizontal {
|
|
144
|
-
.
|
|
145
|
-
.
|
|
146
|
-
.
|
|
147
|
-
.
|
|
148
|
-
.
|
|
149
|
-
.
|
|
143
|
+
.timeline-journey-horizontal { --tjh-node: 12px; --tjh-stem-h: 62px; --tjh-col: 180px; position: relative; width: 100%; height: 245px; }
|
|
144
|
+
.tjh-axis { position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: var(--line-strong); transform: translateY(-50%); }
|
|
145
|
+
.tjh-item { position: absolute; display: flex; flex-direction: column; align-items: center; width: var(--tjh-col); transform: translateX(-50%); }
|
|
146
|
+
.tjh-item--up { bottom: 50%; }
|
|
147
|
+
.tjh-item--down { top: 50%; }
|
|
148
|
+
.tjh-axis-dot, .tjh-tip-dot { width: var(--tjh-node); height: var(--tjh-node); border-radius: 999px; background: var(--tjh-item-color, var(--accent-primary)); flex-shrink: 0; }
|
|
149
|
+
.tjh-item--up .tjh-axis-dot { margin-bottom: calc(-1 * var(--tjh-node) / 2); }
|
|
150
|
+
.tjh-item--down .tjh-axis-dot { margin-top: calc(-1 * var(--tjh-node) / 2); }
|
|
151
|
+
.tjh-stem { width: 1px; height: var(--tjh-stem-h); background-image: repeating-linear-gradient(to bottom, var(--line-strong) 0 4px, transparent 4px 8px); flex-shrink: 0; }
|
|
152
|
+
.tjh-label { display: flex; flex-direction: column; gap: 3px; width: 100%; padding: 0 6px; }
|
|
153
|
+
.tjh-item--up .tjh-label { margin-bottom: 8px; }
|
|
154
|
+
.tjh-item--down .tjh-label { margin-top: 8px; }
|
|
155
|
+
.tjh-date { font-size: 11px; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--tjh-item-color, var(--accent-primary)); line-height: 1.3; white-space: nowrap; }
|
|
156
|
+
.tjh-title { font-size: 17px; font-weight: 700; line-height: 1.15; color: var(--text-primary); }
|
|
157
|
+
.tjh-text { font-size: 13px; line-height: 1.4; color: var(--text-secondary); }
|
|
158
|
+
.timeline-journey-vertical { --tjv-node: 12px; --tjv-stem-w: 46px; position: relative; width: 100%; height: 100%; min-height: 260px; }
|
|
159
|
+
.tjv-axis { position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--line-strong); transform: translateX(-50%); }
|
|
160
|
+
.tjv-item { position: absolute; display: flex; align-items: center; height: 72px; transform: translateY(-50%); }
|
|
161
|
+
.tjv-item--left { right: 50%; flex-direction: row-reverse; }
|
|
162
|
+
.tjv-item--right { left: 50%; flex-direction: row; }
|
|
163
|
+
.tjv-axis-dot { width: var(--tjv-node); height: var(--tjv-node); border-radius: 999px; background: var(--tjv-item-color, var(--accent-primary)); flex-shrink: 0; position: relative; z-index: 1; }
|
|
164
|
+
.tjv-item--left .tjv-axis-dot { margin-right: calc(-1 * var(--tjv-node) / 2); }
|
|
165
|
+
.tjv-item--right .tjv-axis-dot { margin-left: calc(-1 * var(--tjv-node) / 2); }
|
|
166
|
+
.tjv-tip-dot { width: 8px; height: 8px; border-radius: 999px; background: var(--tjv-item-color, var(--accent-primary)); flex-shrink: 0; }
|
|
167
|
+
.tjv-stem { width: var(--tjv-stem-w); height: 1px; background-image: repeating-linear-gradient(to right, var(--line-strong) 0 4px, transparent 4px 8px); flex-shrink: 0; }
|
|
168
|
+
.tjv-label { display: flex; flex-direction: column; gap: 3px; }
|
|
169
|
+
.tjv-item--left .tjv-label { text-align: right; align-items: flex-end; padding-right: 14px; max-width: 220px; }
|
|
170
|
+
.tjv-item--right .tjv-label { text-align: left; align-items: flex-start; padding-left: 14px; max-width: 220px; }
|
|
171
|
+
.tjv-date { font-size: 11px; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--tjv-item-color, var(--accent-primary)); line-height: 1.3; white-space: nowrap; }
|
|
172
|
+
.tjv-title { font-size: 17px; font-weight: 700; line-height: 1.15; color: var(--text-primary); }
|
|
173
|
+
.tjv-text { font-size: 13px; line-height: 1.4; color: var(--text-secondary); max-width: 210px; }
|
|
150
174
|
.svg-motif { position: relative; pointer-events: none; color: var(--text-primary); }
|
|
151
175
|
.svg-motif svg { display: block; width: 100%; height: 100%; overflow: visible; }
|
|
152
176
|
.svg-motif--bottom { position: absolute; left: 0; right: 0; bottom: 0; height: 30%; }
|
|
@@ -156,7 +180,7 @@
|
|
|
156
180
|
</style>
|
|
157
181
|
</head>
|
|
158
182
|
<body>
|
|
159
|
-
<section class="slide" slide-qa="false" data-index="0">
|
|
183
|
+
<section class="slide" slide-qa="false" data-index="0" data-slide-role="cover">
|
|
160
184
|
<div class="slide-canvas">
|
|
161
185
|
<div class="page" style="padding:0;">
|
|
162
186
|
<div class="image-title image-title--left">
|
|
@@ -229,10 +253,22 @@
|
|
|
229
253
|
<div class="slide-canvas">
|
|
230
254
|
<div class="page" style="padding:0;">
|
|
231
255
|
<div class="stacked-grid">
|
|
232
|
-
<div class="stacked-top text-panel reveal" style="padding:
|
|
233
|
-
<div class="stacked-bottom" style="display:grid;grid-template-columns:
|
|
256
|
+
<div class="stacked-top text-panel reveal" style="padding:42px 56px 20px;"><div class="text-panel-body"><p class="eyebrow">Data and process</p><h2>Evidence components stay structural</h2><p>Charts, tables, and journey timelines inherit the active theme while keeping predictable geometry.</p></div></div>
|
|
257
|
+
<div class="stacked-bottom" style="display:grid;grid-template-columns:1fr 1fr;grid-template-rows:minmax(0,1fr) 250px;gap:26px;padding:0 56px 56px;">
|
|
234
258
|
<div class="echart-panel reveal"><div class="echart-panel-header"><p class="eyebrow">Example chart</p><h3>Signal distribution</h3><p class="chart-subtitle">Neutral chart defaults with restrained labels.</p></div><div class="echart-container" id="starter-chart"></div><p class="chart-caption">Source: demo data</p></div>
|
|
235
|
-
<div class="
|
|
259
|
+
<div class="timeline-journey-vertical reveal" data-preview-component="timeline-journey-vertical">
|
|
260
|
+
<div class="tjv-axis"></div>
|
|
261
|
+
<div class="tjv-item tjv-item--left" style="top:18%; --tjv-item-color:var(--accent-primary);"><div class="tjv-axis-dot"></div><div class="tjv-stem"></div><div class="tjv-tip-dot"></div><div class="tjv-label"><span class="tjv-date">Discover</span><span class="tjv-title">Signal scan</span><span class="tjv-text">Map inputs and identify the base pattern.</span></div></div>
|
|
262
|
+
<div class="tjv-item tjv-item--right" style="top:50%; --tjv-item-color:var(--accent-secondary);"><div class="tjv-axis-dot"></div><div class="tjv-stem"></div><div class="tjv-tip-dot"></div><div class="tjv-label"><span class="tjv-date">Build</span><span class="tjv-title">Theme draft</span><span class="tjv-text">Apply visual schema without changing structure.</span></div></div>
|
|
263
|
+
<div class="tjv-item tjv-item--left" style="top:82%; --tjv-item-color:var(--accent-danger);"><div class="tjv-axis-dot"></div><div class="tjv-stem"></div><div class="tjv-tip-dot"></div><div class="tjv-label"><span class="tjv-date">Verify</span><span class="tjv-title">Preview pass</span><span class="tjv-text">Check roles, components, and slide geometry.</span></div></div>
|
|
264
|
+
</div>
|
|
265
|
+
<div class="timeline-journey-horizontal reveal" data-preview-component="timeline-journey-horizontal" style="grid-column:1 / -1;">
|
|
266
|
+
<div class="tjh-axis"></div>
|
|
267
|
+
<div class="tjh-item tjh-item--up" style="left:14%; --tjh-item-color:var(--accent-primary);"><div class="tjh-label"><span class="tjh-date">01</span><span class="tjh-title">Brief</span><span class="tjh-text">Clarify source style.</span></div><div class="tjh-tip-dot"></div><div class="tjh-stem"></div><div class="tjh-axis-dot"></div></div>
|
|
268
|
+
<div class="tjh-item tjh-item--down" style="left:38%; --tjh-item-color:var(--accent-secondary);"><div class="tjh-axis-dot"></div><div class="tjh-stem"></div><div class="tjh-tip-dot"></div><div class="tjh-label"><span class="tjh-date">02</span><span class="tjh-title">Tokens</span><span class="tjh-text">Set color and type.</span></div></div>
|
|
269
|
+
<div class="tjh-item tjh-item--up" style="left:62%; --tjh-item-color:var(--accent-danger);"><div class="tjh-label"><span class="tjh-date">03</span><span class="tjh-title">Modules</span><span class="tjh-text">Skin components.</span></div><div class="tjh-tip-dot"></div><div class="tjh-stem"></div><div class="tjh-axis-dot"></div></div>
|
|
270
|
+
<div class="tjh-item tjh-item--down" style="left:86%; --tjh-item-color:var(--text-muted);"><div class="tjh-axis-dot"></div><div class="tjh-stem"></div><div class="tjh-tip-dot"></div><div class="tjh-label"><span class="tjh-date">04</span><span class="tjh-title">Validate</span><span class="tjh-text">Inspect preview.</span></div></div>
|
|
271
|
+
</div>
|
|
236
272
|
</div>
|
|
237
273
|
</div>
|
|
238
274
|
<div class="page-number">05</div>
|
|
@@ -240,7 +276,7 @@
|
|
|
240
276
|
</div>
|
|
241
277
|
</section>
|
|
242
278
|
|
|
243
|
-
<section class="slide" slide-qa="false" data-index="5">
|
|
279
|
+
<section class="slide" slide-qa="false" data-index="5" data-slide-role="closing">
|
|
244
280
|
<div class="slide-canvas">
|
|
245
281
|
<div class="page">
|
|
246
282
|
<div class="svg-motif svg-motif--corner" aria-hidden="true"><svg viewBox="0 0 600 360"><rect x="80" y="190" width="360" height="34" fill="#dbeafe"/><circle cx="190" cy="150" r="82" fill="#3b82f6" opacity=".82"/><path d="M286 230 C330 120 474 122 516 226 C458 274 348 276 286 230 Z" fill="#64748b" opacity=".68"/><path d="M112 70 l22 -22 l22 22 l-22 22 Z" fill="none" stroke="#17191c" stroke-width="8"/><path d="M470 72 C508 38 548 46 566 88" fill="none" stroke="#17191c" stroke-width="9" stroke-linecap="round"/></svg></div>
|
|
@@ -29,7 +29,7 @@ Given a research brief specifying your topic and axis, you will:
|
|
|
29
29
|
2. Use \`DECKS.json\` through \`revela-decks\` as the workspace material index when it exists
|
|
30
30
|
3. Run a lightweight workspace freshness check when needed
|
|
31
31
|
4. Search the web for current data, reports, and case studies when the brief requires it
|
|
32
|
-
5. Write all findings to ONE structured file: \`researches/{topic-
|
|
32
|
+
5. Write all findings to ONE structured file: \`researches/{topic-key}/{axis-name}.md\`
|
|
33
33
|
6. Return a brief summary of what you found
|
|
34
34
|
|
|
35
35
|
---
|
|
@@ -37,7 +37,7 @@ Given a research brief specifying your topic and axis, you will:
|
|
|
37
37
|
## Step 1 — Research brief and workspace memory
|
|
38
38
|
|
|
39
39
|
Start from the research brief supplied by the primary agent. It should include:
|
|
40
|
-
- shared topic
|
|
40
|
+
- shared topic key
|
|
41
41
|
- your axis filename
|
|
42
42
|
- the specific question for this axis
|
|
43
43
|
- time period, geography, and evidence standard
|
|
@@ -100,7 +100,7 @@ Search strategy:
|
|
|
100
100
|
|
|
101
101
|
Use **\`revela-research-save\`** to write ONE file with all your findings.
|
|
102
102
|
|
|
103
|
-
- \`topic\`: kebab-case
|
|
103
|
+
- \`topic\`: kebab-case topic key shared across all agents for this presentation
|
|
104
104
|
- \`filename\`: your axis name (e.g. \`market-data\`, \`catl-profile\`, \`tech-trends\`)
|
|
105
105
|
- \`content\`: structured findings using the four sections below
|
|
106
106
|
- \`sources\`: list of all URLs and filenames used
|
|
@@ -140,7 +140,7 @@ Content rules:
|
|
|
140
140
|
After writing the file, return this summary (do NOT include the raw data):
|
|
141
141
|
|
|
142
142
|
\`\`\`
|
|
143
|
-
Research complete: {axis-name} → researches/{topic-
|
|
143
|
+
Research complete: {axis-name} → researches/{topic-key}/{axis-name}.md
|
|
144
144
|
|
|
145
145
|
Key findings (3–5, most argument-worthy only):
|
|
146
146
|
- {1–2 sentence highlight with source}
|
|
@@ -79,6 +79,12 @@ const VISUAL_QUALITY_RULES = `Visual extraction and CSS quality rules:
|
|
|
79
79
|
- For SVG motifs: set a viewBox, keep all eyes/mouths/decorations inside that coordinate system, and document intended placement/scale in the component notes.
|
|
80
80
|
- Before saving, review the preview for text overlap, scale drift, lost anchoring, overflow, and whether the preview preserves the reference composition.`
|
|
81
81
|
|
|
82
|
+
const PREVIEW_REQUIREMENTS = `Preview requirements:
|
|
83
|
+
- \`preview.html\` must include a cover slide and a closing slide. Mark their \`<section class="slide">\` elements with \`data-slide-role="cover"\` and \`data-slide-role="closing"\`.
|
|
84
|
+
- \`preview.html\` must showcase every \`@component:*\` defined in \`DESIGN.md\`. Mark each showcased component with \`data-preview-component="<component-name>"\`.
|
|
85
|
+
- Do not save with \`revela-designs-author\` until every component has a corresponding preview marker. If a component is decorative or abstract, include a visible labeled sample state.
|
|
86
|
+
- When the design supports chart styling, \`preview.html\` should include a 3x3 ECharts gallery with at least 9 chart examples. This is a preview quality requirement, not a validation blocker.`
|
|
87
|
+
|
|
82
88
|
export function buildDesignsNewPrompt({ name, base }: DesignsNewArgs): string {
|
|
83
89
|
return `You are creating a new Revela visual design package.
|
|
84
90
|
|
|
@@ -107,6 +113,8 @@ You must replace unless the user explicitly requests otherwise:
|
|
|
107
113
|
|
|
108
114
|
${VISUAL_QUALITY_RULES}
|
|
109
115
|
|
|
116
|
+
${PREVIEW_REQUIREMENTS}
|
|
117
|
+
|
|
110
118
|
Workflow:
|
|
111
119
|
1. Do not generate or save files immediately.
|
|
112
120
|
2. Interview the user first. Ask for visual references such as screenshots/images, webpage URLs, text descriptions, brands, or decks they like.
|
|
@@ -126,6 +134,8 @@ Hard requirements:
|
|
|
126
134
|
- \`DESIGN.md\` must include at least \`@design:foundation\`, \`@design:rules\`, one layout, and one component.
|
|
127
135
|
- \`preview.html\` must be self-contained and directly openable in a browser.
|
|
128
136
|
- Every preview slide must include \`slide-qa="true"\` or \`slide-qa="false"\`.
|
|
137
|
+
- \`preview.html\` must include \`data-slide-role="cover"\` and \`data-slide-role="closing"\` on slide sections.
|
|
138
|
+
- \`preview.html\` must showcase every \`@component:*\` with \`data-preview-component="<component-name>"\` before saving.
|
|
129
139
|
- Do not save anything until the user confirms the brief.
|
|
130
140
|
|
|
131
141
|
Start now by interviewing the user. Keep the first question concise.`
|
|
@@ -144,6 +154,8 @@ Goal:
|
|
|
144
154
|
|
|
145
155
|
${VISUAL_QUALITY_RULES}
|
|
146
156
|
|
|
157
|
+
${PREVIEW_REQUIREMENTS}
|
|
158
|
+
|
|
147
159
|
Workflow:
|
|
148
160
|
1. Do not save files immediately.
|
|
149
161
|
2. Ask the user what they want to change. Accept text descriptions, screenshots/images, webpage URLs, or specific complaints about the current preview.
|
|
@@ -161,6 +173,8 @@ Hard requirements:
|
|
|
161
173
|
- Preserve at least \`@design:foundation\`, \`@design:rules\`, one layout, and one component.
|
|
162
174
|
- \`preview.html\` must be self-contained and directly openable in a browser.
|
|
163
175
|
- Every preview slide must include \`slide-qa="true"\` or \`slide-qa="false"\`.
|
|
176
|
+
- \`preview.html\` must include \`data-slide-role="cover"\` and \`data-slide-role="closing"\` on slide sections.
|
|
177
|
+
- \`preview.html\` must showcase every \`@component:*\` with \`data-preview-component="<component-name>"\` before saving.
|
|
164
178
|
- Do not save anything until the user confirms the edit brief.
|
|
165
179
|
|
|
166
180
|
Start now by asking what the user wants to change in \`${name}\`.`
|
package/lib/commands/edit.ts
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import { openEditableDeck } from "../edit/open"
|
|
2
2
|
|
|
3
3
|
export async function handleEdit(
|
|
4
|
-
input: string,
|
|
5
4
|
options: { client: any; sessionID: string; workspaceRoot: string },
|
|
6
5
|
send: (text: string) => Promise<void>,
|
|
7
6
|
): Promise<void> {
|
|
8
|
-
const target = input.trim()
|
|
9
|
-
|
|
10
7
|
try {
|
|
11
|
-
const result = openEditableDeck(
|
|
8
|
+
const result = openEditableDeck("", {
|
|
12
9
|
client: options.client,
|
|
13
10
|
sessionID: options.sessionID,
|
|
14
11
|
workspaceRoot: options.workspaceRoot,
|
|
15
12
|
})
|
|
16
13
|
|
|
17
14
|
await send(
|
|
18
|
-
`Opened visual editor for deck
|
|
19
|
-
`File: \`${result.deck.file}
|
|
15
|
+
`Opened visual editor for the only deck in \`decks/\`.\n` +
|
|
16
|
+
`File: \`${result.deck.file}\`\n` +
|
|
20
17
|
`${result.stateNote}\n` +
|
|
21
18
|
`URL: ${result.url}\n\n` +
|
|
22
19
|
`Use Ctrl/Cmd + click in the browser to reference elements, write a comment, then send comments. Revela mode has been enabled for the edit prompt.`
|
package/lib/commands/help.ts
CHANGED
|
@@ -27,8 +27,8 @@ export async function handleHelp(
|
|
|
27
27
|
`\`/revela enable\` — enable slide generation mode\n` +
|
|
28
28
|
`\`/revela disable\` — disable slide generation mode\n` +
|
|
29
29
|
`\`/revela init\` — initialize or refresh workspace DECKS.json\n` +
|
|
30
|
-
`\`/revela review
|
|
31
|
-
`\`/revela edit
|
|
30
|
+
`\`/revela review\` — review current deck readiness before writing HTML\n` +
|
|
31
|
+
`\`/revela edit\` — open visual editor for the only deck in decks/\n` +
|
|
32
32
|
`\`/revela remember <text>\` — save an explicit preference to DECKS.json\n` +
|
|
33
33
|
`\`/revela designs\` — list installed designs\n` +
|
|
34
34
|
`\`/revela designs <name>\` — activate a design\n` +
|