@cyber-dash-tech/revela 0.17.20 → 0.17.22
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 +25 -3
- package/README.zh-CN.md +25 -3
- package/designs/monet/DESIGN.md +58 -38
- package/lib/design/designs.ts +113 -2
- package/lib/document-materials/extract.ts +189 -6
- package/lib/domain/domains.ts +221 -1
- package/lib/material-intake.ts +494 -0
- package/lib/runtime/index.ts +114 -1
- package/package.json +1 -1
- package/plugins/revela/.mcp.json +1 -1
- package/plugins/revela/hooks/hooks.json +10 -0
- package/plugins/revela/hooks/revela_guard.ts +19 -0
- package/plugins/revela/hooks/revela_material_notice.ts +58 -0
- package/plugins/revela/hooks/revela_post_write_notice.ts +37 -6
- package/plugins/revela/mcp/revela-server.ts +152 -0
- package/plugins/revela/skills/revela-design/SKILL.md +4 -2
- package/plugins/revela/skills/revela-domain/SKILL.md +13 -1
- package/plugins/revela/skills/revela-init/SKILL.md +18 -8
- package/plugins/revela/skills/revela-upgrade/SKILL.md +33 -0
package/plugins/revela/.mcp.json
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"hooks": {
|
|
3
3
|
"PreToolUse": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "exec_command",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "bun ${PLUGIN_ROOT}/hooks/revela_material_notice.ts",
|
|
10
|
+
"statusMessage": "Checking Revela material intake"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
},
|
|
4
14
|
{
|
|
5
15
|
"matcher": "apply_patch",
|
|
6
16
|
"hooks": [
|
|
@@ -17,6 +17,15 @@ export async function runPreWriteChecks(input: string): Promise<HookResult> {
|
|
|
17
17
|
messages.push(`Revela controls ${controlledStateFile}. Use Revela MCP/runtime tools or file-native narrative files instead of direct ${controlledStateFile} patches.`)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
const cacheTargets = extractNarrativeCachePatchTargets(input)
|
|
21
|
+
if (cacheTargets.length > 0) {
|
|
22
|
+
messages.push([
|
|
23
|
+
"Revela narrative cache patches are blocked.",
|
|
24
|
+
`Controlled cache target(s): ${cacheTargets.map((target) => `\`${target}\``).join(", ")}`,
|
|
25
|
+
"Edit `revela-narrative/**/*.md` instead; compile/cache files under `.opencode/revela/narrative-cache/` are regenerated.",
|
|
26
|
+
].join("\n"))
|
|
27
|
+
}
|
|
28
|
+
|
|
20
29
|
const deckTargets = extractDeckHtmlPatchTargets(input)
|
|
21
30
|
if (deckTargets.length > 0) {
|
|
22
31
|
const pluginRoot = resolve(process.env.PLUGIN_ROOT || dirname(dirname(fileURLToPath(import.meta.url))))
|
|
@@ -55,6 +64,16 @@ export function extractDeckHtmlPatchTargets(input: string): string[] {
|
|
|
55
64
|
return [...targets].sort((a, b) => a.localeCompare(b))
|
|
56
65
|
}
|
|
57
66
|
|
|
67
|
+
export function extractNarrativeCachePatchTargets(input: string): string[] {
|
|
68
|
+
const targets = new Set<string>()
|
|
69
|
+
for (const patch of patchPayloads(input)) {
|
|
70
|
+
const pattern = /(?:^\*\*\* Update File: |^\*\*\* Add File: |^\*\*\* Delete File: |^\*\*\* Move to: )([^\r\n]*\.opencode\/revela\/narrative-cache\/[^\r\n]+)\s*$/gm
|
|
71
|
+
let match: RegExpExecArray | null
|
|
72
|
+
while ((match = pattern.exec(patch))) targets.add(match[1].trim())
|
|
73
|
+
}
|
|
74
|
+
return [...targets].sort((a, b) => a.localeCompare(b))
|
|
75
|
+
}
|
|
76
|
+
|
|
58
77
|
function patchPayloads(input: string): string[] {
|
|
59
78
|
try {
|
|
60
79
|
const parsed = JSON.parse(input)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { dirname, resolve } from "path"
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from "url"
|
|
3
|
+
import { resolveRevelaRuntime } from "../mcp/runtime-resolver"
|
|
4
|
+
import { workspaceRootFromInput } from "./revela_post_write_notice"
|
|
5
|
+
|
|
6
|
+
export interface MaterialNoticeResult {
|
|
7
|
+
ok: true
|
|
8
|
+
messages: string[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function runMaterialReadNotice(input: string): Promise<MaterialNoticeResult> {
|
|
12
|
+
const command = commandFromInput(input)
|
|
13
|
+
if (!command) return { ok: true, messages: [] }
|
|
14
|
+
|
|
15
|
+
const pluginRoot = resolve(process.env.PLUGIN_ROOT || dirname(dirname(fileURLToPath(import.meta.url))))
|
|
16
|
+
const runtime = resolveRevelaRuntime({ pluginRoot })
|
|
17
|
+
if (!runtime.ok || !runtime.runtimePath) return { ok: true, messages: [] }
|
|
18
|
+
|
|
19
|
+
const workspaceRoot = workspaceRootFromInput(input)
|
|
20
|
+
const runtimeModule = await import(pathToFileURL(runtime.runtimePath).href)
|
|
21
|
+
const notice = runtimeModule.materialIntakeNoticeForCommand?.({ workspaceRoot, command })
|
|
22
|
+
return { ok: true, messages: notice ? [notice] : [] }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function commandFromInput(input: string): string | null {
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(input)
|
|
28
|
+
const candidates = [
|
|
29
|
+
parsed.cmd,
|
|
30
|
+
parsed.command,
|
|
31
|
+
parsed.args?.cmd,
|
|
32
|
+
parsed.args?.command,
|
|
33
|
+
parsed.tool_input?.cmd,
|
|
34
|
+
parsed.tool_input?.command,
|
|
35
|
+
parsed.toolInput?.cmd,
|
|
36
|
+
parsed.toolInput?.command,
|
|
37
|
+
]
|
|
38
|
+
for (const candidate of candidates) {
|
|
39
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate
|
|
40
|
+
}
|
|
41
|
+
return null
|
|
42
|
+
} catch {
|
|
43
|
+
return input.trim() || null
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (import.meta.main) {
|
|
48
|
+
const input = await new Response(Bun.stdin.stream()).text()
|
|
49
|
+
try {
|
|
50
|
+
const result = await runMaterialReadNotice(input)
|
|
51
|
+
if (result.messages.length > 0) console.error(result.messages.join("\n\n---\n\n"))
|
|
52
|
+
process.exit(0)
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.error("Revela material intake notice failed to run.")
|
|
55
|
+
console.error(e instanceof Error ? e.message : String(e))
|
|
56
|
+
process.exit(0)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -24,6 +24,20 @@ export function extractDeckHtmlTargets(input: string): string[] {
|
|
|
24
24
|
return [...targets].sort((a, b) => a.localeCompare(b))
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
export function patchPayloadsFromInput(input: string): string[] {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(input)
|
|
30
|
+
return [
|
|
31
|
+
parsed.patch,
|
|
32
|
+
parsed.args?.patch,
|
|
33
|
+
parsed.tool_input?.patch,
|
|
34
|
+
parsed.toolInput?.patch,
|
|
35
|
+
].filter((item): item is string => typeof item === "string")
|
|
36
|
+
} catch {
|
|
37
|
+
return [input]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
27
41
|
export function workspaceRootFromInput(input: string): string {
|
|
28
42
|
try {
|
|
29
43
|
const parsed = JSON.parse(input)
|
|
@@ -47,18 +61,16 @@ export function workspaceRootFromInput(input: string): string {
|
|
|
47
61
|
|
|
48
62
|
export async function runPostWriteChecks(input: string): Promise<HookResult> {
|
|
49
63
|
const messages: string[] = []
|
|
50
|
-
if (/revela-narrative\/.*\.md/.test(input)) {
|
|
51
|
-
messages.push("Revela narrative Markdown changed. Run `revela_markdown_qa` and `revela_compile_narrative` before treating the graph as usable.")
|
|
52
|
-
}
|
|
53
|
-
|
|
54
64
|
const deckTargets = extractDeckHtmlTargets(input)
|
|
55
|
-
|
|
65
|
+
const hasPossibleNarrativeMarkdown = /revela-narrative\/.*\.md/.test(input)
|
|
66
|
+
if (deckTargets.length === 0 && !hasPossibleNarrativeMarkdown) return { ok: true, messages }
|
|
56
67
|
|
|
57
68
|
const pluginRoot = resolve(process.env.PLUGIN_ROOT || dirname(dirname(fileURLToPath(import.meta.url))))
|
|
58
69
|
const runtime = resolveRevelaRuntime({ pluginRoot })
|
|
59
70
|
if (!runtime.ok || !runtime.runtimePath) {
|
|
71
|
+
const changed = deckTargets.length > 0 ? "deck HTML changed" : "narrative Markdown changed"
|
|
60
72
|
messages.push([
|
|
61
|
-
|
|
73
|
+
`Revela ${changed}, but Codex hook could not locate the Revela runtime to run write-after checks.`,
|
|
62
74
|
...runtime.diagnostics.map((item) => `- ${item}`),
|
|
63
75
|
].join("\n"))
|
|
64
76
|
return { ok: false, messages }
|
|
@@ -67,9 +79,28 @@ export async function runPostWriteChecks(input: string): Promise<HookResult> {
|
|
|
67
79
|
const workspaceRoot = workspaceRootFromInput(input)
|
|
68
80
|
const runtimeModule = await import(pathToFileURL(runtime.runtimePath).href)
|
|
69
81
|
let ok = true
|
|
82
|
+
|
|
83
|
+
if (hasPossibleNarrativeMarkdown) {
|
|
84
|
+
const touched = new Set<string>()
|
|
85
|
+
for (const patch of patchPayloadsFromInput(input)) {
|
|
86
|
+
const targets = runtimeModule.extractNarrativeVaultMarkdownPatchTargets({ workspaceRoot, patch })
|
|
87
|
+
for (const target of targets) touched.add(target)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (touched.size > 0) {
|
|
91
|
+
const result = runtimeModule.autoCompileNarrative({ workspaceRoot, touched: [...touched] })
|
|
92
|
+
messages.push(result.markdown ?? JSON.stringify(result, null, 2))
|
|
93
|
+
const notice = runtimeModule.formatMarkdownQaUserNotice?.(result)
|
|
94
|
+
if (notice) messages.push(notice)
|
|
95
|
+
if (!result.ok) ok = false
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
70
99
|
for (const target of deckTargets) {
|
|
71
100
|
const result = await runtimeModule.runDeckQa({ workspaceRoot, file: target })
|
|
72
101
|
messages.push(result.markdown ?? JSON.stringify(result, null, 2))
|
|
102
|
+
const notice = runtimeModule.formatArtifactQaUserNotice?.(result.report)
|
|
103
|
+
if (notice) messages.push(notice)
|
|
73
104
|
if (!result.ok) ok = false
|
|
74
105
|
}
|
|
75
106
|
|
|
@@ -22,9 +22,17 @@ type RuntimeModule = {
|
|
|
22
22
|
designActivate(input: any): any
|
|
23
23
|
designCreate(input: any): any
|
|
24
24
|
designValidate(input: any): any
|
|
25
|
+
designDraftCreate(input: any): any
|
|
26
|
+
designDraftValidate(input: any): any
|
|
27
|
+
designDraftInstall(input: any): any
|
|
25
28
|
domainList(): any
|
|
26
29
|
domainRead(input?: any): any
|
|
27
30
|
domainActivate(input: any): any
|
|
31
|
+
domainCreate(input: any): any
|
|
32
|
+
domainValidate(input: any): any
|
|
33
|
+
domainDraftCreate(input: any): any
|
|
34
|
+
domainDraftValidate(input: any): any
|
|
35
|
+
domainDraftInstall(input: any): any
|
|
28
36
|
storyRead(input?: any): any
|
|
29
37
|
reviewDeckRead(input: any): Promise<any>
|
|
30
38
|
reviewDeckOpen(input: any): Promise<any>
|
|
@@ -32,6 +40,10 @@ type RuntimeModule = {
|
|
|
32
40
|
researchSave(input: any): any
|
|
33
41
|
evaluateResearchFindings(input: any): any
|
|
34
42
|
bindResearchFindings(input: any): any
|
|
43
|
+
prepareLocalMaterials(input: any): Promise<any>
|
|
44
|
+
extractMaterial(input: any): Promise<any>
|
|
45
|
+
recordMaterialReview(input: any): any
|
|
46
|
+
checkMaterialIntake(input: any): any
|
|
35
47
|
}
|
|
36
48
|
|
|
37
49
|
type MessageMode = "framed" | "raw"
|
|
@@ -134,6 +146,35 @@ const tools = [
|
|
|
134
146
|
description: "Validate a local Revela design package.",
|
|
135
147
|
inputSchema: objectSchema({ name: requiredStringProp("Design name to validate.") }, ["name"]),
|
|
136
148
|
},
|
|
149
|
+
{
|
|
150
|
+
name: "revela_design_draft_create",
|
|
151
|
+
description: "Create and validate a workspace-local Revela design draft package.",
|
|
152
|
+
inputSchema: objectSchema({
|
|
153
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
154
|
+
name: requiredStringProp("Design name in kebab-case."),
|
|
155
|
+
base: stringProp("Optional base design used as structural scaffold."),
|
|
156
|
+
designMd: requiredStringProp("Complete DESIGN.md content."),
|
|
157
|
+
previewHtml: requiredStringProp("Complete preview.html content."),
|
|
158
|
+
overwrite: booleanProp("Whether to replace an existing workspace draft. Defaults to false."),
|
|
159
|
+
}, ["name", "designMd", "previewHtml"]),
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: "revela_design_draft_validate",
|
|
163
|
+
description: "Validate a workspace-local Revela design draft package.",
|
|
164
|
+
inputSchema: objectSchema({
|
|
165
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
166
|
+
name: requiredStringProp("Design draft name to validate."),
|
|
167
|
+
}, ["name"]),
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: "revela_design_draft_install",
|
|
171
|
+
description: "Install a validated workspace-local Revela design draft into the user-level design registry.",
|
|
172
|
+
inputSchema: objectSchema({
|
|
173
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
174
|
+
name: requiredStringProp("Design draft name to install."),
|
|
175
|
+
overwrite: booleanProp("Whether to replace an existing user-level design package. Defaults to false."),
|
|
176
|
+
}, ["name"]),
|
|
177
|
+
},
|
|
137
178
|
{
|
|
138
179
|
name: "revela_domain_list",
|
|
139
180
|
description: "List installed Revela narrative domains and the active domain.",
|
|
@@ -149,6 +190,47 @@ const tools = [
|
|
|
149
190
|
description: "Activate a Revela narrative domain for future narrative authoring guidance.",
|
|
150
191
|
inputSchema: objectSchema({ name: requiredStringProp("Domain name to activate.") }, ["name"]),
|
|
151
192
|
},
|
|
193
|
+
{
|
|
194
|
+
name: "revela_domain_create",
|
|
195
|
+
description: "Create and validate a local Revela narrative domain package from complete INDUSTRY.md content.",
|
|
196
|
+
inputSchema: objectSchema({
|
|
197
|
+
name: requiredStringProp("Domain name in kebab-case."),
|
|
198
|
+
domainMd: requiredStringProp("Complete INDUSTRY.md content."),
|
|
199
|
+
overwrite: booleanProp("Whether to replace an existing local domain package. Defaults to false."),
|
|
200
|
+
}, ["name", "domainMd"]),
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "revela_domain_validate",
|
|
204
|
+
description: "Validate a local Revela narrative domain package.",
|
|
205
|
+
inputSchema: objectSchema({ name: requiredStringProp("Domain name to validate.") }, ["name"]),
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: "revela_domain_draft_create",
|
|
209
|
+
description: "Create and validate a workspace-local Revela narrative domain draft package.",
|
|
210
|
+
inputSchema: objectSchema({
|
|
211
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
212
|
+
name: requiredStringProp("Domain name in kebab-case."),
|
|
213
|
+
domainMd: requiredStringProp("Complete INDUSTRY.md content."),
|
|
214
|
+
overwrite: booleanProp("Whether to replace an existing workspace draft. Defaults to false."),
|
|
215
|
+
}, ["name", "domainMd"]),
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: "revela_domain_draft_validate",
|
|
219
|
+
description: "Validate a workspace-local Revela narrative domain draft package.",
|
|
220
|
+
inputSchema: objectSchema({
|
|
221
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
222
|
+
name: requiredStringProp("Domain draft name to validate."),
|
|
223
|
+
}, ["name"]),
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: "revela_domain_draft_install",
|
|
227
|
+
description: "Install a validated workspace-local Revela narrative domain draft into the user-level domain registry.",
|
|
228
|
+
inputSchema: objectSchema({
|
|
229
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
230
|
+
name: requiredStringProp("Domain draft name to install."),
|
|
231
|
+
overwrite: booleanProp("Whether to replace an existing user-level domain package. Defaults to false."),
|
|
232
|
+
}, ["name"]),
|
|
233
|
+
},
|
|
152
234
|
{
|
|
153
235
|
name: "revela_story_read",
|
|
154
236
|
description: "Read a deterministic Revela Story map and optional Markdown view from the canonical narrative vault without mutating files.",
|
|
@@ -209,6 +291,43 @@ const tools = [
|
|
|
209
291
|
evidenceId: stringProp("Optional canonical evidence node id override."),
|
|
210
292
|
}, ["findingsFile"]),
|
|
211
293
|
},
|
|
294
|
+
{
|
|
295
|
+
name: "revela_prepare_local_materials",
|
|
296
|
+
description: "Scan local workspace source materials, create/update the material-intake registry, and optionally extract Office/PDF files into read views.",
|
|
297
|
+
inputSchema: objectSchema({
|
|
298
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
299
|
+
path: stringProp("Optional workspace-relative subdirectory to scan."),
|
|
300
|
+
maxDepth: numberProp("Maximum scan depth. Defaults to 2."),
|
|
301
|
+
autoExtract: booleanProp("Whether to extract Office/PDF sources during prepare. Defaults to true."),
|
|
302
|
+
}),
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: "revela_extract_document_materials",
|
|
306
|
+
description: "Extract text, manifest, read view, and embedded images from a workspace document. Supports pdf, pptx, docx, and xlsx.",
|
|
307
|
+
inputSchema: objectSchema({
|
|
308
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
309
|
+
file: requiredStringProp("Workspace-relative source file path."),
|
|
310
|
+
}, ["file"]),
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: "revela_record_material_review",
|
|
314
|
+
description: "Record that an LLM has read extracted local material and decided what was merged, deferred, ignored, or left as a gap.",
|
|
315
|
+
inputSchema: objectSchema({
|
|
316
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
317
|
+
sourcePath: requiredStringProp("Workspace-relative source file path."),
|
|
318
|
+
reviewedPaths: arrayProp("Workspace-relative extracted paths actually reviewed."),
|
|
319
|
+
reviewSummary: requiredStringProp("Concise summary of the reviewed material."),
|
|
320
|
+
narrativeDecisions: arrayObjectProp("Narrative decisions with kind, optional target, and rationale."),
|
|
321
|
+
}, ["sourcePath", "reviewedPaths", "reviewSummary", "narrativeDecisions"]),
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
name: "revela_check_material_intake",
|
|
325
|
+
description: "Check whether scanned Office/PDF sources were extracted and reviewed before being treated as narrative intake.",
|
|
326
|
+
inputSchema: objectSchema({
|
|
327
|
+
workspaceRoot: stringProp("Optional workspace root."),
|
|
328
|
+
strictness: enumProp(["authoring", "readiness", "render"], "Check strictness."),
|
|
329
|
+
}),
|
|
330
|
+
},
|
|
212
331
|
]
|
|
213
332
|
|
|
214
333
|
let runtimePromise: Promise<RuntimeModule> | undefined
|
|
@@ -278,9 +397,17 @@ async function callTool(name: string, args: any): Promise<any> {
|
|
|
278
397
|
if (name === "revela_design_activate") return r.designActivate(args)
|
|
279
398
|
if (name === "revela_design_create") return r.designCreate(args)
|
|
280
399
|
if (name === "revela_design_validate") return r.designValidate(args)
|
|
400
|
+
if (name === "revela_design_draft_create") return r.designDraftCreate(args)
|
|
401
|
+
if (name === "revela_design_draft_validate") return r.designDraftValidate(args)
|
|
402
|
+
if (name === "revela_design_draft_install") return r.designDraftInstall(args)
|
|
281
403
|
if (name === "revela_domain_list") return r.domainList()
|
|
282
404
|
if (name === "revela_domain_read") return r.domainRead(args)
|
|
283
405
|
if (name === "revela_domain_activate") return r.domainActivate(args)
|
|
406
|
+
if (name === "revela_domain_create") return r.domainCreate(args)
|
|
407
|
+
if (name === "revela_domain_validate") return r.domainValidate(args)
|
|
408
|
+
if (name === "revela_domain_draft_create") return r.domainDraftCreate(args)
|
|
409
|
+
if (name === "revela_domain_draft_validate") return r.domainDraftValidate(args)
|
|
410
|
+
if (name === "revela_domain_draft_install") return r.domainDraftInstall(args)
|
|
284
411
|
if (name === "revela_story_read") return r.storyRead(args)
|
|
285
412
|
if (name === "revela_review_deck_read") return r.reviewDeckRead(args)
|
|
286
413
|
if (name === "revela_review_deck_open") return r.reviewDeckOpen(args)
|
|
@@ -288,6 +415,10 @@ async function callTool(name: string, args: any): Promise<any> {
|
|
|
288
415
|
if (name === "revela_research_save") return r.researchSave(args)
|
|
289
416
|
if (name === "revela_evaluate_research_findings") return r.evaluateResearchFindings(args)
|
|
290
417
|
if (name === "revela_bind_research_findings") return r.bindResearchFindings(args)
|
|
418
|
+
if (name === "revela_prepare_local_materials") return r.prepareLocalMaterials(args)
|
|
419
|
+
if (name === "revela_extract_document_materials") return r.extractMaterial(args)
|
|
420
|
+
if (name === "revela_record_material_review") return r.recordMaterialReview(args)
|
|
421
|
+
if (name === "revela_check_material_intake") return r.checkMaterialIntake(args)
|
|
291
422
|
throw new Error(`Unknown tool: ${name}`)
|
|
292
423
|
}
|
|
293
424
|
|
|
@@ -315,6 +446,10 @@ function booleanProp(description: string) {
|
|
|
315
446
|
return { type: "boolean", description }
|
|
316
447
|
}
|
|
317
448
|
|
|
449
|
+
function numberProp(description: string) {
|
|
450
|
+
return { type: "number", description }
|
|
451
|
+
}
|
|
452
|
+
|
|
318
453
|
function enumProp(values: string[], description: string) {
|
|
319
454
|
return { type: "string", enum: values, description }
|
|
320
455
|
}
|
|
@@ -323,6 +458,23 @@ function arrayProp(description: string) {
|
|
|
323
458
|
return { type: "array", items: { type: "string" }, description }
|
|
324
459
|
}
|
|
325
460
|
|
|
461
|
+
function arrayObjectProp(description: string) {
|
|
462
|
+
return {
|
|
463
|
+
type: "array",
|
|
464
|
+
description,
|
|
465
|
+
items: {
|
|
466
|
+
type: "object",
|
|
467
|
+
properties: {
|
|
468
|
+
kind: { type: "string", enum: ["merged", "gap", "ignored", "deferred"] },
|
|
469
|
+
target: { type: "string" },
|
|
470
|
+
rationale: { type: "string" },
|
|
471
|
+
},
|
|
472
|
+
required: ["kind", "rationale"],
|
|
473
|
+
additionalProperties: false,
|
|
474
|
+
},
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
326
478
|
function writeMessage(message: any, mode: MessageMode = activeResponseMode): void {
|
|
327
479
|
activeResponseMode = mode
|
|
328
480
|
const body = JSON.stringify(message)
|
|
@@ -25,10 +25,12 @@ Design changes are visual/artifact-level unless they change claim meaning, evide
|
|
|
25
25
|
|
|
26
26
|
When the user asks to create a new design, use `starter` as the default base design unless they specify another base. Interview the user before saving anything: collect visual references such as images, webpages, brands, decks, or text descriptions, plus must-have and must-avoid constraints. Summarize the design brief and visual schema, then wait for the user to confirm before creating files.
|
|
27
27
|
|
|
28
|
-
After confirmation, read the base design with `revela_design_read`. Generate complete `DESIGN.md` and complete `preview.html` content, then call `
|
|
28
|
+
After confirmation, read the base design with `revela_design_read`. Generate complete `DESIGN.md` and complete `preview.html` content, then call `revela_design_draft_create` to save a workspace-local draft under `.revela/drafts/designs/<name>/`. Always call `revela_design_draft_validate` after draft creation or overwrite. The direct registry tools `revela_design_create` and `revela_design_validate` remain available for existing workflows, but Codex design authoring should use the draft workflow before install.
|
|
29
|
+
|
|
30
|
+
Install the draft globally only after the user confirms the validated draft should be installed. Call `revela_design_draft_install` to copy the draft into the user-level design registry. If a user-level design already exists, pass `overwrite: true` only after the user confirms replacement. In sandboxed Codex sessions, the install step may require permission to write Revela user config under `~/.config/revela`.
|
|
29
31
|
|
|
30
32
|
`DESIGN.md` must include frontmatter with `name`, `description`, `author`, and `version`, plus valid marker blocks for `@design:foundation`, `@design:rules`, at least one `@layout`, and at least one `@component`.
|
|
31
33
|
|
|
32
34
|
`preview.html` must be self-contained and directly openable in a browser. Every `<section class="slide">` must include `slide-qa` and exactly one direct `.slide-canvas` child. Every direct `.slide-canvas` is the fixed 1920px x 1080px export surface and must use explicit CSS with `width: 1920px` and `height: 1080px`; `.slide` may remain a viewport/navigation wrapper. Include a cover slide with `data-slide-role="cover"`, a closing slide with `data-slide-role="closing"`, and a visible sample for every `@component:*` using `data-preview-component="<component-name>"`.
|
|
33
35
|
|
|
34
|
-
Do not automatically activate a newly created design. Report the
|
|
36
|
+
Do not automatically activate a newly created design. Do not automatically activate a newly installed design. Report the draft path, installed path when installed, and tell the user they can activate it with `revela_design_activate`.
|
|
@@ -5,7 +5,7 @@ description: Use or switch Revela narrative domain guidance in Codex for init, r
|
|
|
5
5
|
|
|
6
6
|
# Revela Domain
|
|
7
7
|
|
|
8
|
-
Use this skill when the user asks about Revela domains, wants domain-specific narrative guidance,
|
|
8
|
+
Use this skill when the user asks about Revela domains, wants domain-specific narrative guidance, asks to switch the active domain, or asks to create a new domain.
|
|
9
9
|
|
|
10
10
|
## Workflow
|
|
11
11
|
|
|
@@ -16,3 +16,15 @@ Use this skill when the user asks about Revela domains, wants domain-specific na
|
|
|
16
16
|
5. Do not treat domain guidance as evidence, source material, or proof for factual claims.
|
|
17
17
|
|
|
18
18
|
Domain changes are narrative-framing preferences. They do not rewrite existing claims, evidence boundaries, artifacts, or deck plans unless the user asks for those updates.
|
|
19
|
+
|
|
20
|
+
## Creating Or Editing Domains
|
|
21
|
+
|
|
22
|
+
When the user asks to create a new domain, interview the user before saving anything. Collect the communication context, typical audience, decisions, claim patterns, evidence expectations, common objections, risks, research-gap heuristics, terminology to use, and terminology to avoid. Summarize the domain brief, then wait for the user to confirm before creating files.
|
|
23
|
+
|
|
24
|
+
After confirmation, generate complete `INDUSTRY.md` content and call `revela_domain_draft_create` to save a workspace-local draft under `.revela/drafts/domains/<name>/`. Always call `revela_domain_draft_validate` after draft creation or overwrite.
|
|
25
|
+
|
|
26
|
+
Install the draft globally only after the user confirms the validated draft should be installed. Call `revela_domain_draft_install` to copy the draft into the user-level domain registry. If a user-level domain already exists, pass `overwrite: true` only after the user confirms replacement. In sandboxed Codex sessions, the install step may require permission to write Revela user config under `~/.config/revela`.
|
|
27
|
+
|
|
28
|
+
`INDUSTRY.md` must include frontmatter with `name`, `description`, `author`, and `version`, followed by concrete narrative guidance for audience framing, decision framing, claim standards, evidence expectations, objection/risk handling, and research-gap interpretation.
|
|
29
|
+
|
|
30
|
+
Do not automatically activate a newly installed domain. Report the draft path, installed path when installed, and tell the user they can activate it with `revela_domain_activate`.
|
|
@@ -18,14 +18,24 @@ Use this skill when the user asks to start Revela, initialize the workspace, ing
|
|
|
18
18
|
|
|
19
19
|
## Workflow
|
|
20
20
|
|
|
21
|
-
1.
|
|
22
|
-
2.
|
|
23
|
-
3.
|
|
24
|
-
4.
|
|
25
|
-
5.
|
|
26
|
-
6.
|
|
27
|
-
7.
|
|
28
|
-
8.
|
|
21
|
+
1. Call `revela_prepare_local_materials` first. Treat scan results as an intake registry and task list, not as source content.
|
|
22
|
+
2. For any registry entry with `requiresExtraction: true`, do not read the original Office/PDF file directly for narrative intake. Use the returned `allowedReadPath` / `read_view_path`; if missing, call `revela_extract_document_materials` first.
|
|
23
|
+
3. Prefer local source materials first: Markdown, text, CSV, PDFs, Office files, existing `researches/`, existing `revela-narrative/`, `deck-plan/`, and `decks/`.
|
|
24
|
+
4. After reading extracted material views, call `revela_record_material_review` for each considered Office/PDF source. Record what was merged, deferred, ignored, or left as a gap.
|
|
25
|
+
5. Call `revela_domain_list` and `revela_domain_read` for active domain guidance before authoring narrative meaning. Treat domain guidance as framing guidance, never as evidence.
|
|
26
|
+
6. If `revela-narrative/` exists, call `revela_markdown_qa` and `revela_compile_narrative`.
|
|
27
|
+
7. If the narrative vault is missing, create the initial `revela-narrative/` Markdown nodes directly with valid frontmatter and plain wikilink relations.
|
|
28
|
+
8. Evidence nodes must preserve source, quote/snippet, support scope, unsupported scope, caveat, and strength before being treated as support.
|
|
29
|
+
9. After writing narrative Markdown, call `revela_markdown_qa` and `revela_compile_narrative` again.
|
|
30
|
+
10. Before the final report, call `revela_check_material_intake` and surface any warnings about scanned-but-unextracted, extracted-but-unreviewed, unsupported, failed, or text-only sources.
|
|
31
|
+
11. End with a concise init report: local materials found, active domain, narrative graph status, material intake status, open gaps, Markdown QA status, and next command/action.
|
|
32
|
+
|
|
33
|
+
## Material Intake Rules
|
|
34
|
+
|
|
35
|
+
- Scan results only prove that files exist; they do not prove file content.
|
|
36
|
+
- For `.docx`, `.pptx`, `.xlsx`, and `.pdf`, read the extracted `read_view_path` instead of using Codex/textutil/raw reads of the original file.
|
|
37
|
+
- Extracted images are candidate materials only. Do not interpret them as evidence unless image meaning is explicitly reviewed or supplied by the user.
|
|
38
|
+
- If a user explicitly asks for text-only inspection, report it as degraded intake and do not treat it as complete source review.
|
|
29
39
|
|
|
30
40
|
## Markdown Rules
|
|
31
41
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: revela-upgrade
|
|
3
|
+
description: Guide Revela Codex plugin upgrade, update, version, and reinstall requests while checking the running runtime version first.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Revela Upgrade
|
|
7
|
+
|
|
8
|
+
Use this skill when the user asks how to upgrade, update, reinstall, or check the version of the Revela Codex plugin.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Call `revela_doctor` first to inspect the currently running Revela runtime version.
|
|
13
|
+
2. Report the current runtime version from doctor output. Do not check the latest version online unless the user explicitly asks you to look it up.
|
|
14
|
+
3. Explain that the Codex Git marketplace ref and `.mcp.json` npm runtime pin are published together for the same Revela release.
|
|
15
|
+
4. If the user wants a fixed release, guide them through removing the installed plugin, removing the marketplace entry, adding the desired release tag, then adding the plugin again:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
codex plugin remove revela@revela
|
|
19
|
+
codex plugin marketplace remove revela
|
|
20
|
+
codex plugin marketplace add https://github.com/cyber-dash-tech/revela --ref vX.Y.Z
|
|
21
|
+
codex plugin add revela@revela
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
5. If the user already tracks a branch or movable ref, guide them through upgrading the marketplace clone, then re-adding the plugin:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
codex plugin marketplace upgrade revela
|
|
28
|
+
codex plugin add revela@revela
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
6. Tell the user to start a new Codex thread after upgrading so Codex reloads the Revela skills, MCP tools, hooks, and runtime pin.
|
|
32
|
+
|
|
33
|
+
Do not run `codex plugin remove`, `codex plugin marketplace remove`, `codex plugin marketplace add`, `codex plugin marketplace upgrade`, or `codex plugin add` unless the user explicitly asks you to perform the upgrade or reinstall.
|