@cyber-dash-tech/revela 0.17.5 → 0.17.7

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.
Files changed (40) hide show
  1. package/README.md +26 -46
  2. package/README.zh-CN.md +26 -46
  3. package/bin/revela.ts +98 -0
  4. package/lib/commands/review.ts +8 -5
  5. package/lib/deck-html/foundation.ts +190 -0
  6. package/lib/edit/prompt.ts +6 -2
  7. package/lib/edit/server.ts +2 -2
  8. package/lib/inspect/prompt.ts +5 -1
  9. package/lib/qa/index.ts +12 -0
  10. package/lib/refine/comment-requests.ts +77 -0
  11. package/lib/refine/open.ts +5 -2
  12. package/lib/refine/prompt-bridge.ts +219 -0
  13. package/lib/refine/qa-suppression.ts +41 -0
  14. package/lib/refine/server.ts +122 -34
  15. package/lib/runtime/index.ts +225 -0
  16. package/lib/runtime/research.ts +175 -0
  17. package/lib/runtime/review.ts +270 -0
  18. package/lib/runtime/story.ts +53 -0
  19. package/package.json +6 -1
  20. package/plugin.ts +6 -2
  21. package/plugins/revela/.codex-plugin/plugin.json +37 -0
  22. package/plugins/revela/.mcp.json +11 -0
  23. package/plugins/revela/assets/README.md +2 -0
  24. package/plugins/revela/hooks/hooks.json +28 -0
  25. package/plugins/revela/hooks/revela_guard.ts +10 -0
  26. package/plugins/revela/hooks/revela_post_write_notice.ts +18 -0
  27. package/plugins/revela/mcp/revela-server.ts +504 -0
  28. package/plugins/revela/mcp/runtime-resolver.ts +109 -0
  29. package/plugins/revela/skills/revela-design/SKILL.md +20 -0
  30. package/plugins/revela/skills/revela-domain/SKILL.md +18 -0
  31. package/plugins/revela/skills/revela-export/SKILL.md +21 -0
  32. package/plugins/revela/skills/revela-init/SKILL.md +36 -0
  33. package/plugins/revela/skills/revela-make-deck/SKILL.md +37 -0
  34. package/plugins/revela/skills/revela-research/SKILL.md +38 -0
  35. package/plugins/revela/skills/revela-review-deck/SKILL.md +33 -0
  36. package/plugins/revela/skills/revela-story/SKILL.md +24 -0
  37. package/skill/SKILL.md +17 -8
  38. package/tools/deck-foundation.ts +48 -0
  39. package/tools/decks.ts +10 -78
  40. package/tools/research-save.ts +8 -72
@@ -0,0 +1,53 @@
1
+ import { resolve } from "path"
2
+ import { loadStoryMap } from "../commands/narrative"
3
+ import { formatNarrativeMap, type NarrativeMap } from "../narrative-state/map"
4
+ import type { formatVaultDiagnosticReport } from "../narrative-vault"
5
+
6
+ export interface StoryReadInput {
7
+ workspaceRoot?: string
8
+ format?: "map" | "markdown"
9
+ }
10
+
11
+ export type StoryReadResult =
12
+ | {
13
+ ok: true
14
+ narrativeHash: string
15
+ map: NarrativeMap
16
+ markdown?: string
17
+ diagnostics: ReturnType<typeof formatVaultDiagnosticReport>
18
+ diagnosticsMarkdown: string
19
+ }
20
+ | {
21
+ ok: false
22
+ error: string
23
+ guidance: string
24
+ diagnostics?: ReturnType<typeof formatVaultDiagnosticReport>
25
+ diagnosticsMarkdown: string
26
+ }
27
+
28
+ export function storyRead(input: StoryReadInput = {}): StoryReadResult {
29
+ const loaded = loadStoryMap(root(input.workspaceRoot))
30
+ if (!loaded.ok) {
31
+ return {
32
+ ok: false,
33
+ error: loaded.error,
34
+ guidance: "Run `/revela init` first to initialize `revela-narrative/`, then retry Story reading.",
35
+ diagnostics: loaded.diagnosticsReport,
36
+ diagnosticsMarkdown: loaded.diagnosticsMarkdown,
37
+ }
38
+ }
39
+
40
+ const map = loaded.map
41
+ return {
42
+ ok: true,
43
+ narrativeHash: map.snapshot.narrativeHash,
44
+ map,
45
+ markdown: input.format === "markdown" ? formatNarrativeMap(map) : undefined,
46
+ diagnostics: loaded.diagnosticsReport,
47
+ diagnosticsMarkdown: loaded.diagnosticsMarkdown,
48
+ }
49
+ }
50
+
51
+ function root(workspaceRoot: string | undefined): string {
52
+ return resolve(workspaceRoot || process.cwd())
53
+ }
package/package.json CHANGED
@@ -1,15 +1,20 @@
1
1
  {
2
2
  "name": "@cyber-dash-tech/revela",
3
- "version": "0.17.5",
3
+ "version": "0.17.7",
4
4
  "description": "OpenCode plugin for trusted narrative artifacts from local sources, research, and evidence",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
7
+ "bin": {
8
+ "revela": "./bin/revela.ts"
9
+ },
7
10
  "exports": {
8
11
  ".": "./index.ts"
9
12
  },
10
13
  "files": [
14
+ "bin/",
11
15
  "plugin.ts",
12
16
  "lib/",
17
+ "plugins/revela/",
13
18
  "tools/",
14
19
  "skill/",
15
20
  "designs/aurora/DESIGN.md",
package/plugin.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * 5. experimental.chat.system.transform: inject three-layer prompt when enabled
12
12
  * 6. chat.message: intercept @-referenced / pasted binary files → extract text → replace FilePart with TextPart
13
13
  * 7. tool.execute.before: intercept read on DOCX/PPTX/XLSX → preRead()
14
- * 8. tool.execute.after: intercept read on PDF/images → postRead(); run static compliance after deck writes/patches/edits
14
+ * 8. tool.execute.after: intercept read on PDF/images → postRead(); run static compliance after deck writes/patches/edits unless Review Apply Fix suppresses it
15
15
  */
16
16
 
17
17
  import type { Plugin } from "@opencode-ai/plugin"
@@ -47,6 +47,7 @@ import { buildPptxNotesPrompt, handlePptx, parsePptxArgs, resolvePptxDeck } from
47
47
  import { handleRefine } from "./lib/commands/refine"
48
48
  import { formatArtifactQAReport, runArtifactQA } from "./lib/qa/artifact"
49
49
  import { ensureRefineDeckOpenForChange } from "./lib/refine/open"
50
+ import { shouldSuppressReviewApplyFixArtifactQa } from "./lib/refine/qa-suppression"
50
51
  import { handleDesignsPreview } from "./lib/commands/designs-preview"
51
52
  import {
52
53
  parseDesignsNewArgs,
@@ -81,6 +82,7 @@ import decksTool from "./tools/decks"
81
82
  import designsAuthorTool from "./tools/designs-author"
82
83
  import designsTool from "./tools/designs"
83
84
  import domainsTool from "./tools/domains"
85
+ import deckFoundationTool from "./tools/deck-foundation"
84
86
  import mediaBatchSaveTool from "./tools/media-batch-save"
85
87
  import mediaSaveTool from "./tools/media-save"
86
88
  import researchImagesListTool from "./tools/research-images-list"
@@ -147,6 +149,7 @@ const server: Plugin = (async (pluginCtx) => {
147
149
 
148
150
  async function runPostWriteArtifactQA(filePath: string, output: any, sessionID = ""): Promise<boolean> {
149
151
  if (!isDeckHtmlPath(filePath)) return true
152
+ if (shouldSuppressReviewApplyFixArtifactQa({ workspaceRoot, file: filePath, sessionID })) return false
150
153
 
151
154
  try {
152
155
  let vocabulary
@@ -586,6 +589,7 @@ const server: Plugin = (async (pluginCtx) => {
586
589
  tool: {
587
590
  "revela-decks": decksTool,
588
591
  "revela-designs": designsTool,
592
+ "revela-deck-foundation": deckFoundationTool,
589
593
  "revela-designs-author": designsAuthorTool,
590
594
  "revela-domains": domainsTool,
591
595
  "revela-media-batch-save": mediaBatchSaveTool,
@@ -785,7 +789,7 @@ Next step: use \`revela-decks\` with action \`init\`, \`upsertDeck\`, \`upsertSl
785
789
  // PDF: extract text, remove base64. Images: jimp compress.
786
790
  //
787
791
  // Also reports writes/patches blocked by the DECKS.json state gate and
788
- // runs artifact QA before opening Refine after successful deck changes.
792
+ // runs artifact QA before opening Refine after successful deck changes, except Review Apply Fix comments.
789
793
  "tool.execute.after": async (input, output) => {
790
794
  // ── Post-read processing ───────────────────────────────────────────
791
795
  if (input.tool === "read") {
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "revela",
3
+ "version": "0.1.0+codex.20260523122203",
4
+ "description": "Use Revela in Codex to build trusted, traceable narrative decision artifacts from local sources and research.",
5
+ "author": {
6
+ "name": "cyber-dash-tech",
7
+ "url": "https://github.com/cyber-dash-tech"
8
+ },
9
+ "repository": "https://github.com/cyber-dash-tech/revela",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "narrative",
13
+ "presentations",
14
+ "research",
15
+ "evidence",
16
+ "codex"
17
+ ],
18
+ "skills": "./skills/",
19
+ "mcpServers": "./.mcp.json",
20
+ "interface": {
21
+ "displayName": "Revela",
22
+ "shortDescription": "Trusted narrative artifacts from local sources and research.",
23
+ "longDescription": "Revela helps Codex initialize a narrative vault, bind evidence, plan decks, generate artifact foundations, run QA, and export decision artifacts while preserving source traceability.",
24
+ "developerName": "cyber-dash-tech",
25
+ "category": "Productivity",
26
+ "capabilities": [
27
+ "Read",
28
+ "Write"
29
+ ],
30
+ "defaultPrompt": [
31
+ "Use Revela to initialize this workspace.",
32
+ "Use Revela to make a deck from the narrative.",
33
+ "Use Revela to review this deck artifact."
34
+ ],
35
+ "brandColor": "#2563EB"
36
+ }
37
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "revela": {
4
+ "command": "bun",
5
+ "args": [
6
+ "--eval",
7
+ "const fs = await import('fs');\nconst path = await import('path');\nconst { pathToFileURL } = await import('url');\nconst candidates = [];\nconst home = process.env.HOME || '';\nconst marketplaceNames = ['revela', 'revela-local'];\ncandidates.push(path.resolve(process.cwd(), 'bin/revela.ts'));\nconst configPath = path.join(home, '.codex', 'config.toml');\nif (fs.existsSync(configPath)) {\n const text = fs.readFileSync(configPath, 'utf-8');\n const sections = text.split(/\\n(?=\\s*\\[)/);\n for (const marketplaceName of marketplaceNames) {\n const section = sections.find((item) => item.trimStart().startsWith(`[marketplaces.${marketplaceName}]`));\n const match = section?.match(/^\\s*source\\s*=\\s*\"([^\"]+)\"/m);\n if (match) candidates.push(path.join(match[1], 'bin/revela.ts'));\n }\n}\nfor (const marketplaceName of marketplaceNames) {\n const cacheRoot = path.join(home, '.codex', 'plugins', 'cache', marketplaceName, 'revela');\n if (fs.existsSync(cacheRoot)) {\n for (const version of fs.readdirSync(cacheRoot).sort().reverse()) candidates.push(path.join(cacheRoot, version, 'bin/revela.ts'));\n }\n}\nconst cli = candidates.find((candidate) => fs.existsSync(candidate));\nif (!cli) {\n console.error(`Could not locate Revela CLI. Checked: ${candidates.join(', ')}`);\n process.exit(1);\n}\nprocess.env.REVELA_CLI_COMMAND = 'mcp';\nawait import(pathToFileURL(cli).href);"
8
+ ]
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,2 @@
1
+ Revela Codex plugin assets live here. Add logo, icon, and screenshots before packaging a published plugin.
2
+
@@ -0,0 +1,28 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "apply_patch",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "bun ${PLUGIN_ROOT}/hooks/revela_guard.ts",
10
+ "statusMessage": "Checking Revela controlled files"
11
+ }
12
+ ]
13
+ }
14
+ ],
15
+ "PostToolUse": [
16
+ {
17
+ "matcher": "apply_patch",
18
+ "hooks": [
19
+ {
20
+ "type": "command",
21
+ "command": "bun ${PLUGIN_ROOT}/hooks/revela_post_write_notice.ts",
22
+ "statusMessage": "Checking Revela QA reminders"
23
+ }
24
+ ]
25
+ }
26
+ ]
27
+ }
28
+ }
@@ -0,0 +1,10 @@
1
+ const input = await new Response(Bun.stdin.stream()).text()
2
+
3
+ if (input.includes("DECKS.json")) {
4
+ console.error("Revela controls DECKS.json. Use Revela MCP/runtime tools or file-native narrative files instead of direct DECKS.json patches.")
5
+ process.exit(2)
6
+ }
7
+
8
+ process.exit(0)
9
+
10
+ export {}
@@ -0,0 +1,18 @@
1
+ const input = await new Response(Bun.stdin.stream()).text()
2
+ const notices: string[] = []
3
+
4
+ if (/revela-narrative\/.*\.md/.test(input)) {
5
+ notices.push("Revela narrative Markdown changed. Run `revela_markdown_qa` and `revela_compile_narrative` before treating the graph as usable.")
6
+ }
7
+
8
+ if (/decks\/.*\.html/.test(input)) {
9
+ notices.push("Revela deck HTML changed. Run `revela_run_deck_qa` before review or export.")
10
+ }
11
+
12
+ if (notices.length > 0) {
13
+ console.error(notices.join("\n"))
14
+ }
15
+
16
+ process.exit(0)
17
+
18
+ export {}