@xenonbyte/da-vinci-workflow 0.2.2 → 0.2.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +49 -14
  3. package/README.zh-CN.md +169 -14
  4. package/commands/claude/dv/breakdown.md +8 -0
  5. package/commands/claude/dv/build.md +16 -0
  6. package/commands/claude/dv/continue.md +4 -0
  7. package/commands/claude/dv/design.md +5 -2
  8. package/commands/claude/dv/tasks.md +14 -0
  9. package/commands/claude/dv/verify.md +11 -0
  10. package/commands/codex/prompts/dv-breakdown.md +8 -0
  11. package/commands/codex/prompts/dv-build.md +16 -0
  12. package/commands/codex/prompts/dv-continue.md +4 -0
  13. package/commands/codex/prompts/dv-design.md +5 -2
  14. package/commands/codex/prompts/dv-tasks.md +14 -0
  15. package/commands/codex/prompts/dv-verify.md +10 -0
  16. package/commands/gemini/dv/breakdown.toml +8 -0
  17. package/commands/gemini/dv/build.toml +16 -0
  18. package/commands/gemini/dv/continue.toml +4 -0
  19. package/commands/gemini/dv/design.toml +5 -2
  20. package/commands/gemini/dv/tasks.toml +14 -0
  21. package/commands/gemini/dv/verify.toml +10 -0
  22. package/commands/templates/dv-continue.shared.md +4 -0
  23. package/docs/discipline-and-orchestration-upgrade.md +83 -0
  24. package/docs/dv-command-reference.md +61 -2
  25. package/docs/execution-chain-migration.md +23 -0
  26. package/docs/execution-chain-plan.md +10 -3
  27. package/docs/mode-use-cases.md +2 -1
  28. package/docs/pencil-rendering-workflow.md +15 -12
  29. package/docs/prompt-entrypoints.md +5 -0
  30. package/docs/prompt-presets/README.md +1 -1
  31. package/docs/prompt-presets/desktop-app.md +3 -3
  32. package/docs/prompt-presets/mobile-app.md +3 -3
  33. package/docs/prompt-presets/tablet-app.md +3 -3
  34. package/docs/prompt-presets/web-app.md +3 -3
  35. package/docs/skill-usage.md +61 -38
  36. package/docs/workflow-examples.md +16 -13
  37. package/docs/workflow-overview.md +19 -0
  38. package/docs/zh-CN/dv-command-reference.md +59 -2
  39. package/docs/zh-CN/execution-chain-migration.md +23 -0
  40. package/docs/zh-CN/mode-use-cases.md +2 -1
  41. package/docs/zh-CN/pencil-rendering-workflow.md +15 -12
  42. package/docs/zh-CN/prompt-entrypoints.md +5 -0
  43. package/docs/zh-CN/prompt-presets/README.md +1 -1
  44. package/docs/zh-CN/prompt-presets/desktop-app.md +3 -3
  45. package/docs/zh-CN/prompt-presets/mobile-app.md +3 -3
  46. package/docs/zh-CN/prompt-presets/tablet-app.md +3 -3
  47. package/docs/zh-CN/prompt-presets/web-app.md +3 -3
  48. package/docs/zh-CN/skill-usage.md +61 -38
  49. package/docs/zh-CN/workflow-examples.md +15 -13
  50. package/docs/zh-CN/workflow-overview.md +19 -0
  51. package/examples/greenfield-spec-markupflow/.da-vinci/state/execution-signals/demo__lint-tasks.json +16 -0
  52. package/lib/audit-parsers.js +166 -10
  53. package/lib/audit.js +3 -26
  54. package/lib/cli.js +156 -2
  55. package/lib/design-source-registry.js +146 -0
  56. package/lib/execution-profile.js +143 -0
  57. package/lib/execution-signals.js +19 -1
  58. package/lib/lint-tasks.js +86 -2
  59. package/lib/planning-parsers.js +255 -18
  60. package/lib/save-current-design.js +790 -0
  61. package/lib/supervisor-review.js +3 -2
  62. package/lib/task-execution.js +160 -0
  63. package/lib/task-review.js +197 -0
  64. package/lib/verify.js +152 -1
  65. package/lib/workflow-bootstrap.js +2 -13
  66. package/lib/workflow-persisted-state.js +3 -1
  67. package/lib/workflow-state.js +503 -33
  68. package/lib/worktree-preflight.js +214 -0
  69. package/package.json +1 -1
  70. package/references/artifact-templates.md +56 -6
  71. package/tui/catalog.js +103 -0
  72. package/tui/index.js +2274 -418
@@ -0,0 +1,214 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { spawnSync } = require("child_process");
4
+ const { STATUS } = require("./workflow-contract");
5
+
6
+ function runGit(projectRoot, args) {
7
+ return spawnSync("git", args, {
8
+ cwd: projectRoot,
9
+ encoding: "utf8",
10
+ maxBuffer: 8 * 1024 * 1024
11
+ });
12
+ }
13
+
14
+ function checkIgnoredDirectory(projectRoot, directoryPath) {
15
+ const relativePath = path.relative(projectRoot, directoryPath) || path.basename(directoryPath);
16
+ const result = runGit(projectRoot, ["check-ignore", relativePath]);
17
+ if (result.error) {
18
+ return {
19
+ directory: directoryPath,
20
+ relativePath,
21
+ ignored: false,
22
+ error: `failed to execute git check-ignore: ${result.error.message || "unknown error"}`
23
+ };
24
+ }
25
+ if (result.status === 0) {
26
+ return {
27
+ directory: directoryPath,
28
+ relativePath,
29
+ ignored: true,
30
+ error: null
31
+ };
32
+ }
33
+ if (result.status === 1) {
34
+ return {
35
+ directory: directoryPath,
36
+ relativePath,
37
+ ignored: false,
38
+ error: null
39
+ };
40
+ }
41
+ const statusText = Number.isFinite(result.status) ? `exit ${result.status}` : "unknown status";
42
+ const stderr = String(result.stderr || "").trim();
43
+ return {
44
+ directory: directoryPath,
45
+ relativePath,
46
+ ignored: false,
47
+ error: `git check-ignore failed (${statusText})${stderr ? `: ${stderr}` : ""}`
48
+ };
49
+ }
50
+
51
+ function readPackageScripts(projectRoot) {
52
+ const packagePath = path.join(projectRoot, "package.json");
53
+ if (!fs.existsSync(packagePath)) {
54
+ return {};
55
+ }
56
+ try {
57
+ const payload = JSON.parse(fs.readFileSync(packagePath, "utf8"));
58
+ return payload && payload.scripts && typeof payload.scripts === "object" ? payload.scripts : {};
59
+ } catch (_error) {
60
+ return {};
61
+ }
62
+ }
63
+
64
+ function runWorktreePreflight(projectPathInput, options = {}) {
65
+ const projectRoot = path.resolve(projectPathInput || process.cwd());
66
+ const findings = {
67
+ failures: [],
68
+ warnings: [],
69
+ notes: []
70
+ };
71
+
72
+ const candidateDirs = [".worktrees", "worktrees"]
73
+ .map((name) => path.join(projectRoot, name))
74
+ .filter((candidate) => fs.existsSync(candidate));
75
+ const gitStatus = runGit(projectRoot, ["status", "--porcelain"]);
76
+ const gitStatusSummary = {
77
+ healthy: false,
78
+ exitCode: Number.isFinite(gitStatus.status) ? gitStatus.status : null,
79
+ message: ""
80
+ };
81
+ const dirtyEntries = [];
82
+ if (gitStatus.error) {
83
+ gitStatusSummary.message = `failed to execute git status: ${gitStatus.error.message || "unknown error"}`;
84
+ findings.warnings.push(
85
+ "Unable to execute `git status`; worktree-isolation preflight cannot be trusted in the current environment."
86
+ );
87
+ } else if (gitStatus.status !== 0) {
88
+ const stderr = String(gitStatus.stderr || "").trim();
89
+ gitStatusSummary.message = stderr || "git status returned non-zero exit";
90
+ if (/not a git repository/i.test(stderr)) {
91
+ findings.warnings.push(
92
+ "Current project is not a git repository; worktree-isolation preflight is advisory-only and recommends isolation."
93
+ );
94
+ } else {
95
+ findings.warnings.push(
96
+ `git status failed (${gitStatusSummary.exitCode !== null ? gitStatusSummary.exitCode : "unknown exit"}); worktree-isolation checks may be unreliable.`
97
+ );
98
+ }
99
+ } else {
100
+ gitStatusSummary.healthy = true;
101
+ const lines = String(gitStatus.stdout || "")
102
+ .split(/\r?\n/)
103
+ .map((line) => line.trim())
104
+ .filter(Boolean);
105
+ dirtyEntries.push(...lines);
106
+ }
107
+
108
+ const ignoreChecks = [];
109
+ if (candidateDirs.length > 0) {
110
+ if (!gitStatusSummary.healthy) {
111
+ findings.warnings.push(
112
+ "Skipped git-ignore safety checks for worktree directories because git status is unavailable."
113
+ );
114
+ } else {
115
+ for (const candidate of candidateDirs) {
116
+ const check = checkIgnoredDirectory(projectRoot, candidate);
117
+ ignoreChecks.push(check);
118
+ if (check.error) {
119
+ findings.warnings.push(
120
+ `Unable to verify git-ignore state for ${check.relativePath}: ${check.error}`
121
+ );
122
+ continue;
123
+ }
124
+ if (!check.ignored) {
125
+ findings.failures.push(
126
+ `Worktree directory ${check.relativePath} is not git-ignored; isolation setup is unsafe.`
127
+ );
128
+ } else {
129
+ findings.notes.push(`Worktree directory ${check.relativePath} is git-ignored.`);
130
+ }
131
+ }
132
+ }
133
+ }
134
+
135
+ if (dirtyEntries.length > 0) {
136
+ findings.warnings.push(
137
+ `Workspace is dirty (${dirtyEntries.length} change(s)); isolated execution is recommended before bounded parallel work.`
138
+ );
139
+ }
140
+
141
+ const scripts = readPackageScripts(projectRoot);
142
+ if (!scripts.test) {
143
+ findings.warnings.push("No `test` script found in package.json; baseline verification heuristics are weak.");
144
+ } else {
145
+ findings.notes.push("Detected package.json test script for baseline verification checks.");
146
+ }
147
+
148
+ if (candidateDirs.length === 0) {
149
+ findings.notes.push("No project-local worktree directory found (.worktrees/ or worktrees/).");
150
+ }
151
+
152
+ const status =
153
+ findings.failures.length > 0
154
+ ? STATUS.BLOCK
155
+ : findings.warnings.length > 0
156
+ ? STATUS.WARN
157
+ : STATUS.PASS;
158
+
159
+ const recommendedIsolation =
160
+ dirtyEntries.length > 0 ||
161
+ options.parallelPreferred === true ||
162
+ findings.failures.length > 0 ||
163
+ !gitStatusSummary.healthy;
164
+
165
+ return {
166
+ status,
167
+ advisory: true,
168
+ projectRoot,
169
+ failures: findings.failures,
170
+ warnings: findings.warnings,
171
+ notes: findings.notes,
172
+ summary: {
173
+ worktreeDirectories: candidateDirs.map((candidate) => path.relative(projectRoot, candidate)),
174
+ ignoreChecks,
175
+ dirtyEntries: dirtyEntries.length,
176
+ gitStatus: gitStatusSummary,
177
+ recommendedIsolation
178
+ }
179
+ };
180
+ }
181
+
182
+ function formatWorktreePreflightReport(result) {
183
+ const lines = [
184
+ "Worktree preflight",
185
+ `Project: ${result.projectRoot}`,
186
+ `Status: ${result.status}`,
187
+ `Advisory: ${result.advisory ? "yes" : "no"}`,
188
+ `Recommended isolation: ${result.summary.recommendedIsolation ? "yes" : "no"}`
189
+ ];
190
+ if (result.failures.length > 0) {
191
+ lines.push("Failures:");
192
+ for (const failure of result.failures) {
193
+ lines.push(`- ${failure}`);
194
+ }
195
+ }
196
+ if (result.warnings.length > 0) {
197
+ lines.push("Warnings:");
198
+ for (const warning of result.warnings) {
199
+ lines.push(`- ${warning}`);
200
+ }
201
+ }
202
+ if (result.notes.length > 0) {
203
+ lines.push("Notes:");
204
+ for (const note of result.notes) {
205
+ lines.push(`- ${note}`);
206
+ }
207
+ }
208
+ return lines.join("\n");
209
+ }
210
+
211
+ module.exports = {
212
+ runWorktreePreflight,
213
+ formatWorktreePreflightReport
214
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenonbyte/da-vinci-workflow",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
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",
@@ -662,21 +662,46 @@ Use this structure:
662
662
  ```md
663
663
  # Tasks
664
664
 
665
+ ## Discipline Markers (Machine-readable)
666
+ - design_approval: approved @ <ISO-8601 timestamp>
667
+ - plan_self_review: complete @ <ISO-8601 timestamp>
668
+ - operator_review_ack: accepted @ <ISO-8601 timestamp>
669
+
665
670
  ## 1. Setup
666
- - [ ] Project or page setup
671
+ - [ ] 1.1 Project or page setup
672
+ - Target files: `<repo path>`
673
+ - Verification command: `<exact command>`
674
+ - Execution intent: `serial`
675
+ - Review intent: `true`
667
676
 
668
677
  ## 2. UI Structure
669
- - [ ] Implement major sections from Pencil
678
+ - [ ] 2.1 Implement major sections from Pencil
679
+ - Target files: `<repo path>`
680
+ - Verification command: `<exact command>`
681
+ - Execution intent: `bounded_parallel`
682
+ - Review intent: `true`
670
683
 
671
684
  ## 3. Behavior
672
- - [ ] Implement states and interactions from spec
685
+ - [ ] 3.1 Implement states and interactions from spec
686
+ - Target files: `<repo path>`
687
+ - Verification command: `<exact command>`
688
+ - Execution intent: `review_required`
689
+ - Review intent: `true`
673
690
 
674
691
  ## 4. Integration
675
- - [ ] Wire required data or services
692
+ - [ ] 4.1 Wire required data or services
693
+ - Target files: `<repo path>`
694
+ - Verification command: `<exact command>`
695
+ - Execution intent: `serial`
696
+ - Review intent: `true`
676
697
 
677
698
  ## 5. Verification
678
- - [ ] Check requirement coverage
679
- - [ ] Check Pencil coverage
699
+ - [ ] 5.1 Check requirement coverage
700
+ - [ ] 5.2 Check Pencil coverage
701
+ - Verification command: `da-vinci verify-bindings --project <path> [--change <id>]`
702
+ - Verification command: `da-vinci verify-implementation --project <path> [--change <id>]`
703
+ - Verification command: `da-vinci verify-structure --project <path> [--change <id>]`
704
+ - Verification command: `da-vinci verify-coverage --project <path> [--change <id>]`
680
705
 
681
706
  ## Metadata Hints (Machine-readable)
682
707
  - Spec slice: `<slice-id>`
@@ -699,8 +724,12 @@ Prefer top-level task groups. They are required for execution checkpoints.
699
724
  Additional guidance:
700
725
 
701
726
  - keep top-level task groups in `X. Title` form to support task-group execution metadata
727
+ - keep checklist numbering in `X.Y` form and avoid placeholder wording such as `TBD` or `TODO`
728
+ - keep discipline markers parseable and timestamped so stale approvals can be detected
702
729
  - include explicit verification actions so `lint-tasks` and `verify-coverage` can consume intent deterministically
703
730
  - keep task text concrete enough that coverage tools can map behavior and state work
731
+ - include explicit file targets or code-area references for each task group
732
+ - include execution intent (`serial`, `bounded_parallel`, or `review_required`) and review intent metadata per group
704
733
 
705
734
  Recommended path:
706
735
 
@@ -780,6 +809,27 @@ Use this structure:
780
809
  - explicit test evidence summary
781
810
  - open gaps
782
811
 
812
+ ## Task Review Evidence
813
+ ### Task Review <task-group-id> (spec)
814
+ - Status: PASS / WARN / BLOCK
815
+ - Reviewer: `<name>`
816
+ - Summary: `<summary>`
817
+ - Issues: `<issue list>`
818
+ - Recorded at: `<ISO-8601 timestamp>`
819
+
820
+ ### Task Review <task-group-id> (quality)
821
+ - Status: PASS / WARN / BLOCK
822
+ - Reviewer: `<name>`
823
+ - Summary: `<summary>`
824
+ - Issues: `<issue list>`
825
+ - Recorded at: `<ISO-8601 timestamp>`
826
+
827
+ ## Verification Freshness
828
+ - verification baseline timestamp
829
+ - latest verify signal timestamps by surface
830
+ - freshness outcome: `fresh` / `stale`
831
+ - stale reasons when freshness is not satisfied
832
+
783
833
  ## Context Delta
784
834
  - Add concise entries after each `execution checkpoint`
785
835
  - Required fields: `time`, `checkpoint_type`, `goal`, `decision`, `constraints`, `impact`, `status`, `next_action`
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,