@xenonbyte/da-vinci-workflow 0.2.1 → 0.2.3
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/CHANGELOG.md +32 -0
- package/README.md +33 -12
- package/README.zh-CN.md +34 -12
- package/bin/da-vinci-tui.js +8 -0
- package/commands/claude/dv/breakdown.md +8 -0
- package/commands/claude/dv/build.md +11 -0
- package/commands/claude/dv/design.md +5 -2
- package/commands/claude/dv/tasks.md +8 -0
- package/commands/claude/dv/verify.md +9 -0
- package/commands/codex/prompts/dv-breakdown.md +8 -0
- package/commands/codex/prompts/dv-build.md +11 -0
- package/commands/codex/prompts/dv-design.md +5 -2
- package/commands/codex/prompts/dv-tasks.md +8 -0
- package/commands/codex/prompts/dv-verify.md +8 -0
- package/commands/gemini/dv/breakdown.toml +8 -0
- package/commands/gemini/dv/build.toml +11 -0
- package/commands/gemini/dv/design.toml +5 -2
- package/commands/gemini/dv/tasks.toml +8 -0
- package/commands/gemini/dv/verify.toml +8 -0
- package/docs/dv-command-reference.md +47 -0
- package/docs/execution-chain-plan.md +10 -3
- package/docs/mode-use-cases.md +2 -1
- package/docs/pencil-rendering-workflow.md +15 -12
- package/docs/prompt-entrypoints.md +2 -0
- package/docs/prompt-presets/README.md +1 -1
- package/docs/prompt-presets/desktop-app.md +3 -3
- package/docs/prompt-presets/mobile-app.md +3 -3
- package/docs/prompt-presets/tablet-app.md +3 -3
- package/docs/prompt-presets/web-app.md +3 -3
- package/docs/skill-usage.md +224 -0
- package/docs/workflow-examples.md +16 -13
- package/docs/workflow-overview.md +3 -0
- package/docs/zh-CN/dv-command-reference.md +47 -0
- package/docs/zh-CN/mode-use-cases.md +2 -1
- package/docs/zh-CN/pencil-rendering-workflow.md +15 -12
- package/docs/zh-CN/prompt-entrypoints.md +2 -0
- package/docs/zh-CN/prompt-presets/README.md +1 -1
- package/docs/zh-CN/prompt-presets/desktop-app.md +3 -3
- package/docs/zh-CN/prompt-presets/mobile-app.md +3 -3
- package/docs/zh-CN/prompt-presets/tablet-app.md +3 -3
- package/docs/zh-CN/prompt-presets/web-app.md +3 -3
- package/docs/zh-CN/skill-usage.md +224 -0
- package/docs/zh-CN/workflow-examples.md +15 -13
- package/docs/zh-CN/workflow-overview.md +3 -0
- package/examples/greenfield-spec-markupflow/.da-vinci/state/execution-signals/demo__lint-tasks.json +16 -0
- package/lib/audit-parsers.js +18 -9
- package/lib/audit.js +3 -26
- package/lib/cli.js +72 -0
- package/lib/design-source-registry.js +146 -0
- package/lib/save-current-design.js +790 -0
- package/lib/supervisor-review.js +1 -1
- package/lib/workflow-bootstrap.js +2 -13
- package/lib/workflow-persisted-state.js +3 -1
- package/lib/workflow-state.js +51 -3
- package/package.json +4 -2
- package/tui/catalog.js +1293 -0
- package/tui/index.js +2583 -0
package/lib/supervisor-review.js
CHANGED
|
@@ -416,7 +416,7 @@ function extractMcpRuntimeGateStatus(markdownText) {
|
|
|
416
416
|
}
|
|
417
417
|
|
|
418
418
|
const statusMatch = String(section).match(
|
|
419
|
-
/(?:^|\n)\s*-\s*(?:Status|状态)\s*:\s*`?(PASS|WARN|BLOCK)`?\b/i
|
|
419
|
+
/(?:^|\n)\s*-\s*(?:Final runtime gate status|Status|状态)\s*:\s*`?(PASS|WARN|BLOCK)`?\b/i
|
|
420
420
|
);
|
|
421
421
|
return statusMatch ? String(statusMatch[1]).toUpperCase() : "";
|
|
422
422
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
|
|
4
|
-
const { isPathInside } = require("./fs-safety");
|
|
5
4
|
const { ensurePenFile } = require("./pen-persistence");
|
|
5
|
+
const { resolvePreferredRegisteredPenPath } = require("./design-source-registry");
|
|
6
6
|
const { pathExists, readTextIfExists, writeFileAtomic } = require("./utils");
|
|
7
7
|
|
|
8
8
|
const DEFAULT_PROJECT_PEN_RELATIVE_PATH = ".da-vinci/designs/project-baseline.pen";
|
|
@@ -20,17 +20,6 @@ function validateChangeId(changeId) {
|
|
|
20
20
|
return normalized;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function extractRegisteredPenPath(projectRoot, registryText) {
|
|
24
|
-
const matches = String(registryText || "").match(/\.da-vinci\/designs\/[^\s`]+\.pen/g) || [];
|
|
25
|
-
for (const relativePath of matches) {
|
|
26
|
-
const resolvedPath = path.resolve(projectRoot, relativePath);
|
|
27
|
-
if (isPathInside(projectRoot, resolvedPath)) {
|
|
28
|
-
return resolvedPath;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return "";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
23
|
function buildProjectTemplates(preferredPenRelativePath) {
|
|
35
24
|
return {
|
|
36
25
|
"DA-VINCI.md": [
|
|
@@ -151,7 +140,7 @@ function bootstrapProjectArtifacts(projectPathInput, options = {}) {
|
|
|
151
140
|
fs.mkdirSync(path.join(projectRoot, ".da-vinci", "changes"), { recursive: true });
|
|
152
141
|
|
|
153
142
|
const existingRegistryText = readTextIfExists(path.join(projectRoot, ".da-vinci", "design-registry.md"));
|
|
154
|
-
const registeredPenPath =
|
|
143
|
+
const registeredPenPath = resolvePreferredRegisteredPenPath(projectRoot, existingRegistryText);
|
|
155
144
|
const preferredPenPath = registeredPenPath || path.join(projectRoot, DEFAULT_PROJECT_PEN_RELATIVE_PATH);
|
|
156
145
|
const preferredPenRelativePath = path.relative(projectRoot, preferredPenPath) || DEFAULT_PROJECT_PEN_RELATIVE_PATH;
|
|
157
146
|
|
|
@@ -2,7 +2,7 @@ const fs = require("fs");
|
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const { writeFileAtomic, pathExists, readTextIfExists } = require("./utils");
|
|
4
4
|
|
|
5
|
-
const WORKFLOW_STATE_VERSION =
|
|
5
|
+
const WORKFLOW_STATE_VERSION = 2;
|
|
6
6
|
const DEFAULT_STALE_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
7
7
|
const PERSISTED_NOTE_EXCLUDE_PATTERNS = [
|
|
8
8
|
/^No persisted workflow state found for this change; deriving from artifacts\.$/i,
|
|
@@ -38,7 +38,9 @@ function fingerprintForPath(targetPath) {
|
|
|
38
38
|
function buildWorkflowFingerprint(projectRoot, changeId) {
|
|
39
39
|
const changeRoot = changeId ? path.join(projectRoot, ".da-vinci", "changes", changeId) : "";
|
|
40
40
|
const candidates = [
|
|
41
|
+
path.join(projectRoot, "DA-VINCI.md"),
|
|
41
42
|
path.join(projectRoot, ".da-vinci", "page-map.md"),
|
|
43
|
+
path.join(projectRoot, ".da-vinci", "design-registry.md"),
|
|
42
44
|
path.join(changeRoot, "proposal.md"),
|
|
43
45
|
path.join(changeRoot, "design.md"),
|
|
44
46
|
path.join(changeRoot, "pencil-design.md"),
|
package/lib/workflow-state.js
CHANGED
|
@@ -13,7 +13,8 @@ const {
|
|
|
13
13
|
STATUS,
|
|
14
14
|
CHECKPOINT_LABELS,
|
|
15
15
|
HANDOFF_GATES,
|
|
16
|
-
getStageById
|
|
16
|
+
getStageById,
|
|
17
|
+
mergeStatuses
|
|
17
18
|
} = require("./workflow-contract");
|
|
18
19
|
const {
|
|
19
20
|
selectPersistedStateForChange,
|
|
@@ -49,6 +50,14 @@ function dedupeFindings(findings) {
|
|
|
49
50
|
findings.notes = dedupeMessages(findings.notes);
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
function normalizeCheckpointStatus(status) {
|
|
54
|
+
const normalized = String(status || "").toUpperCase();
|
|
55
|
+
if (normalized === STATUS.PASS || normalized === STATUS.WARN || normalized === STATUS.BLOCK) {
|
|
56
|
+
return normalized;
|
|
57
|
+
}
|
|
58
|
+
return STATUS.PASS;
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
function collectIntegrityAudit(projectRoot, workflowRoot, signalSummary) {
|
|
53
62
|
if (!pathExists(workflowRoot)) {
|
|
54
63
|
return null;
|
|
@@ -266,6 +275,24 @@ function deriveStageFromArtifacts(artifactState, checkpointStatuses, findings) {
|
|
|
266
275
|
findings.warnings.push("`design checkpoint` is WARN.");
|
|
267
276
|
}
|
|
268
277
|
|
|
278
|
+
const designSourceCheckpoint = checkpointStatuses[CHECKPOINT_LABELS.DESIGN_SOURCE];
|
|
279
|
+
if (designSourceCheckpoint === STATUS.BLOCK) {
|
|
280
|
+
findings.blockers.push("`design source checkpoint` is BLOCK.");
|
|
281
|
+
return "design";
|
|
282
|
+
}
|
|
283
|
+
if (designSourceCheckpoint === STATUS.WARN) {
|
|
284
|
+
findings.warnings.push("`design source checkpoint` is WARN.");
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const runtimeGateCheckpoint = checkpointStatuses[CHECKPOINT_LABELS.RUNTIME_GATE];
|
|
288
|
+
if (runtimeGateCheckpoint === STATUS.BLOCK) {
|
|
289
|
+
findings.blockers.push("`mcp runtime gate` is BLOCK.");
|
|
290
|
+
return "design";
|
|
291
|
+
}
|
|
292
|
+
if (runtimeGateCheckpoint === STATUS.WARN) {
|
|
293
|
+
findings.warnings.push("`mcp runtime gate` is WARN.");
|
|
294
|
+
}
|
|
295
|
+
|
|
269
296
|
const mappingCheckpoint = checkpointStatuses[CHECKPOINT_LABELS.MAPPING];
|
|
270
297
|
if (mappingCheckpoint === STATUS.BLOCK) {
|
|
271
298
|
findings.blockers.push("`mapping checkpoint` is BLOCK.");
|
|
@@ -482,6 +509,15 @@ function deriveWorkflowStatus(projectPathInput, options = {}) {
|
|
|
482
509
|
)
|
|
483
510
|
: {};
|
|
484
511
|
const integrityAudit = collectIntegrityAudit(projectRoot, workflowRoot, signalSummary);
|
|
512
|
+
const designCheckpointStatus = normalizeCheckpointStatus(checkpointStatuses[CHECKPOINT_LABELS.DESIGN]);
|
|
513
|
+
const designSourceCheckpointStatus = normalizeCheckpointStatus(
|
|
514
|
+
checkpointStatuses[CHECKPOINT_LABELS.DESIGN_SOURCE]
|
|
515
|
+
);
|
|
516
|
+
const runtimeGateCheckpointStatus = normalizeCheckpointStatus(
|
|
517
|
+
checkpointStatuses[CHECKPOINT_LABELS.RUNTIME_GATE]
|
|
518
|
+
);
|
|
519
|
+
const mappingCheckpointStatus = normalizeCheckpointStatus(checkpointStatuses[CHECKPOINT_LABELS.MAPPING]);
|
|
520
|
+
const taskCheckpointStatus = normalizeCheckpointStatus(checkpointStatuses[CHECKPOINT_LABELS.TASK]);
|
|
485
521
|
|
|
486
522
|
if (activeChangeId) {
|
|
487
523
|
const persistedSelection = selectPersistedStateForChange(projectRoot, activeChangeId, {
|
|
@@ -579,11 +615,23 @@ function deriveWorkflowStatus(projectPathInput, options = {}) {
|
|
|
579
615
|
const gates = {
|
|
580
616
|
[HANDOFF_GATES.BREAKDOWN_TO_DESIGN]:
|
|
581
617
|
artifactState.proposal && artifactState.specFiles.length > 0 ? STATUS.PASS : STATUS.BLOCK,
|
|
582
|
-
[HANDOFF_GATES.DESIGN_TO_TASKS]:
|
|
618
|
+
[HANDOFF_GATES.DESIGN_TO_TASKS]: mergeStatuses([
|
|
583
619
|
artifactState.design && artifactState.pencilDesign && artifactState.pencilBindings
|
|
584
620
|
? STATUS.PASS
|
|
585
621
|
: STATUS.BLOCK,
|
|
586
|
-
|
|
622
|
+
designCheckpointStatus,
|
|
623
|
+
designSourceCheckpointStatus,
|
|
624
|
+
runtimeGateCheckpointStatus,
|
|
625
|
+
mappingCheckpointStatus
|
|
626
|
+
]),
|
|
627
|
+
[HANDOFF_GATES.TASKS_TO_BUILD]: mergeStatuses([
|
|
628
|
+
artifactState.tasks ? STATUS.PASS : STATUS.BLOCK,
|
|
629
|
+
designCheckpointStatus,
|
|
630
|
+
designSourceCheckpointStatus,
|
|
631
|
+
runtimeGateCheckpointStatus,
|
|
632
|
+
mappingCheckpointStatus,
|
|
633
|
+
taskCheckpointStatus
|
|
634
|
+
]),
|
|
587
635
|
[HANDOFF_GATES.BUILD_TO_VERIFY]: artifactState.verification ? STATUS.PASS : STATUS.BLOCK,
|
|
588
636
|
[HANDOFF_GATES.VERIFY_TO_COMPLETE]:
|
|
589
637
|
completionAudit && completionAudit.status === "PASS" ? STATUS.PASS : STATUS.WARN
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenonbyte/da-vinci-workflow",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Requirement-to-design-to-code workflow skill for Codex, Claude, and Gemini",
|
|
5
5
|
"bin": {
|
|
6
6
|
"da-vinci": "bin/da-vinci.js",
|
|
7
|
-
"design-supervisor": "bin/design-supervisor.js"
|
|
7
|
+
"design-supervisor": "bin/design-supervisor.js",
|
|
8
|
+
"da-vinci-tui": "bin/da-vinci-tui.js"
|
|
8
9
|
},
|
|
9
10
|
"files": [
|
|
10
11
|
"SKILL.md",
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
"examples",
|
|
19
20
|
"bin",
|
|
20
21
|
"lib",
|
|
22
|
+
"tui",
|
|
21
23
|
"scripts/postinstall.js",
|
|
22
24
|
"scripts/validate-assets.js"
|
|
23
25
|
],
|