agent-work-loop 0.0.0 → 0.6.23

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 (54) hide show
  1. package/README.md +272 -12
  2. package/dist/brief-Z3JKXEUP.js +181 -0
  3. package/dist/changelog-R7BNBF2C.js +62 -0
  4. package/dist/chunk-46HZN6UB.js +446 -0
  5. package/dist/chunk-4OCSYHYB.js +274 -0
  6. package/dist/chunk-6E7XEQOH.js +27 -0
  7. package/dist/chunk-7SYRDDTX.js +516 -0
  8. package/dist/chunk-BUWGQVHT.js +1243 -0
  9. package/dist/chunk-C7BR2DCS.js +96 -0
  10. package/dist/chunk-D5OINC3G.js +52 -0
  11. package/dist/chunk-DP4O5ME2.js +307 -0
  12. package/dist/chunk-F5LHXBH7.js +209 -0
  13. package/dist/chunk-G5LAJ5TV.js +453 -0
  14. package/dist/chunk-I77CXOEX.js +693 -0
  15. package/dist/chunk-IMB46O6S.js +286 -0
  16. package/dist/chunk-IXMAFR4Y.js +771 -0
  17. package/dist/chunk-QE2CLNBG.js +347 -0
  18. package/dist/chunk-UOPWVM2H.js +727 -0
  19. package/dist/chunk-YTAHVR4P.js +166 -0
  20. package/dist/chunk-ZE6HXOYG.js +904 -0
  21. package/dist/cli.js +374 -13
  22. package/dist/commit-APXIVOSD.js +411 -0
  23. package/dist/config-TFMW7O4T.js +34 -0
  24. package/dist/doctor-SSKNLPGH.js +29 -0
  25. package/dist/evolve-QPD7TWGO.js +38 -0
  26. package/dist/feedback-KAXNFMUY.js +125 -0
  27. package/dist/gotchas-MCA5Y76R.js +43 -0
  28. package/dist/hold-recheck-WN5EG7HD.js +133 -0
  29. package/dist/init-UDM5AXKI.js +79 -0
  30. package/dist/lane-DAZISODH.js +41 -0
  31. package/dist/loop-summary-XAI6KOGB.js +361 -0
  32. package/dist/metrics-WLRZZRTK.js +25 -0
  33. package/dist/record-UKDIUJ5T.js +68 -0
  34. package/dist/review-ZTHDJ47V.js +118 -0
  35. package/dist/rules-R2UZPIVW.js +33 -0
  36. package/dist/state-XM7NZ2HA.js +37 -0
  37. package/dist/status-L6U5KO6T.js +40 -0
  38. package/dist/uninstall-5DFEOFL5.js +545 -0
  39. package/dist/update-AYTBYAHI.js +61 -0
  40. package/dist/verify-L7ARTK42.js +37 -0
  41. package/dist/version-check-LKGU2DNF.js +14 -0
  42. package/dist/work-KEPTGZ6H.js +50 -0
  43. package/engine/skills/claude/awl-loop/SKILL.md +292 -0
  44. package/engine/skills/claude/awl-loop/reference.md +131 -0
  45. package/engine/skills/claude/awl-pipeline/SKILL.md +89 -0
  46. package/engine/skills/claude/awl-pipeline-exec/SKILL.md +200 -0
  47. package/engine/skills/claude/awl-pipeline-plan/SKILL.md +71 -0
  48. package/engine/skills/claude/awl-pipeline-review/SKILL.md +149 -0
  49. package/engine/skills/codex/AGENTS.awl.md +117 -0
  50. package/engine/templates/block-publish.mjs +9 -0
  51. package/engine/templates/pre-push.sample +7 -0
  52. package/engine/templates/related-cmd-examples.md +37 -0
  53. package/engine/version.json +2 -2
  54. package/package.json +10 -4
@@ -0,0 +1,347 @@
1
+ import {
2
+ protectedFilesMessage
3
+ } from "./chunk-6E7XEQOH.js";
4
+ import {
5
+ gitDirtyFiles
6
+ } from "./chunk-IXMAFR4Y.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
+ };