@cyber-dash-tech/revela 0.15.2 → 0.15.4
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 +62 -108
- package/README.zh-CN.md +63 -108
- package/designs/starter/DESIGN.md +33 -14
- package/designs/starter/preview.html +23 -16
- package/designs/summit/DESIGN.md +35 -42
- package/designs/summit/preview.html +49 -49
- package/lib/commands/brief.ts +1 -1
- package/lib/commands/designs-new.ts +6 -6
- package/lib/commands/designs.ts +9 -9
- package/lib/commands/domains.ts +9 -9
- package/lib/commands/edit.ts +1 -1
- package/lib/commands/help.ts +34 -37
- package/lib/commands/init.ts +1 -1
- package/lib/commands/inspect.ts +2 -20
- package/lib/commands/narrative.ts +3 -3
- package/lib/commands/pdf.ts +3 -3
- package/lib/commands/pptx.ts +2 -2
- package/lib/commands/refine.ts +3 -3
- package/lib/commands/review.ts +14 -7
- package/lib/decks-state.ts +6 -6
- package/lib/edit/deck-state.ts +1 -1
- package/lib/edit/resolve-deck.ts +1 -1
- package/lib/inspect/server.ts +2 -2
- package/lib/prompt-builder.ts +20 -14
- package/lib/refine/server.ts +50 -33
- package/package.json +1 -1
- package/plugin.ts +140 -281
- package/skill/NARRATIVE_SKILL.md +17 -19
- package/skill/SKILL.md +220 -477
- package/tools/edit.ts +6 -6
- package/tools/inspection-result.ts +1 -1
- package/lib/commands/disable.ts +0 -14
- package/lib/commands/enable.ts +0 -48
package/plugin.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* revela — Core OpenCode Plugin
|
|
3
3
|
*
|
|
4
|
-
* Architecture:
|
|
4
|
+
* Architecture: single /revela command surface (DCP style)
|
|
5
5
|
*
|
|
6
6
|
* Responsibilities:
|
|
7
7
|
* 1. On load: seed built-in designs/domains + build initial _active-prompt.md
|
|
@@ -30,8 +30,6 @@ import { extractPdfText } from "./lib/read-hooks/extractors/pdf"
|
|
|
30
30
|
import { createOfficeReadView } from "./lib/read-hooks/office-read-view"
|
|
31
31
|
import { OFFICE_EXTENSIONS, IMAGE_EXTENSIONS, formatExtractedText } from "./lib/read-hooks/dispatch"
|
|
32
32
|
import { handleHelp } from "./lib/commands/help"
|
|
33
|
-
import { handleEnable } from "./lib/commands/enable"
|
|
34
|
-
import { handleDisable } from "./lib/commands/disable"
|
|
35
33
|
import {
|
|
36
34
|
handleDesignsList,
|
|
37
35
|
handleDesignsActivate,
|
|
@@ -46,8 +44,6 @@ import {
|
|
|
46
44
|
} from "./lib/commands/domains"
|
|
47
45
|
import { handlePdf } from "./lib/commands/pdf"
|
|
48
46
|
import { buildPptxNotesPrompt, handlePptx, parsePptxArgs, resolvePptxDeck } from "./lib/commands/pptx"
|
|
49
|
-
import { handleEdit } from "./lib/commands/edit"
|
|
50
|
-
import { handleInspect } from "./lib/commands/inspect"
|
|
51
47
|
import { handleRefine } from "./lib/commands/refine"
|
|
52
48
|
import { formatArtifactQAReport, runArtifactQA } from "./lib/qa/artifact"
|
|
53
49
|
import { ensureRefineDeckOpenForChange } from "./lib/refine/open"
|
|
@@ -61,9 +57,8 @@ import {
|
|
|
61
57
|
import { buildInitPrompt } from "./lib/commands/init"
|
|
62
58
|
import { buildResearchPrompt } from "./lib/commands/research"
|
|
63
59
|
import { handleBrief, parseBriefArgs } from "./lib/commands/brief"
|
|
64
|
-
import { buildNarrativeViewPrompt,
|
|
65
|
-
import {
|
|
66
|
-
import { buildDeckPrompt, buildDeckReviewPrompt, buildReviewPrompt } from "./lib/commands/review"
|
|
60
|
+
import { buildNarrativeViewPrompt, parseStoryArgs } from "./lib/commands/narrative"
|
|
61
|
+
import { buildDeckPrompt } from "./lib/commands/review"
|
|
67
62
|
import {
|
|
68
63
|
extractDeckHtmlTargetsFromPatch,
|
|
69
64
|
extractPatchTextArg,
|
|
@@ -235,7 +230,7 @@ const server: Plugin = (async (pluginCtx) => {
|
|
|
235
230
|
opencodeConfig.command ??= {}
|
|
236
231
|
opencodeConfig.command["revela"] = {
|
|
237
232
|
template: "",
|
|
238
|
-
description: "
|
|
233
|
+
description: "show REVELA help",
|
|
239
234
|
}
|
|
240
235
|
|
|
241
236
|
// Register the research subagent.
|
|
@@ -316,277 +311,131 @@ const server: Plugin = (async (pluginCtx) => {
|
|
|
316
311
|
await handleHelp(send)
|
|
317
312
|
throw new Error("__REVELA_STATUS_HANDLED__")
|
|
318
313
|
}
|
|
319
|
-
if (sub === "enable") {
|
|
320
|
-
await handleEnable(send)
|
|
321
|
-
throw new Error("__REVELA_ENABLE_HANDLED__")
|
|
322
|
-
}
|
|
323
|
-
if (sub === "disable") {
|
|
324
|
-
await handleDisable(send)
|
|
325
|
-
throw new Error("__REVELA_DISABLE_HANDLED__")
|
|
326
|
-
}
|
|
327
|
-
if (sub === "init") {
|
|
328
|
-
queueWorkflowCommand({
|
|
329
|
-
sessionID,
|
|
330
|
-
name: "init",
|
|
331
|
-
mode: "narrative",
|
|
332
|
-
visibleText: "Initialize Revela workspace.",
|
|
333
|
-
hiddenPrompt: buildInitPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
334
|
-
output,
|
|
335
|
-
})
|
|
336
|
-
return
|
|
337
|
-
}
|
|
338
|
-
if (sub === "remember") {
|
|
339
|
-
const parsed = parseRememberArgs(param)
|
|
340
|
-
if (!parsed.ok) {
|
|
341
|
-
await send(parsed.error)
|
|
342
|
-
throw new Error("__REVELA_REMEMBER_USAGE_HANDLED__")
|
|
343
|
-
}
|
|
344
|
-
queueWorkflowCommand({
|
|
345
|
-
sessionID,
|
|
346
|
-
name: "remember",
|
|
347
|
-
mode: "narrative",
|
|
348
|
-
visibleText: "Remember Revela workspace preference.",
|
|
349
|
-
hiddenPrompt: buildRememberPrompt({ memory: parsed.memory, exists: hasDecksState(workspaceRoot) }),
|
|
350
|
-
output,
|
|
351
|
-
})
|
|
352
|
-
return
|
|
353
|
-
}
|
|
354
|
-
if (sub === "research") {
|
|
355
|
-
if (param) {
|
|
356
|
-
await send("`/revela research` does not accept arguments yet. Add the research question in normal chat, or run it to work from open story gaps.")
|
|
357
|
-
throw new Error("__REVELA_RESEARCH_USAGE_HANDLED__")
|
|
358
|
-
}
|
|
359
|
-
queueWorkflowCommand({
|
|
360
|
-
sessionID,
|
|
361
|
-
name: "research",
|
|
362
|
-
mode: "narrative",
|
|
363
|
-
visibleText: "Research Revela story gaps.",
|
|
364
|
-
hiddenPrompt: buildResearchPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
365
|
-
output,
|
|
366
|
-
})
|
|
367
|
-
return
|
|
368
|
-
}
|
|
369
|
-
if (sub === "review") {
|
|
370
|
-
if (param) {
|
|
371
|
-
await send("`/revela review` no longer accepts a deck name. It is a compatibility alias for `/revela story`. Use `/revela make deck --review` for deck/artifact readiness.")
|
|
372
|
-
throw new Error("__REVELA_REVIEW_USAGE_HANDLED__")
|
|
373
|
-
}
|
|
374
|
-
queueWorkflowCommand({
|
|
375
|
-
sessionID,
|
|
376
|
-
name: "review",
|
|
377
|
-
mode: "narrative",
|
|
378
|
-
visibleText: "Review Revela story readiness.",
|
|
379
|
-
hiddenPrompt: buildReviewPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
380
|
-
output,
|
|
381
|
-
})
|
|
382
|
-
return
|
|
383
|
-
}
|
|
384
|
-
if (sub === "story") {
|
|
385
|
-
const parsed = parseStoryArgs(param)
|
|
386
|
-
if (!parsed.ok) {
|
|
387
|
-
await send(parsed.error)
|
|
388
|
-
throw new Error("__REVELA_STORY_USAGE_HANDLED__")
|
|
389
|
-
}
|
|
390
|
-
queueWorkflowCommand({
|
|
391
|
-
sessionID,
|
|
392
|
-
name: "story",
|
|
393
|
-
mode: "narrative",
|
|
394
|
-
visibleText: "Open Revela story workspace.",
|
|
395
|
-
hiddenPrompt: buildNarrativeViewPrompt({ workspaceRoot, language: parsed.args.language }),
|
|
396
|
-
output,
|
|
397
|
-
})
|
|
398
|
-
return
|
|
399
|
-
}
|
|
400
|
-
if (sub === "narrative") {
|
|
401
|
-
if (!param) {
|
|
402
|
-
queueWorkflowCommand({
|
|
403
|
-
sessionID,
|
|
404
|
-
name: "narrative",
|
|
405
|
-
mode: "narrative",
|
|
406
|
-
visibleText: "Open Revela story workspace.",
|
|
407
|
-
hiddenPrompt: buildNarrativeViewPrompt({ workspaceRoot, language: "en" }),
|
|
408
|
-
output,
|
|
409
|
-
})
|
|
410
|
-
return
|
|
411
|
-
}
|
|
412
|
-
const parsed = parseNarrativeArgs(param)
|
|
413
|
-
if (!parsed.ok) {
|
|
414
|
-
await send(parsed.error)
|
|
415
|
-
throw new Error("__REVELA_NARRATIVE_USAGE_HANDLED__")
|
|
416
|
-
}
|
|
417
|
-
if (parsed.args.raw) {
|
|
418
|
-
await handleNarrative({ workspaceRoot, openBrowser: true, language: parsed.args.language }, send)
|
|
419
|
-
throw new Error("__REVELA_NARRATIVE_HANDLED__")
|
|
420
|
-
}
|
|
421
|
-
queueWorkflowCommand({
|
|
422
|
-
sessionID,
|
|
423
|
-
name: "narrative view",
|
|
424
|
-
mode: "narrative",
|
|
425
|
-
visibleText: "Open read-only Revela narrative map.",
|
|
426
|
-
hiddenPrompt: buildNarrativeViewPrompt({ workspaceRoot, language: parsed.args.language }),
|
|
427
|
-
output,
|
|
428
|
-
})
|
|
429
|
-
return
|
|
430
|
-
}
|
|
431
|
-
if (sub === "brief") {
|
|
432
|
-
const parsed = parseBriefArgs(param)
|
|
433
|
-
if (!parsed.ok) {
|
|
434
|
-
await send(parsed.error)
|
|
435
|
-
throw new Error("__REVELA_BRIEF_USAGE_HANDLED__")
|
|
436
|
-
}
|
|
437
|
-
await handleBrief({ workspaceRoot, outputPath: parsed.args.outputPath }, send)
|
|
438
|
-
throw new Error("__REVELA_BRIEF_HANDLED__")
|
|
439
|
-
}
|
|
440
314
|
if (sub === "make") {
|
|
441
315
|
const target = args[1]?.toLowerCase() ?? ""
|
|
442
316
|
const makeParam = args.slice(2).join(" ")
|
|
443
|
-
if (target === "deck") {
|
|
444
|
-
if (makeParam
|
|
445
|
-
await send("Usage: `/revela make
|
|
317
|
+
if (target === "--deck") {
|
|
318
|
+
if (makeParam) {
|
|
319
|
+
await send("Usage: `/revela make --deck`.")
|
|
446
320
|
throw new Error("__REVELA_MAKE_DECK_USAGE_HANDLED__")
|
|
447
321
|
}
|
|
448
322
|
queueWorkflowCommand({
|
|
449
323
|
sessionID,
|
|
450
|
-
name:
|
|
324
|
+
name: "make --deck",
|
|
451
325
|
mode: "deck-render",
|
|
452
|
-
visibleText:
|
|
453
|
-
hiddenPrompt:
|
|
454
|
-
? buildDeckReviewPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot })
|
|
455
|
-
: buildDeckPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
326
|
+
visibleText: "Make Revela deck from approved story.",
|
|
327
|
+
hiddenPrompt: buildDeckPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
456
328
|
output,
|
|
457
329
|
})
|
|
458
330
|
return
|
|
459
331
|
}
|
|
460
|
-
if (target === "brief") {
|
|
332
|
+
if (target === "--brief") {
|
|
461
333
|
const parsed = parseBriefArgs(makeParam)
|
|
462
334
|
if (!parsed.ok) {
|
|
463
|
-
await send(parsed.error.replace("/revela brief", "/revela make brief"))
|
|
335
|
+
await send(parsed.error.replace("/revela brief", "/revela make --brief"))
|
|
464
336
|
throw new Error("__REVELA_MAKE_BRIEF_USAGE_HANDLED__")
|
|
465
337
|
}
|
|
466
338
|
await handleBrief({ workspaceRoot, outputPath: parsed.args.outputPath }, send)
|
|
467
339
|
throw new Error("__REVELA_MAKE_BRIEF_HANDLED__")
|
|
468
340
|
}
|
|
469
|
-
await send("Usage: `/revela make deck
|
|
341
|
+
await send("Usage: `/revela make --deck` or `/revela make --brief [workspace-relative-output.md]`.")
|
|
470
342
|
throw new Error("__REVELA_MAKE_USAGE_HANDLED__")
|
|
471
343
|
}
|
|
472
|
-
if (sub === "
|
|
473
|
-
if (param
|
|
474
|
-
await send("Usage: `/revela
|
|
475
|
-
throw new Error("
|
|
476
|
-
}
|
|
477
|
-
if (!param) {
|
|
478
|
-
queueWorkflowCommand({
|
|
479
|
-
sessionID,
|
|
480
|
-
name: "deck",
|
|
481
|
-
mode: "deck-render",
|
|
482
|
-
visibleText: "Make Revela deck from approved story.",
|
|
483
|
-
hiddenPrompt: buildDeckPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
484
|
-
output,
|
|
485
|
-
})
|
|
486
|
-
return
|
|
344
|
+
if (sub === "review") {
|
|
345
|
+
if (param !== "--deck") {
|
|
346
|
+
await send("Usage: `/revela review --deck`.")
|
|
347
|
+
throw new Error("__REVELA_REVIEW_USAGE_HANDLED__")
|
|
487
348
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
name: "deck --review",
|
|
491
|
-
mode: "deck-render",
|
|
492
|
-
visibleText: "Review Revela deck artifact readiness.",
|
|
493
|
-
hiddenPrompt: buildDeckReviewPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
494
|
-
output,
|
|
495
|
-
})
|
|
496
|
-
return
|
|
349
|
+
await handleRefine({ client, sessionID, workspaceRoot }, send)
|
|
350
|
+
throw new Error("__REVELA_REVIEW_HANDLED__")
|
|
497
351
|
}
|
|
498
352
|
if (sub === "refine") {
|
|
499
|
-
if (param) {
|
|
500
|
-
await send("`/revela
|
|
353
|
+
if (param !== "--deck") {
|
|
354
|
+
await send("Usage: `/revela review --deck`.")
|
|
501
355
|
throw new Error("__REVELA_REFINE_USAGE_HANDLED__")
|
|
502
356
|
}
|
|
357
|
+
await send("`/revela refine --deck` is deprecated. Use `/revela review --deck`.")
|
|
503
358
|
await handleRefine({ client, sessionID, workspaceRoot }, send)
|
|
504
359
|
throw new Error("__REVELA_REFINE_HANDLED__")
|
|
505
360
|
}
|
|
506
|
-
if (sub === "
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
361
|
+
if (sub === "export") {
|
|
362
|
+
const target = args[1]?.toLowerCase() ?? ""
|
|
363
|
+
const format = args[2]?.toLowerCase() ?? ""
|
|
364
|
+
const exportParam = args.slice(3).join(" ")
|
|
365
|
+
if (target !== "--deck" || (format !== "pdf" && format !== "pptx")) {
|
|
366
|
+
await send("Usage: `/revela export --deck pdf [file.html]` or `/revela export --deck pptx [file.html] [--notes]`.")
|
|
367
|
+
throw new Error("__REVELA_EXPORT_USAGE_HANDLED__")
|
|
368
|
+
}
|
|
369
|
+
if (format === "pdf") {
|
|
370
|
+
await handlePdf(exportParam, send, workspaceRoot)
|
|
371
|
+
throw new Error("__REVELA_EXPORT_PDF_HANDLED__")
|
|
372
|
+
}
|
|
373
|
+
const pptxArgs = parsePptxArgs(exportParam)
|
|
374
|
+
if (pptxArgs.notes) {
|
|
375
|
+
try {
|
|
376
|
+
const deck = resolvePptxDeck(workspaceRoot, pptxArgs.filePath)
|
|
377
|
+
queueWorkflowCommand({
|
|
378
|
+
sessionID,
|
|
379
|
+
name: "export --deck pptx --notes",
|
|
380
|
+
mode: "deck-render",
|
|
381
|
+
visibleText: "Export Revela deck to PPTX with speaker notes.",
|
|
382
|
+
hiddenPrompt: buildPptxNotesPrompt(deck),
|
|
383
|
+
output,
|
|
384
|
+
})
|
|
385
|
+
return
|
|
386
|
+
} catch (e) {
|
|
387
|
+
const msg = e instanceof Error ? e.message : String(e)
|
|
388
|
+
await send(`**PPTX export failed**\n\n\`\`\`\n${msg}\n\`\`\``)
|
|
389
|
+
throw new Error("__REVELA_EXPORT_PPTX_HANDLED__")
|
|
390
|
+
}
|
|
518
391
|
}
|
|
519
|
-
await
|
|
520
|
-
throw new Error("
|
|
521
|
-
}
|
|
522
|
-
if (sub === "designs" && !param) {
|
|
523
|
-
await handleDesignsList(send)
|
|
524
|
-
throw new Error("__REVELA_DESIGNS_LIST_HANDLED__")
|
|
525
|
-
}
|
|
526
|
-
if (sub === "designs" && param) {
|
|
527
|
-
await handleDesignsActivate(param, send)
|
|
528
|
-
throw new Error("__REVELA_DESIGNS_ACTIVATE_HANDLED__")
|
|
529
|
-
}
|
|
530
|
-
if (sub === "domains" && !param) {
|
|
531
|
-
await handleDomainsList(send)
|
|
532
|
-
throw new Error("__REVELA_DOMAINS_LIST_HANDLED__")
|
|
533
|
-
}
|
|
534
|
-
if (sub === "domains" && param) {
|
|
535
|
-
await handleDomainsActivate(param, send)
|
|
536
|
-
throw new Error("__REVELA_DOMAINS_ACTIVATE_HANDLED__")
|
|
537
|
-
}
|
|
538
|
-
if (sub === "designs-add") {
|
|
539
|
-
await handleDesignsAdd(param, send)
|
|
540
|
-
throw new Error("__REVELA_DESIGNS_ADD_HANDLED__")
|
|
392
|
+
await handlePptx(exportParam, send, workspaceRoot)
|
|
393
|
+
throw new Error("__REVELA_EXPORT_PPTX_HANDLED__")
|
|
541
394
|
}
|
|
542
395
|
if (sub === "design") {
|
|
543
|
-
const designAction = args[1]?.toLowerCase() ?? "
|
|
396
|
+
const designAction = args[1]?.toLowerCase() ?? ""
|
|
544
397
|
const designParam = args.slice(2).join(" ")
|
|
545
|
-
if (designAction
|
|
546
|
-
if (designParam) {
|
|
547
|
-
await send("Usage: `/revela design list`.")
|
|
548
|
-
throw new Error("__REVELA_DESIGN_LIST_USAGE_HANDLED__")
|
|
549
|
-
}
|
|
398
|
+
if (!designAction) {
|
|
550
399
|
await handleDesignsList(send)
|
|
551
400
|
throw new Error("__REVELA_DESIGN_LIST_HANDLED__")
|
|
552
401
|
}
|
|
553
|
-
if (designAction === "use") {
|
|
402
|
+
if (designAction === "--use") {
|
|
554
403
|
if (!designParam) {
|
|
555
|
-
await send("Usage: `/revela design use <name>`.")
|
|
404
|
+
await send("Usage: `/revela design --use <name>`.")
|
|
556
405
|
throw new Error("__REVELA_DESIGN_USE_USAGE_HANDLED__")
|
|
557
406
|
}
|
|
558
407
|
await handleDesignsActivate(designParam, send)
|
|
559
408
|
throw new Error("__REVELA_DESIGN_USE_HANDLED__")
|
|
560
409
|
}
|
|
561
|
-
if (designAction === "add") {
|
|
410
|
+
if (designAction === "--add") {
|
|
562
411
|
if (!designParam) {
|
|
563
|
-
await send("Usage: `/revela design add <url|github:user/repo|local-path>`.")
|
|
412
|
+
await send("Usage: `/revela design --add <url|github:user/repo|local-path>`.")
|
|
564
413
|
throw new Error("__REVELA_DESIGN_ADD_USAGE_HANDLED__")
|
|
565
414
|
}
|
|
566
415
|
await handleDesignsAdd(designParam, send)
|
|
567
416
|
throw new Error("__REVELA_DESIGN_ADD_HANDLED__")
|
|
568
417
|
}
|
|
569
|
-
if (designAction === "rm"
|
|
418
|
+
if (designAction === "--rm") {
|
|
570
419
|
if (!designParam) {
|
|
571
|
-
await send("Usage: `/revela design rm <name>`.")
|
|
420
|
+
await send("Usage: `/revela design --rm <name>`.")
|
|
572
421
|
throw new Error("__REVELA_DESIGN_RM_USAGE_HANDLED__")
|
|
573
422
|
}
|
|
574
423
|
await handleDesignsRemove(designParam, send)
|
|
575
424
|
throw new Error("__REVELA_DESIGN_RM_HANDLED__")
|
|
576
425
|
}
|
|
577
|
-
if (designAction === "preview") {
|
|
426
|
+
if (designAction === "--preview") {
|
|
578
427
|
await handleDesignsPreview(designParam, send)
|
|
579
428
|
throw new Error("__REVELA_DESIGN_PREVIEW_HANDLED__")
|
|
580
429
|
}
|
|
581
|
-
if (designAction === "new") {
|
|
430
|
+
if (designAction === "--new") {
|
|
582
431
|
const parsed = parseDesignsNewArgs(designParam)
|
|
583
432
|
if (!parsed.ok) {
|
|
584
|
-
await send(parsed.error
|
|
433
|
+
await send(parsed.error)
|
|
585
434
|
throw new Error("__REVELA_DESIGN_NEW_USAGE_HANDLED__")
|
|
586
435
|
}
|
|
587
436
|
queueWorkflowCommand({
|
|
588
437
|
sessionID,
|
|
589
|
-
name: `design new ${parsed.name}`,
|
|
438
|
+
name: `design --new ${parsed.name}`,
|
|
590
439
|
mode: "deck-render",
|
|
591
440
|
visibleText: `Create Revela design ${parsed.name}.`,
|
|
592
441
|
hiddenPrompt: buildDesignsNewPrompt({ name: parsed.name, base: parsed.base }),
|
|
@@ -594,15 +443,15 @@ const server: Plugin = (async (pluginCtx) => {
|
|
|
594
443
|
})
|
|
595
444
|
return
|
|
596
445
|
}
|
|
597
|
-
if (designAction === "edit") {
|
|
446
|
+
if (designAction === "--edit") {
|
|
598
447
|
const parsed = parseDesignsEditArgs(designParam)
|
|
599
448
|
if (!parsed.ok) {
|
|
600
|
-
await send(parsed.error
|
|
449
|
+
await send(parsed.error)
|
|
601
450
|
throw new Error("__REVELA_DESIGN_EDIT_USAGE_HANDLED__")
|
|
602
451
|
}
|
|
603
452
|
queueWorkflowCommand({
|
|
604
453
|
sessionID,
|
|
605
|
-
name: `design edit ${parsed.name}`,
|
|
454
|
+
name: `design --edit ${parsed.name}`,
|
|
606
455
|
mode: "deck-render",
|
|
607
456
|
visibleText: `Edit Revela design ${parsed.name}.`,
|
|
608
457
|
hiddenPrompt: buildDesignsEditPrompt({ name: parsed.name }),
|
|
@@ -610,83 +459,93 @@ const server: Plugin = (async (pluginCtx) => {
|
|
|
610
459
|
})
|
|
611
460
|
return
|
|
612
461
|
}
|
|
613
|
-
await send("Usage: `/revela design [
|
|
462
|
+
await send("Usage: `/revela design [--use <name>|--preview [name]|--new <name>|--edit <name>|--add <source>|--rm <name>]`.")
|
|
614
463
|
throw new Error("__REVELA_DESIGN_USAGE_HANDLED__")
|
|
615
464
|
}
|
|
616
|
-
if (sub === "
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
465
|
+
if (sub === "domain") {
|
|
466
|
+
const domainAction = args[1]?.toLowerCase() ?? ""
|
|
467
|
+
const domainParam = args.slice(2).join(" ")
|
|
468
|
+
if (!domainAction) {
|
|
469
|
+
await handleDomainsList(send)
|
|
470
|
+
throw new Error("__REVELA_DOMAIN_LIST_HANDLED__")
|
|
471
|
+
}
|
|
472
|
+
if (domainAction === "--use") {
|
|
473
|
+
if (!domainParam) {
|
|
474
|
+
await send("Usage: `/revela domain --use <name>`.")
|
|
475
|
+
throw new Error("__REVELA_DOMAIN_USE_USAGE_HANDLED__")
|
|
476
|
+
}
|
|
477
|
+
await handleDomainsActivate(domainParam, send)
|
|
478
|
+
throw new Error("__REVELA_DOMAIN_USE_HANDLED__")
|
|
479
|
+
}
|
|
480
|
+
if (domainAction === "--add") {
|
|
481
|
+
if (!domainParam) {
|
|
482
|
+
await send("Usage: `/revela domain --add <url|github:user/repo|local-path>`.")
|
|
483
|
+
throw new Error("__REVELA_DOMAIN_ADD_USAGE_HANDLED__")
|
|
484
|
+
}
|
|
485
|
+
await handleDomainsAdd(domainParam, send)
|
|
486
|
+
throw new Error("__REVELA_DOMAIN_ADD_HANDLED__")
|
|
621
487
|
}
|
|
488
|
+
if (domainAction === "--rm") {
|
|
489
|
+
if (!domainParam) {
|
|
490
|
+
await send("Usage: `/revela domain --rm <name>`.")
|
|
491
|
+
throw new Error("__REVELA_DOMAIN_RM_USAGE_HANDLED__")
|
|
492
|
+
}
|
|
493
|
+
await handleDomainsRemove(domainParam, send)
|
|
494
|
+
throw new Error("__REVELA_DOMAIN_RM_HANDLED__")
|
|
495
|
+
}
|
|
496
|
+
await send("Usage: `/revela domain [--use <name>|--add <source>|--rm <name>]`.")
|
|
497
|
+
throw new Error("__REVELA_DOMAIN_USAGE_HANDLED__")
|
|
498
|
+
}
|
|
499
|
+
const legacyCommands = new Set([
|
|
500
|
+
"enable", "disable", "review", "narrative", "deck", "brief", "edit", "inspect", "remember",
|
|
501
|
+
"designs", "designs-new", "designs-edit", "designs-preview", "designs-add", "designs-rm",
|
|
502
|
+
"domains", "domains-add", "domains-rm", "pdf", "pptx",
|
|
503
|
+
])
|
|
504
|
+
if (legacyCommands.has(sub)) {
|
|
505
|
+
await send(`\`/revela ${sub}\` is no longer a public command. Run \`/revela\` to see the current REVELA help.`)
|
|
506
|
+
throw new Error("__REVELA_LEGACY_COMMAND_HANDLED__")
|
|
507
|
+
}
|
|
508
|
+
if (sub === "init") {
|
|
622
509
|
queueWorkflowCommand({
|
|
623
510
|
sessionID,
|
|
624
|
-
name:
|
|
625
|
-
mode: "
|
|
626
|
-
visibleText:
|
|
627
|
-
hiddenPrompt:
|
|
511
|
+
name: "init",
|
|
512
|
+
mode: "narrative",
|
|
513
|
+
visibleText: "Initialize Revela workspace.",
|
|
514
|
+
hiddenPrompt: buildInitPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
628
515
|
output,
|
|
629
516
|
})
|
|
630
517
|
return
|
|
631
518
|
}
|
|
632
|
-
if (sub === "
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
throw new Error("__REVELA_DESIGNS_EDIT_USAGE_HANDLED__")
|
|
519
|
+
if (sub === "research") {
|
|
520
|
+
if (param) {
|
|
521
|
+
await send("`/revela research` does not accept arguments yet. Add the research question in normal chat, or run it to work from open story gaps.")
|
|
522
|
+
throw new Error("__REVELA_RESEARCH_USAGE_HANDLED__")
|
|
637
523
|
}
|
|
638
524
|
queueWorkflowCommand({
|
|
639
525
|
sessionID,
|
|
640
|
-
name:
|
|
641
|
-
mode: "
|
|
642
|
-
visibleText:
|
|
643
|
-
hiddenPrompt:
|
|
526
|
+
name: "research",
|
|
527
|
+
mode: "narrative",
|
|
528
|
+
visibleText: "Research Revela story gaps.",
|
|
529
|
+
hiddenPrompt: buildResearchPrompt({ exists: hasDecksState(workspaceRoot), workspaceRoot }),
|
|
644
530
|
output,
|
|
645
531
|
})
|
|
646
532
|
return
|
|
647
533
|
}
|
|
648
|
-
if (sub === "
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
await handleDomainsAdd(param, send)
|
|
654
|
-
throw new Error("__REVELA_DOMAINS_ADD_HANDLED__")
|
|
655
|
-
}
|
|
656
|
-
if (sub === "designs-rm") {
|
|
657
|
-
await handleDesignsRemove(param, send)
|
|
658
|
-
throw new Error("__REVELA_DESIGNS_RM_HANDLED__")
|
|
659
|
-
}
|
|
660
|
-
if (sub === "domains-rm") {
|
|
661
|
-
await handleDomainsRemove(param, send)
|
|
662
|
-
throw new Error("__REVELA_DOMAINS_RM_HANDLED__")
|
|
663
|
-
}
|
|
664
|
-
if (sub === "pdf") {
|
|
665
|
-
await handlePdf(param, send, workspaceRoot)
|
|
666
|
-
throw new Error("__REVELA_PDF_HANDLED__")
|
|
667
|
-
}
|
|
668
|
-
if (sub === "pptx") {
|
|
669
|
-
const args = parsePptxArgs(param)
|
|
670
|
-
if (args.notes) {
|
|
671
|
-
try {
|
|
672
|
-
const deck = resolvePptxDeck(workspaceRoot, args.filePath)
|
|
673
|
-
queueWorkflowCommand({
|
|
674
|
-
sessionID,
|
|
675
|
-
name: "pptx --notes",
|
|
676
|
-
mode: "deck-render",
|
|
677
|
-
visibleText: "Export Revela deck to PPTX with speaker notes.",
|
|
678
|
-
hiddenPrompt: buildPptxNotesPrompt(deck),
|
|
679
|
-
output,
|
|
680
|
-
})
|
|
681
|
-
return
|
|
682
|
-
} catch (e) {
|
|
683
|
-
const msg = e instanceof Error ? e.message : String(e)
|
|
684
|
-
await send(`**PPTX export failed**\n\n\`\`\`\n${msg}\n\`\`\``)
|
|
685
|
-
throw new Error("__REVELA_PPTX_HANDLED__")
|
|
686
|
-
}
|
|
534
|
+
if (sub === "story") {
|
|
535
|
+
const parsed = parseStoryArgs(param)
|
|
536
|
+
if (!parsed.ok) {
|
|
537
|
+
await send(parsed.error)
|
|
538
|
+
throw new Error("__REVELA_STORY_USAGE_HANDLED__")
|
|
687
539
|
}
|
|
688
|
-
|
|
689
|
-
|
|
540
|
+
queueWorkflowCommand({
|
|
541
|
+
sessionID,
|
|
542
|
+
name: "story",
|
|
543
|
+
mode: "narrative",
|
|
544
|
+
visibleText: "Open Revela story workspace.",
|
|
545
|
+
hiddenPrompt: buildNarrativeViewPrompt({ workspaceRoot, language: parsed.args.language }),
|
|
546
|
+
output,
|
|
547
|
+
})
|
|
548
|
+
return
|
|
690
549
|
}
|
|
691
550
|
|
|
692
551
|
await send(`**Unknown sub-command:** \`${sub}\`\nRun \`/revela\` to see available commands.`)
|
|
@@ -817,7 +676,7 @@ const server: Plugin = (async (pluginCtx) => {
|
|
|
817
676
|
// This prevents a silent "revela enabled but not working" scenario.
|
|
818
677
|
output.system.push(
|
|
819
678
|
"\n\n[REVELA ERROR: Failed to load the slide generation prompt. " +
|
|
820
|
-
"Run /revela
|
|
679
|
+
"Run /revela to confirm the plugin is available, then retry the workflow command.]"
|
|
821
680
|
)
|
|
822
681
|
}
|
|
823
682
|
},
|
package/skill/NARRATIVE_SKILL.md
CHANGED
|
@@ -10,7 +10,7 @@ You help the user turn source materials, research, data, and intent into trusted
|
|
|
10
10
|
|
|
11
11
|
Decks are important, but they are render targets. The durable source of truth is the canonical narrative state: audience, decision, thesis, claims, evidence boundaries, objections, risks, research gaps, approval provenance, and artifact coverage.
|
|
12
12
|
|
|
13
|
-
Default mode is narrative-first. Do not generate HTML slides, choose layouts, fetch design CSS/components, or ask for slide count unless the user explicitly enters
|
|
13
|
+
Default mode is narrative-first. Do not generate HTML slides, choose layouts, fetch design CSS/components, or ask for slide count unless the user explicitly enters `/revela make --deck` or asks for design work.
|
|
14
14
|
|
|
15
15
|
## Workflow Model
|
|
16
16
|
|
|
@@ -20,24 +20,22 @@ Use the same phase semantics whether the user invokes a slash command or asks in
|
|
|
20
20
|
- `Research` runs closed loops to fill open story gaps, bind supported findings into canonical evidence, narrow overbroad claims/relations, and reduce caveats without crossing evidence boundaries.
|
|
21
21
|
- `Story` opens the read-only story workspace UI for inspecting claim flow, evidence strength, unsupported scope, caveats, objections, risks, research gaps, approval state, and affected artifacts.
|
|
22
22
|
- `Make` renders an artifact from approved or explicitly overridden narrative state. Supported 0.15 targets are deck and executive brief.
|
|
23
|
-
- `
|
|
23
|
+
- `Review` is the post-artifact workspace for reading, insight, and targeted commenting. Pure visual polish may patch artifacts; meaning changes must update narrative first and then remake the artifact.
|
|
24
24
|
|
|
25
25
|
Public command surface:
|
|
26
26
|
|
|
27
27
|
- `/revela init`
|
|
28
28
|
- `/revela research`
|
|
29
29
|
- `/revela story`
|
|
30
|
-
- `/revela make deck`
|
|
31
|
-
- `/revela make brief`
|
|
32
|
-
- `/revela
|
|
30
|
+
- `/revela make --deck`
|
|
31
|
+
- `/revela make --brief`
|
|
32
|
+
- `/revela review --deck`
|
|
33
|
+
- `/revela export --deck pdf`
|
|
34
|
+
- `/revela export --deck pptx`
|
|
33
35
|
- `/revela design`
|
|
36
|
+
- `/revela domain`
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- `/revela review` means a legacy story readiness report
|
|
38
|
-
- `/revela narrative` means `/revela story`
|
|
39
|
-
- `/revela deck` means `/revela make deck`
|
|
40
|
-
- `/revela brief` means `/revela make brief`
|
|
38
|
+
Deprecated compatibility aliases such as `/revela review`, `/revela narrative`, `/revela deck`, `/revela brief`, `/revela inspect`, `/revela edit`, `/revela pdf`, `/revela pptx`, `/revela designs*`, and `/revela domains*` are no longer public commands. Direct users to `/revela` for current REVELA Help.
|
|
41
39
|
|
|
42
40
|
## Workspace State
|
|
43
41
|
|
|
@@ -87,7 +85,7 @@ During research:
|
|
|
87
85
|
|
|
88
86
|
When the user invokes `/revela story`, open the read-only story workspace UI. Do not turn that command into a blocking readiness report.
|
|
89
87
|
|
|
90
|
-
When the user
|
|
88
|
+
When the user explicitly asks for a readiness report, call `revela-decks` action `reviewNarrative` and report the tool result as authoritative.
|
|
91
89
|
|
|
92
90
|
Use this report shape:
|
|
93
91
|
|
|
@@ -104,7 +102,7 @@ If the narrative is ready for approval, ask the user whether to approve or revis
|
|
|
104
102
|
|
|
105
103
|
## Make Rules
|
|
106
104
|
|
|
107
|
-
For `/revela make deck`
|
|
105
|
+
For `/revela make --deck` deck handoff:
|
|
108
106
|
|
|
109
107
|
- switch to deck-render mode through the command workflow
|
|
110
108
|
- check narrative readiness and current approval before compiling deck specs
|
|
@@ -113,22 +111,22 @@ For `/revela make deck` and compatible deck handoff:
|
|
|
113
111
|
- fetch design layouts/components only after narrative handoff is valid
|
|
114
112
|
- keep the HTML deck contract valid: one `<section class="slide">` per slide, canonical 1-based `data-slide-index`, and matching `DECKS.json` slide specs
|
|
115
113
|
|
|
116
|
-
For `/revela make brief`, render the executive brief from canonical narrative state and graph-backed claim/evidence relationships, not from a deck summary.
|
|
114
|
+
For `/revela make --brief`, render the executive brief from canonical narrative state and graph-backed claim/evidence relationships, not from a deck summary.
|
|
117
115
|
|
|
118
|
-
If story readiness, approval, evidence, or artifact blockers remain, report the blocker and suggest `/revela
|
|
116
|
+
If story readiness, approval, evidence, or artifact blockers remain, report the blocker and suggest `/revela story`, `/revela research`, or a targeted user answer. Do not bypass with invented state.
|
|
119
117
|
|
|
120
|
-
##
|
|
118
|
+
## Review Rules
|
|
121
119
|
|
|
122
|
-
Use `/revela
|
|
120
|
+
Use `/revela review --deck` for post-artifact reading, insight, and commenting.
|
|
123
121
|
|
|
124
122
|
- Reading should explain source, support strength, caveat, unsupported scope, narrative purpose, related risks/objections, research gaps, and artifact coverage.
|
|
125
123
|
- Pure artifact polish may stay artifact-level: layout, typography, spacing, crop, visual hierarchy, export mechanics, and deck contract fixes.
|
|
126
124
|
- Meaning-changing edits must update canonical narrative first, then run story readiness/approval or explicit override, then remake affected artifacts.
|
|
127
|
-
- `/revela edit`
|
|
125
|
+
- `/revela edit` and `/revela inspect` have been removed from the public surface; use `/revela review --deck`.
|
|
128
126
|
|
|
129
127
|
## Design Surface
|
|
130
128
|
|
|
131
|
-
Use `/revela design` for visual-system work: list
|
|
129
|
+
Use `/revela design` for visual-system work: list, `--use`, `--new`, `--edit`, `--preview`, `--add`, and `--rm` designs. Use `/revela domain` for domain list, `--use`, `--add`, and `--rm`.
|
|
132
130
|
|
|
133
131
|
Do not inject design CSS, layout catalogs, component indexes, chart rules, or deck HTML skeletons during init, research, or story. Fetch design context only for make-deck or explicit design-authoring workflows.
|
|
134
132
|
|