@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/cli.js
CHANGED
|
@@ -32,6 +32,11 @@ const {
|
|
|
32
32
|
endPencilSession,
|
|
33
33
|
getPencilSessionStatus
|
|
34
34
|
} = require("./pencil-session");
|
|
35
|
+
const {
|
|
36
|
+
SAVE_STATUS,
|
|
37
|
+
saveCurrentDesign,
|
|
38
|
+
formatSaveCurrentDesignReport
|
|
39
|
+
} = require("./save-current-design");
|
|
35
40
|
const {
|
|
36
41
|
searchIconLibrary,
|
|
37
42
|
formatIconSearchReport
|
|
@@ -74,6 +79,7 @@ const {
|
|
|
74
79
|
const { diffSpec, formatDiffSpecReport } = require("./diff-spec");
|
|
75
80
|
const { scaffoldFromBindings, formatScaffoldReport } = require("./scaffold");
|
|
76
81
|
const { writeExecutionSignal } = require("./execution-signals");
|
|
82
|
+
const { formatTuiHelp, launchTui } = require("../tui");
|
|
77
83
|
|
|
78
84
|
const DEFAULT_MAX_PREFLIGHT_STDIN_BYTES = 1024 * 1024;
|
|
79
85
|
const DEFAULT_MAX_STDIN_TRANSIENT_RETRIES = 2000;
|
|
@@ -81,6 +87,8 @@ const DEFAULT_MAX_STDIN_TRANSIENT_BACKOFF_MS = 25;
|
|
|
81
87
|
const OPTION_FLAGS_WITH_VALUES = new Set([
|
|
82
88
|
"--home",
|
|
83
89
|
"--platform",
|
|
90
|
+
"--lang",
|
|
91
|
+
"--tui-width",
|
|
84
92
|
"--project",
|
|
85
93
|
"--mode",
|
|
86
94
|
"--change",
|
|
@@ -111,6 +119,7 @@ const OPTION_FLAGS_WITH_VALUES = new Set([
|
|
|
111
119
|
"--from",
|
|
112
120
|
"--to",
|
|
113
121
|
"--pen",
|
|
122
|
+
"--pencil-bin",
|
|
114
123
|
"--nodes-file",
|
|
115
124
|
"--variables-file",
|
|
116
125
|
"--version",
|
|
@@ -120,6 +129,8 @@ const OPTION_FLAGS_WITH_VALUES = new Set([
|
|
|
120
129
|
|
|
121
130
|
const HELP_OPTION_SPECS = [
|
|
122
131
|
{ flag: "--platform <value>", description: "codex, claude, gemini, or all" },
|
|
132
|
+
{ flag: "--lang <value>", description: "ui language for `da-vinci tui`: en or zh" },
|
|
133
|
+
{ flag: "--tui-width <cols>", description: "fixed layout width (columns) for `da-vinci tui`" },
|
|
123
134
|
{ flag: "--home <path>", description: "override HOME for installation targets" },
|
|
124
135
|
{ flag: "--project <path>", description: "override project path for audit" },
|
|
125
136
|
{
|
|
@@ -185,12 +196,15 @@ const HELP_OPTION_SPECS = [
|
|
|
185
196
|
flag: "--strict",
|
|
186
197
|
description: "enable strict failure mode for commands that support advisory defaults (for example icon-sync, lint-spec)"
|
|
187
198
|
},
|
|
199
|
+
{ flag: "--alt-screen", description: "enable alternate terminal screen buffer for `da-vinci tui`" },
|
|
200
|
+
{ flag: "--no-alt-screen", description: "disable alternate terminal screen buffer for `da-vinci tui`" },
|
|
188
201
|
{
|
|
189
202
|
flag: "--continue-on-error",
|
|
190
203
|
description: "print BLOCK/FAIL command results without throwing process errors"
|
|
191
204
|
},
|
|
192
205
|
{ flag: "--json", description: "print structured JSON output when supported by the command" },
|
|
193
206
|
{ flag: "--pen <path>", description: "registered .pen path for sync checks" },
|
|
207
|
+
{ flag: "--pencil-bin <path>", description: "override Pencil executable for interactive capture/verify flows" },
|
|
194
208
|
{
|
|
195
209
|
flag: "--from <path>",
|
|
196
210
|
description: "source path for sync-pen-source, or baseline sidecars directory for diff-spec"
|
|
@@ -472,6 +486,7 @@ function printHelp() {
|
|
|
472
486
|
" da-vinci install --platform codex,claude,gemini",
|
|
473
487
|
" da-vinci uninstall --platform codex,claude,gemini",
|
|
474
488
|
" da-vinci status",
|
|
489
|
+
" da-vinci tui [--project <path>] [--change <id>] [--lang en|zh] [--strict] [--json] [--continue-on-error] [--tui-width <cols>] [--alt-screen|--no-alt-screen]",
|
|
475
490
|
" da-vinci workflow-status [--project <path>] [--change <id>] [--json]",
|
|
476
491
|
" da-vinci next-step [--project <path>] [--change <id>] [--json]",
|
|
477
492
|
" da-vinci lint-spec [--project <path>] [--change <id>] [--strict] [--json]",
|
|
@@ -498,6 +513,7 @@ function printHelp() {
|
|
|
498
513
|
" da-vinci check-pen-baseline --pen <path> --baseline <path>[,<path>...] [--baseline <path>] [--prefer-source <path>]",
|
|
499
514
|
" da-vinci sync-pen-source --from <path> --to <path>",
|
|
500
515
|
" da-vinci snapshot-pen --input <path> --output <path>",
|
|
516
|
+
" da-vinci save-current-design --project <path> [--json] [--continue-on-error]",
|
|
501
517
|
" da-vinci pencil-lock acquire --project <path>",
|
|
502
518
|
" da-vinci pencil-lock release --project <path>",
|
|
503
519
|
" da-vinci pencil-lock status",
|
|
@@ -937,6 +953,33 @@ async function runCli(argv) {
|
|
|
937
953
|
return;
|
|
938
954
|
}
|
|
939
955
|
|
|
956
|
+
if (command === "tui") {
|
|
957
|
+
const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
|
|
958
|
+
const changeId = getOption(argv, "--change");
|
|
959
|
+
const lang = getOption(argv, "--lang");
|
|
960
|
+
const tuiWidth = getOption(argv, "--tui-width");
|
|
961
|
+
const altScreen = argv.includes("--alt-screen")
|
|
962
|
+
? true
|
|
963
|
+
: argv.includes("--no-alt-screen")
|
|
964
|
+
? false
|
|
965
|
+
: undefined;
|
|
966
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
967
|
+
console.log(formatTuiHelp(lang));
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
await launchTui({
|
|
971
|
+
projectPath,
|
|
972
|
+
changeId,
|
|
973
|
+
lang,
|
|
974
|
+
tuiWidth,
|
|
975
|
+
altScreen,
|
|
976
|
+
strict: argv.includes("--strict"),
|
|
977
|
+
jsonOutput: argv.includes("--json"),
|
|
978
|
+
continueOnError
|
|
979
|
+
});
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
|
|
940
983
|
if (command === "workflow-status") {
|
|
941
984
|
const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
|
|
942
985
|
const changeId = getOption(argv, "--change");
|
|
@@ -1402,6 +1445,35 @@ async function runCli(argv) {
|
|
|
1402
1445
|
return;
|
|
1403
1446
|
}
|
|
1404
1447
|
|
|
1448
|
+
if (command === "save-current-design") {
|
|
1449
|
+
const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
|
|
1450
|
+
const pencilBin = getOption(argv, "--pencil-bin");
|
|
1451
|
+
const result = await saveCurrentDesign({
|
|
1452
|
+
projectPath,
|
|
1453
|
+
homeDir,
|
|
1454
|
+
pencilBin,
|
|
1455
|
+
allowLocalBridge: true
|
|
1456
|
+
});
|
|
1457
|
+
const useJson = argv.includes("--json");
|
|
1458
|
+
const output = useJson
|
|
1459
|
+
? JSON.stringify(result, null, 2)
|
|
1460
|
+
: formatSaveCurrentDesignReport(result);
|
|
1461
|
+
|
|
1462
|
+
if (
|
|
1463
|
+
emitOrThrowOnStatus(
|
|
1464
|
+
result.status,
|
|
1465
|
+
[SAVE_STATUS.BLOCKED, SAVE_STATUS.UNAVAILABLE],
|
|
1466
|
+
output,
|
|
1467
|
+
continueOnError
|
|
1468
|
+
)
|
|
1469
|
+
) {
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
console.log(output);
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1405
1477
|
if (command === "pencil-lock") {
|
|
1406
1478
|
handlePencilLockCommand(argv, homeDir);
|
|
1407
1479
|
return;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const { isPathInside } = require("./fs-safety");
|
|
3
|
+
|
|
4
|
+
const REGISTERED_PEN_PATTERN = /\.da-vinci\/designs\/[^\s`]+\.pen/g;
|
|
5
|
+
|
|
6
|
+
function normalizeProjectRoot(projectRoot) {
|
|
7
|
+
return path.resolve(projectRoot || process.cwd());
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function collectRegisteredPenReferences(registryText) {
|
|
11
|
+
const matches = String(registryText || "").match(REGISTERED_PEN_PATTERN) || [];
|
|
12
|
+
const seen = new Set();
|
|
13
|
+
const unique = [];
|
|
14
|
+
|
|
15
|
+
for (const match of matches) {
|
|
16
|
+
const normalized = String(match || "").trim();
|
|
17
|
+
if (!normalized || seen.has(normalized)) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
seen.add(normalized);
|
|
21
|
+
unique.push(normalized);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return unique;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function normalizeBoundPenPath(projectRoot, penPath, options = {}) {
|
|
28
|
+
const root = normalizeProjectRoot(projectRoot);
|
|
29
|
+
const raw = typeof penPath === "string" ? penPath.trim() : "";
|
|
30
|
+
|
|
31
|
+
if (!raw) {
|
|
32
|
+
return {
|
|
33
|
+
ok: false,
|
|
34
|
+
code: options.missingCode || "missing_path",
|
|
35
|
+
input: raw,
|
|
36
|
+
resolvedPath: ""
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (options.rejectNew && raw.toLowerCase() === "new") {
|
|
41
|
+
return {
|
|
42
|
+
ok: false,
|
|
43
|
+
code: options.newCode || "active_editor_new",
|
|
44
|
+
input: raw,
|
|
45
|
+
resolvedPath: ""
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const resolvedPath = path.normalize(path.isAbsolute(raw) ? raw : path.resolve(root, raw));
|
|
50
|
+
if (!isPathInside(root, resolvedPath)) {
|
|
51
|
+
return {
|
|
52
|
+
ok: false,
|
|
53
|
+
code: options.outsideCode || "outside_project_root",
|
|
54
|
+
input: raw,
|
|
55
|
+
resolvedPath
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (options.requirePenExtension !== false && !/\.pen$/i.test(resolvedPath)) {
|
|
60
|
+
return {
|
|
61
|
+
ok: false,
|
|
62
|
+
code: options.extensionCode || "not_pen_path",
|
|
63
|
+
input: raw,
|
|
64
|
+
resolvedPath
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
ok: true,
|
|
70
|
+
code: "ok",
|
|
71
|
+
input: raw,
|
|
72
|
+
resolvedPath
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function normalizeRegisteredPenPath(projectRoot, penPath) {
|
|
77
|
+
return normalizeBoundPenPath(projectRoot, penPath, {
|
|
78
|
+
missingCode: "registered_pen_missing",
|
|
79
|
+
outsideCode: "registered_pen_outside_project_root",
|
|
80
|
+
extensionCode: "registered_pen_not_pen_path"
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function normalizeSessionPenPath(projectRoot, penPath) {
|
|
85
|
+
return normalizeBoundPenPath(projectRoot, penPath, {
|
|
86
|
+
missingCode: "session_pen_missing",
|
|
87
|
+
outsideCode: "session_pen_outside_project_root",
|
|
88
|
+
extensionCode: "session_pen_not_pen_path"
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function normalizeActiveEditorPath(projectRoot, activeEditorPath) {
|
|
93
|
+
return normalizeBoundPenPath(projectRoot, activeEditorPath, {
|
|
94
|
+
rejectNew: true,
|
|
95
|
+
missingCode: "active_editor_missing",
|
|
96
|
+
newCode: "active_editor_new",
|
|
97
|
+
outsideCode: "active_editor_outside_project_root",
|
|
98
|
+
extensionCode: "active_editor_not_pen_path"
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function collectRegisteredPenPaths(projectRoot, registryText) {
|
|
103
|
+
const root = normalizeProjectRoot(projectRoot);
|
|
104
|
+
const references = collectRegisteredPenReferences(registryText);
|
|
105
|
+
const validPaths = [];
|
|
106
|
+
const escapedPaths = [];
|
|
107
|
+
const seenResolved = new Set();
|
|
108
|
+
|
|
109
|
+
for (const relativePath of references) {
|
|
110
|
+
const normalized = normalizeRegisteredPenPath(root, relativePath);
|
|
111
|
+
if (normalized.ok) {
|
|
112
|
+
if (!seenResolved.has(normalized.resolvedPath)) {
|
|
113
|
+
seenResolved.add(normalized.resolvedPath);
|
|
114
|
+
validPaths.push(normalized.resolvedPath);
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (normalized.code === "registered_pen_outside_project_root") {
|
|
120
|
+
escapedPaths.push({
|
|
121
|
+
relativePath,
|
|
122
|
+
resolvedPath: normalized.resolvedPath
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
validPaths,
|
|
129
|
+
escapedPaths
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function resolvePreferredRegisteredPenPath(projectRoot, registryText) {
|
|
134
|
+
const resolved = collectRegisteredPenPaths(projectRoot, registryText);
|
|
135
|
+
return resolved.validPaths[0] || "";
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module.exports = {
|
|
139
|
+
collectRegisteredPenReferences,
|
|
140
|
+
normalizeBoundPenPath,
|
|
141
|
+
normalizeRegisteredPenPath,
|
|
142
|
+
normalizeSessionPenPath,
|
|
143
|
+
normalizeActiveEditorPath,
|
|
144
|
+
collectRegisteredPenPaths,
|
|
145
|
+
resolvePreferredRegisteredPenPath
|
|
146
|
+
};
|