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,516 @@
1
+ // src/core/paths.ts
2
+ import fs from "fs";
3
+ import os from "os";
4
+ import path from "path";
5
+ function globalRoot() {
6
+ const override = process.env.AWL_HOME;
7
+ if (override && override.trim() !== "") {
8
+ return path.resolve(override);
9
+ }
10
+ return path.join(os.homedir(), ".awl");
11
+ }
12
+ function engineDir() {
13
+ return path.join(globalRoot(), "engine");
14
+ }
15
+ function recordsDir() {
16
+ return path.join(globalRoot(), "records");
17
+ }
18
+ function gotchasDir() {
19
+ return path.join(globalRoot(), "gotchas");
20
+ }
21
+ function legacyDeltasDir() {
22
+ return path.join(globalRoot(), "deltas");
23
+ }
24
+ function rulesDir() {
25
+ return path.join(globalRoot(), "rules");
26
+ }
27
+ function templatesDir() {
28
+ return path.join(globalRoot(), "templates");
29
+ }
30
+ function generationsDir(project) {
31
+ return path.join(globalRoot(), "generations", project);
32
+ }
33
+ function projectsFile() {
34
+ return path.join(globalRoot(), "projects.json");
35
+ }
36
+ function lockFile() {
37
+ return path.join(globalRoot(), ".lock");
38
+ }
39
+ function npmVersionCachePath() {
40
+ return path.join(globalRoot(), "npm-latest-cache.json");
41
+ }
42
+ function findProjectRoot(cwd = process.cwd()) {
43
+ let dir = path.resolve(cwd);
44
+ for (; ; ) {
45
+ if (fs.existsSync(path.join(dir, ".git")) || fs.existsSync(path.join(dir, ".awl"))) {
46
+ return dir;
47
+ }
48
+ const parent = path.dirname(dir);
49
+ if (parent === dir) {
50
+ break;
51
+ }
52
+ dir = parent;
53
+ }
54
+ throw new Error(
55
+ `\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. '${path.resolve(cwd)}' \uC704\uCABD\uC5D0\uC11C .git \uB610\uB294 .awl \uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.`
56
+ );
57
+ }
58
+
59
+ // src/core/engine.ts
60
+ import fs2 from "fs";
61
+ import path2 from "path";
62
+ function installedEngineVersion() {
63
+ try {
64
+ const j = JSON.parse(
65
+ fs2.readFileSync(path2.join(engineDir(), "version.json"), "utf8")
66
+ );
67
+ if (j && typeof j === "object") {
68
+ const v = j.engineVersion;
69
+ if (typeof v === "string") {
70
+ return v;
71
+ }
72
+ }
73
+ } catch {
74
+ }
75
+ return null;
76
+ }
77
+
78
+ // src/core/tty.ts
79
+ function isTruthy(value) {
80
+ if (value === void 0) {
81
+ return false;
82
+ }
83
+ const v = value.trim().toLowerCase();
84
+ return v !== "" && v !== "0" && v !== "false";
85
+ }
86
+ function detectColor(env, tty, ci) {
87
+ if (ci) {
88
+ return false;
89
+ }
90
+ if (env.NO_COLOR !== void 0 && env.NO_COLOR !== "") {
91
+ return false;
92
+ }
93
+ if (env.TERM === "dumb") {
94
+ return false;
95
+ }
96
+ if (isTruthy(env.FORCE_COLOR)) {
97
+ return true;
98
+ }
99
+ if (!tty) {
100
+ return false;
101
+ }
102
+ return true;
103
+ }
104
+ function detectUnicode(env, platform, tty, ci) {
105
+ if (ci) {
106
+ return false;
107
+ }
108
+ if (env.TERM === "dumb") {
109
+ return false;
110
+ }
111
+ if (!tty) {
112
+ return false;
113
+ }
114
+ if (platform === "win32") {
115
+ if (isTruthy(env.WT_SESSION) || env.TERM_PROGRAM === "vscode") {
116
+ return true;
117
+ }
118
+ return false;
119
+ }
120
+ const locale = env.LC_ALL || env.LC_CTYPE || env.LANG || "";
121
+ return /UTF-?8/i.test(locale);
122
+ }
123
+ function computeCaps(env, platform, isTTY) {
124
+ const tty = isTTY === true;
125
+ const ci = isTruthy(env.CI);
126
+ return {
127
+ tty,
128
+ color: detectColor(env, tty, ci),
129
+ unicode: detectUnicode(env, platform, tty, ci)
130
+ };
131
+ }
132
+ function caps() {
133
+ return computeCaps(process.env, process.platform, process.stdout.isTTY === true);
134
+ }
135
+ function computeRawModeCapable(stdinIsTTY, hasSetRawMode, ci) {
136
+ if (ci) {
137
+ return false;
138
+ }
139
+ return stdinIsTTY && hasSetRawMode;
140
+ }
141
+ function rawModeCapable() {
142
+ return computeRawModeCapable(
143
+ process.stdin.isTTY === true,
144
+ typeof process.stdin.setRawMode === "function",
145
+ isTruthy(process.env.CI)
146
+ );
147
+ }
148
+ function charWidth(codePoint) {
149
+ if (codePoint === 0) {
150
+ return 0;
151
+ }
152
+ if (codePoint < 32 || codePoint >= 127 && codePoint < 160) {
153
+ return 0;
154
+ }
155
+ if (codePoint >= 768 && codePoint <= 879 || // Combining Diacritical Marks
156
+ codePoint >= 8203 && codePoint <= 8207 || // Zero-width space 등
157
+ codePoint >= 65024 && codePoint <= 65039) {
158
+ return 0;
159
+ }
160
+ return isWide(codePoint) ? 2 : 1;
161
+ }
162
+ function isWide(cp) {
163
+ return (
164
+ // emoji-presentation-default 라 VS16 없이도 2칸으로 렌더되는 것만 명시한다.
165
+ // ⚠️ ℹ️ ▶️ ™️ 처럼 기저문자가 좁은 것은 stringWidth 가 VS16(0xFE0F) 유무로 판정한다.
166
+ // (0.6.1 에서 0x2600–0x27bf 전체를 폭2로 넣었더니 텍스트-표현 기호와 awl 자체
167
+ // 글리프 ❯(U+276F 커서)·☑/☐ 체크박스까지 과대계산해 테두리가 어긋났다 — 적대검증.)
168
+ cp === 9989 || // ✅
169
+ cp === 10060 || // ❌
170
+ cp >= 4352 && cp <= 4447 || // Hangul Jamo
171
+ cp >= 11904 && cp <= 12350 || // CJK Radicals ~ CJK Symbols
172
+ cp >= 12353 && cp <= 13311 || // Hiragana ~ CJK Compatibility
173
+ cp >= 13312 && cp <= 19903 || // CJK Ext A
174
+ cp >= 19968 && cp <= 40959 || // CJK Unified Ideographs
175
+ cp >= 40960 && cp <= 42191 || // Yi
176
+ cp >= 44032 && cp <= 55203 || // Hangul Syllables
177
+ cp >= 63744 && cp <= 64255 || // CJK Compatibility Ideographs
178
+ cp >= 65072 && cp <= 65103 || // CJK Compatibility Forms
179
+ cp >= 65280 && cp <= 65376 || // Fullwidth Forms
180
+ cp >= 65504 && cp <= 65510 || // Fullwidth signs
181
+ cp >= 127744 && cp <= 129791 || // 넓은 기호(대비용; 이모지는 우리가 안 씀)
182
+ cp >= 131072 && cp <= 262141
183
+ );
184
+ }
185
+ function stringWidth(str) {
186
+ let width = 0;
187
+ let prevWidth = 0;
188
+ for (const ch of str) {
189
+ const cp = ch.codePointAt(0) ?? 0;
190
+ if (cp === 65039) {
191
+ if (prevWidth === 1) {
192
+ width += 1;
193
+ prevWidth = 2;
194
+ }
195
+ continue;
196
+ }
197
+ const w = charWidth(cp);
198
+ width += w;
199
+ prevWidth = w;
200
+ }
201
+ return width;
202
+ }
203
+ var ANSI_SGR = /\x1b\[[0-9;]*m/g;
204
+ function visibleWidth(str) {
205
+ return stringWidth(str.replace(ANSI_SGR, ""));
206
+ }
207
+ function leadingIndentPrefix(text) {
208
+ const m = /^(\s*(?:[├└│][─│\s]*|[-*•●○▪‣])?\s*)/.exec(text);
209
+ return m?.[0] ?? "";
210
+ }
211
+ function wrapToWidth(text, width, opts) {
212
+ if (width <= 0 || visibleWidth(text) <= width) {
213
+ return [text];
214
+ }
215
+ if (opts?.hanging) {
216
+ const prefix = leadingIndentPrefix(text);
217
+ const hangW = stringWidth(prefix);
218
+ if (hangW > 0 && hangW < width && text.startsWith(prefix)) {
219
+ const rest = text.slice(prefix.length);
220
+ const wrapped = wrapToWidth(rest, width - hangW);
221
+ const pad = " ".repeat(hangW);
222
+ return wrapped.map((line, i2) => i2 === 0 ? prefix + line : pad + line);
223
+ }
224
+ }
225
+ const cells = [];
226
+ let style = "";
227
+ let i = 0;
228
+ const sgr = /^\x1b\[[0-9;]*m/;
229
+ while (i < text.length) {
230
+ const seq = sgr.exec(text.slice(i))?.[0];
231
+ if (seq) {
232
+ style = seq === RESET ? "" : style + seq;
233
+ i += seq.length;
234
+ continue;
235
+ }
236
+ const cp = text.codePointAt(i) ?? 0;
237
+ const ch = String.fromCodePoint(cp);
238
+ cells.push({ style, ch, w: charWidth(cp) });
239
+ i += ch.length;
240
+ }
241
+ const render = (arr) => {
242
+ let out = "";
243
+ let open = "";
244
+ for (const cell of arr) {
245
+ if (cell.style !== open) {
246
+ if (open) out += RESET;
247
+ out += cell.style;
248
+ open = cell.style;
249
+ }
250
+ out += cell.ch;
251
+ }
252
+ return open ? out + RESET : out;
253
+ };
254
+ const lines = [];
255
+ let cur = [];
256
+ let curW = 0;
257
+ const flush = () => {
258
+ let end = cur.length;
259
+ while (end > 0 && cur[end - 1]?.ch === " ") end--;
260
+ lines.push(render(cur.slice(0, end)));
261
+ cur = [];
262
+ curW = 0;
263
+ };
264
+ for (const cell of cells) {
265
+ if (curW + cell.w > width && curW > 0) {
266
+ let br = -1;
267
+ for (let k = cur.length - 1; k >= 0; k--) {
268
+ if (cur[k]?.ch === " ") {
269
+ br = k;
270
+ break;
271
+ }
272
+ }
273
+ if (br > 0) {
274
+ const carry = cur.slice(br + 1);
275
+ cur = cur.slice(0, br);
276
+ flush();
277
+ cur = carry;
278
+ curW = carry.reduce((s, x) => s + x.w, 0);
279
+ } else {
280
+ flush();
281
+ }
282
+ }
283
+ cur.push(cell);
284
+ curW += cell.w;
285
+ }
286
+ if (cur.length) flush();
287
+ return lines.length ? lines : [""];
288
+ }
289
+ function truncateToWidth(text, width) {
290
+ if (width <= 0) {
291
+ return "";
292
+ }
293
+ const plain = text.replace(ANSI_SGR, "");
294
+ if (stringWidth(plain) <= width) {
295
+ return plain;
296
+ }
297
+ let out = "";
298
+ let w = 0;
299
+ for (const ch of plain) {
300
+ const cw = charWidth(ch.codePointAt(0) ?? 0);
301
+ if (w + cw + 1 > width) break;
302
+ out += ch;
303
+ w += cw;
304
+ }
305
+ return `${out}\u2026`;
306
+ }
307
+ function clipToWidth(text, width) {
308
+ if (width <= 0) {
309
+ return "";
310
+ }
311
+ if (visibleWidth(text) <= width) {
312
+ return text;
313
+ }
314
+ const sgr = /^\x1b\[[0-9;]*m/;
315
+ let out = "";
316
+ let w = 0;
317
+ let open = "";
318
+ let i = 0;
319
+ while (i < text.length) {
320
+ const seq = sgr.exec(text.slice(i))?.[0];
321
+ if (seq) {
322
+ out += seq;
323
+ open = seq === RESET ? "" : open + seq;
324
+ i += seq.length;
325
+ continue;
326
+ }
327
+ const cp = text.codePointAt(i) ?? 0;
328
+ const ch = String.fromCodePoint(cp);
329
+ const cw = charWidth(cp);
330
+ if (w + cw + 1 > width) {
331
+ break;
332
+ }
333
+ out += ch;
334
+ w += cw;
335
+ i += ch.length;
336
+ }
337
+ return `${out}\u2026${open ? RESET : ""}`;
338
+ }
339
+ function padEndDisplay(text, width) {
340
+ return text + " ".repeat(Math.max(0, width - stringWidth(text)));
341
+ }
342
+ var UNICODE_SYMBOLS = {
343
+ boxTL: "\u256D",
344
+ boxTR: "\u256E",
345
+ boxBL: "\u2570",
346
+ boxBR: "\u256F",
347
+ boxH: "\u2500",
348
+ boxV: "\u2502",
349
+ midL: "\u251C",
350
+ midR: "\u2524",
351
+ branch: "\u251C\u2500\u2500",
352
+ // 트리 연결자는 사각으로 둔다 — 박스 모서리(둥근 ╭╮╰╯)와 역할이 다르고,
353
+ // 코드베이스 전반이 이미 사각 └── 를 쓰므로 한 벌로 일관되게 맞춘다.
354
+ lastBranch: "\u2514\u2500\u2500",
355
+ vGuide: "\u2502",
356
+ radioOn: "\u25CF",
357
+ radioOff: "\u25CB",
358
+ checkOn: "\u2611",
359
+ checkOff: "\u2610"
360
+ };
361
+ var ASCII_SYMBOLS = {
362
+ boxTL: "+",
363
+ boxTR: "+",
364
+ boxBL: "+",
365
+ boxBR: "+",
366
+ boxH: "-",
367
+ boxV: "|",
368
+ midL: "+",
369
+ midR: "+",
370
+ branch: "|--",
371
+ lastBranch: "`--",
372
+ vGuide: "|",
373
+ radioOn: "(*)",
374
+ radioOff: "( )",
375
+ checkOn: "[x]",
376
+ checkOff: "[ ]"
377
+ };
378
+ function makeSymbols(c) {
379
+ return c.unicode ? UNICODE_SYMBOLS : ASCII_SYMBOLS;
380
+ }
381
+ var sym = makeSymbols(caps());
382
+ var HARD_MAX_WIDTH = 100;
383
+ function viewportWidth() {
384
+ const envCols = Number(process.env.COLUMNS);
385
+ if (process.stdout.columns && process.stdout.columns > 0) {
386
+ return process.stdout.columns;
387
+ }
388
+ if (Number.isFinite(envCols) && envCols > 0) {
389
+ return envCols;
390
+ }
391
+ return HARD_MAX_WIDTH;
392
+ }
393
+ function card(title, lines, c = caps(), minInnerWidth = 0) {
394
+ const s = makeSymbols(c);
395
+ const t = makeTokens(c);
396
+ const pad = 2;
397
+ const maxInner = Math.max(
398
+ minInnerWidth,
399
+ Math.min(HARD_MAX_WIDTH, viewportWidth() - (2 + pad * 2))
400
+ );
401
+ const wrapped = lines.flatMap((line) => wrapToWidth(line, maxInner, { hanging: true }));
402
+ const inner = Math.min(
403
+ maxInner,
404
+ Math.max(minInnerWidth, visibleWidth(title), ...wrapped.map(visibleWidth), 0)
405
+ );
406
+ const frame = (text) => t.frame(text);
407
+ const row = (text) => {
408
+ const gap = Math.max(0, inner - visibleWidth(text));
409
+ return `${frame(s.boxV)}${" ".repeat(pad)}${text}${" ".repeat(gap + pad)}${frame(s.boxV)}`;
410
+ };
411
+ const safeTitle = truncateToWidth(title, inner);
412
+ const tvis = visibleWidth(safeTitle);
413
+ const dash = Math.max(1, inner + pad * 2 - 3 - tvis);
414
+ const top = frame(`${s.boxTL}${s.boxH} `) + t.emphasis(t.accent(safeTitle)) + frame(` ${s.boxH.repeat(dash)}${s.boxTR}`);
415
+ const bottom = frame(`${s.boxBL}${s.boxH.repeat(inner + pad * 2)}${s.boxBR}`);
416
+ return [top, ...wrapped.map(row), bottom].join("\n");
417
+ }
418
+ var RESET = "\x1B[0m";
419
+ function ansi(code, str, enabled) {
420
+ return enabled ? `\x1B[${code}m${str}${RESET}` : str;
421
+ }
422
+ function makeTokens(c) {
423
+ const col = makeColors(c.color);
424
+ return {
425
+ emphasis: col.bold,
426
+ muted: col.dim,
427
+ danger: col.red,
428
+ warning: col.yellow,
429
+ success: col.green,
430
+ accent: col.cyan,
431
+ info: col.blue,
432
+ frame: col.gray
433
+ };
434
+ }
435
+ function signal(c, kind) {
436
+ const color2 = makeColors(c.color);
437
+ const raw = c.unicode ? { ok: "\u2705", warn: "\u26A0\uFE0F", error: "\u274C", info: "\u2139\uFE0F" }[kind] : { ok: "[ok]", warn: "[!]", error: "[x]", info: "[i]" }[kind];
438
+ if (kind === "ok") {
439
+ return color2.green(raw);
440
+ }
441
+ if (kind === "warn") {
442
+ return color2.yellow(raw);
443
+ }
444
+ if (kind === "error") {
445
+ return color2.red(raw);
446
+ }
447
+ return color2.blue(raw);
448
+ }
449
+ function statusBadge(c, status) {
450
+ const t = makeTokens(c);
451
+ const glyph = c.unicode ? { pending: "\u25CB", executing: "\u25B6", reviewing: "\u25D0", complete: "\u25CF", blocked: "\u2717" }[status] : { pending: "[.]", executing: "[>]", reviewing: "[~]", complete: "[ok]", blocked: "[x]" }[status];
452
+ const paint = {
453
+ pending: t.muted,
454
+ executing: t.accent,
455
+ reviewing: t.warning,
456
+ complete: t.success,
457
+ blocked: t.danger
458
+ }[status];
459
+ return paint(glyph);
460
+ }
461
+ function feedback(c, kind, title, detail) {
462
+ const color2 = makeColors(c.color);
463
+ const head = ` ${signal(c, kind)} ${title}`;
464
+ return detail ? `${head}
465
+ ${color2.dim(detail)}` : head;
466
+ }
467
+ function makeColors(enabled) {
468
+ return {
469
+ bold: (s) => ansi(1, s, enabled),
470
+ dim: (s) => ansi(2, s, enabled),
471
+ red: (s) => ansi(31, s, enabled),
472
+ green: (s) => ansi(32, s, enabled),
473
+ yellow: (s) => ansi(33, s, enabled),
474
+ cyan: (s) => ansi(36, s, enabled),
475
+ blue: (s) => ansi(34, s, enabled),
476
+ gray: (s) => ansi(90, s, enabled)
477
+ };
478
+ }
479
+ function gradient(lines, c) {
480
+ if (!c.color) {
481
+ return lines;
482
+ }
483
+ const palette = [51, 45, 39, 135];
484
+ return lines.map((line, index) => `\x1B[38;5;${palette[index % palette.length]}m${line}${RESET}`);
485
+ }
486
+ var color = makeColors(caps().color);
487
+
488
+ export {
489
+ globalRoot,
490
+ engineDir,
491
+ recordsDir,
492
+ gotchasDir,
493
+ legacyDeltasDir,
494
+ rulesDir,
495
+ templatesDir,
496
+ generationsDir,
497
+ projectsFile,
498
+ lockFile,
499
+ npmVersionCachePath,
500
+ findProjectRoot,
501
+ installedEngineVersion,
502
+ caps,
503
+ rawModeCapable,
504
+ stringWidth,
505
+ visibleWidth,
506
+ clipToWidth,
507
+ padEndDisplay,
508
+ makeSymbols,
509
+ card,
510
+ makeTokens,
511
+ signal,
512
+ statusBadge,
513
+ feedback,
514
+ makeColors,
515
+ gradient
516
+ };