@cyber-dash-tech/revela 0.5.1 → 0.6.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 +6 -2
- package/README.zh-CN.md +6 -2
- package/designs/monet/DESIGN.md +3 -3
- package/designs/monet/preview.html +1 -1
- package/designs/starter/DESIGN.md +2 -2
- package/designs/starter/preview.html +1 -1
- package/designs/summit/DESIGN.md +3 -3
- package/designs/summit/preview.html +1 -1
- package/package.json +1 -1
- package/plugin.ts +4 -0
- package/tools/pdf.ts +43 -0
- package/tools/pptx.ts +49 -0
package/README.md
CHANGED
|
@@ -114,7 +114,7 @@ Before the agent writes `decks/humanoid-robotics.html`, it must update `DECKS.js
|
|
|
114
114
|
/revela review humanoid-robotics
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
Export when needed:
|
|
117
|
+
Export when needed, either manually or by asking the agent to export:
|
|
118
118
|
|
|
119
119
|
```text
|
|
120
120
|
/revela pdf decks/humanoid-robotics.html
|
|
@@ -600,13 +600,17 @@ PDF export:
|
|
|
600
600
|
/revela pdf decks/my-deck.html
|
|
601
601
|
```
|
|
602
602
|
|
|
603
|
+
LLM tool equivalent: `revela-pdf` with `{ "file": "decks/my-deck.html" }`.
|
|
604
|
+
|
|
603
605
|
Editable PPTX export:
|
|
604
606
|
|
|
605
607
|
```text
|
|
606
608
|
/revela pptx decks/my-deck.html
|
|
607
609
|
```
|
|
608
610
|
|
|
609
|
-
|
|
611
|
+
LLM tool equivalent: `revela-pptx` with `{ "file": "decks/my-deck.html" }`.
|
|
612
|
+
|
|
613
|
+
Both commands and tools write output beside the source HTML deck. Use the tools when you want the agent to run export as part of the deck workflow instead of asking the user to invoke `/revela pdf` or `/revela pptx` manually.
|
|
610
614
|
|
|
611
615
|
---
|
|
612
616
|
|
package/README.zh-CN.md
CHANGED
|
@@ -113,7 +113,7 @@ Create a 6-slide HTML deck on humanoid robotics supply chains. Cite the main mar
|
|
|
113
113
|
/revela review humanoid-robotics
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
需要导出时,可以手动调用,也可以让 agent 直接导出:
|
|
117
117
|
|
|
118
118
|
```text
|
|
119
119
|
/revela pdf decks/humanoid-robotics.html
|
|
@@ -565,13 +565,17 @@ PDF 导出:
|
|
|
565
565
|
/revela pdf decks/my-deck.html
|
|
566
566
|
```
|
|
567
567
|
|
|
568
|
+
对应的 LLM tool:`revela-pdf`,参数为 `{ "file": "decks/my-deck.html" }`。
|
|
569
|
+
|
|
568
570
|
可编辑 PPTX 导出:
|
|
569
571
|
|
|
570
572
|
```text
|
|
571
573
|
/revela pptx decks/my-deck.html
|
|
572
574
|
```
|
|
573
575
|
|
|
574
|
-
|
|
576
|
+
对应的 LLM tool:`revela-pptx`,参数为 `{ "file": "decks/my-deck.html" }`。
|
|
577
|
+
|
|
578
|
+
命令和 tool 都会把结果写到源 HTML deck 同目录。如果希望 agent 在 deck 工作流中自动完成导出,可以让它调用 tool,而不需要用户手动执行 `/revela pdf` 或 `/revela pptx`。
|
|
575
579
|
|
|
576
580
|
---
|
|
577
581
|
|
package/designs/monet/DESIGN.md
CHANGED
|
@@ -171,8 +171,8 @@ Recommended reusable primitives:
|
|
|
171
171
|
- Every slide uses `.slide-canvas` sized to `1920px x 1080px`, scaled by JS.
|
|
172
172
|
- Every `<section class="slide">` must include `slide-qa="true"` or `slide-qa="false"`.
|
|
173
173
|
- Use `slide-qa="true"` for dense content layouts and `slide-qa="false"` for structural or intentionally sparse layouts.
|
|
174
|
-
-
|
|
175
|
-
-
|
|
174
|
+
- `.slide-canvas` is the export surface and must keep `padding: 0`.
|
|
175
|
+
- Put safe-area spacing on `.page` or inner layout containers, not on `.slide-canvas`.
|
|
176
176
|
- Target strong fill on content-heavy slides while preserving editorial whitespace.
|
|
177
177
|
|
|
178
178
|
### HTML Structure
|
|
@@ -240,7 +240,7 @@ body {
|
|
|
240
240
|
transform-origin: center center;
|
|
241
241
|
position: relative;
|
|
242
242
|
overflow: hidden;
|
|
243
|
-
padding:
|
|
243
|
+
padding: 0;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
.page {
|
|
@@ -89,7 +89,7 @@ For photography, UI screenshots, webpages, and product surfaces, do not convert
|
|
|
89
89
|
|
|
90
90
|
- The browser viewport is a neutral dark frame.
|
|
91
91
|
- The slide page is a light neutral surface.
|
|
92
|
-
-
|
|
92
|
+
- `.slide-canvas` is the export surface and must keep `padding: 0`; put safe-area spacing on `.page` or inner layout containers.
|
|
93
93
|
- Use page edge, rules, cards, panels, and quiet geometry as neutral structure. Avoid built-in industry-specific imagery.
|
|
94
94
|
|
|
95
95
|
### Grid System
|
|
@@ -132,7 +132,7 @@ Every generated presentation must use this exact HTML skeleton:
|
|
|
132
132
|
html { scroll-snap-type: y mandatory; overflow-y: scroll; height: 100%; }
|
|
133
133
|
body { background: var(--bg-frame); color: var(--text-primary); font-family: var(--font-body); -webkit-font-smoothing: antialiased; height: 100%; }
|
|
134
134
|
.slide { min-height: 100dvh; scroll-snap-align: start; display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--bg-frame); }
|
|
135
|
-
.slide-canvas { width: 1920px; height: 1080px; flex-shrink: 0; transform-origin: center center; position: relative; overflow: hidden; padding:
|
|
135
|
+
.slide-canvas { width: 1920px; height: 1080px; flex-shrink: 0; transform-origin: center center; position: relative; overflow: hidden; padding: 0; }
|
|
136
136
|
.page { position: relative; width: 100%; height: 100%; background: var(--bg-page); color: var(--text-primary); padding: 56px 64px 64px; box-shadow: 0 24px 80px var(--shadow-soft); display: flex; flex-direction: column; overflow: hidden; }
|
|
137
137
|
.page.alt { background: var(--bg-page-alt); }
|
|
138
138
|
.eyebrow, .caption, .meta-label { font-size: var(--font-size-meta); line-height: 1.4; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); }
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
html { scroll-snap-type: y mandatory; overflow-y: scroll; height: 100%; }
|
|
36
36
|
body { background: var(--bg-frame); color: var(--text-primary); font-family: var(--font-body); -webkit-font-smoothing: antialiased; height: 100%; }
|
|
37
37
|
.slide { min-height: 100dvh; scroll-snap-align: start; display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--bg-frame); }
|
|
38
|
-
.slide-canvas { width: 1920px; height: 1080px; flex-shrink: 0; transform-origin: center center; position: relative; overflow: hidden; padding:
|
|
38
|
+
.slide-canvas { width: 1920px; height: 1080px; flex-shrink: 0; transform-origin: center center; position: relative; overflow: hidden; padding: 0; }
|
|
39
39
|
.page { position: relative; width: 100%; height: 100%; background: var(--bg-page); color: var(--text-primary); padding: 56px 64px 64px; box-shadow: 0 24px 80px var(--shadow-soft); display: flex; flex-direction: column; overflow: hidden; }
|
|
40
40
|
.page.alt { background: var(--bg-page-alt); }
|
|
41
41
|
.eyebrow, .caption, .meta-label { font-size: var(--font-size-meta); line-height: 1.4; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); }
|
package/designs/summit/DESIGN.md
CHANGED
|
@@ -109,8 +109,8 @@ All sizes are fixed `px` for the 1920x1080 canvas. JS `transform: scale()` handl
|
|
|
109
109
|
- Every slide uses `.slide-canvas` sized to `1920px x 1080px`, scaled by JS.
|
|
110
110
|
- Every `<section class="slide">` must include `slide-qa="true"` or `slide-qa="false"`.
|
|
111
111
|
- Use `slide-qa="true"` for dense content layouts and `slide-qa="false"` for structural or intentionally sparse layouts.
|
|
112
|
-
-
|
|
113
|
-
-
|
|
112
|
+
- `.slide-canvas` is the export surface and must keep `padding: 0`.
|
|
113
|
+
- Put safe-area spacing on `.page` or inner layout containers, not on `.slide-canvas`.
|
|
114
114
|
- Target strong fill on content-heavy slides while preserving editorial whitespace.
|
|
115
115
|
|
|
116
116
|
### HTML Structure
|
|
@@ -178,7 +178,7 @@ body {
|
|
|
178
178
|
transform-origin: center center;
|
|
179
179
|
position: relative;
|
|
180
180
|
overflow: hidden;
|
|
181
|
-
padding:
|
|
181
|
+
padding: 0;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
.page {
|
package/package.json
CHANGED
package/plugin.ts
CHANGED
|
@@ -82,6 +82,8 @@ import researchSaveTool from "./tools/research-save"
|
|
|
82
82
|
import workspaceScanTool from "./tools/workspace-scan"
|
|
83
83
|
import extractDocumentMaterialsTool from "./tools/extract-document-materials"
|
|
84
84
|
import qaTool from "./tools/qa"
|
|
85
|
+
import pdfTool from "./tools/pdf"
|
|
86
|
+
import pptxTool from "./tools/pptx"
|
|
85
87
|
import { RESEARCH_PROMPT, RESEARCH_AGENT_SIGNATURE } from "./lib/agents/research-prompt"
|
|
86
88
|
import { runQA, formatReport } from "./lib/qa"
|
|
87
89
|
import { extractDesignClasses } from "./lib/design/designs"
|
|
@@ -331,6 +333,8 @@ const server: Plugin = (async (pluginCtx) => {
|
|
|
331
333
|
"revela-workspace-scan": workspaceScanTool,
|
|
332
334
|
"revela-extract-document-materials": extractDocumentMaterialsTool,
|
|
333
335
|
"revela-qa": qaTool,
|
|
336
|
+
"revela-pdf": pdfTool,
|
|
337
|
+
"revela-pptx": pptxTool,
|
|
334
338
|
},
|
|
335
339
|
|
|
336
340
|
// ── chat.message: intercept @-referenced / pasted binary files ────────
|
package/tools/pdf.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tools/pdf.ts
|
|
3
|
+
*
|
|
4
|
+
* revela-pdf — Export a Revela HTML slide deck to PDF.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { tool } from "@opencode-ai/plugin"
|
|
8
|
+
import { existsSync } from "fs"
|
|
9
|
+
import { resolve } from "path"
|
|
10
|
+
import { exportToPdf } from "../lib/pdf/export"
|
|
11
|
+
|
|
12
|
+
export default tool({
|
|
13
|
+
description:
|
|
14
|
+
"Export a Revela-generated HTML slide deck to PDF. " +
|
|
15
|
+
"Use this after the deck HTML has been written and layout QA has passed. " +
|
|
16
|
+
"Output is written beside the input file with the same basename and a .pdf extension.",
|
|
17
|
+
args: {
|
|
18
|
+
file: tool.schema
|
|
19
|
+
.string()
|
|
20
|
+
.describe(
|
|
21
|
+
"Path to the HTML slide file to export. " +
|
|
22
|
+
"Can be absolute or relative to the current working directory."
|
|
23
|
+
),
|
|
24
|
+
},
|
|
25
|
+
async execute({ file }, { directory }) {
|
|
26
|
+
const filePath = resolve(directory || process.cwd(), file)
|
|
27
|
+
|
|
28
|
+
if (!existsSync(filePath)) {
|
|
29
|
+
return JSON.stringify({ ok: false, error: `File not found: ${filePath}` })
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!/\.html?$/i.test(filePath)) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: `File must be an HTML file: ${filePath}` })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const result = await exportToPdf(filePath)
|
|
38
|
+
return JSON.stringify({ ok: true, ...result }, null, 2)
|
|
39
|
+
} catch (e: any) {
|
|
40
|
+
return JSON.stringify({ ok: false, error: e?.message ?? String(e) })
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
})
|
package/tools/pptx.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tools/pptx.ts
|
|
3
|
+
*
|
|
4
|
+
* revela-pptx — Export a Revela HTML slide deck to editable PPTX.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { tool } from "@opencode-ai/plugin"
|
|
8
|
+
import { existsSync } from "fs"
|
|
9
|
+
import { resolve } from "path"
|
|
10
|
+
import { exportToPptx } from "../lib/pptx/export"
|
|
11
|
+
|
|
12
|
+
export default tool({
|
|
13
|
+
description:
|
|
14
|
+
"Export a Revela-generated HTML slide deck to editable PPTX. " +
|
|
15
|
+
"Use this after the deck HTML has been written and layout QA has passed. " +
|
|
16
|
+
"Output is written beside the input file with the same basename and a .pptx extension.",
|
|
17
|
+
args: {
|
|
18
|
+
file: tool.schema
|
|
19
|
+
.string()
|
|
20
|
+
.describe(
|
|
21
|
+
"Path to the HTML slide file to export. " +
|
|
22
|
+
"Can be absolute or relative to the current working directory."
|
|
23
|
+
),
|
|
24
|
+
},
|
|
25
|
+
async execute({ file }, { directory }) {
|
|
26
|
+
const filePath = resolve(directory || process.cwd(), file)
|
|
27
|
+
|
|
28
|
+
if (!existsSync(filePath)) {
|
|
29
|
+
return JSON.stringify({ ok: false, error: `File not found: ${filePath}` })
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!/\.html?$/i.test(filePath)) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: `File must be an HTML file: ${filePath}` })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const progress: string[] = []
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const result = await exportToPptx(filePath, {
|
|
40
|
+
onProgress: (event) => {
|
|
41
|
+
progress.push(event.message)
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
return JSON.stringify({ ok: true, ...result, progress }, null, 2)
|
|
45
|
+
} catch (e: any) {
|
|
46
|
+
return JSON.stringify({ ok: false, error: e?.message ?? String(e), progress })
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
})
|