@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.
- package/CHANGELOG.md +28 -0
- package/README.md +49 -14
- package/README.zh-CN.md +169 -14
- package/commands/claude/dv/breakdown.md +8 -0
- package/commands/claude/dv/build.md +16 -0
- package/commands/claude/dv/continue.md +4 -0
- package/commands/claude/dv/design.md +5 -2
- package/commands/claude/dv/tasks.md +14 -0
- package/commands/claude/dv/verify.md +11 -0
- package/commands/codex/prompts/dv-breakdown.md +8 -0
- package/commands/codex/prompts/dv-build.md +16 -0
- package/commands/codex/prompts/dv-continue.md +4 -0
- package/commands/codex/prompts/dv-design.md +5 -2
- package/commands/codex/prompts/dv-tasks.md +14 -0
- package/commands/codex/prompts/dv-verify.md +10 -0
- package/commands/gemini/dv/breakdown.toml +8 -0
- package/commands/gemini/dv/build.toml +16 -0
- package/commands/gemini/dv/continue.toml +4 -0
- package/commands/gemini/dv/design.toml +5 -2
- package/commands/gemini/dv/tasks.toml +14 -0
- package/commands/gemini/dv/verify.toml +10 -0
- package/commands/templates/dv-continue.shared.md +4 -0
- package/docs/discipline-and-orchestration-upgrade.md +83 -0
- package/docs/dv-command-reference.md +61 -2
- package/docs/execution-chain-migration.md +23 -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 +5 -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 +61 -38
- package/docs/workflow-examples.md +16 -13
- package/docs/workflow-overview.md +19 -0
- package/docs/zh-CN/dv-command-reference.md +59 -2
- package/docs/zh-CN/execution-chain-migration.md +23 -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 +5 -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 +61 -38
- package/docs/zh-CN/workflow-examples.md +15 -13
- package/docs/zh-CN/workflow-overview.md +19 -0
- package/examples/greenfield-spec-markupflow/.da-vinci/state/execution-signals/demo__lint-tasks.json +16 -0
- package/lib/audit-parsers.js +166 -10
- package/lib/audit.js +3 -26
- package/lib/cli.js +156 -2
- package/lib/design-source-registry.js +146 -0
- package/lib/execution-profile.js +143 -0
- package/lib/execution-signals.js +19 -1
- package/lib/lint-tasks.js +86 -2
- package/lib/planning-parsers.js +255 -18
- package/lib/save-current-design.js +790 -0
- package/lib/supervisor-review.js +3 -2
- package/lib/task-execution.js +160 -0
- package/lib/task-review.js +197 -0
- package/lib/verify.js +152 -1
- package/lib/workflow-bootstrap.js +2 -13
- package/lib/workflow-persisted-state.js +3 -1
- package/lib/workflow-state.js +503 -33
- package/lib/worktree-preflight.js +214 -0
- package/package.json +1 -1
- package/references/artifact-templates.md +56 -6
- package/tui/catalog.js +103 -0
- 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
|
@@ -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,
|