@phamvuhoang/otto-core 0.1.0

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 (103) hide show
  1. package/README.md +53 -0
  2. package/dist/branch.d.ts +61 -0
  3. package/dist/branch.d.ts.map +1 -0
  4. package/dist/branch.js +215 -0
  5. package/dist/branch.js.map +1 -0
  6. package/dist/cli-help.d.ts +68 -0
  7. package/dist/cli-help.d.ts.map +1 -0
  8. package/dist/cli-help.js +365 -0
  9. package/dist/cli-help.js.map +1 -0
  10. package/dist/detach.d.ts +36 -0
  11. package/dist/detach.d.ts.map +1 -0
  12. package/dist/detach.js +52 -0
  13. package/dist/detach.js.map +1 -0
  14. package/dist/gh-main.d.ts +5 -0
  15. package/dist/gh-main.d.ts.map +1 -0
  16. package/dist/gh-main.js +16 -0
  17. package/dist/gh-main.js.map +1 -0
  18. package/dist/git.d.ts +14 -0
  19. package/dist/git.d.ts.map +1 -0
  20. package/dist/git.js +50 -0
  21. package/dist/git.js.map +1 -0
  22. package/dist/index.d.ts +8 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +8 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/keepalive.d.ts +24 -0
  27. package/dist/keepalive.d.ts.map +1 -0
  28. package/dist/keepalive.js +138 -0
  29. package/dist/keepalive.js.map +1 -0
  30. package/dist/loop.d.ts +42 -0
  31. package/dist/loop.d.ts.map +1 -0
  32. package/dist/loop.js +238 -0
  33. package/dist/loop.js.map +1 -0
  34. package/dist/main.d.ts +5 -0
  35. package/dist/main.d.ts.map +1 -0
  36. package/dist/main.js +16 -0
  37. package/dist/main.js.map +1 -0
  38. package/dist/notify.d.ts +28 -0
  39. package/dist/notify.d.ts.map +1 -0
  40. package/dist/notify.js +119 -0
  41. package/dist/notify.js.map +1 -0
  42. package/dist/pacing.d.ts +8 -0
  43. package/dist/pacing.d.ts.map +1 -0
  44. package/dist/pacing.js +33 -0
  45. package/dist/pacing.js.map +1 -0
  46. package/dist/panel.d.ts +24 -0
  47. package/dist/panel.d.ts.map +1 -0
  48. package/dist/panel.js +202 -0
  49. package/dist/panel.js.map +1 -0
  50. package/dist/rate-limit.d.ts +16 -0
  51. package/dist/rate-limit.d.ts.map +1 -0
  52. package/dist/rate-limit.js +35 -0
  53. package/dist/rate-limit.js.map +1 -0
  54. package/dist/render.d.ts +8 -0
  55. package/dist/render.d.ts.map +1 -0
  56. package/dist/render.js +130 -0
  57. package/dist/render.js.map +1 -0
  58. package/dist/retry.d.ts +17 -0
  59. package/dist/retry.d.ts.map +1 -0
  60. package/dist/retry.js +34 -0
  61. package/dist/retry.js.map +1 -0
  62. package/dist/run-bin.d.ts +35 -0
  63. package/dist/run-bin.d.ts.map +1 -0
  64. package/dist/run-bin.js +241 -0
  65. package/dist/run-bin.js.map +1 -0
  66. package/dist/runner.d.ts +55 -0
  67. package/dist/runner.d.ts.map +1 -0
  68. package/dist/runner.js +297 -0
  69. package/dist/runner.js.map +1 -0
  70. package/dist/stage-exec.d.ts +16 -0
  71. package/dist/stage-exec.d.ts.map +1 -0
  72. package/dist/stage-exec.js +35 -0
  73. package/dist/stage-exec.js.map +1 -0
  74. package/dist/stages.d.ts +38 -0
  75. package/dist/stages.d.ts.map +1 -0
  76. package/dist/stages.js +38 -0
  77. package/dist/stages.js.map +1 -0
  78. package/dist/state.d.ts +25 -0
  79. package/dist/state.d.ts.map +1 -0
  80. package/dist/state.js +30 -0
  81. package/dist/state.js.map +1 -0
  82. package/dist/stream-render.d.ts +68 -0
  83. package/dist/stream-render.d.ts.map +1 -0
  84. package/dist/stream-render.js +162 -0
  85. package/dist/stream-render.js.map +1 -0
  86. package/dist/watch.d.ts +22 -0
  87. package/dist/watch.d.ts.map +1 -0
  88. package/dist/watch.js +93 -0
  89. package/dist/watch.js.map +1 -0
  90. package/package.json +67 -0
  91. package/templates/afk.md +21 -0
  92. package/templates/apply-review.md +71 -0
  93. package/templates/ghafk-issue.md +29 -0
  94. package/templates/ghafk.md +29 -0
  95. package/templates/ghprompt-workflow.md +83 -0
  96. package/templates/ghprompt.md +39 -0
  97. package/templates/prompt.md +97 -0
  98. package/templates/review-lens.md +41 -0
  99. package/templates/review-synth.md +29 -0
  100. package/templates/review-verify.md +52 -0
  101. package/templates/review.md +62 -0
  102. package/templates/superpowers.md +70 -0
  103. package/templates/verify.md +74 -0
package/dist/pacing.js ADDED
@@ -0,0 +1,33 @@
1
+ function abortError() {
2
+ const err = new Error("sleep aborted");
3
+ err.name = "AbortError";
4
+ return err;
5
+ }
6
+ /** Abortable delay. Resolves after `ms`; rejects with an AbortError if `signal` fires. */
7
+ export function sleep(ms, signal) {
8
+ if (ms <= 0)
9
+ return Promise.resolve();
10
+ return new Promise((resolve, reject) => {
11
+ if (signal?.aborted)
12
+ return reject(abortError());
13
+ const onAbort = () => {
14
+ clearTimeout(timer);
15
+ reject(abortError());
16
+ };
17
+ const timer = setTimeout(() => {
18
+ signal?.removeEventListener("abort", onAbort);
19
+ resolve();
20
+ }, ms);
21
+ signal?.addEventListener("abort", onAbort, { once: true });
22
+ });
23
+ }
24
+ export const THROTTLE_RE = /429|overload|rate.?limit/i;
25
+ /** True when a result's `api_error_status` looks like provider throttling. */
26
+ export function isThrottle(apiErrorStatus) {
27
+ return apiErrorStatus != null && THROTTLE_RE.test(apiErrorStatus);
28
+ }
29
+ /** Adaptive cooldown multiplier: reset to 1 when healthy, else double up to `cap`. */
30
+ export function nextCooldownFactor(prev, throttled, cap = 8) {
31
+ return throttled ? Math.min(prev * 2, cap) : 1;
32
+ }
33
+ //# sourceMappingURL=pacing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pacing.js","sourceRoot":"","sources":["../src/pacing.ts"],"names":[],"mappings":"AAAA,SAAS,UAAU;IACjB,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACvC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC;IACxB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,KAAK,CAAC,EAAU,EAAE,MAAoB;IACpD,IAAI,EAAE,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IACtC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QACvB,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAEvD,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,cAA6B;IACtD,OAAO,cAAc,IAAI,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AACpE,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,SAAkB,EAClB,GAAG,GAAG,CAAC;IAEP,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { StageResult } from "./runner.js";
2
+ /** Per-sub-agent control returned by the loop: budget-stop + adaptive cooldown. */
3
+ export type PanelStageControl = {
4
+ stop: boolean;
5
+ cooldownFactor: number;
6
+ };
7
+ export type RunPanelOptions = {
8
+ lenses: string[];
9
+ workspaceDir: string;
10
+ packageDir: string;
11
+ iteration: number;
12
+ maxRetries: number;
13
+ cooldownMs: number;
14
+ signal?: AbortSignal;
15
+ /**
16
+ * Called after every panel sub-agent (each lens + synth) so the loop owns
17
+ * budget + adaptive pacing for them too. Returns whether the budget is now
18
+ * exhausted (stop the panel) and the current adaptive cooldown factor.
19
+ */
20
+ onStage?: (sr: StageResult) => PanelStageControl;
21
+ };
22
+ /** Harness-orchestrated reviewer panel: read-only lens reviews → one synth fix(review) commit. */
23
+ export declare function runPanel(opts: RunPanelOptions): Promise<StageResult>;
24
+ //# sourceMappingURL=panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../src/panel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAmE/C,mFAAmF;AACnF,MAAM,MAAM,iBAAiB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,iBAAiB,CAAC;CAClD,CAAC;AAkBF,kGAAkG;AAClG,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAuJ1E"}
package/dist/panel.js ADDED
@@ -0,0 +1,202 @@
1
+ import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
+ import { join, posix } from "node:path";
3
+ import { git } from "./git.js";
4
+ import { executeStage } from "./stage-exec.js";
5
+ import { sleep } from "./pacing.js";
6
+ import { bold, dim, green, red, SYM } from "./stream-render.js";
7
+ const LENS_STAGE = {
8
+ name: "review-lens",
9
+ template: "review-lens.md",
10
+ permissionMode: "bypassPermissions",
11
+ };
12
+ const VERIFY_STAGE = {
13
+ name: "review-verify",
14
+ template: "review-verify.md",
15
+ permissionMode: "bypassPermissions",
16
+ };
17
+ const SYNTH_STAGE = {
18
+ name: "review-synth",
19
+ template: "review-synth.md",
20
+ permissionMode: "bypassPermissions",
21
+ };
22
+ /** Phase start line: `● review · <label>`. */
23
+ function phaseLine(label) {
24
+ process.stderr.write(`${bold(SYM.bullet)} ${bold("review")} ${dim(`· ${label}`)}\n`);
25
+ }
26
+ /** Phase outcome line: ` ⎿ ✓ <note>` (ok) or ` ⎿ ✗ <note>` (anomaly). */
27
+ function outcomeLine(note, ok = true) {
28
+ const mark = ok ? green(SYM.check) : red(SYM.cross);
29
+ process.stderr.write(`${dim(SYM.cont)} ${mark} ${dim(note)}\n`);
30
+ }
31
+ /** Human count of a lens's findings from its free-form output ("skip" = no commit to review). */
32
+ function findingsNote(result) {
33
+ const t = result.trim();
34
+ if (/<lens>\s*SKIP\s*<\/lens>/i.test(t))
35
+ return "skipped (no commit)";
36
+ const n = t
37
+ .split("\n")
38
+ .map((l) => l.trim())
39
+ .filter((l) => /^[-*]\s+\S/.test(l)).length;
40
+ if (n === 0)
41
+ return "no findings";
42
+ return `${n} finding${n === 1 ? "" : "s"}`;
43
+ }
44
+ function readVerdicts(panelHostDir) {
45
+ try {
46
+ const txt = readFileSync(join(panelHostDir, "verdicts.md"), "utf8");
47
+ return {
48
+ exists: true,
49
+ confirmed: (txt.match(/^\s*CONFIRMED\b/gim) || []).length,
50
+ rejected: (txt.match(/^\s*REJECTED\b/gim) || []).length,
51
+ };
52
+ }
53
+ catch {
54
+ return { exists: false, confirmed: 0, rejected: 0 };
55
+ }
56
+ }
57
+ /** True if the worktree has uncommitted changes (tracked edits or new untracked
58
+ * files), excluding gitignored paths. Null git output (e.g. no repo) = not dirty. */
59
+ function worktreeDirty(workspaceDir) {
60
+ const s = git(["status", "--porcelain"], workspaceDir);
61
+ return s != null && s !== "";
62
+ }
63
+ /** Tracked-only worktree dirtiness ("" = clean). Untracked files are ignored. */
64
+ function trackedStatus(workspaceDir) {
65
+ return git(["status", "--porcelain", "--untracked-files=no"], workspaceDir);
66
+ }
67
+ /** True if HEAD moved or a tracked file changed since `baseHead`. */
68
+ function lensMutatedRepo(workspaceDir, baseHead) {
69
+ if (baseHead == null)
70
+ return false;
71
+ if (git(["rev-parse", "HEAD"], workspaceDir) !== baseHead)
72
+ return true;
73
+ // Tracked-only: a lens scratch file (untracked) is harmless — synth diffs HEAD.
74
+ return trackedStatus(workspaceDir) !== "";
75
+ }
76
+ /** Harness-orchestrated reviewer panel: read-only lens reviews → one synth fix(review) commit. */
77
+ export async function runPanel(opts) {
78
+ const { lenses, workspaceDir, packageDir, iteration, maxRetries, cooldownMs, signal, onStage, } = opts;
79
+ const panelRel = `panel-${process.pid}-${iteration}-${Date.now()}`;
80
+ const panelHostDir = join(workspaceDir, ".otto-tmp", panelRel);
81
+ mkdirSync(panelHostDir, { recursive: true });
82
+ // Lenses are contractually read-only; synth owns the single fix(review:) commit.
83
+ // Snapshot HEAD so we can detect + undo a lens that edits or commits despite the
84
+ // prompt (it runs bypassPermissions, so the OS would let it). We only ENFORCE
85
+ // (reset --hard) when the worktree starts tracked-clean — otherwise a reset would
86
+ // discard pre-existing uncommitted user changes, so we disable the guard and warn.
87
+ const baseHead = git(["rev-parse", "HEAD"], workspaceDir);
88
+ const enforceReadOnly = baseHead != null && trackedStatus(workspaceDir) === "";
89
+ if (baseHead != null && !enforceReadOnly) {
90
+ process.stderr.write(`${red(SYM.cross)} ${dim("worktree has uncommitted tracked changes — panel lens read-only enforcement disabled (won't risk your changes)")}\n`);
91
+ }
92
+ const findingsDirRef = `./${posix.join(".otto-tmp", panelRel)}/`;
93
+ // Restore HEAD if a contractually read-only sub-agent (lens or verifier)
94
+ // committed or edited tracked files despite the prompt. Only safe when the
95
+ // worktree started clean, so reset --hard can discard only the sub-agent's
96
+ // own changes — never pre-existing work. Returns true if it had to restore.
97
+ const restoreIfMutated = (who) => {
98
+ if (enforceReadOnly && lensMutatedRepo(workspaceDir, baseHead)) {
99
+ process.stderr.write(`${red(SYM.cross)} ${dim(`${who} mutated the repo (read-only violation) — restoring to ${baseHead.slice(0, 8)}`)}\n`);
100
+ git(["reset", "--hard", baseHead], workspaceDir);
101
+ return true;
102
+ }
103
+ return false;
104
+ };
105
+ try {
106
+ // 1. Lenses — each finds defects through one lens, read-only.
107
+ for (let i = 0; i < lenses.length; i++) {
108
+ const lens = lenses[i];
109
+ phaseLine(`${lens} lens (${i + 1}/${lenses.length})`);
110
+ const sr = await executeStage({
111
+ stage: LENS_STAGE,
112
+ vars: { LENS: lens },
113
+ workspaceDir,
114
+ packageDir,
115
+ iteration,
116
+ maxRetries,
117
+ signal,
118
+ logLabel: `lens-${lens}`,
119
+ });
120
+ restoreIfMutated(`lens ${lens}`);
121
+ writeFileSync(join(panelHostDir, `findings-${lens}.md`), sr.result, "utf8");
122
+ outcomeLine(findingsNote(sr.result));
123
+ const ctrl = onStage?.(sr) ?? { stop: false, cooldownFactor: 1 };
124
+ if (ctrl.stop)
125
+ return sr; // budget exhausted — skip remaining lenses + verify + synth
126
+ if (cooldownMs > 0)
127
+ await sleep(cooldownMs * ctrl.cooldownFactor, signal);
128
+ }
129
+ // 2. Adversarial verify — a skeptic refutes the lens findings, writing
130
+ // verdicts.md (CONFIRMED/REJECTED) so synth only fixes survivors.
131
+ phaseLine("adversarial verify");
132
+ const verify = await executeStage({
133
+ stage: VERIFY_STAGE,
134
+ vars: { FINDINGS_DIR: findingsDirRef },
135
+ workspaceDir,
136
+ packageDir,
137
+ iteration,
138
+ maxRetries,
139
+ signal,
140
+ logLabel: "verify",
141
+ });
142
+ restoreIfMutated("verify");
143
+ const verdicts = readVerdicts(panelHostDir);
144
+ if (verdicts.exists) {
145
+ outcomeLine(`${verdicts.confirmed} confirmed, ${verdicts.rejected} rejected`);
146
+ }
147
+ else {
148
+ outcomeLine("verifier wrote no verdicts.md (contract violation)", false);
149
+ }
150
+ const vctrl = onStage?.(verify) ?? { stop: false, cooldownFactor: 1 };
151
+ if (vctrl.stop)
152
+ return verify; // budget exhausted — skip synth
153
+ // Contract gate: the verifier MUST write verdicts.md (the template emits
154
+ // `none` when there were no findings). Its absence means synth would run
155
+ // with no validated input — so skip the fix stage rather than let synth
156
+ // patch from unverified findings. Forward progress is preserved: the
157
+ // implementer's commit stands, just unreviewed this iteration.
158
+ if (!verdicts.exists) {
159
+ outcomeLine("skipping synth — no validated verdicts to act on", false);
160
+ return verify;
161
+ }
162
+ if (cooldownMs > 0)
163
+ await sleep(cooldownMs * vctrl.cooldownFactor, signal);
164
+ // 3. Synth — fix only CONFIRMED findings in one fix(review:) commit.
165
+ phaseLine("synthesize & fix");
166
+ const synth = await executeStage({
167
+ stage: SYNTH_STAGE,
168
+ vars: { FINDINGS_DIR: findingsDirRef },
169
+ workspaceDir,
170
+ packageDir,
171
+ iteration,
172
+ maxRetries,
173
+ signal,
174
+ logLabel: "synth",
175
+ });
176
+ // Report from real signals: HEAD movement AND worktree cleanliness. A bare
177
+ // HEAD check would call an edit-without-commit (or a `commit -am` that missed
178
+ // a new file) "clean" — surface the dirty tree instead of hiding it.
179
+ const after = git(["rev-parse", "HEAD"], workspaceDir);
180
+ const committed = baseHead != null && after != null && after !== baseHead;
181
+ const dirty = worktreeDirty(workspaceDir);
182
+ const subject = git(["log", "-1", "--pretty=%s"], workspaceDir) ?? "fix(review)";
183
+ if (committed && !dirty) {
184
+ outcomeLine(`committed: ${subject}`);
185
+ }
186
+ else if (committed && dirty) {
187
+ outcomeLine(`committed: ${subject} — but uncommitted changes remain`, false);
188
+ }
189
+ else if (dirty) {
190
+ outcomeLine("synth edited the worktree but did not commit — left dirty", false);
191
+ }
192
+ else {
193
+ outcomeLine("clean — no fix needed");
194
+ }
195
+ onStage?.(synth);
196
+ return synth;
197
+ }
198
+ finally {
199
+ rmSync(panelHostDir, { recursive: true, force: true });
200
+ }
201
+ }
202
+ //# sourceMappingURL=panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel.js","sourceRoot":"","sources":["../src/panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEhE,MAAM,UAAU,GAAG;IACjB,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,gBAAgB;IAC1B,cAAc,EAAE,mBAAmB;CACpC,CAAC;AACF,MAAM,YAAY,GAAG;IACnB,IAAI,EAAE,eAAe;IACrB,QAAQ,EAAE,kBAAkB;IAC5B,cAAc,EAAE,mBAAmB;CACpC,CAAC;AACF,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,cAAc;IACpB,QAAQ,EAAE,iBAAiB;IAC3B,cAAc,EAAE,mBAAmB;CACpC,CAAC;AAEF,8CAA8C;AAC9C,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,IAAI,CAC/D,CAAC;AACJ,CAAC;AACD,2EAA2E;AAC3E,SAAS,WAAW,CAAC,IAAY,EAAE,EAAE,GAAG,IAAI;IAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,iGAAiG;AACjG,SAAS,YAAY,CAAC,MAAc;IAClC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACxB,IAAI,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,qBAAqB,CAAC;IACtE,MAAM,CAAC,GAAG,CAAC;SACR,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9C,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC;IAClC,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AAC7C,CAAC;AAMD,SAAS,YAAY,CAAC,YAAoB;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;QACpE,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;YACzD,QAAQ,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;SACxD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACtD,CAAC;AACH,CAAC;AAED;sFACsF;AACtF,SAAS,aAAa,CAAC,YAAoB;IACzC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,YAAY,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;AAC/B,CAAC;AAqBD,iFAAiF;AACjF,SAAS,aAAa,CAAC,YAAoB;IACzC,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,sBAAsB,CAAC,EAAE,YAAY,CAAC,CAAC;AAC9E,CAAC;AAED,qEAAqE;AACrE,SAAS,eAAe,CACtB,YAAoB,EACpB,QAAuB;IAEvB,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvE,gFAAgF;IAChF,OAAO,aAAa,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;AAC5C,CAAC;AAED,kGAAkG;AAClG,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAqB;IAClD,MAAM,EACJ,MAAM,EACN,YAAY,EACZ,UAAU,EACV,SAAS,EACT,UAAU,EACV,UAAU,EACV,MAAM,EACN,OAAO,GACR,GAAG,IAAI,CAAC;IACT,MAAM,QAAQ,GAAG,SAAS,OAAO,CAAC,GAAG,IAAI,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACnE,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC/D,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,iFAAiF;IACjF,iFAAiF;IACjF,8EAA8E;IAC9E,kFAAkF;IAClF,mFAAmF;IACnF,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC;IAC1D,MAAM,eAAe,GACnB,QAAQ,IAAI,IAAI,IAAI,aAAa,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IACzD,IAAI,QAAQ,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,gHAAgH,CAAC,IAAI,CAC/I,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC;IAEjE,yEAAyE;IACzE,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAW,EAAE;QAChD,IAAI,eAAe,IAAI,eAAe,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,0DAA0D,QAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CACtH,CAAC;YACF,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAS,CAAC,EAAE,YAAY,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,IAAI,CAAC;QACH,8DAA8D;QAC9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACvB,SAAS,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YACtD,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC;gBAC5B,KAAK,EAAE,UAAU;gBACjB,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;gBACpB,YAAY;gBACZ,UAAU;gBACV,SAAS;gBACT,UAAU;gBACV,MAAM;gBACN,QAAQ,EAAE,QAAQ,IAAI,EAAE;aACzB,CAAC,CAAC;YACH,gBAAgB,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;YACjC,aAAa,CACX,IAAI,CAAC,YAAY,EAAE,YAAY,IAAI,KAAK,CAAC,EACzC,EAAE,CAAC,MAAM,EACT,MAAM,CACP,CAAC;YACF,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YAErC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;YACjE,IAAI,IAAI,CAAC,IAAI;gBAAE,OAAO,EAAE,CAAC,CAAC,4DAA4D;YACtF,IAAI,UAAU,GAAG,CAAC;gBAAE,MAAM,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QAC5E,CAAC;QAED,uEAAuE;QACvE,qEAAqE;QACrE,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;YAChC,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,EAAE,YAAY,EAAE,cAAc,EAAE;YACtC,YAAY;YACZ,UAAU;YACV,SAAS;YACT,UAAU;YACV,MAAM;YACN,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;QACH,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,WAAW,CACT,GAAG,QAAQ,CAAC,SAAS,eAAe,QAAQ,CAAC,QAAQ,WAAW,CACjE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,oDAAoD,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QACtE,IAAI,KAAK,CAAC,IAAI;YAAE,OAAO,MAAM,CAAC,CAAC,gCAAgC;QAE/D,yEAAyE;QACzE,yEAAyE;QACzE,wEAAwE;QACxE,qEAAqE;QACrE,+DAA+D;QAC/D,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,WAAW,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAC;YACvE,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,UAAU,GAAG,CAAC;YAAE,MAAM,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QAE3E,qEAAqE;QACrE,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC;YAC/B,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,EAAE,YAAY,EAAE,cAAc,EAAE;YACtC,YAAY;YACZ,UAAU;YACV,SAAS;YACT,UAAU;YACV,MAAM;YACN,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QACH,2EAA2E;QAC3E,8EAA8E;QAC9E,qEAAqE;QACrE,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,QAAQ,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,QAAQ,CAAC;QAC1E,MAAM,KAAK,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,OAAO,GACX,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,YAAY,CAAC,IAAI,aAAa,CAAC;QACnE,IAAI,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC;YACxB,WAAW,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YAC9B,WAAW,CACT,cAAc,OAAO,mCAAmC,EACxD,KAAK,CACN,CAAC;QACJ,CAAC;aAAM,IAAI,KAAK,EAAE,CAAC;YACjB,WAAW,CACT,2DAA2D,EAC3D,KAAK,CACN,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,uBAAuB,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { StageResult } from "./runner.js";
2
+ /** Thrown when a stage hit a usage/session/rate limit. `resetsAt` is unix seconds
3
+ * (from the rate_limit_event) or null if the limit gave no reset time. */
4
+ export declare class RateLimitError extends Error {
5
+ readonly resetsAt: number | null;
6
+ constructor(message: string, resetsAt: number | null);
7
+ }
8
+ /** True if a `result` event signals a usage/session/rate limit:
9
+ * is_error with an HTTP 429, or the CLI's "session limit" result text. */
10
+ export declare function isLimitResult(r: StageResult): boolean;
11
+ /** resetsAt (unix seconds) from a `rate_limit_event`, else null. */
12
+ export declare function resetsAtFromEvent(ev: unknown): number | null;
13
+ /** Milliseconds to wait before retrying. With a resetsAt: time until it + buffer
14
+ * (never negative). Without: the fallback. */
15
+ export declare function computeWaitMs(resetsAt: number | null, nowMs: number, bufferMs: number, fallbackMs: number): number;
16
+ //# sourceMappingURL=rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;2EAC2E;AAC3E,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;gBACrB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAKrD;AAED;2EAC2E;AAC3E,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAIrD;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAK5D;AAED;+CAC+C;AAC/C,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CAGR"}
@@ -0,0 +1,35 @@
1
+ /** Thrown when a stage hit a usage/session/rate limit. `resetsAt` is unix seconds
2
+ * (from the rate_limit_event) or null if the limit gave no reset time. */
3
+ export class RateLimitError extends Error {
4
+ resetsAt;
5
+ constructor(message, resetsAt) {
6
+ super(message);
7
+ this.name = "RateLimitError";
8
+ this.resetsAt = resetsAt;
9
+ }
10
+ }
11
+ /** True if a `result` event signals a usage/session/rate limit:
12
+ * is_error with an HTTP 429, or the CLI's "session limit" result text. */
13
+ export function isLimitResult(r) {
14
+ if (!r.isError)
15
+ return false;
16
+ if (r.apiErrorStatus != null && /429/.test(r.apiErrorStatus))
17
+ return true;
18
+ return /session limit|usage limit|rate.?limit/i.test(r.result);
19
+ }
20
+ /** resetsAt (unix seconds) from a `rate_limit_event`, else null. */
21
+ export function resetsAtFromEvent(ev) {
22
+ const e = (ev ?? {});
23
+ if (e.type !== "rate_limit_event")
24
+ return null;
25
+ const info = (e.rate_limit_info ?? {});
26
+ return typeof info.resetsAt === "number" ? info.resetsAt : null;
27
+ }
28
+ /** Milliseconds to wait before retrying. With a resetsAt: time until it + buffer
29
+ * (never negative). Without: the fallback. */
30
+ export function computeWaitMs(resetsAt, nowMs, bufferMs, fallbackMs) {
31
+ if (resetsAt == null)
32
+ return fallbackMs;
33
+ return Math.max(0, resetsAt * 1000 - nowMs + bufferMs);
34
+ }
35
+ //# sourceMappingURL=rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAEA;2EAC2E;AAC3E,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,QAAQ,CAAgB;IACjC,YAAY,OAAe,EAAE,QAAuB;QAClD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;2EAC2E;AAC3E,MAAM,UAAU,aAAa,CAAC,CAAc;IAC1C,IAAI,CAAC,CAAC,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC7B,IAAI,CAAC,CAAC,cAAc,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,OAAO,wCAAwC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,EAAW;IAC3C,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAA4B,CAAC;IAChD,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,eAAe,IAAI,EAAE,CAA4B,CAAC;IAClE,OAAO,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAED;+CAC+C;AAC/C,MAAM,UAAU,aAAa,CAC3B,QAAuB,EACvB,KAAa,EACb,QAAgB,EAChB,UAAkB;IAElB,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,UAAU,CAAC;IACxC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type RenderVars = Record<string, string>;
2
+ export type RenderOptions = {
3
+ cwd?: string;
4
+ spillHostDir?: string;
5
+ spillRefPath?: string;
6
+ };
7
+ export declare function renderTemplate(templatePath: string, vars: RenderVars, opts?: RenderOptions): string;
8
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhD,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAcF,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,UAAU,EAChB,IAAI,GAAE,aAAkB,GACvB,MAAM,CA2GR"}
package/dist/render.js ADDED
@@ -0,0 +1,130 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { dirname, isAbsolute, join, resolve } from "node:path";
4
+ // SECURITY INVARIANT: the command bodies of the !`cmd`, !?`cmd`, and @spill tags
5
+ // are executed on the HOST shell (see execSync calls below). Templates are trusted
6
+ // (shipped in the npm tarball) and only ever embed STATIC command strings; {{ INPUTS }}
7
+ // is substituted LAST, into the already-expanded text, and is never re-shelled. Never
8
+ // author a tag whose command body interpolates runtime or untrusted data (issue bodies,
9
+ // commit messages, INPUTS, branch names) — that would be direct host RCE. See SECURITY.md.
10
+ // Order matters: !?`...` (try-shell w/ ||| fallback) must match before plain !`...`.
11
+ const SHELL_TRY_TAG = /!\?`([^`]+)`/g;
12
+ const SHELL_TAG = /!`([^`]+)`/g;
13
+ const INCLUDE_TAG = /@include:([^\s`)]+)/g;
14
+ // @spill[?]:<name>=`cmd[|||fallback]` — runs cmd, writes output to spillHostDir/<name>,
15
+ // substitutes the container-relative file path in the prompt. The `?` form treats
16
+ // non-zero exits as success and writes the fallback string instead of throwing.
17
+ const SPILL_TAG = /@spill(\??):([^\s=]+)=`([^`]+)`/g;
18
+ const GENERIC_TAG = /\{\{\s*([A-Z0-9_]+)\s*\}\}/g;
19
+ const TRY_SEP = "|||";
20
+ // Cap on captured stdout for every shell/@spill tag (64 MiB). Large outputs are
21
+ // meant to go through @spill (written to a file), not be inlined into the prompt.
22
+ const SPILL_MAX_BUFFER = 64 * 1024 * 1024;
23
+ function resolveShell() {
24
+ if (process.platform !== "win32")
25
+ return "/bin/bash";
26
+ // Prefer bash.exe (git-for-windows / WSL passthrough) for POSIX redirects + utils.
27
+ const pathDirs = (process.env.PATH ?? "").split(";");
28
+ for (const d of pathDirs) {
29
+ if (!d)
30
+ continue;
31
+ const candidate = resolve(d, "bash.exe");
32
+ if (existsSync(candidate))
33
+ return candidate;
34
+ }
35
+ return "cmd.exe";
36
+ }
37
+ export function renderTemplate(templatePath, vars, opts = {}) {
38
+ const raw = readFileSync(templatePath, "utf8");
39
+ const templateDir = dirname(templatePath);
40
+ const shell = resolveShell();
41
+ // Expand @include directives recursively until no directives remain.
42
+ // Each pass resolves relative paths against the including file's directory.
43
+ function expandIncludes(text, fromDir) {
44
+ const expanded = text.replace(INCLUDE_TAG, (_match, rel) => {
45
+ const target = isAbsolute(rel) ? rel : resolve(fromDir, rel);
46
+ const content = readFileSync(target, "utf8").replace(/\r?\n$/, "");
47
+ // Recurse so includes within included files are resolved relative to
48
+ // the included file's own directory.
49
+ return expandIncludes(content, dirname(target));
50
+ });
51
+ return expanded;
52
+ }
53
+ const afterInclude = expandIncludes(raw, templateDir);
54
+ const afterSpill = afterInclude.replace(SPILL_TAG, (_match, q, name, body) => {
55
+ if (!opts.spillHostDir || !opts.spillRefPath) {
56
+ throw new Error(`@spill:${name} used but spillHostDir/spillRefPath not provided to renderTemplate`);
57
+ }
58
+ // Reject any name that could escape spillHostDir. Templates are trusted
59
+ // (shipped in the npm tarball) but defense-in-depth — keep file writes
60
+ // confined to the per-iteration spill dir.
61
+ if (name.includes("/") ||
62
+ name.includes("\\") ||
63
+ name === "." ||
64
+ name === ".." ||
65
+ name.includes("..") ||
66
+ isAbsolute(name)) {
67
+ throw new Error(`@spill:${name} — name must be a plain filename (no path separators, no ..)`);
68
+ }
69
+ const tryMode = q === "?";
70
+ let cmd = body;
71
+ let fallback = "";
72
+ if (tryMode) {
73
+ const sep = body.lastIndexOf(TRY_SEP);
74
+ if (sep >= 0) {
75
+ cmd = body.slice(0, sep);
76
+ fallback = body.slice(sep + TRY_SEP.length);
77
+ }
78
+ }
79
+ let out;
80
+ try {
81
+ out = execSync(cmd, {
82
+ shell,
83
+ encoding: "utf8",
84
+ maxBuffer: SPILL_MAX_BUFFER,
85
+ cwd: opts.cwd,
86
+ stdio: ["ignore", "pipe", tryMode ? "ignore" : "pipe"],
87
+ });
88
+ }
89
+ catch (err) {
90
+ if (!tryMode)
91
+ throw err;
92
+ out = fallback;
93
+ }
94
+ mkdirSync(opts.spillHostDir, { recursive: true });
95
+ writeFileSync(join(opts.spillHostDir, name), out, "utf8");
96
+ return `./${opts.spillRefPath}/${name}`;
97
+ });
98
+ const afterShellTry = afterSpill.replace(SHELL_TRY_TAG, (_match, body) => {
99
+ const sep = body.lastIndexOf(TRY_SEP);
100
+ const cmd = sep >= 0 ? body.slice(0, sep) : body;
101
+ const fallback = sep >= 0 ? body.slice(sep + TRY_SEP.length) : "";
102
+ try {
103
+ const out = execSync(cmd, {
104
+ shell,
105
+ encoding: "utf8",
106
+ maxBuffer: SPILL_MAX_BUFFER,
107
+ cwd: opts.cwd,
108
+ stdio: ["ignore", "pipe", "ignore"],
109
+ });
110
+ return out.replace(/\r?\n$/, "");
111
+ }
112
+ catch {
113
+ return fallback;
114
+ }
115
+ });
116
+ const afterShell = afterShellTry.replace(SHELL_TAG, (_match, cmd) => {
117
+ const out = execSync(cmd, {
118
+ shell,
119
+ encoding: "utf8",
120
+ maxBuffer: 64 * 1024 * 1024,
121
+ cwd: opts.cwd,
122
+ });
123
+ return out.replace(/\r?\n$/, "");
124
+ });
125
+ // SECURITY: generic substitution is the last pass and never re-shelled.
126
+ // INPUTS, LENS, FINDINGS_DIR, etc. are harness constants — no new injection surface.
127
+ // Unknown {{ TAG }} are left untouched.
128
+ return afterShell.replace(GENERIC_TAG, (match, key) => Object.prototype.hasOwnProperty.call(vars, key) ? vars[key] : match);
129
+ }
130
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE/D,iFAAiF;AACjF,mFAAmF;AACnF,wFAAwF;AACxF,sFAAsF;AACtF,wFAAwF;AACxF,2FAA2F;AAE3F,qFAAqF;AACrF,MAAM,aAAa,GAAG,eAAe,CAAC;AACtC,MAAM,SAAS,GAAG,aAAa,CAAC;AAChC,MAAM,WAAW,GAAG,sBAAsB,CAAC;AAC3C,wFAAwF;AACxF,kFAAkF;AAClF,gFAAgF;AAChF,MAAM,SAAS,GAAG,kCAAkC,CAAC;AACrD,MAAM,WAAW,GAAG,6BAA6B,CAAC;AAClD,MAAM,OAAO,GAAG,KAAK,CAAC;AACtB,gFAAgF;AAChF,kFAAkF;AAClF,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAY1C,SAAS,YAAY;IACnB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,WAAW,CAAC;IACrD,mFAAmF;IACnF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACzC,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC9C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,YAAoB,EACpB,IAAgB,EAChB,OAAsB,EAAE;IAExB,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAE7B,qEAAqE;IACrE,4EAA4E;IAC5E,SAAS,cAAc,CAAC,IAAY,EAAE,OAAe;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,GAAW,EAAE,EAAE;YACjE,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACnE,qEAAqE;YACrE,qCAAqC;YACrC,OAAO,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAEtD,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CACrC,SAAS,EACT,CAAC,MAAM,EAAE,CAAS,EAAE,IAAY,EAAE,IAAY,EAAE,EAAE;QAChD,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,oEAAoE,CACnF,CAAC;QACJ,CAAC;QACD,wEAAwE;QACxE,uEAAuE;QACvE,2CAA2C;QAC3C,IACE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnB,IAAI,KAAK,GAAG;YACZ,IAAI,KAAK,IAAI;YACb,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnB,UAAU,CAAC,IAAI,CAAC,EAChB,CAAC;YACD,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,8DAA8D,CAC7E,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC;QAC1B,IAAI,GAAG,GAAG,IAAI,CAAC;QACf,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;gBACb,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACzB,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QACD,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE;gBAClB,KAAK;gBACL,QAAQ,EAAE,MAAM;gBAChB,SAAS,EAAE,gBAAgB;gBAC3B,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;aACvD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,OAAO;gBAAE,MAAM,GAAG,CAAC;YACxB,GAAG,GAAG,QAAQ,CAAC;QACjB,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAC1D,OAAO,KAAK,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;IAC1C,CAAC,CACF,CAAC;IAEF,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,CACtC,aAAa,EACb,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACjD,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE;gBACxB,KAAK;gBACL,QAAQ,EAAE,MAAM;gBAChB,SAAS,EAAE,gBAAgB;gBAC3B,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;aACpC,CAAC,CAAC;YACH,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,GAAW,EAAE,EAAE;QAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE;YACxB,KAAK;YACL,QAAQ,EAAE,MAAM;YAChB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;YAC3B,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IACH,wEAAwE;IACxE,qFAAqF;IACrF,wCAAwC;IACxC,OAAO,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE,CAC5D,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CACpE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ export type WithRetriesOptions = {
2
+ /** Maximum retries after the initial attempt. Total calls = max + 1. */
3
+ max: number;
4
+ /** Wait between attempts. backoffMs[i] is the wait before attempt i+1.
5
+ * When attempts exceed array length, the last value is reused. */
6
+ backoffMs: readonly number[];
7
+ /** Fires after each failed attempt, before the wait. */
8
+ onAttempt?: (attempt: number, err: unknown) => void;
9
+ /** Injected for tests so no real wall-clock waits occur. */
10
+ sleep?: (ms: number) => Promise<void>;
11
+ };
12
+ export declare const DEFAULT_BACKOFF_MS: readonly number[];
13
+ export declare const DEFAULT_MAX_RETRIES = 3;
14
+ export declare function withRetries<T>(fn: () => Promise<T>, opts: WithRetriesOptions): Promise<T>;
15
+ /** Wait that withRetries will impose before the Nth retry (1-indexed). */
16
+ export declare function backoffFor(backoffMs: readonly number[], attempt: number): number;
17
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ;uEACmE;IACnE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,wDAAwD;IACxD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,4DAA4D;IAC5D,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAA6B,CAAC;AAC9E,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAMrC,wBAAsB,WAAW,CAAC,CAAC,EACjC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,CAAC,CAAC,CAoBZ;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,CACxB,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,EAAE,MAAM,GACd,MAAM,CAER"}
package/dist/retry.js ADDED
@@ -0,0 +1,34 @@
1
+ export const DEFAULT_BACKOFF_MS = [5_000, 30_000, 120_000];
2
+ export const DEFAULT_MAX_RETRIES = 3;
3
+ function defaultSleep(ms) {
4
+ return new Promise((res) => setTimeout(res, ms));
5
+ }
6
+ export async function withRetries(fn, opts) {
7
+ const sleep = opts.sleep ?? defaultSleep;
8
+ let lastErr;
9
+ for (let attempt = 0; attempt <= opts.max; attempt++) {
10
+ try {
11
+ return await fn();
12
+ }
13
+ catch (err) {
14
+ lastErr = err;
15
+ if (err?.name === "AbortError")
16
+ throw err;
17
+ if (err?.name === "RateLimitError")
18
+ throw err;
19
+ if (attempt === opts.max)
20
+ break;
21
+ opts.onAttempt?.(attempt + 1, err);
22
+ const backoff = opts.backoffMs[attempt] ??
23
+ opts.backoffMs[opts.backoffMs.length - 1] ??
24
+ 0;
25
+ await sleep(backoff);
26
+ }
27
+ }
28
+ throw lastErr;
29
+ }
30
+ /** Wait that withRetries will impose before the Nth retry (1-indexed). */
31
+ export function backoffFor(backoffMs, attempt) {
32
+ return backoffMs[attempt - 1] ?? backoffMs[backoffMs.length - 1] ?? 0;
33
+ }
34
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,kBAAkB,GAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,SAAS,YAAY,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,EAAoB,EACpB,IAAwB;IAExB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC;IACzC,IAAI,OAAgB,CAAC;IACrB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,GAAG,GAAG,CAAC;YACd,IAAK,GAAa,EAAE,IAAI,KAAK,YAAY;gBAAE,MAAM,GAAG,CAAC;YACrD,IAAK,GAAa,EAAE,IAAI,KAAK,gBAAgB;gBAAE,MAAM,GAAG,CAAC;YACzD,IAAI,OAAO,KAAK,IAAI,CAAC,GAAG;gBAAE,MAAM;YAChC,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;YACnC,MAAM,OAAO,GACX,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBACvB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;gBACzC,CAAC,CAAC;YACJ,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,MAAM,OAAO,CAAC;AAChB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CACxB,SAA4B,EAC5B,OAAe;IAEf,OAAO,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { Stage } from "./stages.js";
2
+ export type RunBinConfig = {
3
+ /** Bin name for usage/version/config output (e.g. "otto-afk"). */
4
+ bin: string;
5
+ /** Positional-arg usage string (e.g. "<plan-and-prd> <iterations>"). */
6
+ usage: string;
7
+ /** One-line description for --help. */
8
+ desc: string;
9
+ /** Stage chain; first stage is the gate. */
10
+ stages: [Stage, ...Stage[]];
11
+ /**
12
+ * Whether the bin takes a leading input positional before <iterations>.
13
+ * `true` → argv is `<inputs> <iterations>` (otto-afk; inputs = rest[0]).
14
+ * `false` → argv is `<iterations>` (otto-ghafk; inputs = "").
15
+ */
16
+ takesInputArg: boolean;
17
+ cliVersion?: string;
18
+ /** Whether this bin supports --watch. Only otto-ghafk sets this. */
19
+ supportsWatch?: boolean;
20
+ /** Alternate gate stage used when --issue is set. Only otto-ghafk sets this. */
21
+ issueStage?: Stage;
22
+ /** Single read-only gate stage used when --verify is set. Only otto-afk sets this. */
23
+ verifyStage?: Stage;
24
+ /** Gate stage used when --apply-review is set. Only otto-afk sets this. */
25
+ applyReviewStage?: Stage;
26
+ /** Run mode identifier threaded into runLoop state (e.g. "afk" / "ghafk"). */
27
+ mode: string;
28
+ };
29
+ /**
30
+ * Shared entry for the AFK bins: parse flags, handle --version/--help/--print-config,
31
+ * resolve the workspace / package dirs, validate the positional args,
32
+ * optionally fork into the background (--detach), then drive runLoop.
33
+ */
34
+ export declare function runBin(argv: string[], cfg: RunBinConfig): Promise<void>;
35
+ //# sourceMappingURL=run-bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-bin.d.ts","sourceRoot":"","sources":["../src/run-bin.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG;IACzB,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAC5B;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gFAAgF;IAChF,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,sFAAsF;IACtF,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,KAAK,CAAC;IACzB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAyBF;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuO7E"}