@xenonbyte/da-vinci-workflow 0.2.2 → 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 +15 -0
- package/README.md +24 -14
- package/README.zh-CN.md +25 -14
- 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 +43 -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-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 +45 -38
- package/docs/workflow-examples.md +16 -13
- package/docs/workflow-overview.md +2 -0
- package/docs/zh-CN/dv-command-reference.md +43 -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-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 +45 -38
- package/docs/zh-CN/workflow-examples.md +15 -13
- package/docs/zh-CN/workflow-overview.md +2 -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 +50 -1
- 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 +1 -1
- package/tui/catalog.js +103 -0
- package/tui/index.js +2274 -418
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
package/tui/catalog.js
CHANGED
|
@@ -80,6 +80,86 @@ const STAGES = [
|
|
|
80
80
|
}
|
|
81
81
|
];
|
|
82
82
|
|
|
83
|
+
const SCENES = [
|
|
84
|
+
{
|
|
85
|
+
id: "install-uninstall",
|
|
86
|
+
title: {
|
|
87
|
+
en: "Install & Uninstall",
|
|
88
|
+
zh: "安装与卸载"
|
|
89
|
+
},
|
|
90
|
+
summary: {
|
|
91
|
+
en: "Choose install or uninstall and run it against all supported platforms.",
|
|
92
|
+
zh: "选择安装或卸载,并直接对所有支持平台执行。"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: "current-status",
|
|
97
|
+
title: {
|
|
98
|
+
en: "Current Status",
|
|
99
|
+
zh: "当前状态"
|
|
100
|
+
},
|
|
101
|
+
summary: {
|
|
102
|
+
en: "Run workflow-status plus next-step, then show the current workflow summary and recommended next move.",
|
|
103
|
+
zh: "执行 workflow-status 与 next-step,并汇总当前工作流状态和建议下一步。"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: "switch-work-item",
|
|
108
|
+
title: {
|
|
109
|
+
en: "Switch Work Item",
|
|
110
|
+
zh: "切换工作项"
|
|
111
|
+
},
|
|
112
|
+
summary: {
|
|
113
|
+
en: "Choose the active change from existing work items in this project.",
|
|
114
|
+
zh: "从当前项目已有的工作项目中选择正在处理的 change。"
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: "design-work",
|
|
119
|
+
title: {
|
|
120
|
+
en: "Design Ops",
|
|
121
|
+
zh: "设计操作"
|
|
122
|
+
},
|
|
123
|
+
summary: {
|
|
124
|
+
en: "Run design-save, icon sync, and managed Visual Assist generation.",
|
|
125
|
+
zh: "执行设计保存、图标同步和受控 Visual Assist 生成。"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: "pre-implementation-checks",
|
|
130
|
+
title: {
|
|
131
|
+
en: "Pre-Implementation Checks",
|
|
132
|
+
zh: "实施前检查"
|
|
133
|
+
},
|
|
134
|
+
summary: {
|
|
135
|
+
en: "Run planning and readiness checks before writing implementation code.",
|
|
136
|
+
zh: "在开始实现代码前执行规划与就绪度检查。"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: "pre-completion-validation",
|
|
141
|
+
title: {
|
|
142
|
+
en: "Pre-Acceptance Checks",
|
|
143
|
+
zh: "验收前检查"
|
|
144
|
+
},
|
|
145
|
+
summary: {
|
|
146
|
+
en: "Run the pre-acceptance verify chain before completion claims.",
|
|
147
|
+
zh: "在完成声明前运行验收前 verify 链路。"
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "more",
|
|
152
|
+
title: {
|
|
153
|
+
en: "Settings",
|
|
154
|
+
zh: "设置"
|
|
155
|
+
},
|
|
156
|
+
summary: {
|
|
157
|
+
en: "Language and logs.",
|
|
158
|
+
zh: "语言与日志。"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
];
|
|
162
|
+
|
|
83
163
|
function normalizeLanguage(value) {
|
|
84
164
|
return value === "zh" ? "zh" : "en";
|
|
85
165
|
}
|
|
@@ -765,6 +845,28 @@ const COMMANDS = [
|
|
|
765
845
|
return args;
|
|
766
846
|
}
|
|
767
847
|
}),
|
|
848
|
+
createCommand({
|
|
849
|
+
id: "save-current-design",
|
|
850
|
+
stageId: "pencil",
|
|
851
|
+
title: { en: "save-current-design", zh: "save-current-design" },
|
|
852
|
+
summary: {
|
|
853
|
+
en: "Run the high-level bound-source save flow for the active Pencil design session.",
|
|
854
|
+
zh: "运行高层绑定源保存流程,保存当前活跃 Pencil 设计会话。"
|
|
855
|
+
},
|
|
856
|
+
details: {
|
|
857
|
+
en: "This flow validates registered/session/editor convergence and reports saved, blocked, or unavailable honestly.",
|
|
858
|
+
zh: "该流程会校验 registered/session/editor 三方收敛,并明确返回 saved、blocked 或 unavailable。"
|
|
859
|
+
},
|
|
860
|
+
supportsJson: true,
|
|
861
|
+
supportsContinueOnError: true,
|
|
862
|
+
buildArgs(context) {
|
|
863
|
+
const args = ["save-current-design"];
|
|
864
|
+
maybeProject(args, context, { force: true });
|
|
865
|
+
maybeJson(args, context, true);
|
|
866
|
+
maybeContinueOnError(args, context, true);
|
|
867
|
+
return args;
|
|
868
|
+
}
|
|
869
|
+
}),
|
|
768
870
|
createCommand({
|
|
769
871
|
id: "pencil-session-end",
|
|
770
872
|
stageId: "pencil",
|
|
@@ -1175,6 +1277,7 @@ function tokenizeCommandLine(input) {
|
|
|
1175
1277
|
}
|
|
1176
1278
|
|
|
1177
1279
|
module.exports = {
|
|
1280
|
+
SCENES,
|
|
1178
1281
|
STAGES,
|
|
1179
1282
|
COMMANDS,
|
|
1180
1283
|
buildCommandArgs,
|