@flyin-ai/alloy 0.2.0-beta.1 → 0.2.0-beta.2
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/commands/alloy/apply.md +222 -430
- package/commands/alloy/archive.md +156 -132
- package/commands/alloy/discard.md +26 -11
- package/commands/alloy/finish.md +212 -116
- package/commands/alloy/fix.md +102 -247
- package/commands/alloy/plan.md +204 -301
- package/commands/alloy/references/apply-precheck.md +21 -0
- package/commands/alloy/references/apply-rationalizations.md +18 -0
- package/commands/alloy/references/apply-subagent-commit.md +49 -0
- package/commands/alloy/references/apply-worktree.md +130 -0
- package/commands/alloy/references/archive-rationalizations.md +16 -0
- package/commands/alloy/references/archive-worktree-cleanup.md +94 -0
- package/commands/alloy/references/artifact-hash-commit.md +49 -0
- package/commands/alloy/references/branch-naming.md +65 -0
- package/commands/alloy/references/branch-validation.md +36 -0
- package/commands/alloy/references/fix-precommit-check.md +58 -0
- package/commands/alloy/references/interaction-style.md +34 -1
- package/commands/alloy/references/main-branch-detection.md +3 -6
- package/commands/alloy/references/phase-downgrade-path.md +27 -0
- package/commands/alloy/references/plan-rollback.md +84 -0
- package/commands/alloy/references/spec-sync.md +62 -0
- package/commands/alloy/references/start-rationalizations.md +18 -0
- package/commands/alloy/start.md +178 -238
- package/dist/cli/commands/completion.js +13 -2
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/internal/artifact.d.ts +7 -0
- package/dist/cli/commands/internal/artifact.js +70 -0
- package/dist/cli/commands/internal/artifact.js.map +1 -0
- package/dist/cli/commands/internal/guard.js +204 -2
- package/dist/cli/commands/internal/guard.js.map +1 -1
- package/dist/cli/commands/internal/progress.d.ts +10 -0
- package/dist/cli/commands/internal/progress.js +70 -0
- package/dist/cli/commands/internal/progress.js.map +1 -0
- package/dist/cli/commands/internal/spec-audit.d.ts +42 -0
- package/dist/cli/commands/internal/spec-audit.js +363 -0
- package/dist/cli/commands/internal/spec-audit.js.map +1 -0
- package/dist/cli/commands/internal/state.js +4 -0
- package/dist/cli/commands/internal/state.js.map +1 -1
- package/dist/cli/index.js +30 -0
- package/dist/cli/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -14,7 +14,7 @@ function bashCompletion() {
|
|
|
14
14
|
' local cur="${COMP_WORDS[COMP_CWORD]}"',
|
|
15
15
|
"",
|
|
16
16
|
" if [ \"$COMP_CWORD\" -eq 1 ]; then",
|
|
17
|
-
' COMPREPLY=($(compgen -W "-v --version -h --help init status doctor update completion" -- "$cur"))',
|
|
17
|
+
' COMPREPLY=($(compgen -W "-v --version -h --help init status doctor update completion _spec-audit" -- "$cur"))',
|
|
18
18
|
" return 0",
|
|
19
19
|
" fi",
|
|
20
20
|
"",
|
|
@@ -31,6 +31,9 @@ function bashCompletion() {
|
|
|
31
31
|
" completion)",
|
|
32
32
|
' COMPREPLY=($(compgen -W "bash zsh pwsh powershell" -- "$cur"))',
|
|
33
33
|
" ;;",
|
|
34
|
+
" _spec-audit)",
|
|
35
|
+
' COMPREPLY=($(compgen -W "--fix --help -h" -- "$cur"))',
|
|
36
|
+
" ;;",
|
|
34
37
|
" esac",
|
|
35
38
|
"}",
|
|
36
39
|
"",
|
|
@@ -53,6 +56,7 @@ function zshCompletion() {
|
|
|
53
56
|
" 'doctor:诊断——版本兼容性、文件一致性'",
|
|
54
57
|
" 'update:更新 Alloy skill 文件到最新版'",
|
|
55
58
|
" 'completion:生成 shell 补全脚本'",
|
|
59
|
+
"'_spec-audit:检测 spec/skill behaviors 差异'",
|
|
56
60
|
" )",
|
|
57
61
|
" _describe 'command' cmds",
|
|
58
62
|
"}",
|
|
@@ -90,6 +94,12 @@ function zshCompletion() {
|
|
|
90
94
|
" '--help[显示帮助]' \\",
|
|
91
95
|
" '-h[显示帮助]'",
|
|
92
96
|
" ;;",
|
|
97
|
+
" _spec-audit)",
|
|
98
|
+
" _arguments \\",
|
|
99
|
+
" '--fix[交互式修复差异]' \\",
|
|
100
|
+
" '--help[显示帮助]' \\",
|
|
101
|
+
" '-h[显示帮助]'",
|
|
102
|
+
" ;;",
|
|
93
103
|
" esac",
|
|
94
104
|
" ;;",
|
|
95
105
|
" esac",
|
|
@@ -111,7 +121,7 @@ function powershellCompletion() {
|
|
|
111
121
|
"Register-ArgumentCompleter -Native -CommandName alloy -ScriptBlock {",
|
|
112
122
|
" param($wordToComplete, $commandAst, $cursorPosition)",
|
|
113
123
|
"",
|
|
114
|
-
" $commands = @('init', 'status', 'doctor', 'update', 'completion')",
|
|
124
|
+
" $commands = @('init', 'status', 'doctor', 'update', 'completion', '_spec-audit')",
|
|
115
125
|
" $globalOpts = @('--version', '-v', '--help', '-h')",
|
|
116
126
|
"",
|
|
117
127
|
" $tokens = $commandAst.CommandElements",
|
|
@@ -143,6 +153,7 @@ function powershellCompletion() {
|
|
|
143
153
|
" 'doctor' { $opts = @('--json', '--help', '-h') }",
|
|
144
154
|
" 'update' { $opts = @('--help', '-h') }",
|
|
145
155
|
" 'completion' { $opts = @('bash', 'zsh', 'pwsh', 'powershell', '--help', '-h') }",
|
|
156
|
+
" '_spec-audit' { $opts = @('--fix', '--help', '-h') }",
|
|
146
157
|
" }",
|
|
147
158
|
"",
|
|
148
159
|
" $opts | Where-Object { $_ -like \"$wordToComplete*\" } | ForEach-Object {",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/cli/commands/completion.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,aAAa,EAAE,CAAC;IAClD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;QACxD,OAAO,oBAAoB,EAAE,CAAC;IAChC,OAAO,cAAc,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,cAAc;IACrB,OAAO;QACL,4DAA4D;QAC5D,qCAAqC;QACrC,EAAE;QACF,uBAAuB;QACvB,yCAAyC;QACzC,EAAE;QACF,sCAAsC;QACtC,
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/cli/commands/completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/cli/commands/internal/artifact.ts
|
|
2
|
+
import { existsSync, rmSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { readState, writeState } from "../../utils/state.js";
|
|
5
|
+
import { ARTIFACT_FILES } from "../../../core/artifacts.js";
|
|
6
|
+
/**
|
|
7
|
+
* alloy _artifact <action> <change-dir> [artifact]
|
|
8
|
+
*
|
|
9
|
+
* 动作:
|
|
10
|
+
* reset <change-dir> <artifact> — 清除指定制品的 hash 记录 + 删除文件
|
|
11
|
+
*/
|
|
12
|
+
export async function artifactCommand(args) {
|
|
13
|
+
const action = args[0];
|
|
14
|
+
if (!action) {
|
|
15
|
+
console.error("用法: alloy _artifact reset <change-dir> <artifact>");
|
|
16
|
+
return process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
if (action === "reset") {
|
|
19
|
+
return artifactReset(args.slice(1));
|
|
20
|
+
}
|
|
21
|
+
console.error(`未知操作: ${action} (支持: reset)`);
|
|
22
|
+
return process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
async function artifactReset(args) {
|
|
25
|
+
const changeDir = args[0];
|
|
26
|
+
const artifactId = args[1];
|
|
27
|
+
if (!changeDir || !artifactId) {
|
|
28
|
+
console.error("用法: alloy _artifact reset <change-dir> <artifact>");
|
|
29
|
+
return process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const fileName = ARTIFACT_FILES[artifactId];
|
|
32
|
+
if (!fileName) {
|
|
33
|
+
console.error(`未知制品: ${artifactId} (支持: ${Object.keys(ARTIFACT_FILES).join(", ")})`);
|
|
34
|
+
return process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// 1. 清除 hash 记录
|
|
37
|
+
let state;
|
|
38
|
+
try {
|
|
39
|
+
state = await readState(changeDir);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
console.error(`无法读取状态: ${changeDir}`);
|
|
43
|
+
return process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const originalCount = state.records.length;
|
|
46
|
+
state.records = state.records.filter((r) => r.artifact !== artifactId);
|
|
47
|
+
if (state.records.length === originalCount) {
|
|
48
|
+
console.log(`${artifactId}: no hash record found`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
await writeState(changeDir, state);
|
|
52
|
+
console.log(`${artifactId}: hash record cleared`);
|
|
53
|
+
}
|
|
54
|
+
// 2. 删除制品文件
|
|
55
|
+
const fullPath = join(changeDir, fileName);
|
|
56
|
+
if (existsSync(fullPath)) {
|
|
57
|
+
const st = await import("node:fs/promises").then((m) => m.stat(fullPath));
|
|
58
|
+
if (st.isDirectory()) {
|
|
59
|
+
rmSync(fullPath, { recursive: true, force: true });
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
rmSync(fullPath, { force: true });
|
|
63
|
+
}
|
|
64
|
+
console.log(`${artifactId}: file deleted (${fileName})`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.log(`${artifactId}: file not found (${fileName})`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=artifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact.js","sourceRoot":"","sources":["../../../../src/cli/commands/internal/artifact.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join, basename } from "node:path";
|
|
3
3
|
import { execSync } from "node:child_process";
|
|
4
|
-
import { readState, writeState } from "../../utils/state.js";
|
|
4
|
+
import { readState, writeState, readProjectConfig } from "../../utils/state.js";
|
|
5
5
|
import { computeArtifactHash } from "../../../core/artifacts.js";
|
|
6
6
|
const VALID_TRANSITIONS = {
|
|
7
7
|
started: ["planned"],
|
|
@@ -16,6 +16,21 @@ const ARTIFACT_CHECKS = {
|
|
|
16
16
|
"archived->finished": ["retrospective.md"],
|
|
17
17
|
};
|
|
18
18
|
export async function guardCommand(args) {
|
|
19
|
+
// 子命令路由
|
|
20
|
+
const subCommand = args[0];
|
|
21
|
+
if (subCommand === "branch-position") {
|
|
22
|
+
return branchPositionGuard(args.slice(1));
|
|
23
|
+
}
|
|
24
|
+
if (subCommand === "verify-passed") {
|
|
25
|
+
return verifyPassedGuard(args.slice(1));
|
|
26
|
+
}
|
|
27
|
+
if (subCommand === "precheck") {
|
|
28
|
+
return precheckGuard(args.slice(1));
|
|
29
|
+
}
|
|
30
|
+
if (subCommand === "worktree-status") {
|
|
31
|
+
return worktreeStatusGuard(args.slice(1));
|
|
32
|
+
}
|
|
33
|
+
// 原有 phase 转换校验逻辑
|
|
19
34
|
const changeDir = args[0];
|
|
20
35
|
const targetPhase = args[1];
|
|
21
36
|
const apply = args.includes("--apply");
|
|
@@ -93,4 +108,191 @@ export async function guardCommand(args) {
|
|
|
93
108
|
console.log(`✓ phase: ${currentPhase} → ${targetPhase}`);
|
|
94
109
|
}
|
|
95
110
|
}
|
|
111
|
+
// --- 子命令实现 ---
|
|
112
|
+
/** 获取当前 git 分支名 */
|
|
113
|
+
function getCurrentBranch() {
|
|
114
|
+
try {
|
|
115
|
+
return execSync("git branch --show-current", { stdio: "pipe" }).toString().trim();
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** 获取本地分支列表 */
|
|
122
|
+
function getLocalBranches() {
|
|
123
|
+
try {
|
|
124
|
+
return execSync("git branch --list --format=%(refname:short)", { stdio: "pipe" })
|
|
125
|
+
.toString()
|
|
126
|
+
.trim()
|
|
127
|
+
.split("\n")
|
|
128
|
+
.map((s) => s.trim())
|
|
129
|
+
.filter(Boolean);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** 获取 main 分支名 */
|
|
136
|
+
async function getMainBranch() {
|
|
137
|
+
try {
|
|
138
|
+
const config = await readProjectConfig(process.cwd());
|
|
139
|
+
return config.alloy?.main_branch ?? null;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** 猜测主分支名(config 无记录时从本地分支推断) */
|
|
146
|
+
async function guessMainBranch() {
|
|
147
|
+
const candidates = ["main", "master"];
|
|
148
|
+
const localBranches = getLocalBranches();
|
|
149
|
+
for (const c of candidates) {
|
|
150
|
+
if (localBranches.includes(c))
|
|
151
|
+
return c;
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* alloy _guard branch-position <change-dir>
|
|
157
|
+
* 输出: on-feature|on-main|feature-missing|on-other:<current>|feature-lost:<feature>
|
|
158
|
+
* 退出码: 0=位置正确(on-feature), 1=位置不正确
|
|
159
|
+
*/
|
|
160
|
+
async function branchPositionGuard(args) {
|
|
161
|
+
const changeDir = args[0];
|
|
162
|
+
if (!changeDir) {
|
|
163
|
+
console.error("用法: alloy _guard branch-position <change-dir>");
|
|
164
|
+
return process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
let state;
|
|
167
|
+
try {
|
|
168
|
+
state = await readState(changeDir);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
console.error(`无法读取状态: ${changeDir}`);
|
|
172
|
+
return process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
const featureBranch = state.feature_branch ?? null;
|
|
175
|
+
const currentBranch = getCurrentBranch();
|
|
176
|
+
const mainBranch = await getMainBranch();
|
|
177
|
+
console.log(`current=${currentBranch} main=${mainBranch} feature=${featureBranch}`);
|
|
178
|
+
// mainBranch 未配置时,尝试常见默认值
|
|
179
|
+
const effectiveMain = mainBranch ?? (await guessMainBranch());
|
|
180
|
+
if (effectiveMain && currentBranch === effectiveMain) {
|
|
181
|
+
console.log("on-main");
|
|
182
|
+
return process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
if (featureBranch === null) {
|
|
185
|
+
console.log("feature-missing");
|
|
186
|
+
return process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
if (currentBranch === featureBranch) {
|
|
189
|
+
console.log("on-feature");
|
|
190
|
+
return; // exit(0)
|
|
191
|
+
}
|
|
192
|
+
const localBranches = getLocalBranches();
|
|
193
|
+
if (!localBranches.includes(featureBranch)) {
|
|
194
|
+
console.log(`feature-lost:${featureBranch}`);
|
|
195
|
+
return process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
console.log(`on-other:${currentBranch}`);
|
|
198
|
+
return process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* alloy _guard verify-passed <change-dir>
|
|
202
|
+
* 输出: PASS|FAIL|WARNING
|
|
203
|
+
* 退出码: 0=通过(PASS/WARNING), 1=不通过(FAIL)
|
|
204
|
+
*/
|
|
205
|
+
async function verifyPassedGuard(args) {
|
|
206
|
+
const changeDir = args[0];
|
|
207
|
+
if (!changeDir) {
|
|
208
|
+
console.error("用法: alloy _guard verify-passed <change-dir>");
|
|
209
|
+
return process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
const verifyPath = join(changeDir, "verify.md");
|
|
212
|
+
if (!existsSync(verifyPath)) {
|
|
213
|
+
console.log("FAIL");
|
|
214
|
+
return process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
const content = readFileSync(verifyPath, "utf-8");
|
|
218
|
+
const failMatch = content.match(/^- \[x\].*(?:❌\s*)?FAIL/mi);
|
|
219
|
+
if (failMatch) {
|
|
220
|
+
console.log("FAIL");
|
|
221
|
+
return process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
const warnMatch = content.match(/^- \[x\].*(?:⚠️\s*)?WARNING/mi);
|
|
224
|
+
if (warnMatch) {
|
|
225
|
+
console.log("WARNING");
|
|
226
|
+
return; // exit(0)
|
|
227
|
+
}
|
|
228
|
+
console.log("PASS");
|
|
229
|
+
return; // exit(0)
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
console.log("FAIL");
|
|
233
|
+
return process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* alloy _guard precheck <change-dir> <expected-phase>
|
|
238
|
+
* 输出: PASS:<phase>|FAIL:<reason>
|
|
239
|
+
* 退出码: 0=通过, 1=不通过
|
|
240
|
+
*/
|
|
241
|
+
async function precheckGuard(args) {
|
|
242
|
+
const changeDir = args[0];
|
|
243
|
+
const expectedPhase = args[1];
|
|
244
|
+
if (!changeDir || !expectedPhase) {
|
|
245
|
+
console.error("用法: alloy _guard precheck <change-dir> <expected-phase>");
|
|
246
|
+
return process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
if (!existsSync(changeDir)) {
|
|
249
|
+
console.log(`FAIL:directory not found`);
|
|
250
|
+
return process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
const state = await readState(changeDir);
|
|
254
|
+
// 支持多阶段值(逗号分隔),如 "planned,applied"
|
|
255
|
+
const allowedPhases = expectedPhase.split(",").map((p) => p.trim());
|
|
256
|
+
if (allowedPhases.includes(state.phase)) {
|
|
257
|
+
console.log(`PASS:${state.phase}`);
|
|
258
|
+
return; // exit(0)
|
|
259
|
+
}
|
|
260
|
+
console.log(`FAIL:phase=${state.phase} expected=${expectedPhase}`);
|
|
261
|
+
return process.exit(1);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
console.log("FAIL:state read error");
|
|
265
|
+
return process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* alloy _guard worktree-status <change-dir>
|
|
270
|
+
* 输出: done:<path>:<branch>|stale:<path>|skipped|pending
|
|
271
|
+
* 退出码: 始终 0(查询命令)
|
|
272
|
+
*/
|
|
273
|
+
async function worktreeStatusGuard(args) {
|
|
274
|
+
const changeDir = args[0];
|
|
275
|
+
if (!changeDir) {
|
|
276
|
+
console.error("用法: alloy _guard worktree-status <change-dir>");
|
|
277
|
+
return process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
const state = await readState(changeDir);
|
|
280
|
+
const worktree = state.worktree;
|
|
281
|
+
if (worktree === null || worktree === "null") {
|
|
282
|
+
console.log("pending");
|
|
283
|
+
return; // exit(0)
|
|
284
|
+
}
|
|
285
|
+
if (worktree === "skipped") {
|
|
286
|
+
console.log("skipped");
|
|
287
|
+
return; // exit(0)
|
|
288
|
+
}
|
|
289
|
+
// 有效路径
|
|
290
|
+
if (existsSync(worktree)) {
|
|
291
|
+
const branch = state.worktree_branch ?? "unknown";
|
|
292
|
+
console.log(`done:${worktree}:${branch}`);
|
|
293
|
+
return; // exit(0)
|
|
294
|
+
}
|
|
295
|
+
console.log(`stale:${worktree}`);
|
|
296
|
+
return; // exit(0)
|
|
297
|
+
}
|
|
96
298
|
//# sourceMappingURL=guard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../../src/cli/commands/internal/guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../../src/cli/commands/internal/guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* alloy _progress artifacts <change-dir>
|
|
3
|
+
* 输出每个制品的状态行:<artifact>:<status>[:<detail>]
|
|
4
|
+
* done — 文件存在 + hash 匹配
|
|
5
|
+
* missing — 文件不存在
|
|
6
|
+
* hash-mismatch — 文件存在但 hash 不匹配
|
|
7
|
+
* pending — 文件存在但无 record(未审批)
|
|
8
|
+
* 退出码: 始终 0(查询命令)
|
|
9
|
+
*/
|
|
10
|
+
export declare function progressCommand(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/cli/commands/internal/progress.ts
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { readState } from "../../utils/state.js";
|
|
4
|
+
import { computeArtifactHash, ARTIFACT_FILES } from "../../../core/artifacts.js";
|
|
5
|
+
/**
|
|
6
|
+
* alloy _progress artifacts <change-dir>
|
|
7
|
+
* 输出每个制品的状态行:<artifact>:<status>[:<detail>]
|
|
8
|
+
* done — 文件存在 + hash 匹配
|
|
9
|
+
* missing — 文件不存在
|
|
10
|
+
* hash-mismatch — 文件存在但 hash 不匹配
|
|
11
|
+
* pending — 文件存在但无 record(未审批)
|
|
12
|
+
* 退出码: 始终 0(查询命令)
|
|
13
|
+
*/
|
|
14
|
+
export async function progressCommand(args) {
|
|
15
|
+
const action = args[0];
|
|
16
|
+
if (!action) {
|
|
17
|
+
console.error("用法: alloy _progress artifacts <change-dir>");
|
|
18
|
+
return process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
if (action === "artifacts") {
|
|
21
|
+
return artifactsProgress(args.slice(1));
|
|
22
|
+
}
|
|
23
|
+
console.error(`未知操作: ${action} (支持: artifacts)`);
|
|
24
|
+
return process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
async function artifactsProgress(args) {
|
|
27
|
+
const changeDir = args[0];
|
|
28
|
+
if (!changeDir) {
|
|
29
|
+
console.error("用法: alloy _progress artifacts <change-dir>");
|
|
30
|
+
return process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
let state;
|
|
33
|
+
try {
|
|
34
|
+
state = await readState(changeDir);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
console.error(`无法读取状态: ${changeDir}`);
|
|
38
|
+
return process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const records = state.records || [];
|
|
41
|
+
// 按制品定义顺序输出
|
|
42
|
+
const artifactOrder = ["draft", "proposal", "design", "specs", "tasks", "plans", "verify", "retrospective"];
|
|
43
|
+
for (const artifactId of artifactOrder) {
|
|
44
|
+
const fileName = ARTIFACT_FILES[artifactId];
|
|
45
|
+
if (!fileName)
|
|
46
|
+
continue;
|
|
47
|
+
const fullPath = `${changeDir}/${fileName}`;
|
|
48
|
+
const fileExists = existsSync(fullPath);
|
|
49
|
+
const record = records.find((r) => r.artifact === artifactId);
|
|
50
|
+
if (!fileExists) {
|
|
51
|
+
console.log(`${artifactId}:missing`);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (!record) {
|
|
55
|
+
console.log(`${artifactId}:pending`);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const currentHash = await computeArtifactHash(changeDir, artifactId);
|
|
59
|
+
if (currentHash === null) {
|
|
60
|
+
console.log(`${artifactId}:missing`);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (currentHash !== record.hash) {
|
|
64
|
+
console.log(`${artifactId}:hash-mismatch:${record.hash}!=${currentHash}`);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
console.log(`${artifactId}:done:${record.hash}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../../../src/cli/commands/internal/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface Behaviors {
|
|
2
|
+
stops?: number;
|
|
3
|
+
preconditions?: number;
|
|
4
|
+
hard_stops?: number;
|
|
5
|
+
user_gates?: number;
|
|
6
|
+
warns?: number;
|
|
7
|
+
artifacts: string[];
|
|
8
|
+
transitions_to: string;
|
|
9
|
+
external_calls: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface SkillEntry {
|
|
12
|
+
skillName: string;
|
|
13
|
+
spec: string | undefined;
|
|
14
|
+
behaviors: Behaviors | undefined;
|
|
15
|
+
}
|
|
16
|
+
export interface SpecEntry {
|
|
17
|
+
behaviors: Behaviors | undefined;
|
|
18
|
+
content: string;
|
|
19
|
+
}
|
|
20
|
+
export type FieldDiffType = "number" | "string" | "array" | "missing-block";
|
|
21
|
+
export interface FieldDiff {
|
|
22
|
+
field: string;
|
|
23
|
+
type: FieldDiffType;
|
|
24
|
+
skillValue: unknown;
|
|
25
|
+
specValue: unknown;
|
|
26
|
+
skillExtra?: string[];
|
|
27
|
+
specExtra?: string[];
|
|
28
|
+
}
|
|
29
|
+
export type AuditStatus = "ok" | "diff" | "no-spec-field" | "spec-not-found";
|
|
30
|
+
export interface AuditResult {
|
|
31
|
+
skillName: string;
|
|
32
|
+
status: AuditStatus;
|
|
33
|
+
diffs: FieldDiff[];
|
|
34
|
+
specPath?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function scanSkills(projectRoot: string): Promise<SkillEntry[]>;
|
|
37
|
+
export declare function readSpec(projectRoot: string, specPath: string): Promise<SpecEntry>;
|
|
38
|
+
export declare function compareBehaviors(skillBehaviors: Behaviors, specBehaviors: Behaviors): FieldDiff[];
|
|
39
|
+
export declare function audit(projectRoot: string): Promise<AuditResult[]>;
|
|
40
|
+
export declare function formatDiff(diff: FieldDiff): string[];
|
|
41
|
+
export declare function formatResult(result: AuditResult): string[];
|
|
42
|
+
export declare function specAuditCommand(args: string[]): Promise<void>;
|