@garuda-agent/garuda 0.16.1 → 0.18.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 (63) hide show
  1. package/CHANGELOG.md +319 -0
  2. package/README.md +56 -1074
  3. package/SECURITY.md +9 -2
  4. package/dist/{acpCommand-OTAYW7BS.js → acpCommand-IUZPLPLI.js} +25 -23
  5. package/dist/{anthropic-NQDBCHJU.js → anthropic-NQIZLD64.js} +12 -6
  6. package/dist/{chunk-NP6RIC25.js → chunk-2FIV2VZP.js} +11 -7
  7. package/dist/{chunk-YQTGMCU6.js → chunk-3MRQJKUO.js} +29 -5
  8. package/dist/{chunk-HE2K657U.js → chunk-4BVCYCQT.js} +47 -16
  9. package/dist/{chunk-WMOLXTBU.js → chunk-4LFJFDCF.js} +2 -1
  10. package/dist/{chunk-44QN5SWZ.js → chunk-55CFEEIN.js} +22 -2
  11. package/dist/{chunk-USCUXCAU.js → chunk-5B5HDTUR.js} +3 -3
  12. package/dist/chunk-65NUEOI7.js +143 -0
  13. package/dist/{chunk-TUUEBHG2.js → chunk-6XHON3Q6.js} +2 -2
  14. package/dist/chunk-7KBOIPUT.js +157 -0
  15. package/dist/{chunk-B6FA4I7Q.js → chunk-7TH3NHCQ.js} +2 -2
  16. package/dist/{chunk-OUCV3FCT.js → chunk-AOGFYUKG.js} +3 -3
  17. package/dist/{chunk-GXZACJUI.js → chunk-B4SJY7KT.js} +322 -39
  18. package/dist/{chunk-3EQU2GUX.js → chunk-BHZ6G65V.js} +5 -1
  19. package/dist/chunk-C57GHLKP.js +9 -0
  20. package/dist/chunk-DOCDCQVM.js +484 -0
  21. package/dist/chunk-FOPBOB7W.js +332 -0
  22. package/dist/{chunk-TILFPYWO.js → chunk-NHWHG3SW.js} +1930 -992
  23. package/dist/{chunk-BQTUOO4G.js → chunk-OQ26W5L4.js} +81 -32
  24. package/dist/{chunk-HUIK3WXO.js → chunk-P6XWWIEK.js} +20 -3
  25. package/dist/chunk-Q4P3W657.js +6372 -0
  26. package/dist/{chunk-ZAE25JM2.js → chunk-QANRZW7W.js} +8 -1
  27. package/dist/chunk-UIRJOQQS.js +118 -0
  28. package/dist/chunk-UKIE4AAM.js +472 -0
  29. package/dist/{chunk-KKB5W47S.js → chunk-VTMD5IHD.js} +26 -2
  30. package/dist/cli/index.js +148 -57
  31. package/dist/config-WV2H64TF.js +23 -0
  32. package/dist/{create-VXIH2GUZ.js → create-W6BV75QX.js} +18 -12
  33. package/dist/{deadline-F5RJJ2QW.js → deadline-TP7ZGLT2.js} +4 -2
  34. package/dist/evalCommand-SKJQ6CW2.js +686 -0
  35. package/dist/evalTune-CZRCPSZ3.js +295 -0
  36. package/dist/{export-HN3CT7AV.js → export-SJ3DUP6W.js} +2 -2
  37. package/dist/{inkChat-WEDGQMCY.js → inkChat-WYYAFZXD.js} +20 -19
  38. package/dist/install-TKWN5AYH.js +19 -0
  39. package/dist/{job-3NYDMP2M.js → job-7JOI4YIQ.js} +6 -2
  40. package/dist/jobCommand-2ODQLHB3.js +33 -0
  41. package/dist/{launchd-SSX362VG.js → launchd-3A3ONEW5.js} +9 -8
  42. package/dist/{lspCommand-JRXKRSL7.js → lspCommand-ZZ6R4PA2.js} +7 -6
  43. package/dist/{manager-773PUDFE.js → manager-TCYTA5XU.js} +15 -14
  44. package/dist/{nightCommand-65MUEV32.js → nightCommand-WJU6VZA6.js} +26 -20
  45. package/dist/{openaiCompatible-CJWVJP5M.js → openaiCompatible-6TLDDW5U.js} +29 -15
  46. package/dist/{policy-EJPLEEXP.js → policy-ZJ7RMOFN.js} +10 -4
  47. package/dist/{remove-6GDSTAIO.js → remove-42WQNVPX.js} +8 -7
  48. package/dist/{run-ML6GSPN4.js → run-PTMRQCIU.js} +5 -5
  49. package/dist/{server-NGKVIQEV.js → server-VEYIJHEU.js} +2 -2
  50. package/dist/{setupCommand-VA7D5MZK.js → setupCommand-YMF6I3MD.js} +45 -13
  51. package/dist/text-LS35WSRL.js +17 -0
  52. package/dist/tune-YVI2KWQF.js +31 -0
  53. package/native/bin/garuda-reap +0 -0
  54. package/native/garuda-reap.c +113 -0
  55. package/package.json +39 -13
  56. package/dist/chunk-EIXUSVFX.js +0 -116
  57. package/dist/chunk-R7I2NBPX.js +0 -71
  58. package/dist/chunk-ULAJPMY7.js +0 -107
  59. package/dist/chunk-VBZCNMUD.js +0 -9
  60. package/dist/evalCommand-RGMZRYDR.js +0 -2812
  61. package/dist/install-EWDSPFFZ.js +0 -18
  62. package/dist/jobCommand-ACSGSBQ4.js +0 -32
  63. package/dist/text-J2GD647J.js +0 -11
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ PROPOSER_SYSTEM,
4
+ parseProposal,
5
+ readAddendum,
6
+ tune
7
+ } from "./chunk-FOPBOB7W.js";
8
+ import {
9
+ EVAL_SUITES,
10
+ HELD_OUT_TASKS,
11
+ TOOLCHAINS,
12
+ checkToolchains,
13
+ formatReport,
14
+ requiredToolchains,
15
+ runEvals
16
+ } from "./chunk-Q4P3W657.js";
17
+ import {
18
+ DEFAULT_SEED,
19
+ reportV2,
20
+ shuffled
21
+ } from "./chunk-DOCDCQVM.js";
22
+ import "./chunk-NXJ4XLB5.js";
23
+ import {
24
+ NO_MODEL,
25
+ chooseModel,
26
+ keepProviderKeys,
27
+ loadModelsConfig,
28
+ resolveModel
29
+ } from "./chunk-2FIV2VZP.js";
30
+ import "./chunk-NHWHG3SW.js";
31
+ import "./chunk-65NUEOI7.js";
32
+ import "./chunk-G2AX7MGS.js";
33
+ import "./chunk-A2QAIRQL.js";
34
+ import {
35
+ newSessionId
36
+ } from "./chunk-UKIE4AAM.js";
37
+ import {
38
+ costOf
39
+ } from "./chunk-7KBOIPUT.js";
40
+ import "./chunk-B25VL4RU.js";
41
+ import "./chunk-23FXBNBB.js";
42
+ import "./chunk-C57GHLKP.js";
43
+ import "./chunk-5DEWP3YX.js";
44
+ import "./chunk-PZS3V6P3.js";
45
+ import "./chunk-QANRZW7W.js";
46
+ import "./chunk-ATW7BNIG.js";
47
+ import "./chunk-55CFEEIN.js";
48
+ import "./chunk-AOGFYUKG.js";
49
+ import "./chunk-6XHON3Q6.js";
50
+ import {
51
+ createExecutor
52
+ } from "./chunk-B4SJY7KT.js";
53
+ import "./chunk-BHZ6G65V.js";
54
+ import "./chunk-P6XWWIEK.js";
55
+ import "./chunk-UIRJOQQS.js";
56
+ import "./chunk-4LFJFDCF.js";
57
+ import "./chunk-3NJNVZTK.js";
58
+
59
+ // src/cli/evalTune.ts
60
+ import { mkdirSync, writeFileSync } from "fs";
61
+ import { writeFile } from "fs/promises";
62
+ import { join } from "path";
63
+ import { createInterface } from "readline/promises";
64
+ var DEFAULT_TUNE_PARALLEL = 4;
65
+ function progressLine(label, done, total, r) {
66
+ return `[${label} ${done}/${total}] ${r.passed ? "\u2713" : "\u2717"} ${r.id} (${r.steps} steps)${r.passed ? "" : `: ${(r.reason ?? r.stopReason).split("\n")[0]}`}`;
67
+ }
68
+ var DEFAULT_PROPOSER = "claude-opus-5-5";
69
+ var DEFAULT_TUNE_SUITES = ["basic", "hard", "medium"];
70
+ var whole = (value, fallback, min) => {
71
+ const v = value ?? fallback;
72
+ return Number.isInteger(v) && v >= min ? v : void 0;
73
+ };
74
+ async function askProposer(proposer, input) {
75
+ const client = await proposer.create();
76
+ let response;
77
+ for await (const event of client.stream({
78
+ system: PROPOSER_SYSTEM,
79
+ messages: [{ role: "user", content: [{ type: "text", text: input }] }],
80
+ tools: [],
81
+ maxTokens: 8e3
82
+ })) {
83
+ if (event.type === "response") response = event.response;
84
+ }
85
+ if (response === void 0) return "the proposer gave no answer";
86
+ const text = response.content.filter((b) => b.type === "text").map((b) => b.text).join("");
87
+ const parsed = parseProposal(text);
88
+ if (parsed === void 0) return "the proposer's answer has no <addendum> block";
89
+ const price = proposer.info.price;
90
+ return {
91
+ ...parsed,
92
+ costUsd: price === void 0 ? void 0 : costOf(response.usage, price, response.priceFactor ?? 1)
93
+ };
94
+ }
95
+ async function runEvalTune(options) {
96
+ const rounds = whole(options.rounds, 5, 1);
97
+ const repeat = whole(options.repeat, 3, 1);
98
+ const heldoutRepeat = whole(options.heldoutRepeat, 5, 1);
99
+ const margin = whole(options.margin, 2, 1);
100
+ const seed = whole(options.seed, DEFAULT_SEED, 0);
101
+ const parallel = whole(options.parallel, DEFAULT_TUNE_PARALLEL, 1);
102
+ const maxCost = options.maxCost ?? 20;
103
+ if (rounds === void 0 || repeat === void 0 || heldoutRepeat === void 0 || margin === void 0 || seed === void 0 || parallel === void 0 || !(maxCost > 0)) {
104
+ process.stderr.write(
105
+ "--rounds, --repeat, --heldout-repeat, --margin and --parallel must be whole numbers of 1 or more, --seed 0 or more, and --max-cost above 0.\n"
106
+ );
107
+ return 1;
108
+ }
109
+ const suites = options.suite ?? [...DEFAULT_TUNE_SUITES];
110
+ const devTasks = [];
111
+ for (const name of suites) {
112
+ const tasks = EVAL_SUITES[name];
113
+ if (tasks === void 0) {
114
+ process.stderr.write(`Unknown suite ${name}. Use: ${Object.keys(EVAL_SUITES).join(", ")}.
115
+ `);
116
+ return 1;
117
+ }
118
+ devTasks.push(...tasks);
119
+ }
120
+ const start = await readAddendum(options.addendum, true);
121
+ if ("problem" in start) {
122
+ process.stderr.write(`${start.problem}
123
+ `);
124
+ return 1;
125
+ }
126
+ const models = await loadModelsConfig();
127
+ if (models.problem !== void 0) {
128
+ process.stderr.write(`${models.problem}
129
+ `);
130
+ return 1;
131
+ }
132
+ const modelId = chooseModel(models.config, options.model);
133
+ if (!modelId) {
134
+ process.stderr.write(`${NO_MODEL}
135
+ `);
136
+ return 1;
137
+ }
138
+ let agent;
139
+ let proposer;
140
+ try {
141
+ agent = resolveModel(modelId, models.config);
142
+ proposer = resolveModel(options.proposer ?? DEFAULT_PROPOSER, models.config);
143
+ } catch (error) {
144
+ process.stderr.write(`${error.message}
145
+ `);
146
+ return 1;
147
+ }
148
+ const { assertModelAllowedByPolicy, loadTeamPolicy } = await import("./policy-ZJ7RMOFN.js");
149
+ let team;
150
+ try {
151
+ team = await loadTeamPolicy();
152
+ assertModelAllowedByPolicy(team?.policy, agent.spec);
153
+ assertModelAllowedByPolicy(team?.policy, proposer.spec);
154
+ } catch (error) {
155
+ process.stderr.write(`Team policy: ${error.message}
156
+ `);
157
+ return 1;
158
+ }
159
+ const warning = await keepProviderKeys([agent.def.apiKeyEnv, proposer.def.apiKeyEnv]);
160
+ if (warning !== void 0) process.stderr.write(`${warning}
161
+ `);
162
+ const missing = (await checkToolchains(requiredToolchains([...devTasks, ...HELD_OUT_TASKS]))).filter((s) => !s.ok);
163
+ if (missing.length > 0) {
164
+ for (const status of missing) process.stderr.write(`${TOOLCHAINS[status.id].hint}
165
+ `);
166
+ return 1;
167
+ }
168
+ const perScore = devTasks.length * repeat;
169
+ const heldOutRuns = 2 * HELD_OUT_TASKS.length * heldoutRepeat;
170
+ process.stderr.write(
171
+ [
172
+ `Tuning ${options.addendum} (${start.text.length} characters) with ${agent.spec}; ${proposer.spec} proposes.`,
173
+ `Dev: ${devTasks.length} task(s) from ${suites.join(", ")} \xD7 ${repeat} = ${perScore} runs a score, ${parallel} at a time; up to ${rounds + 1} scores.`,
174
+ `Held-out: ${HELD_OUT_TASKS.length} task(s) \xD7 ${heldoutRepeat}, twice, at the end (${heldOutRuns} runs), if a version is kept.`,
175
+ `Keep rule: +${margin} passing runs, or as many with a lower cost per accepted change (interval below \xD71.0).`,
176
+ `Budget: --max-cost $${maxCost}; the loop stops before a round that would pass it.`,
177
+ `Garuda changes no file outside the run's folder; ${options.addendum} stays as it is.`,
178
+ ""
179
+ ].join("\n")
180
+ );
181
+ if (options.yes !== true) {
182
+ if (!process.stdin.isTTY) {
183
+ process.stderr.write("Add --yes to start without a question.\n");
184
+ return 1;
185
+ }
186
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
187
+ const answer = await rl.question("Start? (y/N) ");
188
+ rl.close();
189
+ if (!/^y(es)?$/i.test(answer.trim())) return 1;
190
+ }
191
+ const { executor, notice } = createExecutor("auto");
192
+ if (notice !== void 0) process.stderr.write(`${notice}
193
+ `);
194
+ const dir = join(process.cwd(), ".garuda", "evals", `tune-${newSessionId()}`);
195
+ mkdirSync(dir, { recursive: true });
196
+ const score = async (addendum, tasks, k, label) => {
197
+ const listed = tasks.flatMap((t) => Array.from({ length: k }, () => t));
198
+ const outDir = join(dir, label);
199
+ let done = 0;
200
+ const results = await runEvals(
201
+ shuffled(listed, seed),
202
+ {
203
+ parallel,
204
+ modelId: agent.spec,
205
+ model: () => agent.create(),
206
+ modelInfo: agent.info,
207
+ ...agent.maxTokens === void 0 ? {} : { maxTokens: agent.maxTokens },
208
+ ...team === void 0 ? {} : { policy: team.policy },
209
+ outDir,
210
+ executor: executor.name === "host" ? "host" : "os",
211
+ ...addendum === "" ? {} : { addendum }
212
+ },
213
+ (r) => {
214
+ done++;
215
+ process.stderr.write(`${progressLine(label, done, listed.length, r)}
216
+ `);
217
+ }
218
+ );
219
+ writeFileSync(
220
+ join(outDir, "report.json"),
221
+ `${JSON.stringify(
222
+ {
223
+ ...await reportV2(
224
+ {
225
+ model: agent.spec,
226
+ provider: agent.provider,
227
+ executor: executor.name,
228
+ isolation: executor.isolation,
229
+ seed,
230
+ shuffle: true,
231
+ split: label.startsWith("heldout") ? "heldout" : "dev",
232
+ ...addendum === "" ? {} : { addendum: { file: `${label}.md`, text: addendum } }
233
+ },
234
+ tasks,
235
+ results
236
+ ),
237
+ results
238
+ },
239
+ null,
240
+ 2
241
+ )}
242
+ `
243
+ );
244
+ process.stderr.write(`
245
+ ${label}:
246
+ ${formatReport(results, { seed })}
247
+
248
+ `);
249
+ return results;
250
+ };
251
+ const result = await tune({
252
+ start: start.text,
253
+ devTasks,
254
+ heldOutTasks: HELD_OUT_TASKS,
255
+ score,
256
+ propose: async (input) => {
257
+ const answer = await askProposer(proposer, input);
258
+ if (typeof answer === "string") {
259
+ return { addendum: "", reason: answer, costUsd: 0 };
260
+ }
261
+ return answer;
262
+ },
263
+ rounds,
264
+ repeat,
265
+ heldoutRepeat,
266
+ margin,
267
+ maxCostUsd: maxCost,
268
+ seed,
269
+ save: (name, text) => writeFile(join(dir, name), text),
270
+ log: (line) => process.stderr.write(`${line}
271
+ `)
272
+ });
273
+ const kept = result.history.filter((h) => h.decision?.kept === true);
274
+ process.stdout.write(
275
+ [
276
+ "",
277
+ `Rounds: ${result.history.length}; kept: ${kept.length === 0 ? "none" : kept.map((h) => h.version).join(", ")}. Spent about $${result.spentUsd.toFixed(2)}${result.stopped === "rounds" ? "" : ` (stopped: ${result.stopped})`}.`,
278
+ ...result.heldOut === void 0 ? [] : ["", "Held-out (the only number to quote):", result.heldOut],
279
+ "",
280
+ `The final addendum: ${join(dir, "final.md")}. To use it, copy it into GARUDA.md yourself.`,
281
+ `Every version, the proposer's inputs and history.json: ${dir}`,
282
+ ""
283
+ ].join("\n")
284
+ );
285
+ return 0;
286
+ }
287
+ export {
288
+ DEFAULT_PROPOSER,
289
+ DEFAULT_TUNE_PARALLEL,
290
+ DEFAULT_TUNE_SUITES,
291
+ askProposer,
292
+ progressLine,
293
+ runEvalTune
294
+ };
295
+ //# sourceMappingURL=evalTune-CZRCPSZ3.js.map
@@ -11,7 +11,7 @@ import {
11
11
  PathOutsideRootError,
12
12
  displayPath,
13
13
  resolveInRoot
14
- } from "./chunk-WMOLXTBU.js";
14
+ } from "./chunk-4LFJFDCF.js";
15
15
 
16
16
  // src/cli/export.ts
17
17
  import { mkdir, writeFile } from "fs/promises";
@@ -155,4 +155,4 @@ export {
155
155
  sessionMarkdown,
156
156
  writeExport
157
157
  };
158
- //# sourceMappingURL=export-HN3CT7AV.js.map
158
+ //# sourceMappingURL=export-SJ3DUP6W.js.map
@@ -6,7 +6,11 @@ import {
6
6
  fuzzyFiles,
7
7
  runChat,
8
8
  statusOf
9
- } from "./chunk-BQTUOO4G.js";
9
+ } from "./chunk-OQ26W5L4.js";
10
+ import {
11
+ colorPreview,
12
+ header
13
+ } from "./chunk-4JSUUDFQ.js";
10
14
  import {
11
15
  retryText,
12
16
  serverToolOutput,
@@ -15,30 +19,27 @@ import {
15
19
  summariseResult,
16
20
  todoLines
17
21
  } from "./chunk-FARS4R67.js";
18
- import {
19
- colorPreview,
20
- header
21
- } from "./chunk-4JSUUDFQ.js";
22
- import "./chunk-TILFPYWO.js";
22
+ import "./chunk-NHWHG3SW.js";
23
+ import "./chunk-65NUEOI7.js";
23
24
  import "./chunk-G2AX7MGS.js";
24
25
  import "./chunk-A2QAIRQL.js";
25
- import "./chunk-ULAJPMY7.js";
26
- import "./chunk-EIXUSVFX.js";
27
- import "./chunk-R7I2NBPX.js";
26
+ import "./chunk-UKIE4AAM.js";
27
+ import "./chunk-7KBOIPUT.js";
28
28
  import "./chunk-B25VL4RU.js";
29
29
  import "./chunk-23FXBNBB.js";
30
30
  import "./chunk-EU7PA45O.js";
31
- import "./chunk-VBZCNMUD.js";
31
+ import "./chunk-C57GHLKP.js";
32
32
  import "./chunk-5DEWP3YX.js";
33
- import "./chunk-ZAE25JM2.js";
34
- import "./chunk-ATW7BNIG.js";
35
33
  import "./chunk-PZS3V6P3.js";
36
- import "./chunk-OUCV3FCT.js";
37
- import "./chunk-GXZACJUI.js";
38
- import "./chunk-WMOLXTBU.js";
39
- import "./chunk-3EQU2GUX.js";
40
- import "./chunk-HUIK3WXO.js";
41
- import "./chunk-KKB5W47S.js";
34
+ import "./chunk-QANRZW7W.js";
35
+ import "./chunk-ATW7BNIG.js";
36
+ import "./chunk-AOGFYUKG.js";
37
+ import "./chunk-B4SJY7KT.js";
38
+ import "./chunk-BHZ6G65V.js";
39
+ import "./chunk-P6XWWIEK.js";
40
+ import "./chunk-VTMD5IHD.js";
41
+ import "./chunk-UIRJOQQS.js";
42
+ import "./chunk-4LFJFDCF.js";
42
43
  import "./chunk-3NJNVZTK.js";
43
44
 
44
45
  // src/cli/chat/inkChat.ts
@@ -1193,4 +1194,4 @@ async function runInkChat(runtime, approver, setEventTarget, banner, sessionPath
1193
1194
  export {
1194
1195
  runInkChat
1195
1196
  };
1196
- //# sourceMappingURL=inkChat-WEDGQMCY.js.map
1197
+ //# sourceMappingURL=inkChat-WYYAFZXD.js.map
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ INSTALL_TIMEOUT_MS,
4
+ installCommand,
5
+ installServer
6
+ } from "./chunk-7TH3NHCQ.js";
7
+ import "./chunk-EU7PA45O.js";
8
+ import "./chunk-B4SJY7KT.js";
9
+ import "./chunk-BHZ6G65V.js";
10
+ import "./chunk-P6XWWIEK.js";
11
+ import "./chunk-UIRJOQQS.js";
12
+ import "./chunk-4LFJFDCF.js";
13
+ import "./chunk-3NJNVZTK.js";
14
+ export {
15
+ INSTALL_TIMEOUT_MS,
16
+ installCommand,
17
+ installServer
18
+ };
19
+ //# sourceMappingURL=install-TKWN5AYH.js.map
@@ -8,11 +8,14 @@ import {
8
8
  listJobs,
9
9
  loadJob,
10
10
  newJobId,
11
+ parseJob,
11
12
  planPermissions,
12
13
  planTitle,
13
14
  saveJob,
14
15
  settleJob
15
- } from "./chunk-KKB5W47S.js";
16
+ } from "./chunk-VTMD5IHD.js";
17
+ import "./chunk-UIRJOQQS.js";
18
+ import "./chunk-4LFJFDCF.js";
16
19
  import "./chunk-3NJNVZTK.js";
17
20
  export {
18
21
  DEFAULT_JOB_MAX_STEPS,
@@ -23,9 +26,10 @@ export {
23
26
  listJobs,
24
27
  loadJob,
25
28
  newJobId,
29
+ parseJob,
26
30
  planPermissions,
27
31
  planTitle,
28
32
  saveJob,
29
33
  settleJob
30
34
  };
31
- //# sourceMappingURL=job-3NYDMP2M.js.map
35
+ //# sourceMappingURL=job-7JOI4YIQ.js.map
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ JOB_TEST_TIMEOUT_MS,
4
+ finishJob,
5
+ msUntil,
6
+ prepareJob,
7
+ testsBefore
8
+ } from "./chunk-4BVCYCQT.js";
9
+ import "./chunk-N4I6YS3E.js";
10
+ import "./chunk-UKIE4AAM.js";
11
+ import "./chunk-7KBOIPUT.js";
12
+ import "./chunk-5DEWP3YX.js";
13
+ import "./chunk-PZS3V6P3.js";
14
+ import "./chunk-55CFEEIN.js";
15
+ import "./chunk-5B5HDTUR.js";
16
+ import "./chunk-3MRQJKUO.js";
17
+ import "./chunk-AOGFYUKG.js";
18
+ import "./chunk-6XHON3Q6.js";
19
+ import "./chunk-B4SJY7KT.js";
20
+ import "./chunk-BHZ6G65V.js";
21
+ import "./chunk-P6XWWIEK.js";
22
+ import "./chunk-VTMD5IHD.js";
23
+ import "./chunk-UIRJOQQS.js";
24
+ import "./chunk-4LFJFDCF.js";
25
+ import "./chunk-3NJNVZTK.js";
26
+ export {
27
+ JOB_TEST_TIMEOUT_MS,
28
+ finishJob,
29
+ msUntil,
30
+ prepareJob,
31
+ testsBefore
32
+ };
33
+ //# sourceMappingURL=jobCommand-2ODQLHB3.js.map
@@ -14,13 +14,14 @@ import {
14
14
  removeSpec,
15
15
  specPath,
16
16
  specPlist
17
- } from "./chunk-USCUXCAU.js";
18
- import "./chunk-TUUEBHG2.js";
19
- import "./chunk-GXZACJUI.js";
20
- import "./chunk-WMOLXTBU.js";
21
- import "./chunk-3EQU2GUX.js";
22
- import "./chunk-HUIK3WXO.js";
23
- import "./chunk-KKB5W47S.js";
17
+ } from "./chunk-5B5HDTUR.js";
18
+ import "./chunk-6XHON3Q6.js";
19
+ import "./chunk-B4SJY7KT.js";
20
+ import "./chunk-BHZ6G65V.js";
21
+ import "./chunk-P6XWWIEK.js";
22
+ import "./chunk-VTMD5IHD.js";
23
+ import "./chunk-UIRJOQQS.js";
24
+ import "./chunk-4LFJFDCF.js";
24
25
  import "./chunk-3NJNVZTK.js";
25
26
  export {
26
27
  agentLabel,
@@ -38,4 +39,4 @@ export {
38
39
  specPath,
39
40
  specPlist
40
41
  };
41
- //# sourceMappingURL=launchd-SSX362VG.js.map
42
+ //# sourceMappingURL=launchd-3A3ONEW5.js.map
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-36GQIVGT.js";
6
6
  import {
7
7
  installServer
8
- } from "./chunk-B6FA4I7Q.js";
8
+ } from "./chunk-7TH3NHCQ.js";
9
9
  import {
10
10
  LSP_CONFIG_FILE,
11
11
  loadLspConfig
@@ -18,10 +18,11 @@ import {
18
18
  HostExecutor,
19
19
  createExecutor,
20
20
  loadSettings
21
- } from "./chunk-GXZACJUI.js";
22
- import "./chunk-WMOLXTBU.js";
23
- import "./chunk-3EQU2GUX.js";
24
- import "./chunk-HUIK3WXO.js";
21
+ } from "./chunk-B4SJY7KT.js";
22
+ import "./chunk-BHZ6G65V.js";
23
+ import "./chunk-P6XWWIEK.js";
24
+ import "./chunk-UIRJOQQS.js";
25
+ import "./chunk-4LFJFDCF.js";
25
26
  import "./chunk-3NJNVZTK.js";
26
27
 
27
28
  // src/cli/lspCommand.ts
@@ -97,4 +98,4 @@ export {
97
98
  lspInstallCommand,
98
99
  lspStatusCommand
99
100
  };
100
- //# sourceMappingURL=lspCommand-JRXKRSL7.js.map
101
+ //# sourceMappingURL=lspCommand-ZZ6R4PA2.js.map
@@ -11,33 +11,34 @@ import {
11
11
  } from "./chunk-4P26OKTP.js";
12
12
  import {
13
13
  VERSION
14
- } from "./chunk-VBZCNMUD.js";
14
+ } from "./chunk-C57GHLKP.js";
15
15
  import {
16
16
  USER_SCOPE
17
17
  } from "./chunk-5DEWP3YX.js";
18
+ import {
19
+ capText,
20
+ cleanJson,
21
+ cleanLine,
22
+ cleanText,
23
+ neutralizeTags
24
+ } from "./chunk-PZS3V6P3.js";
18
25
  import {
19
26
  commandLine,
20
27
  defHash,
21
28
  expandEnv,
22
29
  isHttp
23
- } from "./chunk-ZAE25JM2.js";
30
+ } from "./chunk-QANRZW7W.js";
24
31
  import {
25
32
  isLoopbackHost
26
33
  } from "./chunk-ATW7BNIG.js";
27
- import {
28
- capText,
29
- cleanJson,
30
- cleanLine,
31
- cleanText,
32
- neutralizeTags
33
- } from "./chunk-PZS3V6P3.js";
34
34
  import {
35
35
  DEFAULT_ENV_ALLOWLIST,
36
36
  sandboxPaths
37
- } from "./chunk-GXZACJUI.js";
38
- import "./chunk-WMOLXTBU.js";
39
- import "./chunk-3EQU2GUX.js";
40
- import "./chunk-HUIK3WXO.js";
37
+ } from "./chunk-B4SJY7KT.js";
38
+ import "./chunk-BHZ6G65V.js";
39
+ import "./chunk-P6XWWIEK.js";
40
+ import "./chunk-UIRJOQQS.js";
41
+ import "./chunk-4LFJFDCF.js";
41
42
  import "./chunk-3NJNVZTK.js";
42
43
 
43
44
  // src/mcp/manager.ts
@@ -845,4 +846,4 @@ export {
845
846
  changeLines,
846
847
  warnings
847
848
  };
848
- //# sourceMappingURL=manager-773PUDFE.js.map
849
+ //# sourceMappingURL=manager-TCYTA5XU.js.map
@@ -1,41 +1,46 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  msUntil
4
- } from "./chunk-HE2K657U.js";
4
+ } from "./chunk-4BVCYCQT.js";
5
5
  import {
6
6
  notificationBytes,
7
7
  pickChannel
8
8
  } from "./chunk-N4I6YS3E.js";
9
- import "./chunk-ULAJPMY7.js";
10
- import "./chunk-R7I2NBPX.js";
9
+ import "./chunk-UKIE4AAM.js";
10
+ import "./chunk-7KBOIPUT.js";
11
11
  import "./chunk-5DEWP3YX.js";
12
12
  import "./chunk-PZS3V6P3.js";
13
- import "./chunk-44QN5SWZ.js";
13
+ import "./chunk-55CFEEIN.js";
14
14
  import {
15
15
  defaultAgentEnv,
16
16
  nightSpec,
17
17
  removeSpec
18
- } from "./chunk-USCUXCAU.js";
19
- import "./chunk-YQTGMCU6.js";
18
+ } from "./chunk-5B5HDTUR.js";
19
+ import {
20
+ formatCost,
21
+ jobCost,
22
+ sumCosts
23
+ } from "./chunk-3MRQJKUO.js";
20
24
  import {
21
25
  testSummary
22
- } from "./chunk-OUCV3FCT.js";
26
+ } from "./chunk-AOGFYUKG.js";
23
27
  import {
24
28
  hostCommand,
25
29
  shellWord
26
- } from "./chunk-TUUEBHG2.js";
30
+ } from "./chunk-6XHON3Q6.js";
27
31
  import {
28
32
  createExecutor
29
- } from "./chunk-GXZACJUI.js";
30
- import "./chunk-WMOLXTBU.js";
31
- import "./chunk-3EQU2GUX.js";
32
- import "./chunk-HUIK3WXO.js";
33
+ } from "./chunk-B4SJY7KT.js";
34
+ import "./chunk-BHZ6G65V.js";
35
+ import "./chunk-P6XWWIEK.js";
33
36
  import {
34
37
  JOBS_DIR,
35
38
  listJobs,
36
39
  loadJob,
37
40
  settleJob
38
- } from "./chunk-KKB5W47S.js";
41
+ } from "./chunk-VTMD5IHD.js";
42
+ import "./chunk-UIRJOQQS.js";
43
+ import "./chunk-4LFJFDCF.js";
39
44
  import "./chunk-3NJNVZTK.js";
40
45
 
41
46
  // src/cli/nightCommand.ts
@@ -100,14 +105,15 @@ async function runQueue(jobs, run, parallel, report = {}) {
100
105
  }
101
106
  function nightDigest(jobs, started, ended) {
102
107
  const ready = jobs.filter((j) => j.result?.proof?.verdict === "ready");
103
- const cost = jobs.reduce(
104
- (sum, j) => sum + (j.result?.costUsd ?? 0) + (j.result?.proof?.review?.costUsd ?? 0),
105
- 0
108
+ const cost = sumCosts(
109
+ jobs.map(
110
+ (j) => j.result !== void 0 ? jobCost(j.result) : { usd: 0, incomplete: j.status !== "scheduled" }
111
+ )
106
112
  );
107
113
  const lines = [
108
114
  `# Garuda night shift: ${local(started)}`,
109
115
  "",
110
- `${jobs.length} job(s): ${ready.length} ready to merge, ${jobs.length - ready.length} need a look. Time ${Math.round((ended.getTime() - started.getTime()) / 6e4)} min \xB7 cost $${cost.toFixed(4)}.`,
116
+ `${jobs.length} job(s): ${ready.length} ready to merge, ${jobs.length - ready.length} need a look. Time ${Math.round((ended.getTime() - started.getTime()) / 6e4)} min \xB7 cost ${formatCost(cost)}.`,
111
117
  "",
112
118
  "| Job | Verdict | Tests after | Files | Cost | Branch |",
113
119
  "| --- | --- | --- | --- | --- | --- |"
@@ -115,9 +121,9 @@ function nightDigest(jobs, started, ended) {
115
121
  for (const j of jobs) {
116
122
  const r = j.result;
117
123
  const verdict = r?.proof === void 0 ? j.status : r.proof.verdict === "ready" ? "ready to merge" : "needs a look";
118
- const jobCost = r === void 0 ? "\u2013" : `$${((r.costUsd ?? 0) + (r.proof?.review?.costUsd ?? 0)).toFixed(4)}`;
124
+ const costText = r === void 0 ? "\u2013" : formatCost(jobCost(r));
119
125
  lines.push(
120
- `| ${j.id}: ${cell(j.title)} | ${verdict} | ${j.test === void 0 ? "no tests" : testSummary(r?.proof?.after)} | ${r?.files.length ?? 0} | ${jobCost} | ${j.branch} |`
126
+ `| ${j.id}: ${cell(j.title)} | ${verdict} | ${j.test === void 0 ? "no tests" : testSummary(r?.proof?.after)} | ${r?.files.length ?? 0} | ${costText} | ${j.branch} |`
121
127
  );
122
128
  }
123
129
  const looks = jobs.filter((j) => j.result?.proof?.verdict !== "ready");
@@ -246,4 +252,4 @@ Digest: ${file}`);
246
252
  export {
247
253
  nightCommand
248
254
  };
249
- //# sourceMappingURL=nightCommand-65MUEV32.js.map
255
+ //# sourceMappingURL=nightCommand-WJU6VZA6.js.map