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,133 @@
1
+ import {
2
+ pipelineLanes
3
+ } from "./chunk-FBEUJR2P.js";
4
+ import "./chunk-X5LMP5J7.js";
5
+ import "./chunk-LMWAVN7B.js";
6
+ import "./chunk-D5OINC3G.js";
7
+ import "./chunk-O7GRZZPJ.js";
8
+ import "./chunk-6E7XEQOH.js";
9
+ import "./chunk-CCMG377E.js";
10
+ import "./chunk-TKPHC32G.js";
11
+ import "./chunk-VU6IPRRM.js";
12
+ import "./chunk-ZLTOL3D3.js";
13
+ import "./chunk-C7TN3LM3.js";
14
+ import "./chunk-F5LHXBH7.js";
15
+ import "./chunk-I77CXOEX.js";
16
+ import "./chunk-4OCSYHYB.js";
17
+ import {
18
+ resolveProjectRoot
19
+ } from "./chunk-UOPWVM2H.js";
20
+ import "./chunk-BUWGQVHT.js";
21
+ import {
22
+ caps,
23
+ card,
24
+ makeColors,
25
+ signal
26
+ } from "./chunk-7SYRDDTX.js";
27
+
28
+ // src/commands/hold-recheck.ts
29
+ import fs from "fs";
30
+ import path from "path";
31
+ var HOLD_SUFFIX = ".hold.md";
32
+ var CONDITION_MARKER_RE = /un-hold\s*조건/i;
33
+ var DEP_ID_RE = /[a-z][a-z0-9]*(?:-[a-z0-9]+)+/g;
34
+ function parseHoldDependencies(content) {
35
+ const marker = CONDITION_MARKER_RE.exec(content);
36
+ if (!marker) {
37
+ return [];
38
+ }
39
+ const afterMarker = content.slice(marker.index + marker[0].length);
40
+ let clause = "";
41
+ for (const rawLine of afterMarker.split("\n")) {
42
+ const line = rawLine.replace(/^[*#\s::]+/, "").trim();
43
+ if (line.length > 0) {
44
+ clause = line;
45
+ break;
46
+ }
47
+ }
48
+ if (!clause) {
49
+ return [];
50
+ }
51
+ const ids = clause.match(DEP_ID_RE) ?? [];
52
+ return [...new Set(ids)];
53
+ }
54
+ function readDirNames(dir) {
55
+ try {
56
+ return fs.readdirSync(dir);
57
+ } catch {
58
+ return [];
59
+ }
60
+ }
61
+ function recheckHolds(root) {
62
+ const planDir = path.join(root, ".tasks", "plan");
63
+ const execDir = path.join(root, ".tasks", "exec");
64
+ const reviewDir = path.join(root, ".tasks", "review");
65
+ const planFiles = readDirNames(planDir);
66
+ const execFiles = readDirNames(execDir);
67
+ const reviewFiles = readDirNames(reviewDir);
68
+ const lanes = pipelineLanes(planFiles, execFiles, reviewFiles);
69
+ const landed = (id) => lanes.find((l) => l.name === id)?.status === "complete";
70
+ const unheld = [];
71
+ const kept = [];
72
+ for (const file of planFiles) {
73
+ if (!file.endsWith(HOLD_SUFFIX)) {
74
+ continue;
75
+ }
76
+ const name = file.slice(0, -HOLD_SUFFIX.length);
77
+ const fullPath = path.join(planDir, file);
78
+ const content = fs.readFileSync(fullPath, "utf8");
79
+ const deps = parseHoldDependencies(content);
80
+ if (deps.length === 0) {
81
+ kept.push({ name, reason: "no-condition" });
82
+ continue;
83
+ }
84
+ const waitingOn = deps.filter((d) => !landed(d));
85
+ if (waitingOn.length > 0) {
86
+ kept.push({ name, reason: "unsatisfied", waitingOn });
87
+ continue;
88
+ }
89
+ fs.renameSync(fullPath, path.join(planDir, `${name}.md`));
90
+ unheld.push(name);
91
+ }
92
+ unheld.sort();
93
+ return { unheld, kept };
94
+ }
95
+ async function runHoldRecheck(opts) {
96
+ const root = resolveProjectRoot();
97
+ if (!root) {
98
+ const cc = caps();
99
+ process.stderr.write(
100
+ `
101
+ ${signal(cc, "error")} \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
102
+ awl init \uC744 \uC2E4\uD589\uD558\uC138\uC694.
103
+ `
104
+ );
105
+ process.exit(1);
106
+ }
107
+ const result = recheckHolds(root);
108
+ if (opts.json) {
109
+ process.stdout.write(`${JSON.stringify(result, null, 2)}
110
+ `);
111
+ return;
112
+ }
113
+ const c = caps();
114
+ const color = makeColors(c.color);
115
+ const lines = [];
116
+ if (result.unheld.length === 0 && result.kept.length === 0) {
117
+ lines.push("\uC7AC\uC810\uAC80\uD560 hold \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.");
118
+ }
119
+ for (const name of result.unheld) {
120
+ lines.push(`${signal(c, "ok")} ${color.bold(name)} un-hold (\uC758\uC874 \uCC29\uC9C0+\uD569\uACA9)`);
121
+ }
122
+ for (const k of result.kept) {
123
+ const why = k.reason === "no-condition" ? "\uD328\uD134 \uC5C6\uC74C(\uC804\uB7B5\uBB38\uC11C \uB4F1)" : `\uB300\uAE30: ${(k.waitingOn ?? []).join(", ")}`;
124
+ lines.push(`${signal(c, "warn")} ${color.dim(k.name)} hold \uC720\uC9C0 ${color.dim(`(${why})`)}`);
125
+ }
126
+ process.stdout.write(`${card("hold \uC7AC\uC810\uAC80", lines, c)}
127
+ `);
128
+ }
129
+ export {
130
+ parseHoldDependencies,
131
+ recheckHolds,
132
+ runHoldRecheck
133
+ };
@@ -0,0 +1,79 @@
1
+ import {
2
+ LANG_OPTIONS,
3
+ LANG_VALUES,
4
+ applyInit,
5
+ applyVerifyCwd,
6
+ ask,
7
+ buildConfig,
8
+ buildScreens,
9
+ claudeSkillLabel,
10
+ detectAgents,
11
+ detectLanguage,
12
+ detectVerify,
13
+ detectWorkspacePackages,
14
+ ensureGitignore,
15
+ installClaudeSkill,
16
+ installCodexSkill,
17
+ installSafetyHook,
18
+ isGlobalInstalled,
19
+ nonInteractiveInputs,
20
+ packageEngineDir,
21
+ promptNumber,
22
+ promptVerifyLocation,
23
+ registerProject,
24
+ renderNonTtyNotice,
25
+ renderResult,
26
+ resolveProjectChoice,
27
+ runInit,
28
+ scaffoldGlobal,
29
+ scanGitProjects,
30
+ selectMulti,
31
+ selectSingle,
32
+ skillsVersionPath,
33
+ splitEnv,
34
+ syncExistingInstall,
35
+ verifyStepLines,
36
+ writeConfig,
37
+ writeSkillsVersionStamp,
38
+ writeState
39
+ } from "./chunk-BUWGQVHT.js";
40
+ import "./chunk-7SYRDDTX.js";
41
+ export {
42
+ LANG_OPTIONS,
43
+ LANG_VALUES,
44
+ applyInit,
45
+ applyVerifyCwd,
46
+ ask,
47
+ buildConfig,
48
+ buildScreens,
49
+ claudeSkillLabel,
50
+ detectAgents,
51
+ detectLanguage,
52
+ detectVerify,
53
+ detectWorkspacePackages,
54
+ ensureGitignore,
55
+ installClaudeSkill,
56
+ installCodexSkill,
57
+ installSafetyHook,
58
+ isGlobalInstalled,
59
+ nonInteractiveInputs,
60
+ packageEngineDir,
61
+ promptNumber,
62
+ promptVerifyLocation,
63
+ registerProject,
64
+ renderNonTtyNotice,
65
+ renderResult,
66
+ resolveProjectChoice,
67
+ runInit,
68
+ scaffoldGlobal,
69
+ scanGitProjects,
70
+ selectMulti,
71
+ selectSingle,
72
+ skillsVersionPath,
73
+ splitEnv,
74
+ syncExistingInstall,
75
+ verifyStepLines,
76
+ writeConfig,
77
+ writeSkillsVersionStamp,
78
+ writeState
79
+ };
@@ -0,0 +1,41 @@
1
+ import {
2
+ WORKTREES_DIR,
3
+ branchOf,
4
+ collectLanes,
5
+ laneBranchMap,
6
+ parseWorktreeBranches,
7
+ renderLaneList,
8
+ runLaneList,
9
+ runLaneNew,
10
+ runLaneRemove,
11
+ unmergedCommitCount,
12
+ worktreeUntracked
13
+ } from "./chunk-X5LMP5J7.js";
14
+ import "./chunk-LMWAVN7B.js";
15
+ import "./chunk-D5OINC3G.js";
16
+ import "./chunk-O7GRZZPJ.js";
17
+ import "./chunk-6E7XEQOH.js";
18
+ import "./chunk-CCMG377E.js";
19
+ import "./chunk-TKPHC32G.js";
20
+ import "./chunk-VU6IPRRM.js";
21
+ import "./chunk-ZLTOL3D3.js";
22
+ import "./chunk-C7TN3LM3.js";
23
+ import "./chunk-F5LHXBH7.js";
24
+ import "./chunk-I77CXOEX.js";
25
+ import "./chunk-4OCSYHYB.js";
26
+ import "./chunk-UOPWVM2H.js";
27
+ import "./chunk-BUWGQVHT.js";
28
+ import "./chunk-7SYRDDTX.js";
29
+ export {
30
+ WORKTREES_DIR,
31
+ branchOf,
32
+ collectLanes,
33
+ laneBranchMap,
34
+ parseWorktreeBranches,
35
+ renderLaneList,
36
+ runLaneList,
37
+ runLaneNew,
38
+ runLaneRemove,
39
+ unmergedCommitCount,
40
+ worktreeUntracked
41
+ };
@@ -0,0 +1,361 @@
1
+ import {
2
+ computeCostDelta,
3
+ readCostSnapshot
4
+ } from "./chunk-D5OINC3G.js";
5
+ import {
6
+ computeDurationMs,
7
+ fmtDuration,
8
+ loadGenerations
9
+ } from "./chunk-F5LHXBH7.js";
10
+ import {
11
+ collectDeferred,
12
+ readRecords
13
+ } from "./chunk-I77CXOEX.js";
14
+ import {
15
+ loadState
16
+ } from "./chunk-4OCSYHYB.js";
17
+ import {
18
+ requireConfig
19
+ } from "./chunk-UOPWVM2H.js";
20
+ import "./chunk-BUWGQVHT.js";
21
+ import {
22
+ caps,
23
+ card,
24
+ makeColors,
25
+ padEndDisplay
26
+ } from "./chunk-7SYRDDTX.js";
27
+
28
+ // src/commands/loop-summary.ts
29
+ function gateAuto(rec) {
30
+ return typeof rec.auto === "boolean" ? rec.auto : void 0;
31
+ }
32
+ function computeInterventionLens(records) {
33
+ const gates = records.filter((r) => r.type === "gate");
34
+ const autonomous = gates.filter((r) => gateAuto(r) === true).length;
35
+ const humanGateCount = gates.length - autonomous;
36
+ const deferCount = collectDeferred(records).length;
37
+ const humanInterventions = humanGateCount + deferCount;
38
+ const total = autonomous + humanInterventions;
39
+ const unmannedRate = total > 0 ? Math.round(autonomous / total * 100) : void 0;
40
+ return { autonomous, humanInterventions, humanGateCount, deferCount, unmannedRate };
41
+ }
42
+ function computeQualityLens(records, criteria) {
43
+ const reviews = records.filter((r) => r.type === "review");
44
+ const reviewRejects = reviews.filter(
45
+ (r) => Array.isArray(r.findings) && r.findings.length > 0
46
+ ).length;
47
+ const blocked = records.filter((r) => r.type === "blocked").length;
48
+ const num = (v) => typeof v === "number" ? v : 0;
49
+ const total = criteria.length;
50
+ const implementationFailures = criteria.reduce((s, c) => s + num(c.attempts), 0);
51
+ const proceduralErrors = criteria.reduce((s, c) => s + num(c.proceduralErrors), 0);
52
+ const avgAttempts = total > 0 ? Math.round(implementationFailures / total * 100) / 100 : 0;
53
+ return {
54
+ reviewCount: reviews.length,
55
+ reviewRejects,
56
+ blocked,
57
+ avgAttempts,
58
+ implementationFailures,
59
+ proceduralErrors
60
+ };
61
+ }
62
+ function computeEfficiencyLens(records, costDelta) {
63
+ const ats = records.map((r) => typeof r.at === "string" ? r.at : "").filter((s) => s !== "").sort();
64
+ const gate1 = records.find((r) => r.type === "gate" && r.gate === 1);
65
+ const start = gate1 && typeof gate1.at === "string" ? gate1.at : ats[0];
66
+ const end = ats.length > 0 ? ats[ats.length - 1] : void 0;
67
+ const durationMs = start !== void 0 && end !== void 0 ? computeDurationMs(start, end) : void 0;
68
+ return { durationMs, costDelta };
69
+ }
70
+ function computeOutputLens(records, criteria) {
71
+ const passedCriteria = criteria.filter((c) => c.status === "passed").length;
72
+ const commitHashes = new Set(
73
+ criteria.map((c) => c.commit).filter((h) => typeof h === "string" && h.length > 0)
74
+ );
75
+ const gotchaApplied = records.filter((r) => r.type === "gotcha-applied").length;
76
+ const gotchaMissed = records.filter((r) => r.type === "gotcha-missed").length;
77
+ const gate1 = records.find((r) => r.type === "gate" && r.gate === 1);
78
+ const exclusions = gate1 && Array.isArray(gate1.presentedExclusions) ? gate1.presentedExclusions.length : 0;
79
+ return {
80
+ passedCriteria,
81
+ totalCriteria: criteria.length,
82
+ commits: commitHashes.size,
83
+ gotchaApplied,
84
+ gotchaMissed,
85
+ exclusions
86
+ };
87
+ }
88
+ function assembleLoopSummary(workitem, records, criteria, costDelta) {
89
+ return {
90
+ workitem,
91
+ hasRecords: records.length > 0,
92
+ intervention: computeInterventionLens(records),
93
+ quality: computeQualityLens(records, criteria),
94
+ efficiency: computeEfficiencyLens(records, costDelta),
95
+ output: computeOutputLens(records, criteria)
96
+ };
97
+ }
98
+ var LABEL_WIDTH = 7;
99
+ function buildSummaryLines(summary) {
100
+ if (!summary.hasRecords) {
101
+ return ["\uAE30\uB85D \uC5C6\uC74C \u2014 record-trail-guard \uCC38\uC870", "\uBE48 0 \uD1B5\uACC4\uB85C \uC624\uB3C4\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."];
102
+ }
103
+ const iv = summary.intervention;
104
+ const rate = iv.unmannedRate !== void 0 ? ` (\uBB34\uC778\uC728 ${iv.unmannedRate}%)` : "";
105
+ const lines = [`\uC0AC\uB78C \uAC1C\uC785 ${iv.humanInterventions} \xB7 \uC790\uC728 ${iv.autonomous}${rate}`];
106
+ lines.push(` \uAC8C\uC774\uD2B8 \uC790\uC728 ${iv.autonomous} \xB7 \uC0AC\uB78C ${iv.humanGateCount} \xB7 defer ${iv.deferCount}`);
107
+ lines.push("");
108
+ const q = summary.quality;
109
+ lines.push(
110
+ `${padEndDisplay("\uD488\uC9C8", LABEL_WIDTH)}\uB9AC\uBDF0 ${q.reviewCount}(\uBC18\uB824 ${q.reviewRejects}) \xB7 blocked ${q.blocked} \xB7 \uD3C9\uADE0\uC2DC\uB3C4/AC ${q.avgAttempts}`
111
+ );
112
+ lines.push(
113
+ `${padEndDisplay("", LABEL_WIDTH)}\uC2E4\uD328 \uC6D0\uC778 \uAD6C\uD604 ${q.implementationFailures} \xB7 \uC808\uCC28 ${q.proceduralErrors} (\uD658\uACBD \uBBF8\uAE30\uB85D)`
114
+ );
115
+ const e = summary.efficiency;
116
+ const eff = [];
117
+ if (e.durationMs !== void 0) {
118
+ eff.push(`\uC18C\uC694 ${fmtDuration(e.durationMs)}`);
119
+ }
120
+ if (e.costDelta !== void 0) {
121
+ eff.push(`\uBE44\uC6A9 ~$${e.costDelta}`);
122
+ }
123
+ lines.push(
124
+ `${padEndDisplay("\uD6A8\uC728", LABEL_WIDTH)}${eff.length > 0 ? eff.join(" \xB7 ") : "\uC2DC\uAC04\xB7\uBE44\uC6A9 \uC18C\uC2A4 \uBD80\uC7AC\uB85C \uC0DD\uB7B5"}`
125
+ );
126
+ const o = summary.output;
127
+ lines.push(
128
+ `${padEndDisplay("\uC0B0\uCD9C", LABEL_WIDTH)}\uC644\uB8CC AC ${o.passedCriteria}/${o.totalCriteria} \xB7 \uACA9\uB9AC\uCEE4\uBC0B ${o.commits} \xB7 gotcha \uC801\uC6A9 ${o.gotchaApplied}/\uB204\uB77D ${o.gotchaMissed} \xB7 \uBC94\uC704\uBC30\uC81C ${o.exclusions}`
129
+ );
130
+ return lines;
131
+ }
132
+ function renderLoopSummary(summary, c) {
133
+ const color = makeColors(c.color);
134
+ const lines = buildSummaryLines(summary);
135
+ const styled = lines.map((ln, i) => {
136
+ if (i === 0) {
137
+ return color.bold(ln);
138
+ }
139
+ if (ln.startsWith(" ")) {
140
+ return color.dim(ln);
141
+ }
142
+ return ln;
143
+ });
144
+ const title = summary.workitem ? `\uC791\uC5C5 \uC644\uB8CC \uC694\uC57D \xB7 ${summary.workitem}` : "\uC791\uC5C5 \uC644\uB8CC \uC694\uC57D";
145
+ return card(title, styled, c);
146
+ }
147
+ function summaryToJson(summary) {
148
+ if (!summary.hasRecords) {
149
+ return {
150
+ workitem: summary.workitem,
151
+ hasRecords: false,
152
+ note: "\uAE30\uB85D \uC5C6\uC74C \u2014 record-trail-guard \uCC38\uC870"
153
+ };
154
+ }
155
+ return summary;
156
+ }
157
+ var round2 = (n) => Math.round(n * 100) / 100;
158
+ var round0 = (n) => Math.round(n);
159
+ function avgDefined(values, round) {
160
+ const defined = values.filter((v) => typeof v === "number");
161
+ return defined.length > 0 ? round(defined.reduce((s, v) => s + v, 0) / defined.length) : void 0;
162
+ }
163
+ function aggregateLoopSummaries(summaries) {
164
+ const n = summaries.length;
165
+ const sum = (f) => summaries.reduce((s, x) => s + f(x), 0);
166
+ const avg = (f) => n > 0 ? round2(sum(f) / n) : 0;
167
+ return {
168
+ count: n,
169
+ intervention: {
170
+ autonomous: sum((s) => s.intervention.autonomous),
171
+ humanInterventions: sum((s) => s.intervention.humanInterventions),
172
+ humanGateCount: sum((s) => s.intervention.humanGateCount),
173
+ deferCount: sum((s) => s.intervention.deferCount),
174
+ unmannedRate: avgDefined(
175
+ summaries.map((s) => s.intervention.unmannedRate),
176
+ round0
177
+ )
178
+ },
179
+ quality: {
180
+ reviewCount: sum((s) => s.quality.reviewCount),
181
+ reviewRejects: sum((s) => s.quality.reviewRejects),
182
+ blocked: sum((s) => s.quality.blocked),
183
+ avgAttempts: avg((s) => s.quality.avgAttempts),
184
+ implementationFailures: sum((s) => s.quality.implementationFailures),
185
+ proceduralErrors: sum((s) => s.quality.proceduralErrors)
186
+ },
187
+ efficiency: {
188
+ durationMs: avgDefined(
189
+ summaries.map((s) => s.efficiency.durationMs),
190
+ round0
191
+ ),
192
+ costDelta: avgDefined(
193
+ summaries.map((s) => s.efficiency.costDelta),
194
+ round2
195
+ )
196
+ },
197
+ output: {
198
+ passedCriteria: sum((s) => s.output.passedCriteria),
199
+ totalCriteria: sum((s) => s.output.totalCriteria),
200
+ commits: sum((s) => s.output.commits),
201
+ gotchaApplied: sum((s) => s.output.gotchaApplied),
202
+ gotchaMissed: sum((s) => s.output.gotchaMissed),
203
+ exclusions: sum((s) => s.output.exclusions)
204
+ }
205
+ };
206
+ }
207
+ function buildAggregateLines(agg) {
208
+ const iv = agg.intervention;
209
+ const rate = iv.unmannedRate !== void 0 ? ` (\uBB34\uC778\uC728 \uD3C9\uADE0 ${iv.unmannedRate}%)` : "";
210
+ const lines = [
211
+ `\uC0AC\uB78C \uAC1C\uC785 \uD569 ${iv.humanInterventions} \xB7 \uC790\uC728 \uD569 ${iv.autonomous}${rate}`
212
+ ];
213
+ lines.push(` \uAC8C\uC774\uD2B8 \uC790\uC728 ${iv.autonomous} \xB7 \uC0AC\uB78C ${iv.humanGateCount} \xB7 defer ${iv.deferCount}`);
214
+ lines.push("");
215
+ const q = agg.quality;
216
+ lines.push(
217
+ `${padEndDisplay("\uD488\uC9C8", LABEL_WIDTH)}\uB9AC\uBDF0 ${q.reviewCount}(\uBC18\uB824 ${q.reviewRejects}) \xB7 blocked ${q.blocked} \xB7 \uD3C9\uADE0\uC2DC\uB3C4/AC \uD3C9\uADE0 ${q.avgAttempts}`
218
+ );
219
+ lines.push(
220
+ `${padEndDisplay("", LABEL_WIDTH)}\uC2E4\uD328 \uC6D0\uC778 \uD569 \uAD6C\uD604 ${q.implementationFailures} \xB7 \uC808\uCC28 ${q.proceduralErrors}`
221
+ );
222
+ const e = agg.efficiency;
223
+ const eff = [];
224
+ if (e.durationMs !== void 0) {
225
+ eff.push(`\uC18C\uC694 \uD3C9\uADE0 ${fmtDuration(e.durationMs)}`);
226
+ }
227
+ if (e.costDelta !== void 0) {
228
+ eff.push(`\uBE44\uC6A9 \uD3C9\uADE0 ~$${e.costDelta}`);
229
+ }
230
+ lines.push(
231
+ `${padEndDisplay("\uD6A8\uC728", LABEL_WIDTH)}${eff.length > 0 ? eff.join(" \xB7 ") : "\uC2DC\uAC04\xB7\uBE44\uC6A9 \uC18C\uC2A4 \uBD80\uC7AC\uB85C \uC0DD\uB7B5"} (\uCC38\uACE0\uC6A9 \u2014 wall-clock \uC544\uB2D8)`
232
+ );
233
+ const o = agg.output;
234
+ lines.push(
235
+ `${padEndDisplay("\uC0B0\uCD9C", LABEL_WIDTH)}\uC644\uB8CC AC \uD569 ${o.passedCriteria}/${o.totalCriteria} \xB7 \uACA9\uB9AC\uCEE4\uBC0B \uD569 ${o.commits} \xB7 gotcha \uC801\uC6A9 \uD569 ${o.gotchaApplied}/\uB204\uB77D \uD569 ${o.gotchaMissed} \xB7 \uBC94\uC704\uBC30\uC81C \uD569 ${o.exclusions}`
236
+ );
237
+ return lines;
238
+ }
239
+ function renderAggregateLoopSummary(agg, c) {
240
+ const color = makeColors(c.color);
241
+ const lines = buildAggregateLines(agg);
242
+ const styled = lines.map((ln, i) => {
243
+ if (i === 0) {
244
+ return color.bold(ln);
245
+ }
246
+ if (ln.startsWith(" ")) {
247
+ return color.dim(ln);
248
+ }
249
+ return ln;
250
+ });
251
+ return card(`\uC804\uCCB4 \uC9D1\uACC4 \xB7 \uC6CC\uD06C\uC544\uC774\uD15C ${agg.count}\uAC1C`, styled, c);
252
+ }
253
+ function resolveBatchWorkitems(opts, generations) {
254
+ if (opts.workitems && opts.workitems.length > 0) {
255
+ return opts.workitems;
256
+ }
257
+ if (opts.since !== void 0) {
258
+ const sinceMs = Date.parse(opts.since);
259
+ if (Number.isNaN(sinceMs)) {
260
+ return [];
261
+ }
262
+ return generations.filter((g) => {
263
+ const t = Date.parse(g.at);
264
+ return !Number.isNaN(t) && t >= sinceMs;
265
+ }).map((g) => g.workitem);
266
+ }
267
+ return [];
268
+ }
269
+ function criteriaFor(state, workitem, current) {
270
+ if (workitem !== null && workitem === current && Array.isArray(state.criteria)) {
271
+ return state.criteria;
272
+ }
273
+ const reg = state.workitems && typeof state.workitems === "object" && !Array.isArray(state.workitems) ? state.workitems : {};
274
+ const entry = workitem !== null ? reg[workitem] : void 0;
275
+ if (entry && Array.isArray(entry.criteria)) {
276
+ return entry.criteria;
277
+ }
278
+ return [];
279
+ }
280
+ function startCostOf(state, workitem, current) {
281
+ if (workitem === null || workitem !== current) {
282
+ return void 0;
283
+ }
284
+ const c = state.costAtStart;
285
+ return c && typeof c === "object" && !Array.isArray(c) ? c : void 0;
286
+ }
287
+ function buildBatchSummaries(ids, state, current, usagePath) {
288
+ const nowSnapshot = readCostSnapshot(usagePath);
289
+ return ids.map((id) => {
290
+ const records = readRecords({ workitem: id });
291
+ const criteria = criteriaFor(state, id, current);
292
+ const costDelta = computeCostDelta(startCostOf(state, id, current), nowSnapshot);
293
+ return assembleLoopSummary(id, records, criteria, costDelta);
294
+ });
295
+ }
296
+ function runLoopSummaryBatch(opts) {
297
+ const { config, projectRoot } = requireConfig();
298
+ const state = loadState(projectRoot);
299
+ const current = typeof state.workitem === "string" ? state.workitem : null;
300
+ const generations = opts.since !== void 0 ? loadGenerations(config.project) : [];
301
+ const ids = resolveBatchWorkitems({ workitems: opts.workitems, since: opts.since }, generations);
302
+ const summaries = buildBatchSummaries(ids, state, current, opts.usagePath);
303
+ const aggregate = aggregateLoopSummaries(summaries);
304
+ if (opts.json) {
305
+ process.stdout.write(
306
+ `${JSON.stringify({ summaries: summaries.map(summaryToJson), aggregate }, null, 2)}
307
+ `
308
+ );
309
+ return;
310
+ }
311
+ if (summaries.length === 0) {
312
+ process.stdout.write(
313
+ "\uBC30\uCE58 \uB300\uC0C1 \uC6CC\uD06C\uC544\uC774\uD15C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 --workitems \uB610\uB294 --since \uB97C \uD655\uC778\uD558\uC138\uC694.\n"
314
+ );
315
+ return;
316
+ }
317
+ const c = caps();
318
+ const blocks = summaries.map((s) => renderLoopSummary(s, c)).join("\n");
319
+ process.stdout.write(`${blocks}
320
+ ${renderAggregateLoopSummary(aggregate, c)}
321
+ `);
322
+ }
323
+ function runLoopSummary(opts) {
324
+ if (opts.workitems && opts.workitems.length > 0 || opts.since !== void 0) {
325
+ runLoopSummaryBatch(opts);
326
+ return;
327
+ }
328
+ const { projectRoot } = requireConfig();
329
+ const state = loadState(projectRoot);
330
+ const current = typeof state.workitem === "string" ? state.workitem : null;
331
+ const workitem = opts.workitem ?? current;
332
+ const records = workitem ? readRecords({ workitem }) : [];
333
+ const criteria = criteriaFor(state, workitem, current);
334
+ const costDelta = computeCostDelta(
335
+ startCostOf(state, workitem, current),
336
+ readCostSnapshot(opts.usagePath)
337
+ );
338
+ const summary = assembleLoopSummary(workitem, records, criteria, costDelta);
339
+ if (opts.json) {
340
+ process.stdout.write(`${JSON.stringify(summaryToJson(summary), null, 2)}
341
+ `);
342
+ return;
343
+ }
344
+ process.stdout.write(`${renderLoopSummary(summary, caps())}
345
+ `);
346
+ }
347
+ export {
348
+ aggregateLoopSummaries,
349
+ assembleLoopSummary,
350
+ buildAggregateLines,
351
+ buildSummaryLines,
352
+ computeEfficiencyLens,
353
+ computeInterventionLens,
354
+ computeOutputLens,
355
+ computeQualityLens,
356
+ renderAggregateLoopSummary,
357
+ renderLoopSummary,
358
+ resolveBatchWorkitems,
359
+ runLoopSummary,
360
+ summaryToJson
361
+ };
@@ -0,0 +1,25 @@
1
+ import {
2
+ computeDurationMs,
3
+ experimentKey,
4
+ fmtDuration,
5
+ groupByExperiment,
6
+ loadGenerations,
7
+ renderCompare,
8
+ renderMetrics,
9
+ renderMetricsCaveat,
10
+ runMetrics
11
+ } from "./chunk-F5LHXBH7.js";
12
+ import "./chunk-UOPWVM2H.js";
13
+ import "./chunk-BUWGQVHT.js";
14
+ import "./chunk-7SYRDDTX.js";
15
+ export {
16
+ computeDurationMs,
17
+ experimentKey,
18
+ fmtDuration,
19
+ groupByExperiment,
20
+ loadGenerations,
21
+ renderCompare,
22
+ renderMetrics,
23
+ renderMetricsCaveat,
24
+ runMetrics
25
+ };
@@ -0,0 +1,68 @@
1
+ import {
2
+ AWL_FEEDBACK_AREAS,
3
+ AWL_FEEDBACK_SEVERITIES,
4
+ BANNED_QUALITATIVE_WORDS,
5
+ DEFER_SEVERITIES,
6
+ GATE1_DECISIONS,
7
+ GATE2_DECISIONS,
8
+ NARRATIVE_KINDS,
9
+ RECORD_TYPES,
10
+ REFACTOR_KINDS,
11
+ SCHEMAS,
12
+ appendRecord,
13
+ buildRecord,
14
+ captureDiff,
15
+ collectDeferred,
16
+ computeCoverage,
17
+ detailTierFor,
18
+ hasApprovedGate1,
19
+ loadProjectName,
20
+ measureDiffSize,
21
+ monthFile,
22
+ newRecordId,
23
+ readRecords,
24
+ renderDeferSummary,
25
+ renderRecords,
26
+ resolveBlockedBaseline,
27
+ runDeferSummary,
28
+ runRecord,
29
+ runRecords,
30
+ selectMonthFiles,
31
+ shouldDefer
32
+ } from "./chunk-I77CXOEX.js";
33
+ import "./chunk-4OCSYHYB.js";
34
+ import "./chunk-UOPWVM2H.js";
35
+ import "./chunk-BUWGQVHT.js";
36
+ import "./chunk-7SYRDDTX.js";
37
+ export {
38
+ AWL_FEEDBACK_AREAS,
39
+ AWL_FEEDBACK_SEVERITIES,
40
+ BANNED_QUALITATIVE_WORDS,
41
+ DEFER_SEVERITIES,
42
+ GATE1_DECISIONS,
43
+ GATE2_DECISIONS,
44
+ NARRATIVE_KINDS,
45
+ RECORD_TYPES,
46
+ REFACTOR_KINDS,
47
+ SCHEMAS,
48
+ appendRecord,
49
+ buildRecord,
50
+ captureDiff,
51
+ collectDeferred,
52
+ computeCoverage,
53
+ detailTierFor,
54
+ hasApprovedGate1,
55
+ loadProjectName,
56
+ measureDiffSize,
57
+ monthFile,
58
+ newRecordId,
59
+ readRecords,
60
+ renderDeferSummary,
61
+ renderRecords,
62
+ resolveBlockedBaseline,
63
+ runDeferSummary,
64
+ runRecord,
65
+ runRecords,
66
+ selectMonthFiles,
67
+ shouldDefer
68
+ };