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.
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-4OCSYHYB.js +274 -0
  5. package/dist/chunk-6E7XEQOH.js +27 -0
  6. package/dist/chunk-7SYRDDTX.js +516 -0
  7. package/dist/chunk-BUWGQVHT.js +1243 -0
  8. package/dist/chunk-C7TN3LM3.js +448 -0
  9. package/dist/chunk-CCMG377E.js +771 -0
  10. package/dist/chunk-D5OINC3G.js +52 -0
  11. package/dist/chunk-F5LHXBH7.js +209 -0
  12. package/dist/chunk-FBEUJR2P.js +446 -0
  13. package/dist/chunk-I77CXOEX.js +693 -0
  14. package/dist/chunk-LMWAVN7B.js +904 -0
  15. package/dist/chunk-O7GRZZPJ.js +347 -0
  16. package/dist/chunk-TKPHC32G.js +96 -0
  17. package/dist/chunk-UOPWVM2H.js +727 -0
  18. package/dist/chunk-VU6IPRRM.js +166 -0
  19. package/dist/chunk-X5LMP5J7.js +307 -0
  20. package/dist/chunk-ZLTOL3D3.js +286 -0
  21. package/dist/cli.js +373 -11
  22. package/dist/commit-APXIVOSD.js +411 -0
  23. package/dist/config-TFMW7O4T.js +34 -0
  24. package/dist/doctor-BU6HWXE4.js +29 -0
  25. package/dist/evolve-NNQX2A43.js +38 -0
  26. package/dist/feedback-KAXNFMUY.js +125 -0
  27. package/dist/gotchas-CW4KZDEF.js +43 -0
  28. package/dist/hold-recheck-SLI7NDLU.js +133 -0
  29. package/dist/init-UDM5AXKI.js +79 -0
  30. package/dist/lane-MIVLTDEU.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-NTZ3HY3N.js +118 -0
  35. package/dist/rules-4VDP5LZW.js +33 -0
  36. package/dist/state-XM7NZ2HA.js +37 -0
  37. package/dist/status-I3MQOCQM.js +40 -0
  38. package/dist/uninstall-MOHJDMQH.js +545 -0
  39. package/dist/update-AYTBYAHI.js +61 -0
  40. package/dist/verify-6YF5FXWM.js +37 -0
  41. package/dist/version-check-G27JYMTZ.js +14 -0
  42. package/dist/work-6MMIQMUC.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 +83 -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 +9 -3
@@ -0,0 +1,545 @@
1
+ import {
2
+ branchOf,
3
+ collectLanes,
4
+ laneBranchMap,
5
+ unmergedCommitCount,
6
+ worktreeUntracked
7
+ } from "./chunk-X5LMP5J7.js";
8
+ import {
9
+ removeGitWorktree,
10
+ worktreeDirtyTracked
11
+ } from "./chunk-LMWAVN7B.js";
12
+ import "./chunk-D5OINC3G.js";
13
+ import "./chunk-O7GRZZPJ.js";
14
+ import "./chunk-6E7XEQOH.js";
15
+ import "./chunk-CCMG377E.js";
16
+ import "./chunk-TKPHC32G.js";
17
+ import "./chunk-VU6IPRRM.js";
18
+ import "./chunk-ZLTOL3D3.js";
19
+ import "./chunk-C7TN3LM3.js";
20
+ import "./chunk-F5LHXBH7.js";
21
+ import "./chunk-I77CXOEX.js";
22
+ import "./chunk-4OCSYHYB.js";
23
+ import {
24
+ resolveProjectRoot
25
+ } from "./chunk-UOPWVM2H.js";
26
+ import {
27
+ packageEngineDir
28
+ } from "./chunk-BUWGQVHT.js";
29
+ import {
30
+ caps,
31
+ card,
32
+ engineDir,
33
+ globalRoot,
34
+ gotchasDir,
35
+ legacyDeltasDir,
36
+ lockFile,
37
+ makeColors,
38
+ npmVersionCachePath,
39
+ projectsFile,
40
+ recordsDir,
41
+ rulesDir,
42
+ signal,
43
+ templatesDir
44
+ } from "./chunk-7SYRDDTX.js";
45
+
46
+ // src/commands/uninstall.ts
47
+ import fs from "fs";
48
+ import path from "path";
49
+ function requireRoot() {
50
+ const root = resolveProjectRoot();
51
+ if (!root) {
52
+ process.stderr.write("\n \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. awl init \uC744 \uC2E4\uD589\uD558\uC138\uC694.\n");
53
+ process.exit(1);
54
+ }
55
+ return root;
56
+ }
57
+ function exists(p) {
58
+ try {
59
+ return fs.existsSync(p);
60
+ } catch {
61
+ return false;
62
+ }
63
+ }
64
+ var AGENTS_MARKER_START = "<!-- awl-loop:start -->";
65
+ var AGENTS_MARKER_END = "<!-- awl-loop:end -->";
66
+ function stripAwlAgentsBlock(content) {
67
+ const start = content.indexOf(AGENTS_MARKER_START);
68
+ if (start === -1) {
69
+ return { content, removed: false };
70
+ }
71
+ const endIdx = content.indexOf(AGENTS_MARKER_END, start);
72
+ if (endIdx === -1) {
73
+ return { content, removed: false };
74
+ }
75
+ const blockEnd = endIdx + AGENTS_MARKER_END.length;
76
+ let removeStart = start;
77
+ while (removeStart > 0 && content[removeStart - 1] === "\n") {
78
+ removeStart--;
79
+ }
80
+ let removeEnd = blockEnd;
81
+ while (removeEnd < content.length && content[removeEnd] === "\n") {
82
+ removeEnd++;
83
+ }
84
+ const before = content.slice(0, removeStart);
85
+ const after = content.slice(removeEnd);
86
+ const next = before.length > 0 && after.length > 0 ? `${before}
87
+
88
+ ${after}` : `${before}${after}`;
89
+ return { content: next, removed: true };
90
+ }
91
+ function prePushMatchesTemplate(prePushPath) {
92
+ try {
93
+ const actual = fs.readFileSync(prePushPath, "utf8").trim();
94
+ const template = fs.readFileSync(path.join(packageEngineDir(), "templates", "pre-push.sample"), "utf8").trim();
95
+ return actual === template;
96
+ } catch {
97
+ return false;
98
+ }
99
+ }
100
+ var LOCK_STALE_SECS = 60;
101
+ function isProcessAlive(pid) {
102
+ try {
103
+ process.kill(pid, 0);
104
+ return true;
105
+ } catch (e) {
106
+ return e.code === "EPERM";
107
+ }
108
+ }
109
+ function checkLiveLocks(tasksDir, nowMs = Date.now()) {
110
+ const roles = ["exec", "review"];
111
+ const results = [];
112
+ for (const role of roles) {
113
+ const lockDir = path.join(tasksDir, ".locks", role);
114
+ if (!exists(lockDir)) {
115
+ continue;
116
+ }
117
+ let pid;
118
+ try {
119
+ pid = Number.parseInt(fs.readFileSync(path.join(lockDir, "pid"), "utf8").trim(), 10);
120
+ } catch {
121
+ pid = void 0;
122
+ }
123
+ if (pid === void 0 || Number.isNaN(pid) || !isProcessAlive(pid)) {
124
+ results.push({
125
+ role,
126
+ path: lockDir,
127
+ live: false,
128
+ pid,
129
+ reason: "pid \uC5C6\uC74C \uB610\uB294 \uC8FD\uC740 \uD504\uB85C\uC138\uC2A4"
130
+ });
131
+ continue;
132
+ }
133
+ let beatSec;
134
+ try {
135
+ beatSec = Number.parseInt(fs.readFileSync(path.join(lockDir, "beat"), "utf8").trim(), 10);
136
+ } catch {
137
+ beatSec = void 0;
138
+ }
139
+ const ageSec = beatSec === void 0 || Number.isNaN(beatSec) ? Number.POSITIVE_INFINITY : Math.floor(nowMs / 1e3) - beatSec;
140
+ const live = ageSec < LOCK_STALE_SECS;
141
+ results.push({
142
+ role,
143
+ path: lockDir,
144
+ live,
145
+ pid,
146
+ ageSec,
147
+ reason: live ? void 0 : `heartbeat stale(${LOCK_STALE_SECS}\uCD08 \uC774\uC0C1)`
148
+ });
149
+ }
150
+ return results;
151
+ }
152
+ function awlSkillDirNames(root) {
153
+ const dir = path.join(root, ".claude", "skills");
154
+ try {
155
+ return fs.readdirSync(dir, { withFileTypes: true }).filter(
156
+ (e) => e.isDirectory() && (e.name === "awl-loop" || e.name.startsWith("awl-pipeline"))
157
+ ).map((e) => e.name).sort();
158
+ } catch {
159
+ return [];
160
+ }
161
+ }
162
+ function findMarkerLegacyFiles(root) {
163
+ const base = path.join(root, ".tasks");
164
+ const out = [];
165
+ const walk = (dir) => {
166
+ let entries;
167
+ try {
168
+ entries = fs.readdirSync(dir, { withFileTypes: true });
169
+ } catch {
170
+ return;
171
+ }
172
+ for (const e of entries) {
173
+ const p = path.join(dir, e.name);
174
+ if (e.isDirectory()) {
175
+ walk(p);
176
+ } else if (e.isFile() && e.name.endsWith(".md") && e.name.includes("\u314D")) {
177
+ out.push(p);
178
+ }
179
+ }
180
+ };
181
+ walk(base);
182
+ return out;
183
+ }
184
+ function scanProjectLocal(root) {
185
+ const items = [];
186
+ const push = (partial) => {
187
+ items.push({ scope: "project", legacy: false, removable: true, ...partial });
188
+ };
189
+ const dotAwl = path.join(root, ".awl");
190
+ push({
191
+ category: ".awl/ (config\xB7state\xB7skills-version\xB7verify-baseline\xB7state.lock\xB7home)",
192
+ kind: "dir",
193
+ path: dotAwl,
194
+ present: exists(dotAwl)
195
+ });
196
+ for (const name of awlSkillDirNames(root)) {
197
+ const p = path.join(root, ".claude", "skills", name);
198
+ push({ category: `.claude/skills/${name}`, kind: "dir", path: p, present: true });
199
+ }
200
+ const agentsMd = path.join(root, "AGENTS.md");
201
+ const hasMarker = exists(agentsMd) && fs.readFileSync(agentsMd, "utf8").includes("awl-loop:start");
202
+ push({
203
+ category: "AGENTS.md (awl \uB9C8\uCEE4 \uAD6C\uAC04\uB9CC \u2014 \uB098\uBA38\uC9C0 \uB0B4\uC6A9 \uBCF4\uC874)",
204
+ kind: "partial",
205
+ path: agentsMd,
206
+ present: hasMarker
207
+ });
208
+ for (const sub of ["plan", "exec", "review", "archive"]) {
209
+ const p = path.join(root, ".tasks", sub);
210
+ push({ category: `.tasks/${sub}`, kind: "dir", path: p, present: exists(p) });
211
+ }
212
+ const locksPath = path.join(root, ".tasks", ".locks");
213
+ push({ category: ".tasks/.locks", kind: "dir", path: locksPath, present: exists(locksPath) });
214
+ const prePush = path.join(root, ".git", "hooks", "pre-push");
215
+ const prePushPresent = exists(prePush);
216
+ const prePushMatches = !prePushPresent || prePushMatchesTemplate(prePush);
217
+ push({
218
+ category: ".git/hooks/pre-push (awl \uD15C\uD50C\uB9BF\uACFC \uC77C\uCE58\uD560 \uB54C\uB9CC)",
219
+ kind: "partial",
220
+ path: prePush,
221
+ present: prePushPresent,
222
+ removable: prePushMatches,
223
+ detail: prePushPresent && !prePushMatches ? "\uB0B4\uC6A9\uC774 awl \uD15C\uD50C\uB9BF\uACFC \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uBCD1\uD569\uB428) \u2014 \uBCF4\uC874" : void 0
224
+ });
225
+ const legacyAwlHome = path.join(root, ".awl-home");
226
+ push({
227
+ category: ".awl-home (0.6.17 \uC774\uC804 \uB808\uAC70\uC2DC \uACBD\uB85C)",
228
+ kind: "dir",
229
+ path: legacyAwlHome,
230
+ present: exists(legacyAwlHome),
231
+ legacy: true
232
+ });
233
+ for (const f of findMarkerLegacyFiles(root)) {
234
+ push({ category: "\u314D \uB9C8\uCEE4 \uC794\uC7AC", kind: "file", path: f, present: true, legacy: true });
235
+ }
236
+ return items;
237
+ }
238
+ function findDeltasBackups(gRoot) {
239
+ try {
240
+ return fs.readdirSync(gRoot).filter((n) => n.startsWith("deltas.backup-")).map((n) => path.join(gRoot, n));
241
+ } catch {
242
+ return [];
243
+ }
244
+ }
245
+ function scanGlobal() {
246
+ const items = [];
247
+ const push = (category, p, kind = "dir", legacy = false) => {
248
+ items.push({
249
+ scope: "global",
250
+ legacy,
251
+ kind,
252
+ path: p,
253
+ present: exists(p),
254
+ removable: true,
255
+ category
256
+ });
257
+ };
258
+ push("engine/", engineDir());
259
+ push("records/", recordsDir());
260
+ push("gotchas/", gotchasDir());
261
+ push("rules/", rulesDir());
262
+ push("generations/", path.join(globalRoot(), "generations"));
263
+ push("templates/", templatesDir());
264
+ push("projects.json", projectsFile(), "file");
265
+ push(".lock", lockFile(), "file");
266
+ push("npm-latest-cache.json", npmVersionCachePath(), "file");
267
+ push("deltas/ (\uB808\uAC70\uC2DC, gotchas \uAC1C\uBA85 \uC774\uC804)", legacyDeltasDir(), "dir", true);
268
+ for (const b of findDeltasBackups(globalRoot())) {
269
+ items.push({
270
+ scope: "global",
271
+ legacy: true,
272
+ kind: "file",
273
+ path: b,
274
+ present: true,
275
+ removable: true,
276
+ category: "deltas.backup-* (\uB808\uAC70\uC2DC)"
277
+ });
278
+ }
279
+ return items;
280
+ }
281
+ async function removeLaneSafely(root, lane) {
282
+ const branches = await laneBranchMap(root);
283
+ const branch = branchOf(branches, lane.path) ?? `work/${lane.name}`;
284
+ const dirty = await worktreeDirtyTracked(root, lane.path);
285
+ if (dirty.dirty) {
286
+ return {
287
+ name: lane.name,
288
+ removed: false,
289
+ reason: `\uCEE4\uBC0B\uB418\uC9C0 \uC54A\uC740 \uBCC0\uACBD ${dirty.count}\uAC74 (\uC608: ${dirty.first})`
290
+ };
291
+ }
292
+ const untracked = await worktreeUntracked(root, lane.path);
293
+ if (untracked.untracked) {
294
+ return {
295
+ name: lane.name,
296
+ removed: false,
297
+ reason: `\uCEE4\uBC0B\uB418\uC9C0 \uC54A\uC740 \uC0C8 \uD30C\uC77C ${untracked.count}\uAC74 (\uC608: ${untracked.first})`
298
+ };
299
+ }
300
+ const unmerged = await unmergedCommitCount(root, branch);
301
+ if (unmerged === null) {
302
+ return {
303
+ name: lane.name,
304
+ removed: false,
305
+ reason: `\uB808\uC778 \uBE0C\uB79C\uCE58 ${branch} \uC758 \uBBF8\uBA38\uC9C0 \uCEE4\uBC0B \uC218\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`
306
+ };
307
+ }
308
+ if (unmerged > 0) {
309
+ return {
310
+ name: lane.name,
311
+ removed: false,
312
+ reason: `\uB808\uC778 \uBE0C\uB79C\uCE58 ${branch} \uC5D0 \uBCD1\uD569\uB418\uC9C0 \uC54A\uC740 \uCEE4\uBC0B ${unmerged}\uAC1C`
313
+ };
314
+ }
315
+ const removed = await removeGitWorktree(root, lane.path, branch);
316
+ if (!removed.ok) {
317
+ return { name: lane.name, removed: false, reason: removed.error };
318
+ }
319
+ if (fs.existsSync(lane.path)) {
320
+ fs.rmSync(lane.path, { recursive: true, force: true });
321
+ }
322
+ return { name: lane.name, removed: true };
323
+ }
324
+ function resolveScope(opts) {
325
+ if (opts.all) {
326
+ return { project: true, global: true };
327
+ }
328
+ if (opts.global) {
329
+ return { project: opts.project === true, global: true };
330
+ }
331
+ return { project: true, global: false };
332
+ }
333
+ function readOtherProjects(currentRoot) {
334
+ try {
335
+ const raw = JSON.parse(fs.readFileSync(projectsFile(), "utf8"));
336
+ if (!Array.isArray(raw)) {
337
+ return [];
338
+ }
339
+ const currentResolved = path.resolve(currentRoot);
340
+ return raw.filter((p) => !!p && typeof p === "object").filter((p) => typeof p.path === "string" && path.resolve(p.path) !== currentResolved).map((p) => ({
341
+ name: typeof p.name === "string" ? p.name : void 0,
342
+ path: p.path
343
+ }));
344
+ } catch {
345
+ return [];
346
+ }
347
+ }
348
+ function renderPlan(scope, project, lanes, global, otherProjects, lockStatuses, c) {
349
+ const color = makeColors(c.color);
350
+ const lines = [];
351
+ if (scope.project) {
352
+ lines.push(color.bold("\uD504\uB85C\uC81D\uD2B8 \uB85C\uCEEC"));
353
+ const pFound = project.filter((i) => i.present);
354
+ if (pFound.length === 0 && lanes.length === 0) {
355
+ lines.push(" (\uBC1C\uACAC\uB41C \uAC83 \uC5C6\uC74C)");
356
+ }
357
+ for (const it of pFound) {
358
+ const mark = it.removable ? signal(c, "ok") : signal(c, "warn");
359
+ const suffix = it.detail ? ` \u2014 ${it.detail}` : "";
360
+ lines.push(` ${mark} ${it.legacy ? "[\uB808\uAC70\uC2DC] " : ""}${it.category}${suffix}`);
361
+ }
362
+ for (const lane of lanes) {
363
+ lines.push(
364
+ ` ${signal(c, "ok")} .awl-worktrees/${lane.name} (git worktree remove \u2014 \uACA9\uB9AC \uD559\uC2B5\uC740 \uBCD1\uD569 \uC5C6\uC774 \uD3D0\uAE30\uB429\uB2C8\uB2E4)`
365
+ );
366
+ }
367
+ const liveLocks = lockStatuses.filter((l) => l.live);
368
+ if (liveLocks.length > 0) {
369
+ lines.push("");
370
+ lines.push(` ${signal(c, "error")} \uB77C\uC774\uBE0C \uD504\uB85C\uC138\uC2A4 \uAC10\uC9C0 \u2014 --yes \uC2E4\uD589 \uC2DC \uC911\uB2E8\uB429\uB2C8\uB2E4(AC-06):`);
371
+ for (const l of liveLocks) {
372
+ lines.push(` .tasks/.locks/${l.role} PID ${l.pid} \xB7 ${l.ageSec}\uCD08 \uC804 heartbeat`);
373
+ }
374
+ }
375
+ lines.push("");
376
+ }
377
+ if (scope.global) {
378
+ lines.push(color.bold("\uC804\uC5ED (~/.awl, \uB2E4\uB978 \uD504\uB85C\uC81D\uD2B8\uC640 \uACF5\uC720)"));
379
+ if (otherProjects.length > 0) {
380
+ lines.push(
381
+ ` ${signal(c, "warn")} \uB2E4\uB978 \uB4F1\uB85D \uD504\uB85C\uC81D\uD2B8 ${otherProjects.length}\uAC1C\uC758 \uD559\uC2B5(gotchas/rules/records)\uB3C4 \uD568\uAED8 \uC0AC\uB77C\uC9D1\uB2C8\uB2E4:`
382
+ );
383
+ for (const p of otherProjects) {
384
+ lines.push(` - ${p.name ?? "(\uC774\uB984 \uC5C6\uC74C)"} (${p.path})`);
385
+ }
386
+ }
387
+ const gFound = global.filter((i) => i.present);
388
+ if (gFound.length === 0) {
389
+ lines.push(" (\uBC1C\uACAC\uB41C \uAC83 \uC5C6\uC74C)");
390
+ }
391
+ for (const it of gFound) {
392
+ lines.push(` ${signal(c, "ok")} ${it.legacy ? "[\uB808\uAC70\uC2DC] " : ""}${it.category}`);
393
+ }
394
+ lines.push("");
395
+ } else {
396
+ lines.push(color.dim("\uC804\uC5ED(~/.awl) \u2014 --global \uB610\uB294 --all \uB85C\uB9CC \uD3EC\uD568\uB429\uB2C8\uB2E4 (\uC0DD\uB7B5)"));
397
+ lines.push("");
398
+ }
399
+ lines.push(
400
+ color.dim(
401
+ "npm \uD328\uD0A4\uC9C0 \uC790\uCCB4\uB294 \uC774 \uBA85\uB839\uC73C\uB85C \uC9C0\uC6B0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uD544\uC694\uD558\uBA74 npm uninstall -g agent-work-loop \uB97C \uC9C1\uC811 \uC2E4\uD589\uD558\uC138\uC694."
402
+ )
403
+ );
404
+ return card("awl uninstall \u2014 \uB4DC\uB77C\uC774\uB7F0(dry run)", lines, c, 40);
405
+ }
406
+ async function runUninstall(opts) {
407
+ const root = requireRoot();
408
+ const c = caps();
409
+ const scope = resolveScope(opts);
410
+ const project = scope.project ? scanProjectLocal(root) : [];
411
+ const lanes = scope.project ? await collectLanes(root) : [];
412
+ const global = scope.global ? scanGlobal() : [];
413
+ const otherProjects = scope.global ? readOtherProjects(root) : [];
414
+ const lockStatuses = scope.project ? checkLiveLocks(path.join(root, ".tasks")) : [];
415
+ if (!opts.json) {
416
+ process.stdout.write(
417
+ `
418
+ ${renderPlan(scope, project, lanes, global, otherProjects, lockStatuses, c)}
419
+ `
420
+ );
421
+ }
422
+ if (!opts.yes) {
423
+ if (opts.json) {
424
+ process.stdout.write(
425
+ `${JSON.stringify(
426
+ {
427
+ dryRun: true,
428
+ scope,
429
+ project: project.filter((i) => i.present),
430
+ lanes: lanes.map((l) => l.name),
431
+ global: global.filter((i) => i.present),
432
+ otherProjects,
433
+ liveLocks: lockStatuses
434
+ },
435
+ null,
436
+ 2
437
+ )}
438
+ `
439
+ );
440
+ }
441
+ return;
442
+ }
443
+ if (scope.project) {
444
+ const liveLocks = lockStatuses.filter((l) => l.live);
445
+ if (liveLocks.length > 0) {
446
+ if (opts.json) {
447
+ process.stdout.write(
448
+ `${JSON.stringify({ dryRun: false, aborted: true, reason: "live-lock", liveLocks }, null, 2)}
449
+ `
450
+ );
451
+ } else {
452
+ const detail = liveLocks.map((l) => `.tasks/.locks/${l.role} PID ${l.pid} (${l.ageSec}\uCD08 \uC804 heartbeat)`).join(", ");
453
+ process.stderr.write(
454
+ `
455
+ ${signal(c, "error")} \uB77C\uC774\uBE0C \uD504\uB85C\uC138\uC2A4\uAC00 \uAC10\uC9C0\uB3FC \uC911\uB2E8\uD569\uB2C8\uB2E4 \u2014 ${detail}
456
+ `
457
+ );
458
+ }
459
+ process.exit(1);
460
+ }
461
+ }
462
+ const laneResults = [];
463
+ for (const lane of lanes) {
464
+ laneResults.push(await removeLaneSafely(root, lane));
465
+ }
466
+ const skippedItems = [];
467
+ for (const item of [...project, ...global]) {
468
+ if (!item.present) {
469
+ continue;
470
+ }
471
+ if (!item.removable) {
472
+ skippedItems.push({ category: item.category, reason: item.detail ?? "\uBCF4\uC874" });
473
+ continue;
474
+ }
475
+ if (path.basename(item.path) === "AGENTS.md") {
476
+ const current = fs.readFileSync(item.path, "utf8");
477
+ const stripped = stripAwlAgentsBlock(current);
478
+ if (stripped.removed) {
479
+ if (stripped.content.trim() === "") {
480
+ fs.rmSync(item.path, { force: true });
481
+ } else {
482
+ fs.writeFileSync(
483
+ item.path,
484
+ stripped.content.endsWith("\n") ? stripped.content : `${stripped.content}
485
+ `
486
+ );
487
+ }
488
+ }
489
+ continue;
490
+ }
491
+ fs.rmSync(item.path, { recursive: true, force: true });
492
+ }
493
+ const skippedLanes = laneResults.filter((r) => !r.removed);
494
+ if (opts.json) {
495
+ process.stdout.write(
496
+ `${JSON.stringify(
497
+ {
498
+ dryRun: false,
499
+ done: true,
500
+ scope,
501
+ removedLanes: laneResults.filter((r) => r.removed).map((r) => r.name),
502
+ skippedLanes,
503
+ skippedItems
504
+ },
505
+ null,
506
+ 2
507
+ )}
508
+ `
509
+ );
510
+ return;
511
+ }
512
+ const color = makeColors(c.color);
513
+ if (skippedLanes.length > 0) {
514
+ process.stdout.write(`
515
+ ${signal(c, "warn")} \uBCF4\uC874\uB41C \uB808\uC778(\uAC15\uC81C \uC81C\uAC70 \uC548 \uD568):
516
+ `);
517
+ for (const r of skippedLanes) {
518
+ process.stdout.write(` .awl-worktrees/${r.name} \u2014 ${r.reason}
519
+ `);
520
+ }
521
+ }
522
+ if (skippedItems.length > 0) {
523
+ process.stdout.write(`
524
+ ${signal(c, "warn")} \uBCF4\uC874\uB41C \uD56D\uBAA9(\uADF8\uB300\uB85C \uB460):
525
+ `);
526
+ for (const s of skippedItems) {
527
+ process.stdout.write(` ${s.category} \u2014 ${s.reason}
528
+ `);
529
+ }
530
+ }
531
+ process.stdout.write(`
532
+ ${signal(c, "ok")} ${color.bold("\uC0AD\uC81C \uC644\uB8CC")}
533
+ `);
534
+ }
535
+ export {
536
+ checkLiveLocks,
537
+ findMarkerLegacyFiles,
538
+ readOtherProjects,
539
+ removeLaneSafely,
540
+ resolveScope,
541
+ runUninstall,
542
+ scanGlobal,
543
+ scanProjectLocal,
544
+ stripAwlAgentsBlock
545
+ };
@@ -0,0 +1,61 @@
1
+ import {
2
+ packageEngineDir
3
+ } from "./chunk-BUWGQVHT.js";
4
+ import {
5
+ caps,
6
+ card,
7
+ engineDir,
8
+ installedEngineVersion,
9
+ makeSymbols,
10
+ signal
11
+ } from "./chunk-7SYRDDTX.js";
12
+
13
+ // src/commands/update.ts
14
+ import fs from "fs";
15
+ function applyUpdate() {
16
+ const fromVersion = installedEngineVersion();
17
+ if (fromVersion === null) {
18
+ return { updated: false, reason: "not-installed", fromVersion: null, toVersion: null };
19
+ }
20
+ fs.cpSync(packageEngineDir(), engineDir(), { recursive: true });
21
+ const toVersion = installedEngineVersion();
22
+ return { updated: true, fromVersion, toVersion };
23
+ }
24
+ function runUpdate() {
25
+ const result = applyUpdate();
26
+ const c = caps();
27
+ const s = makeSymbols(c);
28
+ if (!result.updated) {
29
+ process.stdout.write(
30
+ `
31
+ ${card("\uC5D4\uC9C4 \uD15C\uD50C\uB9BF", [`${signal(c, "warn")} ~/.awl \uC5D0 \uC124\uCE58\uB41C \uC5D4\uC9C4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.`, `${s.lastBranch} awl init \uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.`], c)}
32
+ `
33
+ );
34
+ return;
35
+ }
36
+ if (result.fromVersion === result.toVersion) {
37
+ process.stdout.write(
38
+ `
39
+ ${card("\uC5D4\uC9C4 \uD15C\uD50C\uB9BF", [`${signal(c, "ok")} \uC774\uBBF8 \uCD5C\uC2E0\uC785\uB2C8\uB2E4.`, `${s.lastBranch} Engine Template: v${result.toVersion}`], c)}
40
+ `
41
+ );
42
+ return;
43
+ }
44
+ process.stdout.write(
45
+ `
46
+ ${card(
47
+ "\uC5D4\uC9C4 \uD15C\uD50C\uB9BF",
48
+ [
49
+ `${signal(c, "ok")} \uC5D4\uC9C4\uC744 \uAC31\uC2E0\uD588\uC2B5\uB2C8\uB2E4.`,
50
+ `${s.branch} v${result.fromVersion ?? "(\uC5C6\uC74C)"} \u2192 v${result.toVersion}`,
51
+ `${s.lastBranch} \uD504\uB85C\uC81D\uD2B8\uBCC4 \uC124\uC815/\uC2A4\uD0AC\uC740 \uAC01 \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C awl init \uC73C\uB85C \uAC31\uC2E0\uD558\uC138\uC694.`
52
+ ],
53
+ c
54
+ )}
55
+ `
56
+ );
57
+ }
58
+ export {
59
+ applyUpdate,
60
+ runUpdate
61
+ };
@@ -0,0 +1,37 @@
1
+ import {
2
+ buildVerifyBaseline,
3
+ compareSinceBaseline,
4
+ isCheckPassed,
5
+ readVerifyBaseline,
6
+ resolveSinceBaseline,
7
+ runRelatedTests,
8
+ runVerify,
9
+ runVerifyChecks,
10
+ sinceBaselineFallbackMessage,
11
+ substituteRelatedCmd,
12
+ verifyBaselinePath,
13
+ writeVerifyBaseline
14
+ } from "./chunk-O7GRZZPJ.js";
15
+ import "./chunk-6E7XEQOH.js";
16
+ import "./chunk-CCMG377E.js";
17
+ import "./chunk-TKPHC32G.js";
18
+ import "./chunk-VU6IPRRM.js";
19
+ import "./chunk-I77CXOEX.js";
20
+ import "./chunk-4OCSYHYB.js";
21
+ import "./chunk-UOPWVM2H.js";
22
+ import "./chunk-BUWGQVHT.js";
23
+ import "./chunk-7SYRDDTX.js";
24
+ export {
25
+ buildVerifyBaseline,
26
+ compareSinceBaseline,
27
+ isCheckPassed,
28
+ readVerifyBaseline,
29
+ resolveSinceBaseline,
30
+ runRelatedTests,
31
+ runVerify,
32
+ runVerifyChecks,
33
+ sinceBaselineFallbackMessage,
34
+ substituteRelatedCmd,
35
+ verifyBaselinePath,
36
+ writeVerifyBaseline
37
+ };
@@ -0,0 +1,14 @@
1
+ import {
2
+ gatherVersionInputs,
3
+ renderVersionCheck,
4
+ runVersionCheck
5
+ } from "./chunk-TKPHC32G.js";
6
+ import "./chunk-VU6IPRRM.js";
7
+ import "./chunk-UOPWVM2H.js";
8
+ import "./chunk-BUWGQVHT.js";
9
+ import "./chunk-7SYRDDTX.js";
10
+ export {
11
+ gatherVersionInputs,
12
+ renderVersionCheck,
13
+ runVersionCheck
14
+ };
@@ -0,0 +1,50 @@
1
+ import {
2
+ abandonWorkitem,
3
+ createWorkitem,
4
+ markWorkitemDone,
5
+ removeGitWorktree,
6
+ removeWorkitemFromState,
7
+ renderWorkList,
8
+ restoreWorkitem,
9
+ runWorkAbandon,
10
+ runWorkDone,
11
+ runWorkList,
12
+ runWorkNew,
13
+ runWorkSwitch,
14
+ sanitizeForGit,
15
+ summarizeWorkitems,
16
+ withCostAtStart,
17
+ worktreeDirtyTracked
18
+ } from "./chunk-LMWAVN7B.js";
19
+ import "./chunk-D5OINC3G.js";
20
+ import "./chunk-O7GRZZPJ.js";
21
+ import "./chunk-6E7XEQOH.js";
22
+ import "./chunk-CCMG377E.js";
23
+ import "./chunk-TKPHC32G.js";
24
+ import "./chunk-VU6IPRRM.js";
25
+ import "./chunk-ZLTOL3D3.js";
26
+ import "./chunk-C7TN3LM3.js";
27
+ import "./chunk-F5LHXBH7.js";
28
+ import "./chunk-I77CXOEX.js";
29
+ import "./chunk-4OCSYHYB.js";
30
+ import "./chunk-UOPWVM2H.js";
31
+ import "./chunk-BUWGQVHT.js";
32
+ import "./chunk-7SYRDDTX.js";
33
+ export {
34
+ abandonWorkitem,
35
+ createWorkitem,
36
+ markWorkitemDone,
37
+ removeGitWorktree,
38
+ removeWorkitemFromState,
39
+ renderWorkList,
40
+ restoreWorkitem,
41
+ runWorkAbandon,
42
+ runWorkDone,
43
+ runWorkList,
44
+ runWorkNew,
45
+ runWorkSwitch,
46
+ sanitizeForGit,
47
+ summarizeWorkitems,
48
+ withCostAtStart,
49
+ worktreeDirtyTracked
50
+ };