@cyber-dash-tech/revela 0.19.0 → 0.19.2
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 +21 -21
- package/README.zh-CN.md +21 -21
- package/designs/lucent/DESIGN.md +2 -1
- package/designs/lucent-dark/DESIGN.md +2 -1
- package/designs/monet/DESIGN.md +2 -1
- package/designs/starter/DESIGN.md +2 -1
- package/designs/summit/DESIGN.md +2 -1
- package/lib/design/designs.ts +12 -0
- package/lib/page-templates/built-in-preview.html +4 -4
- package/lib/page-templates/render.ts +43 -23
- package/lib/page-templates/templates/index.ts +2 -0
- package/lib/page-templates/templates/milestone.ts +3 -0
- package/lib/page-templates/templates/timeline.ts +3 -0
- package/lib/page-templates/vocabulary.ts +5 -3
- package/package.json +1 -1
- package/plugins/revela/.codex-plugin/plugin.json +1 -1
- package/plugins/revela/hooks/revela_post_write_notice.ts +4 -4
- package/plugins/revela/mcp/revela-server.ts +10 -8
- package/plugins/revela/skills/revela/SKILL.md +1 -1
- package/plugins/revela/skills/revela-design/SKILL.md +2 -1
- package/plugins/revela/skills/revela-helper/SKILL.md +1 -1
- package/plugins/revela/skills/revela-make-deck/SKILL.md +3 -3
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
Revela is a Codex plugin for turning source materials, research, data, and intent into trusted, traceable, presentation-ready decision artifacts.
|
|
12
12
|
|
|
13
|
-
In your local workspace, Revela reviews materials, saves source-linked research, builds an explicit `deck-plan.md`, generates HTML decks, surfaces them as Codex Browser website cards for annotation, and exports PDF/PPTX/PNG artifacts.
|
|
13
|
+
In your local workspace, Revela reviews materials, saves source-linked research, builds an explicit `deck-plan.md`, generates HTML decks, surfaces them as localhost Codex Browser website cards for annotation, and exports PDF/PPTX/PNG artifacts.
|
|
14
14
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
@@ -39,7 +39,7 @@ npm_config_cache=/tmp/revela-npm-cache bun run smoke:mcp-pack
|
|
|
39
39
|
Install Revela through the Codex Git marketplace:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
codex plugin marketplace add https://github.com/cyber-dash-tech/revela --ref v0.19.
|
|
42
|
+
codex plugin marketplace add https://github.com/cyber-dash-tech/revela --ref v0.19.2
|
|
43
43
|
codex plugin add revela@revela
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -49,7 +49,7 @@ You do not need to run `bun install` inside the Codex marketplace clone.
|
|
|
49
49
|
|
|
50
50
|
Start a new Codex thread after installing so Codex loads the Revela skills, MCP tools, and hooks.
|
|
51
51
|
|
|
52
|
-
Codex uses eight Revela skills: `revela` for routing the next workflow step, `revela-spec` for writing root-level `spec.md`, `revela-helper` for status and active design/domain, `revela-design` for custom design creation/validation/activation, `revela-domain` for custom narrative domain creation/validation/activation, `revela-research` for local and web research saved under `researches/` plus the design-aware `deck-plan.md` handoff, `revela-make-deck` for generating HTML deck artifacts from an existing plan and surfacing the QA-passed deck as a Codex Browser website card, and `revela-export` for PDF/PPTX/PNG.
|
|
52
|
+
Codex uses eight Revela skills: `revela` for routing the next workflow step, `revela-spec` for writing root-level `spec.md`, `revela-helper` for status and active design/domain, `revela-design` for custom design creation/validation/activation, `revela-domain` for custom narrative domain creation/validation/activation, `revela-research` for local and web research saved under `researches/` plus the design-aware `deck-plan.md` handoff, `revela-make-deck` for generating HTML deck artifacts from an existing plan and surfacing the QA-passed deck as a localhost Codex Browser website card, and `revela-export` for PDF/PPTX/PNG.
|
|
53
53
|
|
|
54
54
|
For release-aligned local validation, run `bun run smoke:mcp-pack`. It packs the current checkout to a temporary npm tarball, extracts it, and starts the MCP server through the packaged Codex plugin launcher path without requiring a registry publish.
|
|
55
55
|
|
|
@@ -92,7 +92,7 @@ Revela includes built-in deck designs. Design previews are generated from the bu
|
|
|
92
92
|
<p align="center">
|
|
93
93
|
<img src="assets/img/summit-01.jpg" alt="Summit design cover preview" width="32%" />
|
|
94
94
|
<img src="assets/img/summit-02.jpg" alt="Summit design agenda preview" width="32%" />
|
|
95
|
-
<img src="assets/img/summit-03.jpg" alt="Summit design vertical timeline
|
|
95
|
+
<img src="assets/img/summit-03.jpg" alt="Summit design vertical timeline preview" width="32%" />
|
|
96
96
|
</p>
|
|
97
97
|
|
|
98
98
|
### monet
|
|
@@ -116,12 +116,12 @@ Revela includes built-in deck designs. Design previews are generated from the bu
|
|
|
116
116
|
<p align="center">
|
|
117
117
|
<img src="assets/img/lucent-dark-01.jpg" alt="Lucent Dark design cover preview" width="32%" />
|
|
118
118
|
<img src="assets/img/lucent-dark-02.jpg" alt="Lucent Dark design agenda preview" width="32%" />
|
|
119
|
-
<img src="assets/img/lucent-dark-03.jpg" alt="Lucent Dark design horizontal
|
|
119
|
+
<img src="assets/img/lucent-dark-03.jpg" alt="Lucent Dark design horizontal milestone preview" width="32%" />
|
|
120
120
|
</p>
|
|
121
121
|
|
|
122
122
|
To switch designs in Codex, ask:
|
|
123
123
|
|
|
124
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
124
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), use summit as the design.
|
|
125
125
|
|
|
126
126
|
In Codex, ask Revela to list or switch designs; the plugin uses the active design when making decks.
|
|
127
127
|
|
|
@@ -129,7 +129,7 @@ In Codex, ask Revela to list or switch designs; the plugin uses the active desig
|
|
|
129
129
|
|
|
130
130
|
Domains add topic-specific communication guidance, such as consulting, product, or investor communication. Use them when you want Revela to adapt deck framing to a specific context.
|
|
131
131
|
|
|
132
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
132
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), list available domains.
|
|
133
133
|
|
|
134
134
|
In Codex, ask Revela to list or switch domains; the active domain guides deck framing during init, research, and planning.
|
|
135
135
|
|
|
@@ -139,52 +139,52 @@ Use these prompts in Codex from the workspace that contains your source material
|
|
|
139
139
|
|
|
140
140
|
1. Choose the narrative domain before authoring so Revela frames the audience, decision, risks, and objections for your context.
|
|
141
141
|
|
|
142
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
142
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), use consulting as the domain.
|
|
143
143
|
|
|
144
144
|
2. Choose the deck design before rendering so generated artifacts use the intended visual language.
|
|
145
145
|
|
|
146
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
146
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), use summit as the design.
|
|
147
147
|
|
|
148
148
|
3. Create a custom design when you want a different visual direction.
|
|
149
149
|
|
|
150
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
150
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), create a new design named neon-finance with a crisp financial-dashboard style: dark surfaces, precise grids, and bright green accents.
|
|
151
151
|
|
|
152
152
|
Revela may ask for references or constraints, then creates a workspace draft with `DESIGN.md`, `design.css`, and any local `assets/**`. It generates a preview from the built-in page-template fixture plus that CSS so you can review cover, agenda, timelines, charts, tables, cards, and visual slots before installing. When it is ready, switch to it:
|
|
153
153
|
|
|
154
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
154
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), use neon-finance as the design.
|
|
155
155
|
|
|
156
156
|
4. Initialize local material intake. Init scans, extracts, and reviews workspace sources; it does not create a Narrative Vault.
|
|
157
157
|
|
|
158
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
158
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), help me init this workspace from the local materials.
|
|
159
159
|
|
|
160
160
|
5. Research source-linked deck inputs and save findings.
|
|
161
161
|
|
|
162
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
162
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), research the public evidence and examples needed for this deck.
|
|
163
163
|
|
|
164
164
|
6. Create or update the deck plan before generating HTML so slide order, chapter structure, source links, unresolved inputs, source limitations, and visual intent are explicit.
|
|
165
165
|
|
|
166
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
166
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), create or update the deck plan before generating HTML.
|
|
167
167
|
|
|
168
168
|
7. Make an HTML deck from the current deck plan.
|
|
169
169
|
|
|
170
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
170
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), make the deck from the current deck plan.
|
|
171
171
|
|
|
172
|
-
8. Review and annotate the generated deck from the website card after make-deck completes.
|
|
172
|
+
8. Review and annotate the generated deck from the localhost website card after make-deck completes.
|
|
173
173
|
|
|
174
|
-
Use Codex Browser's native annotation tools on the opened HTML deck.
|
|
174
|
+
Revela serves the deck from `http://127.0.0.1:<port>/decks/<file>.html` so you can click the card and open it in Codex Browser. Use Codex Browser's native annotation tools on the opened HTML deck.
|
|
175
175
|
|
|
176
176
|
9. Export a PDF after deck QA passes.
|
|
177
177
|
|
|
178
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
178
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), export the deck to PDF.
|
|
179
179
|
|
|
180
180
|
10. Export an editable PPTX after deck QA passes.
|
|
181
181
|
|
|
182
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
182
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), export the deck to PPTX.
|
|
183
183
|
|
|
184
184
|
11. Export per-slide PNG files after deck QA passes.
|
|
185
185
|
|
|
186
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
186
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md), export the deck to PNG.
|
|
187
187
|
|
|
188
188
|
## Annotate A Deck
|
|
189
189
|
|
|
190
|
-
After `revela-make-deck` generates an HTML deck and Artifact QA passes, Codex replies with a website card that
|
|
190
|
+
After `revela-make-deck` generates an HTML deck and Artifact QA passes, Codex replies with a localhost website card that you can click to open the deck in Codex Browser. Use the browser's native annotation tools for targeted edits such as layout, copy, hierarchy, spacing, or visual changes.
|
package/README.zh-CN.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
Revela 是 Codex plugin,用来把来源材料、调研、数据和用户意图转成可信、可追踪、可直接用于决策沟通的 deck artifact。
|
|
12
12
|
|
|
13
|
-
在你的本地 workspace 中,Revela 会审阅本地资料、保存 source-linked research、生成明确的 `deck-plan.md`、产出 HTML deck
|
|
13
|
+
在你的本地 workspace 中,Revela 会审阅本地资料、保存 source-linked research、生成明确的 `deck-plan.md`、产出 HTML deck,并以 localhost Codex Browser website card 交付以便 annotation,并支持 PDF/PPTX/PNG 导出。
|
|
14
14
|
|
|
15
15
|
## 安装
|
|
16
16
|
|
|
@@ -39,7 +39,7 @@ npm_config_cache=/tmp/revela-npm-cache bun run smoke:mcp-pack
|
|
|
39
39
|
通过 Codex Git marketplace 安装 Revela:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
codex plugin marketplace add https://github.com/cyber-dash-tech/revela --ref v0.19.
|
|
42
|
+
codex plugin marketplace add https://github.com/cyber-dash-tech/revela --ref v0.19.2
|
|
43
43
|
codex plugin add revela@revela
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -49,7 +49,7 @@ Git marketplace 安装的是 Codex plugin 壳、skills、hooks 和 MCP 配置。
|
|
|
49
49
|
|
|
50
50
|
安装后开启一个新的 Codex thread,让 Codex 加载 Revela 的 skills、MCP tools 和 hooks。
|
|
51
51
|
|
|
52
|
-
Codex 使用八个 Revela skills:`revela` 路由下一步 workflow,`revela-spec` 产出根目录 `spec.md`,`revela-helper` 查看状态和 active design/domain,`revela-design` 创建、验证、激活 custom design,`revela-domain` 创建、验证、激活 custom narrative domain,`revela-research` 调研本地与网络资料、保存到 `researches/`,并产出 design-aware `deck-plan.md` handoff;`revela-make-deck` 基于已有 plan 生成 HTML deck artifact,并在 QA 通过后以 Codex Browser website card 形式交付,`revela-export` 导出 PDF/PPTX/PNG。
|
|
52
|
+
Codex 使用八个 Revela skills:`revela` 路由下一步 workflow,`revela-spec` 产出根目录 `spec.md`,`revela-helper` 查看状态和 active design/domain,`revela-design` 创建、验证、激活 custom design,`revela-domain` 创建、验证、激活 custom narrative domain,`revela-research` 调研本地与网络资料、保存到 `researches/`,并产出 design-aware `deck-plan.md` handoff;`revela-make-deck` 基于已有 plan 生成 HTML deck artifact,并在 QA 通过后以 localhost Codex Browser website card 形式交付,`revela-export` 导出 PDF/PPTX/PNG。
|
|
53
53
|
|
|
54
54
|
如果要按发布路径做本地验证,运行 `bun run smoke:mcp-pack`。它会把当前 checkout 打成临时 npm tarball,解包后通过打包出的 Codex plugin launcher 路径启动 MCP server,不需要先发布到 registry。
|
|
55
55
|
|
|
@@ -92,7 +92,7 @@ Revela 内置多个 deck design。Design preview 由内置 page-template preview
|
|
|
92
92
|
<p align="center">
|
|
93
93
|
<img src="assets/img/summit-01.jpg" alt="Summit design cover preview" width="32%" />
|
|
94
94
|
<img src="assets/img/summit-02.jpg" alt="Summit design agenda preview" width="32%" />
|
|
95
|
-
<img src="assets/img/summit-03.jpg" alt="Summit design vertical timeline
|
|
95
|
+
<img src="assets/img/summit-03.jpg" alt="Summit design vertical timeline preview" width="32%" />
|
|
96
96
|
</p>
|
|
97
97
|
|
|
98
98
|
### monet
|
|
@@ -116,12 +116,12 @@ Revela 内置多个 deck design。Design preview 由内置 page-template preview
|
|
|
116
116
|
<p align="center">
|
|
117
117
|
<img src="assets/img/lucent-dark-01.jpg" alt="Lucent Dark design cover preview" width="32%" />
|
|
118
118
|
<img src="assets/img/lucent-dark-02.jpg" alt="Lucent Dark design agenda preview" width="32%" />
|
|
119
|
-
<img src="assets/img/lucent-dark-03.jpg" alt="Lucent Dark design horizontal
|
|
119
|
+
<img src="assets/img/lucent-dark-03.jpg" alt="Lucent Dark design horizontal milestone preview" width="32%" />
|
|
120
120
|
</p>
|
|
121
121
|
|
|
122
122
|
在 Codex 中切换 design,可以这样问:
|
|
123
123
|
|
|
124
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
124
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),use summit as design.
|
|
125
125
|
|
|
126
126
|
在 Codex 中,可以直接让 Revela 列出或切换 design;生成 deck 时会使用 active design。
|
|
127
127
|
|
|
@@ -129,7 +129,7 @@ Revela 内置多个 deck design。Design preview 由内置 page-template preview
|
|
|
129
129
|
|
|
130
130
|
Domain 提供特定场景的沟通 guidance,例如 consulting、product 或 investor communication。需要让 Revela 按具体沟通场景调整 deck framing 时使用。
|
|
131
131
|
|
|
132
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
132
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),列出 available domains。
|
|
133
133
|
|
|
134
134
|
在 Codex 中,可以直接让 Revela 列出或切换 domain;active domain 会用于 init、research 和 deck planning 阶段的 framing。
|
|
135
135
|
|
|
@@ -139,52 +139,52 @@ Domain 提供特定场景的沟通 guidance,例如 consulting、product 或 in
|
|
|
139
139
|
|
|
140
140
|
1. 先选择 domain,让 Revela 按你的沟通场景 framing 受众、决策、风险和潜在质疑。
|
|
141
141
|
|
|
142
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
142
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),use consulting as domain.
|
|
143
143
|
|
|
144
144
|
2. 再选择 design,让后续生成的 deck 使用指定视觉风格。
|
|
145
145
|
|
|
146
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
146
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),use summit as design.
|
|
147
147
|
|
|
148
148
|
3. 如果需要不同的视觉方向,可以创建一个自定义 design。
|
|
149
149
|
|
|
150
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
150
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),创建一个名为 neon-finance 的新 design:金融仪表盘风格,深色界面、精密网格、亮绿色重点色。
|
|
151
151
|
|
|
152
152
|
Revela 可能会继续询问参考图、风格约束或禁忌项,然后在 workspace draft 中创建 `DESIGN.md`、`design.css` 和需要的本地 `assets/**`。它会用内置 page-template fixture 加上这份 CSS 生成 preview,让你在 install 前先检查 cover、agenda、timeline、chart、table、card 和 visual slot。创建完成后再切换使用:
|
|
153
153
|
|
|
154
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
154
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),使用 neon-finance 作为 design。
|
|
155
155
|
|
|
156
156
|
4. 初始化本地 material intake。Init 会扫描、抽取并审阅 workspace source;它不会创建 Narrative Vault。
|
|
157
157
|
|
|
158
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
158
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),帮我 init 这个 workspace,先读本地材料。
|
|
159
159
|
|
|
160
160
|
5. 针对 deck 所需输入做 research,并保存带来源的 findings。
|
|
161
161
|
|
|
162
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
162
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),research 这个 deck 需要的公开证据、案例和 source。
|
|
163
163
|
|
|
164
164
|
6. 先创建或更新 deck plan,明确 slide 顺序、章节结构、source links、unresolved inputs、source limitations 和 visual intent,再生成 HTML。
|
|
165
165
|
|
|
166
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
166
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),生成 HTML 前先 create or update deck plan。
|
|
167
167
|
|
|
168
168
|
7. 基于当前 deck plan 生成 HTML deck。
|
|
169
169
|
|
|
170
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
170
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),基于当前 deck plan make deck。
|
|
171
171
|
|
|
172
|
-
8. make-deck 完成后,从 website card 打开生成的 deck,并在 Codex Browser 中做 annotation 和定向修改。
|
|
172
|
+
8. make-deck 完成后,从 localhost website card 打开生成的 deck,并在 Codex Browser 中做 annotation 和定向修改。
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
Revela 会通过 `http://127.0.0.1:<port>/decks/<file>.html` 服务 deck,你点击 card 后在 Codex Browser 中打开。使用 Codex Browser 原生 annotation 工具标注打开的 HTML deck。
|
|
175
175
|
|
|
176
176
|
9. QA 通过后导出 PDF。
|
|
177
177
|
|
|
178
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
178
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),把 deck export 成 PDF。
|
|
179
179
|
|
|
180
180
|
10. QA 通过后导出可编辑 PPTX。
|
|
181
181
|
|
|
182
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
182
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),把 deck export 成 PPTX。
|
|
183
183
|
|
|
184
184
|
11. QA 通过后导出每页 PNG。
|
|
185
185
|
|
|
186
|
-
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.
|
|
186
|
+
> [$revela:revela](/Users/mengdigao/.codex/plugins/cache/revela/revela/0.19.2/skills/revela/SKILL.md),把 deck export 成 PNG。
|
|
187
187
|
|
|
188
188
|
## Annotate Deck
|
|
189
189
|
|
|
190
|
-
`revela-make-deck` 生成 HTML deck 且 Artifact QA
|
|
190
|
+
`revela-make-deck` 生成 HTML deck 且 Artifact QA 通过后,会在对话中回复可点击打开的 localhost website card。使用 Codex Browser 原生 annotation 工具标注 layout、文案、层级、间距或视觉修改。
|
package/designs/lucent/DESIGN.md
CHANGED
|
@@ -260,7 +260,8 @@ Lucent skins Revela built-in page templates without owning their semantic struct
|
|
|
260
260
|
- `cover`, `section-divider`, `closing`: use full-bleed hero treatment with Lucent package assets.
|
|
261
261
|
- `agenda`, `executive-summary`, `problem-context`, `key-message-evidence`, `claim-supporting-visual`: use report-story/card-grid language with quiet surfaces.
|
|
262
262
|
- `metric-highlight`, `chart-takeaways`, `table-comparison`: use data-forward Lucent panels with explicit interpretation regions.
|
|
263
|
-
- `
|
|
263
|
+
- `milestone`: map to the horizontal roadmap visual system. Dots remain milestone anchors inside each milestone item; do not absolutely position detached decorative dots.
|
|
264
|
+
- `timeline`: map to the vertical timeline visual system. Dots remain event anchors inside each timeline item; do not absolutely position detached decorative dots.
|
|
264
265
|
- `process-steps`, `recommendation-decision`, `risks-tradeoffs`: use recommendation and steps surfaces with no nested card-in-card framing.
|
|
265
266
|
|
|
266
267
|
<!-- @design:page-templates:end -->
|
|
@@ -260,7 +260,8 @@ Lucent skins Revela built-in page templates without owning their semantic struct
|
|
|
260
260
|
- `cover`, `section-divider`, `closing`: use full-bleed hero treatment with Lucent package assets.
|
|
261
261
|
- `agenda`, `executive-summary`, `problem-context`, `key-message-evidence`, `claim-supporting-visual`: use report-story/card-grid language with quiet surfaces.
|
|
262
262
|
- `metric-highlight`, `chart-takeaways`, `table-comparison`: use data-forward Lucent panels with explicit interpretation regions.
|
|
263
|
-
- `
|
|
263
|
+
- `milestone`: map to the horizontal roadmap visual system. Dots remain milestone anchors inside each milestone item; do not absolutely position detached decorative dots.
|
|
264
|
+
- `timeline`: map to the vertical timeline visual system. Dots remain event anchors inside each timeline item; do not absolutely position detached decorative dots.
|
|
264
265
|
- `process-steps`, `recommendation-decision`, `risks-tradeoffs`: use recommendation and steps surfaces with no nested card-in-card framing.
|
|
265
266
|
|
|
266
267
|
<!-- @design:page-templates:end -->
|
package/designs/monet/DESIGN.md
CHANGED
|
@@ -2887,7 +2887,8 @@ Monet skins Revela built-in page templates with soft editorial rhythm, painterly
|
|
|
2887
2887
|
- `cover`, `section-divider`, `closing`: use expressive title-led structural pages.
|
|
2888
2888
|
- `agenda`, `executive-summary`, `problem-context`, `key-message-evidence`, `claim-supporting-visual`: use soft narrative regions with no heavy outer box.
|
|
2889
2889
|
- `metric-highlight`, `chart-takeaways`, `table-comparison`: use calm data surfaces and readable interpretation zones.
|
|
2890
|
-
- `
|
|
2890
|
+
- `milestone`: dots remain milestone anchors inside each horizontal milestone item; do not position detached decorative markers.
|
|
2891
|
+
- `timeline`: dots remain event anchors inside each vertical timeline item; do not position detached decorative markers.
|
|
2891
2892
|
- `process-steps`, `recommendation-decision`, `risks-tradeoffs`: use quiet action and tradeoff panels.
|
|
2892
2893
|
|
|
2893
2894
|
<!-- @design:page-templates:end -->
|
|
@@ -911,7 +911,8 @@ Starter skins Revela built-in page templates as a neutral authoring system. The
|
|
|
911
911
|
- `cover`, `section-divider`, `closing`: use clear title-first structural pages.
|
|
912
912
|
- `agenda`, `executive-summary`, `problem-context`, `key-message-evidence`, `claim-supporting-visual`: use plain narrative and card-grid surfaces.
|
|
913
913
|
- `metric-highlight`, `chart-takeaways`, `table-comparison`: use direct data panels with minimal decoration.
|
|
914
|
-
- `
|
|
914
|
+
- `milestone`: dots remain milestone anchors inside each horizontal milestone item; do not position detached decorative markers.
|
|
915
|
+
- `timeline`: dots remain event anchors inside each vertical timeline item; do not position detached decorative markers.
|
|
915
916
|
- `process-steps`, `recommendation-decision`, `risks-tradeoffs`: use simple step and decision panels.
|
|
916
917
|
|
|
917
918
|
<!-- @design:page-templates:end -->
|
package/designs/summit/DESIGN.md
CHANGED
|
@@ -2671,7 +2671,8 @@ Summit skins Revela built-in page templates with editorial hierarchy, broad whit
|
|
|
2671
2671
|
- `cover`, `section-divider`, `closing`: use strong editorial title pages.
|
|
2672
2672
|
- `agenda`, `executive-summary`, `problem-context`, `key-message-evidence`, `claim-supporting-visual`: use borderless narrative groupings with clear hierarchy.
|
|
2673
2673
|
- `metric-highlight`, `chart-takeaways`, `table-comparison`: use evidence-first data regions without outer container borders.
|
|
2674
|
-
- `
|
|
2674
|
+
- `milestone`: dots remain milestone anchors inside each horizontal milestone item; do not position detached decorative markers.
|
|
2675
|
+
- `timeline`: dots remain event anchors inside each vertical timeline item; do not position detached decorative markers.
|
|
2675
2676
|
- `process-steps`, `recommendation-decision`, `risks-tradeoffs`: use decisive action panels with minimal framing.
|
|
2676
2677
|
|
|
2677
2678
|
<!-- @design:page-templates:end -->
|
package/lib/design/designs.ts
CHANGED
|
@@ -166,6 +166,12 @@ export interface MaterializeDesignPreviewResult {
|
|
|
166
166
|
previewDir: string
|
|
167
167
|
previewPath: string
|
|
168
168
|
previewUrl: string
|
|
169
|
+
browserHandoff: {
|
|
170
|
+
serveRoot: string
|
|
171
|
+
path: string
|
|
172
|
+
urlTemplate: string
|
|
173
|
+
instructions: string
|
|
174
|
+
}
|
|
169
175
|
designCssPath: string
|
|
170
176
|
files: string[]
|
|
171
177
|
warnings: string[]
|
|
@@ -374,6 +380,12 @@ export function materializeDesignPreview(args: MaterializeDesignPreviewArgs): Ma
|
|
|
374
380
|
previewDir,
|
|
375
381
|
previewPath,
|
|
376
382
|
previewUrl: pathToFileURL(previewPath).href,
|
|
383
|
+
browserHandoff: {
|
|
384
|
+
serveRoot: previewDir,
|
|
385
|
+
path: "preview.html",
|
|
386
|
+
urlTemplate: "http://127.0.0.1:<port>/preview.html",
|
|
387
|
+
instructions: "Start a read-only local static server from serveRoot, then reply with the localhost URL so the user can click it open in Codex Browser. Do not open the file:// preview directly.",
|
|
388
|
+
},
|
|
377
389
|
designCssPath,
|
|
378
390
|
files: listDesignPackageFiles(previewDir),
|
|
379
391
|
warnings,
|
|
@@ -162,12 +162,12 @@
|
|
|
162
162
|
<div class="template-page-number">11</div>
|
|
163
163
|
</div>
|
|
164
164
|
</section>
|
|
165
|
-
<section class="slide template-slide" slide-qa="true" data-slide-index="12" data-design="built-in-preview" data-template="
|
|
165
|
+
<section class="slide template-slide" slide-qa="true" data-slide-index="12" data-design="built-in-preview" data-template="milestone">
|
|
166
166
|
<div class="slide-canvas">
|
|
167
167
|
<div class="template-frame">
|
|
168
168
|
<header>
|
|
169
169
|
<p class="template-eyebrow">Template 12 / 16</p>
|
|
170
|
-
<h1 class="template-title">
|
|
170
|
+
<h1 class="template-title">milestone</h1>
|
|
171
171
|
</header><div class="template-body"><div class="template-timeline template-timeline--horizontal" data-template-slot="timeline" style="--timeline-count:5"><article class="template-timeline-item">
|
|
172
172
|
<div class="template-timeline-copy template-card">
|
|
173
173
|
<i class="template-insight-icon" data-lucide="scan-search" aria-hidden="true"></i>
|
|
@@ -214,12 +214,12 @@
|
|
|
214
214
|
<div class="template-page-number">12</div>
|
|
215
215
|
</div>
|
|
216
216
|
</section>
|
|
217
|
-
<section class="slide template-slide" slide-qa="true" data-slide-index="13" data-design="built-in-preview" data-template="timeline
|
|
217
|
+
<section class="slide template-slide" slide-qa="true" data-slide-index="13" data-design="built-in-preview" data-template="timeline">
|
|
218
218
|
<div class="slide-canvas">
|
|
219
219
|
<div class="template-frame">
|
|
220
220
|
<header>
|
|
221
221
|
<p class="template-eyebrow">Template 13 / 16</p>
|
|
222
|
-
<h1 class="template-title">timeline
|
|
222
|
+
<h1 class="template-title">timeline</h1>
|
|
223
223
|
</header><div class="template-body"><div class="template-timeline-layout template-timeline-layout--left"><div class="template-side-panel template-text-panel" data-template-slot="insight"><h2 class="template-side-panel-title template-text-panel-title">Reading the journey</h2><p class="template-side-panel-body template-text-panel-body">The timeline should show sequence and decision rhythm, while the side panel explains why the milestones matter.</p></div><div class="template-timeline template-timeline--vertical" data-template-slot="timeline" style="--timeline-count:4"><article class="template-timeline-item">
|
|
224
224
|
<span class="template-timeline-dot" aria-hidden="true"></span>
|
|
225
225
|
<div class="template-timeline-copy">
|
|
@@ -150,10 +150,13 @@ const templates: PageTemplateDefinition[] = [
|
|
|
150
150
|
field("insightBody", "string", "Interpretation, reading note, or caveat below the table."),
|
|
151
151
|
field("insightIcon", "string", "Lucide icon name for the insight title."),
|
|
152
152
|
], ["Keep rows scannable.", "Do not use a table for pure prose."], ["Table has headers and body rows."]),
|
|
153
|
-
define("
|
|
153
|
+
define("milestone", "Milestone", "Show dated phases or milestones on a horizontal roadmap axis.", [
|
|
154
154
|
field("title", "string", "Slide title.", true),
|
|
155
|
-
field("
|
|
156
|
-
|
|
155
|
+
field("milestones", "milestones[]", "Horizontal milestones.", true),
|
|
156
|
+
], ["Use 3-6 milestones.", "Milestone cards sit above the axis and date labels sit below it.", "Each dot belongs to the same DOM item as its copy."], ["Timeline root exists.", "Every milestone has dot and copy.", "Dot and copy are sibling anchors inside one timeline item."]),
|
|
157
|
+
define("timeline", "Timeline", "Show dated events, journey steps, or sequence as a vertical timeline.", [
|
|
158
|
+
field("title", "string", "Slide title.", true),
|
|
159
|
+
field("milestones", "milestones[]", "Timeline events.", true),
|
|
157
160
|
field("insightTitle", "string", "Side panel title."),
|
|
158
161
|
field("insightBody", "string", "Timeline interpretation, so-what, or caveat."),
|
|
159
162
|
field("insightSide", "string", "left or right side panel placement."),
|
|
@@ -188,19 +191,21 @@ export function listPageTemplates(): { ok: true; templates: PageTemplateDefiniti
|
|
|
188
191
|
}
|
|
189
192
|
|
|
190
193
|
export function renderTemplateSlide(input: RenderTemplateSlideInput): RenderTemplateSlideResult {
|
|
191
|
-
const
|
|
194
|
+
const requestedTemplateId = normalizeTemplateId(input.templateId)
|
|
195
|
+
const template = getPageTemplate(requestedTemplateId)
|
|
192
196
|
const slideIndex = positiveIndex(input.slideIndex)
|
|
193
197
|
const content = input.content ?? {}
|
|
194
198
|
const designName = input.designName || "lucent"
|
|
195
199
|
const warnings = validateRequiredFields(template, content)
|
|
200
|
+
const outputTemplate = requestedTemplateId === "timeline-roadmap" ? { ...template, id: "timeline-roadmap", title: "Timeline / Roadmap" } : template
|
|
196
201
|
const html = renderSlideShell({
|
|
197
|
-
template,
|
|
202
|
+
template: outputTemplate,
|
|
198
203
|
slideIndex,
|
|
199
204
|
designName,
|
|
200
205
|
title: stringValue(content.title) || template.title,
|
|
201
|
-
body: renderBody(
|
|
206
|
+
body: renderBody(requestedTemplateId, content),
|
|
202
207
|
})
|
|
203
|
-
return { ok: true, templateId:
|
|
208
|
+
return { ok: true, templateId: outputTemplate.id, slideIndex, designName, html, warnings }
|
|
204
209
|
}
|
|
205
210
|
|
|
206
211
|
export function builtInPreviewFixtures(): BuiltInPreviewFixture[] {
|
|
@@ -284,9 +289,8 @@ export function builtInPreviewFixtures(): BuiltInPreviewFixture[] {
|
|
|
284
289
|
insightIcon: "lightbulb",
|
|
285
290
|
insightBody: "The template layer owns structure, while the design layer owns visual treatment. This keeps agent edits bounded without freezing the final look.",
|
|
286
291
|
}),
|
|
287
|
-
fixture("
|
|
288
|
-
title: "
|
|
289
|
-
orientation: "horizontal",
|
|
292
|
+
fixture("milestone", {
|
|
293
|
+
title: "milestone",
|
|
290
294
|
milestones: [
|
|
291
295
|
{ date: "2022", label: "Signal", description: "Map the baseline." },
|
|
292
296
|
{ date: "2023", label: "Proof", description: "Validate the evidence threshold." },
|
|
@@ -295,9 +299,8 @@ export function builtInPreviewFixtures(): BuiltInPreviewFixture[] {
|
|
|
295
299
|
{ date: "2026", label: "Decision", description: "Commit to the next path." },
|
|
296
300
|
],
|
|
297
301
|
}),
|
|
298
|
-
fixture("timeline
|
|
299
|
-
title: "timeline
|
|
300
|
-
orientation: "vertical",
|
|
302
|
+
fixture("timeline", {
|
|
303
|
+
title: "timeline",
|
|
301
304
|
insightTitle: "Reading the journey",
|
|
302
305
|
insightBody: "The timeline should show sequence and decision rhythm, while the side panel explains why the milestones matter.",
|
|
303
306
|
milestones: [
|
|
@@ -785,7 +788,7 @@ export function validatePageTemplateContracts(filePath: string): PageTemplateCon
|
|
|
785
788
|
const body = section[2]
|
|
786
789
|
const slideIndex = Number(/data-slide-index=["'](\d+)["']/i.exec(section[0])?.[1])
|
|
787
790
|
issues.push(...validateVocabularyContract(templateId, body, Number.isInteger(slideIndex) ? slideIndex : undefined))
|
|
788
|
-
if (templateId
|
|
791
|
+
if (isTimelineTemplateId(templateId)) issues.push(...validateTimelineContract(templateId, body, Number.isInteger(slideIndex) ? slideIndex : undefined))
|
|
789
792
|
}
|
|
790
793
|
return { ok: !issues.some((issue) => issue.severity === "error"), issues }
|
|
791
794
|
}
|
|
@@ -815,7 +818,7 @@ export function validateBoundedTemplateEdit(input: BoundedTemplateEditInput): Pa
|
|
|
815
818
|
} else {
|
|
816
819
|
const templateId = /data-template=["']([^"']+)["']/i.exec(target)?.[1] || "unknown"
|
|
817
820
|
issues.push(...validateVocabularyContract(templateId, target, slideIndex))
|
|
818
|
-
if (templateId
|
|
821
|
+
if (isTimelineTemplateId(templateId)) issues.push(...validateTimelineContract(templateId, target, slideIndex))
|
|
819
822
|
}
|
|
820
823
|
return { ok: !issues.some((issue) => issue.severity === "error"), issues }
|
|
821
824
|
}
|
|
@@ -824,23 +827,23 @@ function define(id: string, title: string, purpose: string, fields: PageTemplate
|
|
|
824
827
|
return { id, title, purpose, status: "renderable", fields, contentRules, qaRules }
|
|
825
828
|
}
|
|
826
829
|
|
|
827
|
-
function validateTimelineContract(html: string, slideIndex?: number): PageTemplateContractIssue[] {
|
|
830
|
+
function validateTimelineContract(templateId: string, html: string, slideIndex?: number): PageTemplateContractIssue[] {
|
|
828
831
|
const issues: PageTemplateContractIssue[] = []
|
|
829
832
|
const root = /class=["'][^"']*\btemplate-timeline\b[^"']*["']/i.test(html)
|
|
830
833
|
if (!root) {
|
|
831
|
-
issues.push({ severity: "error", templateId
|
|
834
|
+
issues.push({ severity: "error", templateId, slideIndex, message: "Missing .template-timeline root." })
|
|
832
835
|
return issues
|
|
833
836
|
}
|
|
834
837
|
const itemMatches = [...html.matchAll(/<article\b[^>]*class=["'][^"']*\btemplate-timeline-item\b[^"']*["'][^>]*>([\s\S]*?)<\/article>/gi)]
|
|
835
|
-
if (itemMatches.length < 3) issues.push({ severity: "warning", templateId
|
|
838
|
+
if (itemMatches.length < 3) issues.push({ severity: "warning", templateId, slideIndex, message: "Timeline should usually contain at least three milestones." })
|
|
836
839
|
for (let index = 0; index < itemMatches.length; index++) {
|
|
837
840
|
const item = itemMatches[index][1]
|
|
838
|
-
if (!/class=["'][^"']*\btemplate-timeline-dot\b[^"']*["']/i.test(item)) issues.push({ severity: "error", templateId
|
|
839
|
-
if (!/class=["'][^"']*\btemplate-timeline-copy\b[^"']*["']/i.test(item)) issues.push({ severity: "error", templateId
|
|
841
|
+
if (!/class=["'][^"']*\btemplate-timeline-dot\b[^"']*["']/i.test(item)) issues.push({ severity: "error", templateId, slideIndex, message: `Milestone ${index + 1} is missing .template-timeline-dot inside its item.` })
|
|
842
|
+
if (!/class=["'][^"']*\btemplate-timeline-copy\b[^"']*["']/i.test(item)) issues.push({ severity: "error", templateId, slideIndex, message: `Milestone ${index + 1} is missing .template-timeline-copy inside its item.` })
|
|
840
843
|
}
|
|
841
844
|
const dotCount = (html.match(/\btemplate-timeline-dot\b/g) ?? []).length
|
|
842
845
|
const copyCount = (html.match(/\btemplate-timeline-copy\b/g) ?? []).length
|
|
843
|
-
if (dotCount !== copyCount) issues.push({ severity: "error", templateId
|
|
846
|
+
if (dotCount !== copyCount) issues.push({ severity: "error", templateId, slideIndex, message: `Timeline dot count (${dotCount}) must match copy count (${copyCount}).` })
|
|
844
847
|
return issues
|
|
845
848
|
}
|
|
846
849
|
|
|
@@ -889,12 +892,26 @@ function field(name: string, type: PageTemplateField["type"], description: strin
|
|
|
889
892
|
}
|
|
890
893
|
|
|
891
894
|
function getPageTemplate(templateId: string): PageTemplateDefinition {
|
|
892
|
-
const id =
|
|
895
|
+
const id = canonicalTemplateId(templateId)
|
|
893
896
|
const template = templates.find((item) => item.id === id)
|
|
894
897
|
if (!template) throw new Error(`Unknown page template: ${templateId}`)
|
|
895
898
|
return template
|
|
896
899
|
}
|
|
897
900
|
|
|
901
|
+
function normalizeTemplateId(templateId: string): string {
|
|
902
|
+
return String(templateId || "").trim()
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
function canonicalTemplateId(templateId: string): string {
|
|
906
|
+
const id = normalizeTemplateId(templateId)
|
|
907
|
+
if (id === "timeline-roadmap") return "milestone"
|
|
908
|
+
return id
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
function isTimelineTemplateId(templateId: string): boolean {
|
|
912
|
+
return ["milestone", "timeline", "timeline-roadmap"].includes(templateId)
|
|
913
|
+
}
|
|
914
|
+
|
|
898
915
|
function renderSlideShell(input: { template: PageTemplateDefinition; slideIndex: number; designName: string; title: string; body: string; catalog?: any }): string {
|
|
899
916
|
const hero = ["cover", "section-divider", "closing"].includes(input.template.id)
|
|
900
917
|
const slideQa = hero ? "false" : "true"
|
|
@@ -946,6 +963,8 @@ function renderBody(templateId: string, content: Record<string, any>): string {
|
|
|
946
963
|
if (templateId === "metric-highlight") return `${renderHeader(content, "Metric Highlight")}<div class="template-body">${metricHighlight(content)}</div>`
|
|
947
964
|
if (templateId === "chart-takeaways") return `${renderHeader(content, "Chart + Takeaways")}<div class="template-body template-grid template-chart-layout">${visualSlotPanel()}${chartTakeawayPanel(content)}</div>`
|
|
948
965
|
if (templateId === "table-comparison") return `${renderHeader(content, "Table / Comparison")}<div class="template-body" data-template-slot="table">${table(content)}</div>`
|
|
966
|
+
if (templateId === "milestone") return `${renderHeader(content, "Milestone")}<div class="template-body">${timeline({ ...content, orientation: "horizontal" })}</div>`
|
|
967
|
+
if (templateId === "timeline") return `${renderHeader(content, "Timeline")}<div class="template-body">${timeline({ ...content, orientation: "vertical" })}</div>`
|
|
949
968
|
if (templateId === "timeline-roadmap") return `${renderHeader(content, "Timeline / Roadmap")}<div class="template-body">${timeline(content)}</div>`
|
|
950
969
|
if (templateId === "process-steps") return `${renderHeader(content, "Process / Steps")}<div class="template-body"><div class="template-steps" data-template-slot="steps">${steps(content.steps)}</div></div>`
|
|
951
970
|
if (templateId === "recommendation-decision") return `${renderHeader(content, "Recommendation / Decision")}<div class="template-body template-grid cols-3"><div class="template-card" data-template-slot="recommendation"><h2>Recommendation</h2><p>${escapeHtml(stringValue(content.recommendation))}</p>${imageCard(content)}</div><div data-template-slot="rationale">${cards(items(content).slice(0, 1), "h3")}</div><div class="template-card" data-template-slot="next-steps"><h2>Next steps</h2>${orderedSteps(content.steps)}</div></div>`
|
|
@@ -1132,7 +1151,8 @@ function scaffoldSeed(templateId: string, seed: Record<string, any>): Record<str
|
|
|
1132
1151
|
if (templateId === "metric-highlight") return { metrics: [{ value: "67%", label: "Metric", description: "Replace with interpretation." }, { value: "3x", label: "Comparison", description: "Replace with reading note." }, { value: "14d", label: "Window", description: "Replace with time context." }], insightTitle: "Read the signal", insightBody: "Replace with the decision implication, caveat, or next reading step.", ...base }
|
|
1133
1152
|
if (templateId === "chart-takeaways") return { takeawaysTitle: "What to read", items: defaultItems(["Trend", "Driver", "Decision use"]), ...base }
|
|
1134
1153
|
if (templateId === "table-comparison") return { columns: ["Dimension", "Current", "Target"], rows: [["Replace", "Current state", "Target state"], ["Caveat", "Known limit", "Next proof"]], insightTitle: "Insight", insightBody: "Replace with the table reading note or caveat.", ...base }
|
|
1135
|
-
if (templateId === "timeline-roadmap") return { orientation: "horizontal", milestones: [{ date: "2022", label: "Signal", description: "Name the starting condition." }, { date: "2023", label: "Proof", description: "Show the evidence threshold." }, { date: "2024", label: "Inflection", description: "Use the pivotal moment to frame the shift." }, { date: "2025", label: "Scale", description: "Use a taller card for the highlighted milestone.", highlight: true }, { date: "2026", label: "Decision", description: "State what changes next." }], ...base }
|
|
1154
|
+
if (templateId === "milestone" || templateId === "timeline-roadmap") return { orientation: "horizontal", milestones: [{ date: "2022", label: "Signal", description: "Name the starting condition." }, { date: "2023", label: "Proof", description: "Show the evidence threshold." }, { date: "2024", label: "Inflection", description: "Use the pivotal moment to frame the shift." }, { date: "2025", label: "Scale", description: "Use a taller card for the highlighted milestone.", highlight: true }, { date: "2026", label: "Decision", description: "State what changes next." }], ...base }
|
|
1155
|
+
if (templateId === "timeline") return { orientation: "vertical", insightTitle: "Reading the journey", insightBody: "Replace with the timeline interpretation or caveat.", milestones: [{ date: "Mar 2019", label: "Launch", description: "Name the starting event." }, { date: "Nov 2019", label: "Audit", description: "Show the evidence threshold." }, { date: "May 2020", label: "Scale", description: "Explain the operating cadence." }, { date: "Feb 2021", label: "Review", description: "State what changes next." }], ...base }
|
|
1136
1156
|
if (templateId === "process-steps") return { steps: defaultItems(["Step 1", "Step 2", "Step 3"]), ...base }
|
|
1137
1157
|
if (templateId === "recommendation-decision") return { recommendation: "Replace with the recommended decision.", items: defaultItems(["Rationale"]), steps: defaultItems(["Pilot", "Validate", "Ship"]), ...base }
|
|
1138
1158
|
if (templateId === "risks-tradeoffs") return { items: defaultItems(["Risk", "Tradeoff", "Mitigation"]), ...base }
|
|
@@ -10,10 +10,12 @@ export * from "./cover"
|
|
|
10
10
|
export * from "./executive-summary"
|
|
11
11
|
export * from "./key-message-evidence"
|
|
12
12
|
export * from "./metric-highlight"
|
|
13
|
+
export * from "./milestone"
|
|
13
14
|
export * from "./problem-context"
|
|
14
15
|
export * from "./process-steps"
|
|
15
16
|
export * from "./recommendation-decision"
|
|
16
17
|
export * from "./risks-tradeoffs"
|
|
17
18
|
export * from "./section-divider"
|
|
18
19
|
export * from "./table-comparison"
|
|
20
|
+
export * from "./timeline"
|
|
19
21
|
export * from "./timeline-roadmap"
|
|
@@ -57,7 +57,8 @@ export const PAGE_TEMPLATE_VOCABULARY: PageTemplateVocabulary[] = [
|
|
|
57
57
|
vocab("metric-highlight", ["template-stat-grid"], ["metrics"], ["metrics", "insight"], ["Metric values should remain visible outside prose."]),
|
|
58
58
|
vocab("chart-takeaways", ["template-chart-panel", "template-chart-takeaway-panel"], ["visual", "takeaways"], ["visual", "takeaways"], ["Chart/image slot and takeaway text panel must both remain present."]),
|
|
59
59
|
vocab("table-comparison", ["template-table-wrap", "template-table"], ["table"], ["table", "insight"], ["Table headers and body should remain structured, not prose-only."]),
|
|
60
|
-
vocab("
|
|
60
|
+
vocab("milestone", ["template-timeline", "template-timeline-item", "template-timeline-dot", "template-timeline-copy", "template-insight-icon"], ["timeline"], ["timeline"], ["Each milestone item must keep dot and copy as sibling anchors inside one item.", "Milestone cards reuse .template-card; highlight uses the item modifier."]),
|
|
61
|
+
vocab("timeline", ["template-timeline", "template-timeline-item", "template-timeline-dot", "template-timeline-copy"], ["timeline"], ["timeline", "insight"], ["Each timeline item must keep dot and copy as sibling anchors inside one item.", "The optional insight slot explains the sequence without replacing event copy."]),
|
|
61
62
|
vocab("process-steps", ["template-steps", "template-step-number"], ["steps"], ["steps"], ["Steps should remain ordered in DOM order."]),
|
|
62
63
|
vocab("recommendation-decision", ["template-card"], ["recommendation", "rationale", "next-steps"], ["recommendation", "rationale", "next-steps"], ["Keep recommendation, rationale, and next steps separate."]),
|
|
63
64
|
vocab("risks-tradeoffs", ["template-card"], ["risks"], ["risks"], ["Risk/tradeoff cards should name uncertainty explicitly."]),
|
|
@@ -132,9 +133,10 @@ export function listPageTemplateVocabulary(): PageTemplateVocabulary[] {
|
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
export function getPageTemplateVocabulary(templateId: string): PageTemplateVocabulary {
|
|
135
|
-
const
|
|
136
|
+
const id = templateId === "timeline-roadmap" ? "milestone" : templateId
|
|
137
|
+
const vocabulary = PAGE_TEMPLATE_VOCABULARY.find((item) => item.templateId === id)
|
|
136
138
|
if (!vocabulary) throw new Error(`Unknown page template vocabulary: ${templateId}`)
|
|
137
|
-
return vocabulary
|
|
139
|
+
return templateId === "timeline-roadmap" ? { ...vocabulary, templateId } : vocabulary
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
function vocab(templateId: string, requiredClasses: string[], slotNames: string[], replaceableSlots: string[], contractNotes: string[]): PageTemplateVocabulary {
|
package/package.json
CHANGED
|
@@ -71,16 +71,16 @@ function titleFromDeckHtml(absolutePath: string): string {
|
|
|
71
71
|
|
|
72
72
|
export function formatDeckWebsiteCardHandoffNotice(workspaceRoot: string, target: string): string {
|
|
73
73
|
const absolutePath = resolve(workspaceRoot, target)
|
|
74
|
-
const deckUrl = pathToFileURL(absolutePath).href
|
|
75
74
|
const title = titleFromDeckHtml(absolutePath)
|
|
75
|
+
const httpUrlTemplate = `http://127.0.0.1:<port>/${target}`
|
|
76
76
|
return [
|
|
77
77
|
"**Deck website card ready**",
|
|
78
78
|
"",
|
|
79
|
-
`Artifact QA passed for \`${target}\`.
|
|
79
|
+
`Artifact QA passed for \`${target}\`. Do not open the deck file directly. Start a read-only local static server from the workspace root, then reply with this standalone deck link so Codex renders an Open in Browser website card the user can click:`,
|
|
80
80
|
"",
|
|
81
|
-
`[${title}](${
|
|
81
|
+
`[${title}](${httpUrlTemplate})`,
|
|
82
82
|
"",
|
|
83
|
-
`
|
|
83
|
+
`Replace \`<port>\` with the actual localhost port. Keep \`file://\` only for non-Codex surfaces that allow direct local-file navigation.`,
|
|
84
84
|
].join("\n")
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -113,7 +113,7 @@ const tools = [
|
|
|
113
113
|
inputSchema: objectSchema({
|
|
114
114
|
workspaceRoot: stringProp("Optional workspace root."),
|
|
115
115
|
designName: stringProp("Optional design name. Defaults to the active design."),
|
|
116
|
-
templateId: requiredStringProp("Built-in template id, such as timeline
|
|
116
|
+
templateId: requiredStringProp("Built-in template id, such as milestone or timeline."),
|
|
117
117
|
slideIndex: requiredNumberProp("Positive 1-based slide index."),
|
|
118
118
|
content: objectProp("Template content fields. The built-in template renderer owns the HTML skeleton."),
|
|
119
119
|
}, ["templateId", "slideIndex", "content"]),
|
|
@@ -122,14 +122,14 @@ const tools = [
|
|
|
122
122
|
name: "revela_page_template_foundation",
|
|
123
123
|
description: "Read the built-in template foundation for custom design authoring: scaffold HTML, CSS hooks, slots, and contract notes.",
|
|
124
124
|
inputSchema: objectSchema({
|
|
125
|
-
templateId: requiredStringProp("Built-in template id, such as timeline
|
|
125
|
+
templateId: requiredStringProp("Built-in template id, such as milestone or timeline."),
|
|
126
126
|
}, ["templateId"]),
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
129
|
name: "revela_page_template_vocabulary",
|
|
130
130
|
description: "Read machine-readable classes, slots, editable regions, replaceable regions, and contract notes for one page template.",
|
|
131
131
|
inputSchema: objectSchema({
|
|
132
|
-
templateId: requiredStringProp("Built-in template id, such as timeline
|
|
132
|
+
templateId: requiredStringProp("Built-in template id, such as milestone or timeline."),
|
|
133
133
|
}, ["templateId"]),
|
|
134
134
|
},
|
|
135
135
|
{
|
|
@@ -138,7 +138,7 @@ const tools = [
|
|
|
138
138
|
inputSchema: objectSchema({
|
|
139
139
|
workspaceRoot: stringProp("Optional workspace root."),
|
|
140
140
|
designName: stringProp("Optional design name. Defaults to the active design."),
|
|
141
|
-
templateId: requiredStringProp("Built-in template id, such as timeline
|
|
141
|
+
templateId: requiredStringProp("Built-in template id, such as milestone or timeline."),
|
|
142
142
|
slideIndex: requiredNumberProp("Positive 1-based slide index."),
|
|
143
143
|
seed: objectProp("Optional scaffold seed fields. This is not the final authoring interface."),
|
|
144
144
|
}, ["templateId", "slideIndex"]),
|
|
@@ -150,7 +150,7 @@ const tools = [
|
|
|
150
150
|
workspaceRoot: stringProp("Optional workspace root."),
|
|
151
151
|
outputPath: requiredStringProp("Workspace-relative HTML deck path."),
|
|
152
152
|
designName: stringProp("Optional design name. Defaults to the active design."),
|
|
153
|
-
templateId: requiredStringProp("Built-in template id, such as timeline
|
|
153
|
+
templateId: requiredStringProp("Built-in template id, such as milestone or timeline."),
|
|
154
154
|
slideIndex: requiredNumberProp("Positive 1-based slide index."),
|
|
155
155
|
seed: objectProp("Optional scaffold seed fields. LLM should bounded-edit the inserted slide after scaffold creation."),
|
|
156
156
|
}, ["outputPath", "templateId", "slideIndex"]),
|
|
@@ -162,7 +162,7 @@ const tools = [
|
|
|
162
162
|
workspaceRoot: stringProp("Optional workspace root."),
|
|
163
163
|
outputPath: requiredStringProp("Workspace-relative HTML deck path."),
|
|
164
164
|
designName: stringProp("Optional design name. Defaults to the active design."),
|
|
165
|
-
templateId: requiredStringProp("Built-in template id, such as timeline
|
|
165
|
+
templateId: requiredStringProp("Built-in template id, such as milestone or timeline."),
|
|
166
166
|
slideIndex: requiredNumberProp("Positive 1-based slide index."),
|
|
167
167
|
content: objectProp("Template content fields. Prefer scaffold-first flow for new deck creation."),
|
|
168
168
|
}, ["outputPath", "templateId", "slideIndex", "content"]),
|
|
@@ -288,7 +288,7 @@ const tools = [
|
|
|
288
288
|
inputSchema: objectSchema({
|
|
289
289
|
workspaceRoot: stringProp("Optional workspace root."),
|
|
290
290
|
name: requiredStringProp("Design name to preview."),
|
|
291
|
-
source:
|
|
291
|
+
source: enumProp(["draft", "installed", "builtin"], "Optional source. Defaults to draft when present, otherwise installed/builtin."),
|
|
292
292
|
}, ["name"]),
|
|
293
293
|
},
|
|
294
294
|
{
|
|
@@ -476,10 +476,12 @@ async function handle(req: JsonRpcRequest): Promise<any | undefined> {
|
|
|
476
476
|
bootLog("request", { id: req.id, method: req.method })
|
|
477
477
|
if (req.method === "initialize") {
|
|
478
478
|
bootLog("initialize-received", { id: req.id, protocolVersion: req.params?.protocolVersion })
|
|
479
|
+
const runtimeInfo = await runtime()
|
|
480
|
+
const doctor = runtimeInfo.doctor({})
|
|
479
481
|
return result(req.id, {
|
|
480
482
|
protocolVersion: req.params?.protocolVersion || "2024-11-05",
|
|
481
483
|
capabilities: { tools: {} },
|
|
482
|
-
serverInfo: { name: "revela", version:
|
|
484
|
+
serverInfo: { name: "revela", version: doctor.version },
|
|
483
485
|
})
|
|
484
486
|
}
|
|
485
487
|
if (req.method === "tools/list") {
|
|
@@ -29,7 +29,7 @@ Use this skill as the main Revela entrypoint in Codex. It should inspect intent
|
|
|
29
29
|
- `spec.md` exists but source support, material review, or findings are missing: use `revela-research`.
|
|
30
30
|
- `spec.md` and sufficient findings exist but `deck-plan.md` is missing or needs normal authoring: use `revela-research` Planning Handoff.
|
|
31
31
|
- Valid `deck-plan.md` exists and the user asks to make, generate, render, or update a deck: use `revela-make-deck`.
|
|
32
|
-
- Existing deck artifact and the user asks to review, annotate, diagnose, QA, or refine: use Codex Browser's native browsing/annotation flow. If the deck was not just generated, reply with the existing deck as a website card/link and use native annotations after
|
|
32
|
+
- Existing deck artifact and the user asks to review, annotate, diagnose, QA, or refine: use Codex Browser's native browsing/annotation flow. If the deck was not just generated, start a read-only local static server from the workspace root, reply with the existing deck as a localhost website card/link, and use native annotations after the user opens it; route export requests to `revela-export`.
|
|
33
33
|
- Existing deck artifact and the user asks for PDF, PPTX, or PNG output: use `revela-export`.
|
|
34
34
|
- If the next step is still ambiguous after inspection, ask the smallest missing question and recommend the safest next specialist skill.
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ For new or edited designs:
|
|
|
38
38
|
5. Draft complete `DESIGN.md` and complete `design.css` content.
|
|
39
39
|
6. Call `revela_design_draft_create` with `designCss`; when uploaded or local design material exists, pass `assets: [{ path: "assets/...", contentBase64|content|sourcePath }]` so the files are written into the draft package.
|
|
40
40
|
7. Call `revela_design_draft_validate`.
|
|
41
|
-
8. Call `revela_design_preview` for the draft and
|
|
41
|
+
8. Call `revela_design_preview` for the draft, start a read-only local static server from the returned `browserHandoff.serveRoot`, and reply with the resulting localhost preview link for the user to open in Codex Browser.
|
|
42
42
|
9. If validation or preview review fails, revise the draft content and repeat draft create/validate/preview.
|
|
43
43
|
10. Call `revela_design_draft_install` only after the draft validates and the user intent is to install it.
|
|
44
44
|
11. Call `revela_design_activate` only when the user asks to make it active.
|
|
@@ -66,6 +66,7 @@ Use `revela_design_create` only when the user explicitly requests direct local c
|
|
|
66
66
|
- Optional assets must live under `assets/**`; reference them as package-relative paths like `assets/cover-background.png`.
|
|
67
67
|
- `DESIGN.md` may reference package assets in rules, layouts, or components with `assets/...`; do not reference workspace `assets/` media manifest entries for design-owned visuals.
|
|
68
68
|
- `revela_design_preview` must generate the visual preview; do not hand-write package `preview.html` for ordinary CSS-native design drafts.
|
|
69
|
+
- Do not open `file://` preview URLs in Codex Browser. Use the returned `browserHandoff` fields to serve the preview over `http://127.0.0.1:<port>/preview.html` and let the user click the link.
|
|
69
70
|
- If design assets are present, the generated preview should visibly use the saved `assets/...` files when the design CSS references them.
|
|
70
71
|
- Generated preview should show the built-in page templates with normal, dense, chart/table, timeline, image, and source-note-like states.
|
|
71
72
|
- Preserve source inspiration and limitations explicitly; do not copy copyrighted design text or assets into the package.
|
|
@@ -46,7 +46,7 @@ Report:
|
|
|
46
46
|
- `spec.md` exists but no `researches/`: run `revela-research`.
|
|
47
47
|
- Research exists but no `deck-plan.md`: continue `revela-research` to the Planning Handoff.
|
|
48
48
|
- Valid `deck-plan.md` but no deck artifact: run `revela-make-deck`.
|
|
49
|
-
- Existing deck artifact: surface the HTML deck as a website card/link for Codex Browser native annotation, or run `revela-export` for PDF/PPTX/PNG.
|
|
49
|
+
- Existing deck artifact: start a read-only local static server from the workspace root and surface the HTML deck as a localhost website card/link for Codex Browser native annotation, or run `revela-export` for PDF/PPTX/PNG.
|
|
50
50
|
|
|
51
51
|
## Must Not
|
|
52
52
|
|
|
@@ -17,7 +17,7 @@ Use this skill when the user asks to make, generate, render, or update a Revela
|
|
|
17
17
|
- Deck-local `decks/_revela-design/**/design.css` files are generated design snapshots. Do not patch them during deck making; regenerate the deck foundation or enter the design workflow instead.
|
|
18
18
|
- Active/requested domain guidance may inform communication framing, but it is not source evidence.
|
|
19
19
|
- Generated artifacts live under `decks/*.html`.
|
|
20
|
-
- After final Artifact QA passes, reply with the generated HTML deck as a standalone website link/card that
|
|
20
|
+
- After final Artifact QA passes, reply with the generated HTML deck as a standalone localhost website link/card that the user can click to open in Codex Browser for native browsing and annotation.
|
|
21
21
|
- Do not require a Narrative Vault before generating a deck.
|
|
22
22
|
- This skill does not own normal plan authoring; `revela-research` owns source preparation and `deck-plan.md` planning handoff.
|
|
23
23
|
- `deck-plan.md` is required for normal deck generation.
|
|
@@ -93,8 +93,8 @@ Use this phase when the user asks to make, generate, render, or update an HTML d
|
|
|
93
93
|
12. Every slide must have exactly one direct `.slide-canvas` child.
|
|
94
94
|
13. Keep the HTML valid after each write.
|
|
95
95
|
14. After every HTML write, call `revela_run_deck_qa` and repair hard errors before continuing or export.
|
|
96
|
-
15. After the final `revela_run_deck_qa` passes with zero hard errors, reply with a standalone Markdown link to the generated HTML deck artifact so
|
|
97
|
-
16.
|
|
96
|
+
15. After the final `revela_run_deck_qa` passes with zero hard errors, do not open the deck file directly. Start a read-only local static server from the workspace root and reply with a standalone Markdown link to the generated HTML deck artifact so the user can click it open in Codex Browser.
|
|
97
|
+
16. Use the exact `http://127.0.0.1:<port>/decks/<file>.html` URL for the card, replacing `<port>` with the actual localhost port. Keep `file://` only for non-Codex surfaces that allow direct local-file navigation.
|
|
98
98
|
|
|
99
99
|
## Outputs
|
|
100
100
|
|