agent-work-loop 0.0.0 → 0.6.22
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/README.md +272 -12
- package/dist/brief-Z3JKXEUP.js +181 -0
- package/dist/changelog-R7BNBF2C.js +62 -0
- package/dist/chunk-4OCSYHYB.js +274 -0
- package/dist/chunk-6E7XEQOH.js +27 -0
- package/dist/chunk-7SYRDDTX.js +516 -0
- package/dist/chunk-BUWGQVHT.js +1243 -0
- package/dist/chunk-C7TN3LM3.js +448 -0
- package/dist/chunk-CCMG377E.js +771 -0
- package/dist/chunk-D5OINC3G.js +52 -0
- package/dist/chunk-F5LHXBH7.js +209 -0
- package/dist/chunk-FBEUJR2P.js +446 -0
- package/dist/chunk-I77CXOEX.js +693 -0
- package/dist/chunk-LMWAVN7B.js +904 -0
- package/dist/chunk-O7GRZZPJ.js +347 -0
- package/dist/chunk-TKPHC32G.js +96 -0
- package/dist/chunk-UOPWVM2H.js +727 -0
- package/dist/chunk-VU6IPRRM.js +166 -0
- package/dist/chunk-X5LMP5J7.js +307 -0
- package/dist/chunk-ZLTOL3D3.js +286 -0
- package/dist/cli.js +373 -11
- package/dist/commit-APXIVOSD.js +411 -0
- package/dist/config-TFMW7O4T.js +34 -0
- package/dist/doctor-BU6HWXE4.js +29 -0
- package/dist/evolve-NNQX2A43.js +38 -0
- package/dist/feedback-KAXNFMUY.js +125 -0
- package/dist/gotchas-CW4KZDEF.js +43 -0
- package/dist/hold-recheck-SLI7NDLU.js +133 -0
- package/dist/init-UDM5AXKI.js +79 -0
- package/dist/lane-MIVLTDEU.js +41 -0
- package/dist/loop-summary-XAI6KOGB.js +361 -0
- package/dist/metrics-WLRZZRTK.js +25 -0
- package/dist/record-UKDIUJ5T.js +68 -0
- package/dist/review-NTZ3HY3N.js +118 -0
- package/dist/rules-4VDP5LZW.js +33 -0
- package/dist/state-XM7NZ2HA.js +37 -0
- package/dist/status-I3MQOCQM.js +40 -0
- package/dist/uninstall-MOHJDMQH.js +545 -0
- package/dist/update-AYTBYAHI.js +61 -0
- package/dist/verify-6YF5FXWM.js +37 -0
- package/dist/version-check-G27JYMTZ.js +14 -0
- package/dist/work-6MMIQMUC.js +50 -0
- package/engine/skills/claude/awl-loop/SKILL.md +292 -0
- package/engine/skills/claude/awl-loop/reference.md +131 -0
- package/engine/skills/claude/awl-pipeline/SKILL.md +83 -0
- package/engine/skills/claude/awl-pipeline-exec/SKILL.md +200 -0
- package/engine/skills/claude/awl-pipeline-plan/SKILL.md +71 -0
- package/engine/skills/claude/awl-pipeline-review/SKILL.md +149 -0
- package/engine/skills/codex/AGENTS.awl.md +117 -0
- package/engine/templates/block-publish.mjs +9 -0
- package/engine/templates/pre-push.sample +7 -0
- package/engine/templates/related-cmd-examples.md +37 -0
- package/engine/version.json +2 -2
- package/package.json +9 -3
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import {
|
|
2
|
+
protectedFilesMessage
|
|
3
|
+
} from "./chunk-6E7XEQOH.js";
|
|
4
|
+
import {
|
|
5
|
+
gitDirtyFiles
|
|
6
|
+
} from "./chunk-CCMG377E.js";
|
|
7
|
+
import {
|
|
8
|
+
applyVerificationAttempts,
|
|
9
|
+
loadState,
|
|
10
|
+
writeState
|
|
11
|
+
} from "./chunk-4OCSYHYB.js";
|
|
12
|
+
import {
|
|
13
|
+
CommandNotFoundError,
|
|
14
|
+
VERIFY_ORDER,
|
|
15
|
+
requireConfig,
|
|
16
|
+
run
|
|
17
|
+
} from "./chunk-UOPWVM2H.js";
|
|
18
|
+
import {
|
|
19
|
+
caps,
|
|
20
|
+
card,
|
|
21
|
+
makeColors,
|
|
22
|
+
signal
|
|
23
|
+
} from "./chunk-7SYRDDTX.js";
|
|
24
|
+
|
|
25
|
+
// src/commands/verify.ts
|
|
26
|
+
import fs from "fs";
|
|
27
|
+
import path from "path";
|
|
28
|
+
async function runVerifyChecks(verify, projectRoot, opts) {
|
|
29
|
+
const results = [];
|
|
30
|
+
let passed = true;
|
|
31
|
+
for (const name of VERIFY_ORDER) {
|
|
32
|
+
const entry = verify[name];
|
|
33
|
+
if (!entry) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const cwd = entry.cwd ? path.isAbsolute(entry.cwd) ? entry.cwd : path.join(projectRoot, entry.cwd) : projectRoot;
|
|
37
|
+
if (!fs.existsSync(cwd) || !fs.statSync(cwd).isDirectory()) {
|
|
38
|
+
passed = false;
|
|
39
|
+
results.push({
|
|
40
|
+
name,
|
|
41
|
+
exitCode: null,
|
|
42
|
+
durationMs: 0,
|
|
43
|
+
output: "",
|
|
44
|
+
error: "cwd_not_found"
|
|
45
|
+
});
|
|
46
|
+
if (opts.bail) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const r = await run({
|
|
53
|
+
cmd: entry.cmd,
|
|
54
|
+
env: entry.env,
|
|
55
|
+
cwd,
|
|
56
|
+
timeoutMs: 6e5
|
|
57
|
+
});
|
|
58
|
+
const result = {
|
|
59
|
+
name,
|
|
60
|
+
exitCode: r.exitCode,
|
|
61
|
+
durationMs: r.durationMs,
|
|
62
|
+
output: `${r.stdout}${r.stderr}`.trim(),
|
|
63
|
+
timedOut: r.timedOut
|
|
64
|
+
};
|
|
65
|
+
const ok = isCheckPassed(result);
|
|
66
|
+
if (!ok) {
|
|
67
|
+
passed = false;
|
|
68
|
+
}
|
|
69
|
+
results.push(result);
|
|
70
|
+
if (!ok && opts.bail) {
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
} catch (e) {
|
|
74
|
+
passed = false;
|
|
75
|
+
if (e instanceof CommandNotFoundError) {
|
|
76
|
+
results.push({
|
|
77
|
+
name,
|
|
78
|
+
exitCode: null,
|
|
79
|
+
durationMs: 0,
|
|
80
|
+
output: "",
|
|
81
|
+
error: "command_not_found"
|
|
82
|
+
});
|
|
83
|
+
} else {
|
|
84
|
+
results.push({ name, exitCode: null, durationMs: 0, output: String(e) });
|
|
85
|
+
}
|
|
86
|
+
if (opts.bail) {
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { passed, results };
|
|
92
|
+
}
|
|
93
|
+
function renderVerify(report, c) {
|
|
94
|
+
const color = makeColors(c.color);
|
|
95
|
+
const out = [];
|
|
96
|
+
for (const r of report.results) {
|
|
97
|
+
const mark = r.error === "command_not_found" ? `${signal(c, "error")} \uBA85\uB839 \uC5C6\uC74C` : r.error === "cwd_not_found" ? `${signal(c, "error")} cwd \uC5C6\uC74C` : isCheckPassed(r) ? `${signal(c, "ok")} \uD1B5\uACFC` : `${signal(c, "error")} \uC2E4\uD328`;
|
|
98
|
+
const dur = r.error ? "" : color.dim(`${r.durationMs}ms`);
|
|
99
|
+
out.push(`${r.name.padEnd(10, " ")}${mark} ${dur}`);
|
|
100
|
+
}
|
|
101
|
+
out.push("");
|
|
102
|
+
out.push(
|
|
103
|
+
report.passed ? `${signal(c, "ok")} \uC804\uBD80 \uD1B5\uACFC\uD588\uC2B5\uB2C8\uB2E4.` : `${signal(c, "error")} \uC2E4\uD328\uD55C \uAC80\uC99D\uC774 \uC788\uC2B5\uB2C8\uB2E4.`
|
|
104
|
+
);
|
|
105
|
+
return card("\uAC80\uC99D \uACB0\uACFC", out, c);
|
|
106
|
+
}
|
|
107
|
+
function isCheckPassed(r) {
|
|
108
|
+
return !r.error && !r.timedOut && r.exitCode === 0;
|
|
109
|
+
}
|
|
110
|
+
function buildVerifyBaseline(report, capturedAt, workitem) {
|
|
111
|
+
return {
|
|
112
|
+
capturedAt,
|
|
113
|
+
workitem,
|
|
114
|
+
results: report.results.map((r) => ({ name: r.name, passed: isCheckPassed(r) }))
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function verifyBaselinePath(projectRoot) {
|
|
118
|
+
return path.join(projectRoot, ".awl", "verify-baseline.json");
|
|
119
|
+
}
|
|
120
|
+
function ensureVerifyBaselineGitignored(projectRoot) {
|
|
121
|
+
const gi = path.join(projectRoot, ".gitignore");
|
|
122
|
+
const target = ".awl/verify-baseline.json";
|
|
123
|
+
const content = fs.existsSync(gi) ? fs.readFileSync(gi, "utf8") : "";
|
|
124
|
+
if (content.split(/\r?\n/).some((line) => line.trim() === target)) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const prefix = content.length > 0 && !content.endsWith("\n") ? "\n" : "";
|
|
128
|
+
fs.writeFileSync(gi, `${content}${prefix}${target}
|
|
129
|
+
`);
|
|
130
|
+
}
|
|
131
|
+
function writeVerifyBaseline(projectRoot, baseline) {
|
|
132
|
+
const p = verifyBaselinePath(projectRoot);
|
|
133
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
134
|
+
fs.writeFileSync(p, `${JSON.stringify(baseline, null, 2)}
|
|
135
|
+
`);
|
|
136
|
+
ensureVerifyBaselineGitignored(projectRoot);
|
|
137
|
+
}
|
|
138
|
+
function readVerifyBaseline(projectRoot) {
|
|
139
|
+
try {
|
|
140
|
+
const raw = JSON.parse(fs.readFileSync(verifyBaselinePath(projectRoot), "utf8"));
|
|
141
|
+
if (!raw || !Array.isArray(raw.results)) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
return raw;
|
|
145
|
+
} catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function compareSinceBaseline(report, baseline) {
|
|
150
|
+
const baselineMap = new Map(baseline.results.map((r) => [r.name, r.passed]));
|
|
151
|
+
const newFailures = [];
|
|
152
|
+
const preExistingFailures = [];
|
|
153
|
+
const resolved = [];
|
|
154
|
+
for (const r of report.results) {
|
|
155
|
+
const nowPassed = isCheckPassed(r);
|
|
156
|
+
const wasPassed = baselineMap.get(r.name);
|
|
157
|
+
if (nowPassed) {
|
|
158
|
+
if (wasPassed === false) {
|
|
159
|
+
resolved.push(r.name);
|
|
160
|
+
}
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (wasPassed === false) {
|
|
164
|
+
preExistingFailures.push(r.name);
|
|
165
|
+
} else {
|
|
166
|
+
newFailures.push(r.name);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return { passed: newFailures.length === 0, newFailures, preExistingFailures, resolved };
|
|
170
|
+
}
|
|
171
|
+
function renderSinceBaseline(c, caps2) {
|
|
172
|
+
const color = makeColors(caps2.color);
|
|
173
|
+
const out = ["", " \uBCA0\uC774\uC2A4\uB77C\uC778 \uB300\uBE44"];
|
|
174
|
+
if (c.newFailures.length > 0) {
|
|
175
|
+
out.push(` ${color.red("\uC2E0\uADDC \uC2E4\uD328")}: ${c.newFailures.join(", ")}`);
|
|
176
|
+
}
|
|
177
|
+
if (c.preExistingFailures.length > 0) {
|
|
178
|
+
out.push(` ${color.dim("\uC0AC\uC804 \uACB0\uD568(\uBCC0\uD654 \uC5C6\uC74C)")}: ${c.preExistingFailures.join(", ")}`);
|
|
179
|
+
}
|
|
180
|
+
if (c.resolved.length > 0) {
|
|
181
|
+
out.push(` ${color.green("\uD574\uC18C\uB428")}: ${c.resolved.join(", ")}`);
|
|
182
|
+
}
|
|
183
|
+
if (c.newFailures.length === 0 && c.preExistingFailures.length === 0 && c.resolved.length === 0) {
|
|
184
|
+
out.push(` ${color.dim("\uBCC0\uD654 \uC5C6\uC74C")}`);
|
|
185
|
+
}
|
|
186
|
+
out.push("");
|
|
187
|
+
out.push(c.passed ? ` ${color.green("\uD68C\uADC0 \uC5C6\uC74C.")}` : ` ${color.red("\uD68C\uADC0\uAC00 \uC788\uC2B5\uB2C8\uB2E4.")}`);
|
|
188
|
+
return out.join("\n");
|
|
189
|
+
}
|
|
190
|
+
function resolveSinceBaseline(report, baseline, currentWorkitem) {
|
|
191
|
+
if (!baseline) {
|
|
192
|
+
return { available: false, reason: "no_baseline" };
|
|
193
|
+
}
|
|
194
|
+
if (baseline.workitem !== currentWorkitem) {
|
|
195
|
+
return { available: false, reason: "workitem_mismatch" };
|
|
196
|
+
}
|
|
197
|
+
return { available: true, comparison: compareSinceBaseline(report, baseline) };
|
|
198
|
+
}
|
|
199
|
+
function sinceBaselineFallbackMessage(reason) {
|
|
200
|
+
if (reason === "workitem_mismatch") {
|
|
201
|
+
return "\n \uAC80\uC99D \uBCA0\uC774\uC2A4\uB77C\uC778\uC774 \uB2E4\uB978 \uC6CC\uD06C\uC544\uC774\uD15C \uAC83\uC785\uB2C8\uB2E4 \u2014 --since-baseline \uC744 \uBABB \uC501\uB2C8\uB2E4. \uC804\uCCB4 \uAC80\uC99D \uACB0\uACFC\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.\n (\uC774 \uC6CC\uD06C\uC544\uC774\uD15C\uC758 \uBCA0\uC774\uC2A4\uB77C\uC778\uC744 \uB2E4\uC2DC \uCEA1\uCC98\uD558\uB294 \uAE30\uB2A5\uC740 \uC544\uC9C1 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uC9C0\uAE08\uC740 \uC704 \uC804\uCCB4 \uAC80\uC99D \uACB0\uACFC\uB85C \uD310\uB2E8\uD558\uC138\uC694.)\n";
|
|
202
|
+
}
|
|
203
|
+
return "\n \uAC80\uC99D \uBCA0\uC774\uC2A4\uB77C\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 --since-baseline \uC744 \uBABB \uC501\uB2C8\uB2E4. \uC804\uCCB4 \uAC80\uC99D \uACB0\uACFC\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.\n (awl work new \uB85C \uC6CC\uD06C\uC544\uC774\uD15C\uC744 \uC2DC\uC791\uD558\uBA74 \uBCA0\uC774\uC2A4\uB77C\uC778\uC774 \uC790\uB3D9\uC73C\uB85C \uC7A1\uD799\uB2C8\uB2E4.)\n";
|
|
204
|
+
}
|
|
205
|
+
function substituteRelatedCmd(template, changedFiles) {
|
|
206
|
+
const quoted = changedFiles.map((f) => `"${f}"`).join(" ");
|
|
207
|
+
return template.replaceAll("{files}", quoted);
|
|
208
|
+
}
|
|
209
|
+
async function runOneCommand(name, cmd, env, cwd) {
|
|
210
|
+
try {
|
|
211
|
+
const r = await run({ cmd, env, cwd, timeoutMs: 6e5 });
|
|
212
|
+
return {
|
|
213
|
+
name,
|
|
214
|
+
exitCode: r.exitCode,
|
|
215
|
+
durationMs: r.durationMs,
|
|
216
|
+
output: `${r.stdout}${r.stderr}`.trim(),
|
|
217
|
+
timedOut: r.timedOut
|
|
218
|
+
};
|
|
219
|
+
} catch (e) {
|
|
220
|
+
return {
|
|
221
|
+
name,
|
|
222
|
+
exitCode: null,
|
|
223
|
+
durationMs: 0,
|
|
224
|
+
output: "",
|
|
225
|
+
error: e instanceof CommandNotFoundError ? "command_not_found" : void 0
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async function runRelatedTests(config, projectRoot, changedFiles) {
|
|
230
|
+
if (config.relatedCmd) {
|
|
231
|
+
const cmd = substituteRelatedCmd(config.relatedCmd, changedFiles);
|
|
232
|
+
return {
|
|
233
|
+
usedRelatedCmd: true,
|
|
234
|
+
changedFiles,
|
|
235
|
+
result: await runOneCommand("related", cmd, void 0, projectRoot)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
const testEntry = config.verify.test;
|
|
239
|
+
if (!testEntry) {
|
|
240
|
+
return {
|
|
241
|
+
usedRelatedCmd: false,
|
|
242
|
+
changedFiles,
|
|
243
|
+
result: {
|
|
244
|
+
name: "test",
|
|
245
|
+
exitCode: null,
|
|
246
|
+
durationMs: 0,
|
|
247
|
+
output: "",
|
|
248
|
+
error: "command_not_found"
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
usedRelatedCmd: false,
|
|
254
|
+
changedFiles,
|
|
255
|
+
result: await runOneCommand("test", testEntry.cmd, testEntry.env, projectRoot)
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
async function runVerify(opts) {
|
|
259
|
+
const { projectRoot, config } = requireConfig();
|
|
260
|
+
if (!opts.force) {
|
|
261
|
+
const protection = await protectedFilesMessage(projectRoot, config.protectedFiles);
|
|
262
|
+
if (protection) {
|
|
263
|
+
process.stderr.write(`
|
|
264
|
+
${signal(caps(), "error")} ${protection}
|
|
265
|
+
`);
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (opts.related) {
|
|
270
|
+
const changedFiles = await gitDirtyFiles(projectRoot) ?? [];
|
|
271
|
+
const outcome = await runRelatedTests(config, projectRoot, changedFiles);
|
|
272
|
+
persistVerificationAttempts(projectRoot, isCheckPassed(outcome.result));
|
|
273
|
+
if (opts.json) {
|
|
274
|
+
process.stdout.write(`${JSON.stringify(outcome, null, 2)}
|
|
275
|
+
`);
|
|
276
|
+
} else {
|
|
277
|
+
if (!outcome.usedRelatedCmd) {
|
|
278
|
+
process.stdout.write(
|
|
279
|
+
"\n relatedCmd \uAC00 \uC124\uC815\uB3FC \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 \uC804\uCCB4 \uD14C\uC2A4\uD2B8\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.\n (config.json \uC5D0 relatedCmd \uB97C \uC124\uC815\uD558\uBA74 \uBCC0\uACBD \uD30C\uC77C\uC5D0 \uAD00\uB828\uB41C \uD14C\uC2A4\uD2B8\uB9CC \uC2E4\uD589\uD569\uB2C8\uB2E4. \uC608\uC2DC: engine/templates/related-cmd-examples.md)\n"
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
process.stdout.write(
|
|
283
|
+
`${renderVerify({ passed: isCheckPassed(outcome.result), results: [outcome.result] }, caps())}
|
|
284
|
+
`
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
process.exit(isCheckPassed(outcome.result) ? 0 : 1);
|
|
288
|
+
}
|
|
289
|
+
const report = await runVerifyChecks(config.verify, projectRoot, { bail: opts.bail });
|
|
290
|
+
persistVerificationAttempts(projectRoot, report.passed);
|
|
291
|
+
if (opts.sinceBaseline) {
|
|
292
|
+
const baseline = readVerifyBaseline(projectRoot);
|
|
293
|
+
const state = loadState(projectRoot);
|
|
294
|
+
const currentWorkitem = typeof state.workitem === "string" ? state.workitem : null;
|
|
295
|
+
const resolution = resolveSinceBaseline(report, baseline, currentWorkitem);
|
|
296
|
+
if (opts.json) {
|
|
297
|
+
process.stdout.write(
|
|
298
|
+
`${JSON.stringify({ ...report, sinceBaseline: resolution }, null, 2)}
|
|
299
|
+
`
|
|
300
|
+
);
|
|
301
|
+
} else {
|
|
302
|
+
process.stdout.write(`${renderVerify(report, caps())}
|
|
303
|
+
`);
|
|
304
|
+
if (resolution.available) {
|
|
305
|
+
process.stdout.write(`${renderSinceBaseline(resolution.comparison, caps())}
|
|
306
|
+
`);
|
|
307
|
+
} else {
|
|
308
|
+
process.stdout.write(sinceBaselineFallbackMessage(resolution.reason));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
process.exit((resolution.available ? resolution.comparison.passed : report.passed) ? 0 : 1);
|
|
312
|
+
}
|
|
313
|
+
if (opts.json) {
|
|
314
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}
|
|
315
|
+
`);
|
|
316
|
+
} else {
|
|
317
|
+
process.stdout.write(`${renderVerify(report, caps())}
|
|
318
|
+
`);
|
|
319
|
+
}
|
|
320
|
+
process.exit(report.passed ? 0 : 1);
|
|
321
|
+
}
|
|
322
|
+
function persistVerificationAttempts(projectRoot, passed) {
|
|
323
|
+
const attempted = applyVerificationAttempts(loadState(projectRoot), passed);
|
|
324
|
+
writeState(projectRoot, attempted.state);
|
|
325
|
+
if (attempted.blocked.length > 0) {
|
|
326
|
+
process.stderr.write(
|
|
327
|
+
`
|
|
328
|
+
${signal(caps(), "warn")} \uAC80\uC99D 3\uD68C \uC2E4\uD328: ${attempted.blocked.join(", ")} \uC744(\uB97C) \uC790\uB3D9 \uCC28\uB2E8\uD588\uC2B5\uB2C8\uB2E4. (autoBlocked)
|
|
329
|
+
`
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export {
|
|
335
|
+
runVerifyChecks,
|
|
336
|
+
isCheckPassed,
|
|
337
|
+
buildVerifyBaseline,
|
|
338
|
+
verifyBaselinePath,
|
|
339
|
+
writeVerifyBaseline,
|
|
340
|
+
readVerifyBaseline,
|
|
341
|
+
compareSinceBaseline,
|
|
342
|
+
resolveSinceBaseline,
|
|
343
|
+
sinceBaselineFallbackMessage,
|
|
344
|
+
substituteRelatedCmd,
|
|
345
|
+
runRelatedTests,
|
|
346
|
+
runVerify
|
|
347
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkVersions,
|
|
3
|
+
getLatestVersionCached,
|
|
4
|
+
name,
|
|
5
|
+
version
|
|
6
|
+
} from "./chunk-VU6IPRRM.js";
|
|
7
|
+
import {
|
|
8
|
+
resolveProjectRoot
|
|
9
|
+
} from "./chunk-UOPWVM2H.js";
|
|
10
|
+
import {
|
|
11
|
+
packageEngineDir,
|
|
12
|
+
skillsVersionPath
|
|
13
|
+
} from "./chunk-BUWGQVHT.js";
|
|
14
|
+
import {
|
|
15
|
+
caps,
|
|
16
|
+
card,
|
|
17
|
+
installedEngineVersion,
|
|
18
|
+
makeColors,
|
|
19
|
+
makeSymbols,
|
|
20
|
+
makeTokens,
|
|
21
|
+
signal
|
|
22
|
+
} from "./chunk-7SYRDDTX.js";
|
|
23
|
+
|
|
24
|
+
// src/commands/version-check.ts
|
|
25
|
+
import fs from "fs";
|
|
26
|
+
import path from "path";
|
|
27
|
+
function readJson(p) {
|
|
28
|
+
try {
|
|
29
|
+
return JSON.parse(fs.readFileSync(p, "utf8"));
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function readVersionField(p, field) {
|
|
35
|
+
const raw = readJson(p);
|
|
36
|
+
if (raw && typeof raw === "object") {
|
|
37
|
+
const v = raw[field];
|
|
38
|
+
if (typeof v === "string") {
|
|
39
|
+
return v;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function gatherVersionInputs(projectRoot, npmLatestVersion = null) {
|
|
45
|
+
const engineSourceVersion = readVersionField(
|
|
46
|
+
path.join(packageEngineDir(), "version.json"),
|
|
47
|
+
"engineVersion"
|
|
48
|
+
);
|
|
49
|
+
const installed = installedEngineVersion();
|
|
50
|
+
const projectEngineVersion = projectRoot ? readVersionField(path.join(projectRoot, ".awl", "config.json"), "engineVersion") : null;
|
|
51
|
+
const skillsRaw = projectRoot ? readJson(skillsVersionPath(projectRoot)) : null;
|
|
52
|
+
const installedSkillVersions = {
|
|
53
|
+
claude: skillsRaw && typeof skillsRaw === "object" ? typeof skillsRaw.claude === "string" ? skillsRaw.claude : null : null,
|
|
54
|
+
codex: skillsRaw && typeof skillsRaw === "object" ? typeof skillsRaw.codex === "string" ? skillsRaw.codex : null : null
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
packageVersion: version,
|
|
58
|
+
engineSourceVersion,
|
|
59
|
+
installedEngineVersion: installed,
|
|
60
|
+
projectEngineVersion,
|
|
61
|
+
installedSkillVersions,
|
|
62
|
+
npmLatestVersion
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function renderVersionCheck(result, c) {
|
|
66
|
+
const color = makeColors(c.color);
|
|
67
|
+
const s = makeSymbols(c);
|
|
68
|
+
const t = makeTokens(c);
|
|
69
|
+
if (result.ok) {
|
|
70
|
+
return card("\uBC84\uC804 \uD655\uC778", [`${signal(c, "ok")} \uBC84\uC804\uC774 \uC804\uBD80 \uC77C\uCE58\uD569\uB2C8\uB2E4.`], c);
|
|
71
|
+
}
|
|
72
|
+
const out = [];
|
|
73
|
+
for (const m of result.mismatches) {
|
|
74
|
+
out.push(`${signal(c, "warn")} ${m.kind}: ${t.emphasis(m.a)} / ${t.emphasis(m.b)}`);
|
|
75
|
+
out.push(`${s.lastBranch} ${color.dim(m.hint)}`);
|
|
76
|
+
}
|
|
77
|
+
return card(`\uBC84\uC804 \uBD88\uC77C\uCE58 ${result.mismatches.length}\uAC74`, out, c);
|
|
78
|
+
}
|
|
79
|
+
async function runVersionCheck(opts) {
|
|
80
|
+
const projectRoot = resolveProjectRoot();
|
|
81
|
+
const npmLatestVersion = await getLatestVersionCached(name);
|
|
82
|
+
const inputs = gatherVersionInputs(projectRoot, npmLatestVersion);
|
|
83
|
+
const result = checkVersions(inputs);
|
|
84
|
+
if (opts.json) {
|
|
85
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
86
|
+
`);
|
|
87
|
+
} else {
|
|
88
|
+
process.stdout.write(renderVersionCheck(result, caps()));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export {
|
|
93
|
+
gatherVersionInputs,
|
|
94
|
+
renderVersionCheck,
|
|
95
|
+
runVersionCheck
|
|
96
|
+
};
|