@cyber-dash-tech/revela 0.1.15 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,6 +34,7 @@ export async function handleHelp(
34
34
  `\`/revela domains-add <url>\` — install a domain from URL / github:user/repo\n` +
35
35
  `\`/revela designs-rm <name>\` — remove an installed design\n` +
36
36
  `\`/revela domains-rm <name>\` — remove an installed domain\n` +
37
- `\`/revela pdf <file>\` — export HTML slide deck to PDF`
37
+ `\`/revela pdf <file>\` — export HTML slide deck to PDF\n` +
38
+ `\`/revela pptx <file>\` — export HTML slide deck to PPTX`
38
39
  )
39
40
  }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * lib/commands/pptx.ts
3
+ *
4
+ * Handler for `/revela pptx <file_path>` — exports an HTML slide deck to PPTX.
5
+ *
6
+ * Output: same directory and base name as the input, with .pptx extension.
7
+ * Example: decks/my-deck.html → decks/my-deck.pptx
8
+ */
9
+
10
+ import { resolve } from "path"
11
+ import { exportToPptx } from "../pptx/export"
12
+
13
+ function formatSecs(ms: number): string {
14
+ return `${(ms / 1000).toFixed(1)}s`
15
+ }
16
+
17
+ export async function handlePptx(
18
+ filePath: string,
19
+ send: (text: string) => Promise<void>,
20
+ ): Promise<void> {
21
+ if (!filePath) {
22
+ await send(
23
+ "**Usage:** `/revela pptx <file_path>`\n\n" +
24
+ "Example: `/revela pptx decks/my-deck.html`"
25
+ )
26
+ return
27
+ }
28
+
29
+ const abs = resolve(filePath)
30
+ await send(`Exporting \`${abs}\` to PPTX...`)
31
+
32
+ try {
33
+ let lastSlideUpdate = 0
34
+ let longDeckThreshold: number | null = null
35
+
36
+ const result = await exportToPptx(filePath, {
37
+ onProgress: async (progress) => {
38
+ if (progress.kind === "stage") {
39
+ await send(progress.message)
40
+ return
41
+ }
42
+
43
+ const current = progress.current ?? 0
44
+ const total = progress.total ?? 0
45
+ if (!total) return
46
+
47
+ if (longDeckThreshold === null) {
48
+ longDeckThreshold = total >= 8 ? (total > 20 ? 5 : 2) : -1
49
+ }
50
+ if (longDeckThreshold < 0) return
51
+
52
+ const shouldSend = current === 1 || current === total || current - lastSlideUpdate >= longDeckThreshold
53
+ if (!shouldSend) return
54
+
55
+ lastSlideUpdate = current
56
+ await send(`Editable export progress: slide ${current}/${total}`)
57
+ },
58
+ })
59
+
60
+ await send(
61
+ `**PPTX exported successfully**\n\n` +
62
+ `- Output: \`${result.outputPath}\`\n` +
63
+ `- Slides: ${result.slideCount}\n` +
64
+ `- Time: ${formatSecs(result.durationMs)}\n` +
65
+ `- Prepare: ${formatSecs(result.timingsMs.prepareMs)}\n` +
66
+ `- Page setup: ${formatSecs(result.timingsMs.pageSetupMs)}\n` +
67
+ `- Slide export: ${formatSecs(result.timingsMs.slideExportMs)}\n` +
68
+ `- Merge: ${formatSecs(result.timingsMs.mergeMs)}\n` +
69
+ `- Write: ${formatSecs(result.timingsMs.writeMs)}`
70
+ )
71
+ } catch (e) {
72
+ const msg = e instanceof Error ? e.message : String(e)
73
+ await send(`**PPTX export failed**\n\n\`\`\`\n${msg}\n\`\`\``)
74
+ }
75
+ }