brass-runtime 1.13.5 → 1.13.6

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.
@@ -1,29 +1,29 @@
1
1
  #!/usr/bin/env node
2
- "use strict"; function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
- var _chunkHRVX2IYWjs = require('../../chunk-HRVX2IYW.js');
21
-
22
-
23
-
24
-
25
-
26
- var _chunkTGOMLZ65js = require('../../chunk-TGOMLZ65.js');
2
+ import {
3
+ NodeShell,
4
+ autoApproveApprovals,
5
+ discoverNodeWorkspaceRoot,
6
+ goalForAgentPreset,
7
+ isAgentPreset,
8
+ loadNodeAgentConfig,
9
+ makeAutoDenyApprovals,
10
+ makeConfiguredPermissions,
11
+ makeFakeLLM,
12
+ makeGoogleGenerativeAILLM,
13
+ makeNodeFileSystem,
14
+ makeNodePatchService,
15
+ makeOpenAICompatibleLLM,
16
+ observationStatus,
17
+ runAgent,
18
+ summarizeAgentAction,
19
+ summarizeAgentObservation
20
+ } from "../../chunk-HRVX2IYW.js";
21
+ import {
22
+ Cause,
23
+ Exit,
24
+ Runtime,
25
+ async
26
+ } from "../../chunk-TGOMLZ65.js";
27
27
 
28
28
  // src/agent/cli/approvals.ts
29
29
  var dynamicImport = new Function("specifier", "return import(specifier)");
@@ -39,35 +39,35 @@ var answerToResponse = (answer, request) => {
39
39
  return { type: "rejected", reason: `Unrecognized approval answer: ${answer}` };
40
40
  };
41
41
  var makeCliApprovalService = (options = {}) => ({
42
- request: (request) => _chunkTGOMLZ65js.async.call(void 0, (_env, cb) => {
42
+ request: (request) => async((_env, cb) => {
43
43
  let closed = false;
44
44
  let rl;
45
45
  dynamicImport("node:readline/promises").then(({ createInterface }) => {
46
46
  if (closed) return void 0;
47
- const input = _nullishCoalesce(options.input, () => ( process.stdin));
48
- const output = _nullishCoalesce(_nullishCoalesce(options.output, () => ( process.stderr)), () => ( process.stdout));
47
+ const input = options.input ?? process.stdin;
48
+ const output = options.output ?? process.stderr ?? process.stdout;
49
49
  const defaultHint = request.defaultAnswer === "approve" ? "Y/n" : "y/N";
50
50
  rl = createInterface({ input, output });
51
- _optionalChain([output, 'optionalAccess', _ => _.write, 'optionalCall', _2 => _2(`
51
+ output?.write?.(`
52
52
  Approval required (${request.risk})
53
- `)]);
54
- _optionalChain([output, 'optionalAccess', _3 => _3.write, 'optionalCall', _4 => _4(`Action: ${_chunkHRVX2IYWjs.summarizeAgentAction.call(void 0, request.action)}
55
- `)]);
56
- _optionalChain([output, 'optionalAccess', _5 => _5.write, 'optionalCall', _6 => _6(`Reason: ${request.reason}
57
- `)]);
53
+ `);
54
+ output?.write?.(`Action: ${summarizeAgentAction(request.action)}
55
+ `);
56
+ output?.write?.(`Reason: ${request.reason}
57
+ `);
58
58
  return rl.question(`Approve? [${defaultHint}] `);
59
59
  }).then((answer) => {
60
60
  if (answer === void 0 || closed) return;
61
61
  closed = true;
62
- _optionalChain([rl, 'optionalAccess', _7 => _7.close, 'optionalCall', _8 => _8()]);
63
- cb(_chunkTGOMLZ65js.Exit.succeed(answerToResponse(answer, request)));
62
+ rl?.close?.();
63
+ cb(Exit.succeed(answerToResponse(answer, request)));
64
64
  }).catch((cause) => {
65
65
  if (closed) return;
66
66
  closed = true;
67
- _optionalChain([rl, 'optionalAccess', _9 => _9.close, 'optionalCall', _10 => _10()]);
67
+ rl?.close?.();
68
68
  cb(
69
- _chunkTGOMLZ65js.Exit.failCause(
70
- _chunkTGOMLZ65js.Cause.fail({
69
+ Exit.failCause(
70
+ Cause.fail({
71
71
  _tag: "AgentLoopError",
72
72
  message: `Approval prompt failed: ${String(cause)}`
73
73
  })
@@ -77,55 +77,55 @@ Approval required (${request.risk})
77
77
  return () => {
78
78
  if (closed) return;
79
79
  closed = true;
80
- _optionalChain([rl, 'optionalAccess', _11 => _11.close, 'optionalCall', _12 => _12()]);
80
+ rl?.close?.();
81
81
  };
82
82
  })
83
83
  });
84
84
 
85
85
  // src/agent/cli/doctor.ts
86
- var _fs = require('fs');
87
- var _promises = require('fs/promises');
88
- var _path = require('path');
89
- var _child_process = require('child_process');
86
+ import { existsSync, readdirSync, readFileSync } from "fs";
87
+ import { access, constants } from "fs/promises";
88
+ import { join, resolve } from "path";
89
+ import { spawnSync } from "child_process";
90
90
  var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
91
91
  var readJsonFile = (path) => {
92
92
  try {
93
- return JSON.parse(_fs.readFileSync.call(void 0, path, "utf8"));
94
- } catch (e) {
93
+ return JSON.parse(readFileSync(path, "utf8"));
94
+ } catch {
95
95
  return void 0;
96
96
  }
97
97
  };
98
98
  var findPackageRoot = (start, packageName) => {
99
- let current = _path.resolve.call(void 0, start);
99
+ let current = resolve(start);
100
100
  while (true) {
101
- const packageJsonPath = _path.join.call(void 0, current, "package.json");
101
+ const packageJsonPath = join(current, "package.json");
102
102
  const json = readJsonFile(packageJsonPath);
103
103
  if (isRecord(json) && json.name === packageName) return current;
104
- const parent = _path.resolve.call(void 0, current, "..");
104
+ const parent = resolve(current, "..");
105
105
  if (parent === current) return void 0;
106
106
  current = parent;
107
107
  }
108
108
  };
109
109
  var commandVersion = (command, args = ["--version"], cwd) => {
110
- const result = _child_process.spawnSync.call(void 0, command, [...args], {
110
+ const result = spawnSync(command, [...args], {
111
111
  cwd,
112
112
  encoding: "utf8",
113
113
  shell: false,
114
114
  timeout: 1e4
115
115
  });
116
- if (result.error || (_nullishCoalesce(result.status, () => ( 0))) !== 0) return void 0;
117
- return `${_nullishCoalesce(result.stdout, () => ( ""))}${_nullishCoalesce(result.stderr, () => ( ""))}`.trim().split(/\r?\n/g)[0];
116
+ if (result.error || (result.status ?? 0) !== 0) return void 0;
117
+ return `${result.stdout ?? ""}${result.stderr ?? ""}`.trim().split(/\r?\n/g)[0];
118
118
  };
119
119
  var hasEnv = (name) => Boolean(name && process.env[name]);
120
120
  var launchedFromVsCodeExtension = () => process.env.BRASS_AGENT_VSCODE_EXTENSION === "1";
121
121
  var packageManagerFromWorkspace = (cwd) => {
122
- const packageJson = readJsonFile(_path.join.call(void 0, cwd, "package.json"));
122
+ const packageJson = readJsonFile(join(cwd, "package.json"));
123
123
  const packageManager = isRecord(packageJson) && typeof packageJson.packageManager === "string" ? packageJson.packageManager.split("@")[0] : void 0;
124
124
  if (packageManager) return { manager: packageManager, source: "package.json packageManager" };
125
- if (_fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "pnpm-lock.yaml"))) return { manager: "pnpm", source: "pnpm-lock.yaml" };
126
- if (_fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "yarn.lock"))) return { manager: "yarn", source: "yarn.lock" };
127
- if (_fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "bun.lockb")) || _fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "bun.lock"))) return { manager: "bun", source: "bun lockfile" };
128
- if (_fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "package-lock.json")) || _fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "npm-shrinkwrap.json"))) return { manager: "npm", source: "npm lockfile" };
125
+ if (existsSync(join(cwd, "pnpm-lock.yaml"))) return { manager: "pnpm", source: "pnpm-lock.yaml" };
126
+ if (existsSync(join(cwd, "yarn.lock"))) return { manager: "yarn", source: "yarn.lock" };
127
+ if (existsSync(join(cwd, "bun.lockb")) || existsSync(join(cwd, "bun.lock"))) return { manager: "bun", source: "bun lockfile" };
128
+ if (existsSync(join(cwd, "package-lock.json")) || existsSync(join(cwd, "npm-shrinkwrap.json"))) return { manager: "npm", source: "npm lockfile" };
129
129
  return { manager: "npm", source: "fallback" };
130
130
  };
131
131
  var packageScripts = (packageJson) => isRecord(packageJson) && isRecord(packageJson.scripts) ? Object.entries(packageJson.scripts).filter(([, value]) => typeof value === "string").map(([name]) => name).sort() : [];
@@ -145,7 +145,7 @@ var projectProfileCheck = (cwd, packageJson) => {
145
145
  "turbo.json",
146
146
  "nx.json",
147
147
  "pnpm-workspace.yaml"
148
- ].filter((path) => _fs.existsSync.call(void 0, _path.join.call(void 0, cwd, path)));
148
+ ].filter((path) => existsSync(join(cwd, path)));
149
149
  const stacks = [];
150
150
  if (isRecord(packageJson)) stacks.push("node");
151
151
  if (markers.some((marker) => marker === "Cargo.toml" || marker === "Cargo.lock" || marker.endsWith("Cargo.toml"))) stacks.push("rust");
@@ -222,8 +222,8 @@ var envFileCheck = (load) => {
222
222
  };
223
223
  };
224
224
  var llmCheck = (config) => {
225
- const provider = _optionalChain([(_nullishCoalesce(process.env.BRASS_LLM_PROVIDER, () => ( _optionalChain([config, 'optionalAccess', _13 => _13.llm, 'optionalAccess', _14 => _14.provider])))), 'optionalAccess', _15 => _15.trim, 'call', _16 => _16(), 'access', _17 => _17.toLowerCase, 'call', _18 => _18()]);
226
- const configuredApiKeyEnv = _optionalChain([config, 'optionalAccess', _19 => _19.llm, 'optionalAccess', _20 => _20.apiKeyEnv]);
225
+ const provider = (process.env.BRASS_LLM_PROVIDER ?? config?.llm?.provider)?.trim().toLowerCase();
226
+ const configuredApiKeyEnv = config?.llm?.apiKeyEnv;
227
227
  if (provider === "fake") {
228
228
  return {
229
229
  id: "llm",
@@ -242,7 +242,7 @@ var llmCheck = (config) => {
242
242
  };
243
243
  }
244
244
  if (provider === "openai" || provider === "openai-compatible") {
245
- const endpointPresent = Boolean(_nullishCoalesce(process.env.BRASS_LLM_ENDPOINT, () => ( _optionalChain([config, 'optionalAccess', _21 => _21.llm, 'optionalAccess', _22 => _22.endpoint]))));
245
+ const endpointPresent = Boolean(process.env.BRASS_LLM_ENDPOINT ?? config?.llm?.endpoint);
246
246
  const keyPresent = hasEnv(configuredApiKeyEnv) || hasEnv("BRASS_LLM_API_KEY");
247
247
  return {
248
248
  id: "llm",
@@ -259,7 +259,7 @@ var llmCheck = (config) => {
259
259
  message: "Google/Gemini credentials are available and will be auto-detected."
260
260
  };
261
261
  }
262
- if ((_nullishCoalesce(process.env.BRASS_LLM_ENDPOINT, () => ( _optionalChain([config, 'optionalAccess', _23 => _23.llm, 'optionalAccess', _24 => _24.endpoint])))) && hasEnv("BRASS_LLM_API_KEY")) {
262
+ if ((process.env.BRASS_LLM_ENDPOINT ?? config?.llm?.endpoint) && hasEnv("BRASS_LLM_API_KEY")) {
263
263
  return {
264
264
  id: "llm",
265
265
  label: "LLM provider",
@@ -275,26 +275,26 @@ var llmCheck = (config) => {
275
275
  };
276
276
  };
277
277
  var workspaceSettingsCommand = (cwd) => {
278
- const settings = readJsonFile(_path.join.call(void 0, cwd, ".vscode", "settings.json"));
278
+ const settings = readJsonFile(join(cwd, ".vscode", "settings.json"));
279
279
  if (!isRecord(settings)) return void 0;
280
280
  const command = settings["brassAgent.command"];
281
281
  return typeof command === "string" ? command : void 0;
282
282
  };
283
283
  var newestVsix = (extensionDir) => {
284
284
  try {
285
- return _fs.readdirSync.call(void 0, extensionDir).filter((name) => name.endsWith(".vsix")).sort().at(-1);
286
- } catch (e2) {
285
+ return readdirSync(extensionDir).filter((name) => name.endsWith(".vsix")).sort().at(-1);
286
+ } catch {
287
287
  return void 0;
288
288
  }
289
289
  };
290
290
  var push = (checks, check) => {
291
291
  checks.push(check);
292
292
  };
293
- var runAgentDoctor = _chunkTGOMLZ65js.async.call(void 0, options) => {
294
- const cwd = _path.resolve.call(void 0, options.cwd);
293
+ var runAgentDoctor = async (options) => {
294
+ const cwd = resolve(options.cwd);
295
295
  const checks = [];
296
- const repoRoot = _nullishCoalesce(findPackageRoot(cwd, "brass-runtime"), () => ( findPackageRoot(process.cwd(), "brass-runtime")));
297
- const nodeMajor = Number(_nullishCoalesce(process.versions.node.split(".")[0], () => ( "0")));
296
+ const repoRoot = findPackageRoot(cwd, "brass-runtime") ?? findPackageRoot(process.cwd(), "brass-runtime");
297
+ const nodeMajor = Number(process.versions.node.split(".")[0] ?? "0");
298
298
  push(checks, {
299
299
  id: "node",
300
300
  label: "Node.js",
@@ -325,8 +325,8 @@ var runAgentDoctor = _chunkTGOMLZ65js.async.call(void 0, options) => {
325
325
  push(checks, {
326
326
  id: "workspace",
327
327
  label: "Workspace",
328
- status: _fs.existsSync.call(void 0, cwd) ? "ok" : "fail",
329
- message: _fs.existsSync.call(void 0, cwd) ? cwd : `Workspace does not exist: ${cwd}`
328
+ status: existsSync(cwd) ? "ok" : "fail",
329
+ message: existsSync(cwd) ? cwd : `Workspace does not exist: ${cwd}`
330
330
  });
331
331
  if (options.workspaceDiscovery) {
332
332
  const discovery = options.workspaceDiscovery;
@@ -337,7 +337,7 @@ var runAgentDoctor = _chunkTGOMLZ65js.async.call(void 0, options) => {
337
337
  message: discovery.disabled ? "Workspace discovery disabled by --no-discover-workspace." : discovery.marker ? `${discovery.changed ? `Resolved ${discovery.inputCwd} -> ${discovery.cwd}` : `Using ${discovery.cwd}`} via ${discovery.marker}.` : `No workspace marker found upward from ${discovery.inputCwd}; using input cwd.`
338
338
  });
339
339
  }
340
- const packageJsonPath = _path.join.call(void 0, cwd, "package.json");
340
+ const packageJsonPath = join(cwd, "package.json");
341
341
  const packageJson = readJsonFile(packageJsonPath);
342
342
  push(checks, {
343
343
  id: "workspace.packageJson",
@@ -372,7 +372,7 @@ var runAgentDoctor = _chunkTGOMLZ65js.async.call(void 0, options) => {
372
372
  message: options.configPath ? `Loaded ${options.configPath}` : "No .brass-agent.json / brass-agent.config.json loaded; using built-in defaults and VS Code/CLI settings."
373
373
  });
374
374
  if (options.includeVsCode !== false) {
375
- const codeVersion = commandVersion(_nullishCoalesce(process.env.BRASS_CODE_CMD, () => ( "code")));
375
+ const codeVersion = commandVersion(process.env.BRASS_CODE_CMD ?? "code");
376
376
  push(checks, {
377
377
  id: "vscode.code",
378
378
  label: "VS Code CLI",
@@ -385,13 +385,13 @@ var runAgentDoctor = _chunkTGOMLZ65js.async.call(void 0, options) => {
385
385
  id: "vscode.settings",
386
386
  label: "VS Code extension setting",
387
387
  status: configured ? "ok" : launchedByExtension ? "skip" : "warn",
388
- message: configured ? `brassAgent.command = ${configured}` : launchedByExtension ? `No workspace brassAgent.command needed; launched by the VS Code extension (${_nullishCoalesce(process.env.BRASS_AGENT_VSCODE_CLI_SOURCE, () => ( "auto"))}).` : "No workspace .vscode/settings.json brassAgent.command found."
388
+ message: configured ? `brassAgent.command = ${configured}` : launchedByExtension ? `No workspace brassAgent.command needed; launched by the VS Code extension (${process.env.BRASS_AGENT_VSCODE_CLI_SOURCE ?? "auto"}).` : "No workspace .vscode/settings.json brassAgent.command found."
389
389
  });
390
390
  }
391
391
  if (repoRoot) {
392
- const cliSource = _path.join.call(void 0, repoRoot, "src", "agent", "cli", "main.ts");
393
- const cliBuild = _path.join.call(void 0, repoRoot, "dist", "agent", "cli", "main.cjs");
394
- const extensionDir = _path.join.call(void 0, repoRoot, "extensions", "vscode-brass-agent");
392
+ const cliSource = join(repoRoot, "src", "agent", "cli", "main.ts");
393
+ const cliBuild = join(repoRoot, "dist", "agent", "cli", "main.cjs");
394
+ const extensionDir = join(repoRoot, "extensions", "vscode-brass-agent");
395
395
  push(checks, {
396
396
  id: "repo.root",
397
397
  label: "brass-runtime repo",
@@ -401,26 +401,26 @@ var runAgentDoctor = _chunkTGOMLZ65js.async.call(void 0, options) => {
401
401
  push(checks, {
402
402
  id: "repo.cliSource",
403
403
  label: "CLI source",
404
- status: _fs.existsSync.call(void 0, cliSource) ? "ok" : "fail",
405
- message: _fs.existsSync.call(void 0, cliSource) ? `Found ${cliSource}` : `Missing ${cliSource}`
404
+ status: existsSync(cliSource) ? "ok" : "fail",
405
+ message: existsSync(cliSource) ? `Found ${cliSource}` : `Missing ${cliSource}`
406
406
  });
407
407
  push(checks, {
408
408
  id: "repo.cliBuild",
409
409
  label: "CLI build",
410
- status: _fs.existsSync.call(void 0, cliBuild) ? "ok" : "warn",
411
- message: _fs.existsSync.call(void 0, cliBuild) ? `Found ${cliBuild}` : "dist/agent/cli/main.cjs is missing; run npm run build."
410
+ status: existsSync(cliBuild) ? "ok" : "warn",
411
+ message: existsSync(cliBuild) ? `Found ${cliBuild}` : "dist/agent/cli/main.cjs is missing; run npm run build."
412
412
  });
413
413
  push(checks, {
414
414
  id: "repo.extensionDir",
415
415
  label: "VS Code extension source",
416
- status: _fs.existsSync.call(void 0, _path.join.call(void 0, extensionDir, "package.json")) ? "ok" : "warn",
417
- message: _fs.existsSync.call(void 0, _path.join.call(void 0, extensionDir, "package.json")) ? extensionDir : "extensions/vscode-brass-agent was not found."
416
+ status: existsSync(join(extensionDir, "package.json")) ? "ok" : "warn",
417
+ message: existsSync(join(extensionDir, "package.json")) ? extensionDir : "extensions/vscode-brass-agent was not found."
418
418
  });
419
419
  push(checks, {
420
420
  id: "repo.extensionBuild",
421
421
  label: "VS Code extension build",
422
- status: _fs.existsSync.call(void 0, _path.join.call(void 0, extensionDir, "out", "extension.js")) ? "ok" : "warn",
423
- message: _fs.existsSync.call(void 0, _path.join.call(void 0, extensionDir, "out", "extension.js")) ? "out/extension.js exists." : "Extension output missing; run npm run agent:vscode:package or compile the extension."
422
+ status: existsSync(join(extensionDir, "out", "extension.js")) ? "ok" : "warn",
423
+ message: existsSync(join(extensionDir, "out", "extension.js")) ? "out/extension.js exists." : "Extension output missing; run npm run agent:vscode:package or compile the extension."
424
424
  });
425
425
  const vsix = newestVsix(extensionDir);
426
426
  push(checks, {
@@ -429,7 +429,7 @@ var runAgentDoctor = _chunkTGOMLZ65js.async.call(void 0, options) => {
429
429
  status: vsix ? "ok" : "warn",
430
430
  message: vsix ? `Found ${vsix}` : "No .vsix found in extensions/vscode-brass-agent."
431
431
  });
432
- const cliReadable = await _promises.access.call(void 0, cliBuild, _promises.constants.R_OK).then(() => true).catch(() => false);
432
+ const cliReadable = await access(cliBuild, constants.R_OK).then(() => true).catch(() => false);
433
433
  push(checks, {
434
434
  id: "repo.cliReadable",
435
435
  label: "CLI artifact readable",
@@ -479,8 +479,8 @@ var printAgentDoctorReport = (report) => {
479
479
  };
480
480
 
481
481
  // src/agent/cli/envFile.ts
482
-
483
-
482
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
483
+ import { isAbsolute, join as join2, resolve as resolve2 } from "path";
484
484
  var DEFAULT_AGENT_ENV_FILE_NAMES = [".brass-agent.env", ".env.local", ".env"];
485
485
  var BASE_ALLOWED_ENV_KEYS = /* @__PURE__ */ new Set([
486
486
  "BRASS_LLM_PROVIDER",
@@ -519,20 +519,20 @@ var parseEnvLine = (line) => {
519
519
  const withoutExport = trimmed.startsWith("export ") ? trimmed.slice("export ".length).trimStart() : trimmed;
520
520
  const match = /^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(withoutExport);
521
521
  if (!match) return { type: "invalid" };
522
- const key = _nullishCoalesce(match[1], () => ( ""));
523
- const rawValue = _nullishCoalesce(match[2], () => ( ""));
522
+ const key = match[1] ?? "";
523
+ const rawValue = match[2] ?? "";
524
524
  const compact = rawValue.trim();
525
525
  const quoted = parseQuotedValue(compact);
526
- const value = _nullishCoalesce(quoted, () => ( compact.replace(/\s+#.*$/u, "").trim()));
526
+ const value = quoted ?? compact.replace(/\s+#.*$/u, "").trim();
527
527
  return { type: "assignment", key, value };
528
528
  };
529
529
  var candidatePaths = (cwd, envFile) => {
530
- if (envFile) return [_path.isAbsolute.call(void 0, envFile) ? envFile : _path.resolve.call(void 0, cwd, envFile)];
531
- return DEFAULT_AGENT_ENV_FILE_NAMES.map((name) => _path.join.call(void 0, cwd, name));
530
+ if (envFile) return [isAbsolute(envFile) ? envFile : resolve2(cwd, envFile)];
531
+ return DEFAULT_AGENT_ENV_FILE_NAMES.map((name) => join2(cwd, name));
532
532
  };
533
533
  var loadAgentEnvFile = (options) => {
534
- const cwd = _path.resolve.call(void 0, options.cwd);
535
- const extraKeys = _nullishCoalesce(_optionalChain([options, 'access', _25 => _25.allowedExtraKeys, 'optionalAccess', _26 => _26.filter, 'call', _27 => _27(Boolean)]), () => ( []));
534
+ const cwd = resolve2(options.cwd);
535
+ const extraKeys = options.allowedExtraKeys?.filter(Boolean) ?? [];
536
536
  const allowedKeys = /* @__PURE__ */ new Set([...BASE_ALLOWED_ENV_KEYS, ...extraKeys]);
537
537
  const files = options.noEnvFile ? [] : candidatePaths(cwd, options.envFile);
538
538
  const paths = [];
@@ -557,14 +557,14 @@ var loadAgentEnvFile = (options) => {
557
557
  };
558
558
  }
559
559
  for (const path of files) {
560
- if (!_fs.existsSync.call(void 0, path)) {
560
+ if (!existsSync2(path)) {
561
561
  if (options.envFile) errors.push(`Env file does not exist: ${path}`);
562
562
  continue;
563
563
  }
564
564
  paths.push(path);
565
565
  let raw;
566
566
  try {
567
- raw = _fs.readFileSync.call(void 0, path, "utf8").replace(/^\uFEFF/u, "");
567
+ raw = readFileSync2(path, "utf8").replace(/^\uFEFF/u, "");
568
568
  } catch (error) {
569
569
  errors.push(`Could not read env file ${path}: ${error instanceof Error ? error.message : String(error)}`);
570
570
  continue;
@@ -595,7 +595,7 @@ var loadAgentEnvFile = (options) => {
595
595
  return {
596
596
  cwd,
597
597
  disabled: false,
598
- ...options.envFile ? { explicitPath: _path.isAbsolute.call(void 0, options.envFile) ? options.envFile : _path.resolve.call(void 0, cwd, options.envFile) } : {},
598
+ ...options.envFile ? { explicitPath: isAbsolute(options.envFile) ? options.envFile : resolve2(cwd, options.envFile) } : {},
599
599
  filesChecked: files,
600
600
  paths,
601
601
  loadedKeys: unique(loadedKeys),
@@ -608,36 +608,36 @@ var loadAgentEnvFile = (options) => {
608
608
  };
609
609
 
610
610
  // src/agent/cli/init.ts
611
-
612
-
613
-
611
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
612
+ import { mkdir, writeFile } from "fs/promises";
613
+ import { dirname, join as join3, resolve as resolve3 } from "path";
614
614
  var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
615
615
  var readJsonFile2 = (path) => {
616
616
  try {
617
- return JSON.parse(_fs.readFileSync.call(void 0, path, "utf8"));
618
- } catch (e3) {
617
+ return JSON.parse(readFileSync3(path, "utf8"));
618
+ } catch {
619
619
  return void 0;
620
620
  }
621
621
  };
622
622
  var readPackageJson = (cwd) => {
623
- const json = readJsonFile2(_path.join.call(void 0, cwd, "package.json"));
623
+ const json = readJsonFile2(join3(cwd, "package.json"));
624
624
  return isRecord2(json) ? json : void 0;
625
625
  };
626
626
  var scriptNames = (packageJson) => {
627
- const scripts = _optionalChain([packageJson, 'optionalAccess', _28 => _28.scripts]);
627
+ const scripts = packageJson?.scripts;
628
628
  if (!isRecord2(scripts)) return [];
629
629
  return Object.entries(scripts).filter(([, value]) => typeof value === "string").map(([name]) => name).sort();
630
630
  };
631
631
  var hasAnyScript = (scripts, candidates) => candidates.some((candidate) => scripts.includes(candidate));
632
632
  var inferPackageManager = (cwd, packageJson) => {
633
- const packageManager = typeof _optionalChain([packageJson, 'optionalAccess', _29 => _29.packageManager]) === "string" ? packageJson.packageManager.split("@")[0] : void 0;
633
+ const packageManager = typeof packageJson?.packageManager === "string" ? packageJson.packageManager.split("@")[0] : void 0;
634
634
  if (packageManager === "npm" || packageManager === "pnpm" || packageManager === "yarn" || packageManager === "bun") {
635
635
  return packageManager;
636
636
  }
637
- if (_fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "pnpm-lock.yaml"))) return "pnpm";
638
- if (_fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "yarn.lock"))) return "yarn";
639
- if (_fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "bun.lockb")) || _fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "bun.lock"))) return "bun";
640
- if (_fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "package-lock.json")) || _fs.existsSync.call(void 0, _path.join.call(void 0, cwd, "npm-shrinkwrap.json"))) return "npm";
637
+ if (existsSync3(join3(cwd, "pnpm-lock.yaml"))) return "pnpm";
638
+ if (existsSync3(join3(cwd, "yarn.lock"))) return "yarn";
639
+ if (existsSync3(join3(cwd, "bun.lockb")) || existsSync3(join3(cwd, "bun.lock"))) return "bun";
640
+ if (existsSync3(join3(cwd, "package-lock.json")) || existsSync3(join3(cwd, "npm-shrinkwrap.json"))) return "npm";
641
641
  return "auto";
642
642
  };
643
643
  var llmConfigForProfile = (profile) => {
@@ -877,13 +877,13 @@ var nextStepsForProfile = (profile) => {
877
877
  }
878
878
  return steps;
879
879
  };
880
- var writeInitFile = _chunkTGOMLZ65js.async.call(void 0, options) => {
881
- const path = _path.resolve.call(void 0, options.cwd, options.relativePath);
882
- const exists = _fs.existsSync.call(void 0, path);
880
+ var writeInitFile = async (options) => {
881
+ const path = resolve3(options.cwd, options.relativePath);
882
+ const exists = existsSync3(path);
883
883
  const status = exists ? options.force ? "overwritten" : "skipped" : "created";
884
884
  if (!options.dryRun && status !== "skipped") {
885
- await _promises.mkdir.call(void 0, _path.dirname.call(void 0, path), { recursive: true });
886
- await _promises.writeFile.call(void 0, path, options.content, "utf8");
885
+ await mkdir(dirname(path), { recursive: true });
886
+ await writeFile(path, options.content, "utf8");
887
887
  }
888
888
  return {
889
889
  path,
@@ -892,11 +892,11 @@ var writeInitFile = _chunkTGOMLZ65js.async.call(void 0, options) => {
892
892
  bytes: Buffer.byteLength(options.content, "utf8")
893
893
  };
894
894
  };
895
- var initializeAgentWorkspace = _chunkTGOMLZ65js.async.call(void 0, options) => {
896
- const cwd = _path.resolve.call(void 0, options.cwd);
897
- const profile = _nullishCoalesce(options.profile, () => ( "default"));
898
- const force = _nullishCoalesce(options.force, () => ( false));
899
- const dryRun = _nullishCoalesce(options.dryRun, () => ( false));
895
+ var initializeAgentWorkspace = async (options) => {
896
+ const cwd = resolve3(options.cwd);
897
+ const profile = options.profile ?? "default";
898
+ const force = options.force ?? false;
899
+ const dryRun = options.dryRun ?? false;
900
900
  const config = buildAgentConfig(cwd, profile);
901
901
  const files = await Promise.all([
902
902
  writeInitFile({
@@ -964,7 +964,7 @@ var printAgentInitResult = (result) => {
964
964
 
965
965
  // src/agent/cli/main.ts
966
966
  var dynamicImport2 = new Function("specifier", "return import(specifier)");
967
- var readPatchFile = _chunkTGOMLZ65js.async.call(void 0, cwd, patchFile) => {
967
+ var readPatchFile = async (cwd, patchFile) => {
968
968
  const nodePath = await dynamicImport2("node:path");
969
969
  const nodeFs = await dynamicImport2("node:fs/promises");
970
970
  return nodeFs.readFile(nodePath.resolve(cwd, patchFile), "utf8");
@@ -1098,7 +1098,7 @@ var parseCliArgs = (argv) => {
1098
1098
  }
1099
1099
  if (arg === "--preset" || arg.startsWith("--preset=")) {
1100
1100
  const [value, nextIndex] = readFlagValue(argv, index, "--preset");
1101
- if (!_chunkHRVX2IYWjs.isAgentPreset.call(void 0, value)) {
1101
+ if (!isAgentPreset(value)) {
1102
1102
  throw new Error("--preset requires one of: fix-tests, inspect, typecheck, lint");
1103
1103
  }
1104
1104
  preset = value;
@@ -1274,7 +1274,7 @@ var parseBatchGoal = (value, path) => {
1274
1274
  if (cwd !== void 0 && typeof cwd !== "string") throw new Error(`${path}.cwd must be a string.`);
1275
1275
  if (patchFile !== void 0 && typeof patchFile !== "string") throw new Error(`${path}.patchFile must be a string.`);
1276
1276
  if (saveRunDir !== void 0 && typeof saveRunDir !== "string") throw new Error(`${path}.saveRunDir must be a string.`);
1277
- if (preset !== void 0 && (typeof preset !== "string" || !_chunkHRVX2IYWjs.isAgentPreset.call(void 0, preset))) {
1277
+ if (preset !== void 0 && (typeof preset !== "string" || !isAgentPreset(preset))) {
1278
1278
  throw new Error(`${path}.preset must be one of: fix-tests, inspect, typecheck, lint.`);
1279
1279
  }
1280
1280
  if (mode !== void 0 && (typeof mode !== "string" || !isAgentMode(mode))) {
@@ -1301,7 +1301,7 @@ var parseBatchGoalsJson = (value) => {
1301
1301
  if (!rawGoals) throw new Error("Batch file must be a JSON array or an object with a goals array.");
1302
1302
  return rawGoals.map((goal, index) => parseBatchGoal(goal, `goals[${index}]`));
1303
1303
  };
1304
- var readBatchFile = _chunkTGOMLZ65js.async.call(void 0, cwd, batchFile) => {
1304
+ var readBatchFile = async (cwd, batchFile) => {
1305
1305
  const nodePath = await dynamicImport2("node:path");
1306
1306
  const nodeFs = await dynamicImport2("node:fs/promises");
1307
1307
  const path = nodePath.isAbsolute(batchFile) ? batchFile : nodePath.resolve(cwd, batchFile);
@@ -1318,21 +1318,21 @@ var readBatchFile = _chunkTGOMLZ65js.async.call(void 0, cwd, batchFile) => {
1318
1318
  var resolveBatchGoalText = (item, fallbackPatchFile) => {
1319
1319
  if (typeof item === "string") return item;
1320
1320
  if (item.goal) return item.goal;
1321
- if (item.preset) return _chunkHRVX2IYWjs.goalForAgentPreset.call(void 0, item.preset);
1322
- if (_nullishCoalesce(item.patchFile, () => ( fallbackPatchFile))) return "apply supplied patch";
1321
+ if (item.preset) return goalForAgentPreset(item.preset);
1322
+ if (item.patchFile ?? fallbackPatchFile) return "apply supplied patch";
1323
1323
  return "";
1324
1324
  };
1325
1325
  var resolveBatchMode = (item, parsed, config) => {
1326
1326
  if (typeof item !== "string" && item.mode) return item.mode;
1327
1327
  if (typeof item !== "string" && item.preset === "inspect" && !parsed.modeSpecified) return "read-only";
1328
- return parsed.modeSpecified ? parsed.mode : _nullishCoalesce(config.mode, () => ( parsed.mode));
1328
+ return parsed.modeSpecified ? parsed.mode : config.mode ?? parsed.mode;
1329
1329
  };
1330
1330
  var resolveBatchRuns = (items, parsed, config) => items.map((item, index) => {
1331
1331
  const goalText = resolveBatchGoalText(item, parsed.patchFile);
1332
- const cwd = typeof item === "string" ? parsed.cwd : _nullishCoalesce(item.cwd, () => ( parsed.cwd));
1333
- const patchFile = typeof item === "string" ? parsed.patchFile : _nullishCoalesce(item.patchFile, () => ( parsed.patchFile));
1334
- const patchFileMode = typeof item === "string" ? parsed.patchFileMode : _nullishCoalesce(item.patchFileMode, () => ( parsed.patchFileMode));
1335
- const saveRunDir = typeof item === "string" ? parsed.saveRunDir : _nullishCoalesce(item.saveRunDir, () => ( parsed.saveRunDir));
1332
+ const cwd = typeof item === "string" ? parsed.cwd : item.cwd ?? parsed.cwd;
1333
+ const patchFile = typeof item === "string" ? parsed.patchFile : item.patchFile ?? parsed.patchFile;
1334
+ const patchFileMode = typeof item === "string" ? parsed.patchFileMode : item.patchFileMode ?? parsed.patchFileMode;
1335
+ const saveRunDir = typeof item === "string" ? parsed.saveRunDir : item.saveRunDir ?? parsed.saveRunDir;
1336
1336
  if (!goalText) throw new Error(`Batch goal ${index + 1} resolved to an empty goal.`);
1337
1337
  return {
1338
1338
  index,
@@ -1344,8 +1344,8 @@ var resolveBatchRuns = (items, parsed, config) => items.map((item, index) => {
1344
1344
  ...saveRunDir ? { saveRunDir } : {}
1345
1345
  };
1346
1346
  });
1347
- var resolveParsedConfig = _chunkTGOMLZ65js.async.call(void 0, parsed) => {
1348
- const workspaceDiscovery = _chunkHRVX2IYWjs.discoverNodeWorkspaceRoot.call(void 0, parsed.cwd, {
1347
+ var resolveParsedConfig = async (parsed) => {
1348
+ const workspaceDiscovery = discoverNodeWorkspaceRoot(parsed.cwd, {
1349
1349
  enabled: parsed.discoverWorkspace
1350
1350
  });
1351
1351
  const cwdResolved = workspaceDiscovery.cwd;
@@ -1353,7 +1353,7 @@ var resolveParsedConfig = _chunkTGOMLZ65js.async.call(void 0, parsed) => {
1353
1353
  ...parsed,
1354
1354
  cwd: cwdResolved
1355
1355
  };
1356
- const loaded = await _chunkHRVX2IYWjs.loadNodeAgentConfig.call(void 0, {
1356
+ const loaded = await loadNodeAgentConfig({
1357
1357
  cwd: cwdResolved,
1358
1358
  configPath: parsed.configPath,
1359
1359
  noConfig: parsed.noConfig
@@ -1362,20 +1362,20 @@ var resolveParsedConfig = _chunkTGOMLZ65js.async.call(void 0, parsed) => {
1362
1362
  cwd: cwdResolved,
1363
1363
  envFile: parsed.envFile,
1364
1364
  noEnvFile: parsed.noEnvFile,
1365
- allowedExtraKeys: _optionalChain([loaded, 'access', _30 => _30.config, 'access', _31 => _31.llm, 'optionalAccess', _32 => _32.apiKeyEnv]) ? [loaded.config.llm.apiKeyEnv] : []
1365
+ allowedExtraKeys: loaded.config.llm?.apiKeyEnv ? [loaded.config.llm.apiKeyEnv] : []
1366
1366
  });
1367
1367
  const shouldUseConfigBatch = !parsed.goalText && !parsed.preset && !parsed.patchFile;
1368
- const batchItems = parsed.batchFile ? await readBatchFile(cwdResolved, parsed.batchFile) : shouldUseConfigBatch ? _nullishCoalesce(_optionalChain([loaded, 'access', _33 => _33.config, 'access', _34 => _34.batch, 'optionalAccess', _35 => _35.goals]), () => ( [])) : [];
1368
+ const batchItems = parsed.batchFile ? await readBatchFile(cwdResolved, parsed.batchFile) : shouldUseConfigBatch ? loaded.config.batch?.goals ?? [] : [];
1369
1369
  const batchRuns = resolveBatchRuns(batchItems, parsedAtWorkspace, loaded.config);
1370
1370
  return {
1371
1371
  ...parsedAtWorkspace,
1372
- goalText: parsed.goalText || (parsed.preset ? _chunkHRVX2IYWjs.goalForAgentPreset.call(void 0, parsed.preset) : parsed.patchFile ? "apply supplied patch" : parsed.goalText),
1373
- mode: parsed.modeSpecified ? parsed.mode : parsed.preset === "inspect" ? "read-only" : _nullishCoalesce(loaded.config.mode, () => ( parsed.mode)),
1374
- approval: parsed.approvalSpecified ? parsed.approval : _nullishCoalesce(loaded.config.approval, () => ( parsed.approval)),
1372
+ goalText: parsed.goalText || (parsed.preset ? goalForAgentPreset(parsed.preset) : parsed.patchFile ? "apply supplied patch" : parsed.goalText),
1373
+ mode: parsed.modeSpecified ? parsed.mode : parsed.preset === "inspect" ? "read-only" : loaded.config.mode ?? parsed.mode,
1374
+ approval: parsed.approvalSpecified ? parsed.approval : loaded.config.approval ?? parsed.approval,
1375
1375
  config: loaded.config,
1376
1376
  workspaceDiscovery,
1377
1377
  batchRuns,
1378
- batchStopOnFailureResolved: _nullishCoalesce(_nullishCoalesce(parsed.batchStopOnFailure, () => ( _optionalChain([loaded, 'access', _36 => _36.config, 'access', _37 => _37.batch, 'optionalAccess', _38 => _38.stopOnFailure]))), () => ( parsed.ci)),
1378
+ batchStopOnFailureResolved: parsed.batchStopOnFailure ?? loaded.config.batch?.stopOnFailure ?? parsed.ci,
1379
1379
  envFileLoad,
1380
1380
  ...loaded.path ? { resolvedConfigPath: loaded.path } : {}
1381
1381
  };
@@ -1491,32 +1491,32 @@ var printHelp = () => {
1491
1491
  };
1492
1492
  var envByName = (name) => name ? process.env[name] : void 0;
1493
1493
  var makeGoogleLLMFromEnv = (config) => {
1494
- const apiKey = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(envByName(_optionalChain([config, 'optionalAccess', _39 => _39.apiKeyEnv])), () => ( process.env.BRASS_GOOGLE_API_KEY)), () => ( process.env.GOOGLE_API_KEY)), () => ( process.env.GEMINI_API_KEY));
1494
+ const apiKey = envByName(config?.apiKeyEnv) ?? process.env.BRASS_GOOGLE_API_KEY ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
1495
1495
  if (!apiKey) return void 0;
1496
- return _chunkHRVX2IYWjs.makeGoogleGenerativeAILLM.call(void 0, {
1496
+ return makeGoogleGenerativeAILLM({
1497
1497
  apiKey,
1498
- model: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(process.env.BRASS_GOOGLE_MODEL, () => ( process.env.BRASS_LLM_MODEL)), () => ( _optionalChain([config, 'optionalAccess', _40 => _40.model]))), () => ( "gemini-2.5-flash")),
1499
- apiVersion: _nullishCoalesce(_nullishCoalesce(process.env.BRASS_GOOGLE_API_VERSION, () => ( _optionalChain([config, 'optionalAccess', _41 => _41.apiVersion]))), () => ( "v1beta")),
1500
- baseUrl: _nullishCoalesce(process.env.BRASS_GOOGLE_BASE_URL, () => ( _optionalChain([config, 'optionalAccess', _42 => _42.baseUrl]))),
1501
- endpoint: _nullishCoalesce(process.env.BRASS_GOOGLE_ENDPOINT, () => ( _optionalChain([config, 'optionalAccess', _43 => _43.endpoint]))),
1502
- systemInstruction: _nullishCoalesce(process.env.BRASS_GOOGLE_SYSTEM_INSTRUCTION, () => ( _optionalChain([config, 'optionalAccess', _44 => _44.systemInstruction]))),
1503
- temperature: _nullishCoalesce(parseOptionalNumber(process.env.BRASS_GOOGLE_TEMPERATURE), () => ( _optionalChain([config, 'optionalAccess', _45 => _45.temperature]))),
1504
- topP: _nullishCoalesce(parseOptionalNumber(process.env.BRASS_GOOGLE_TOP_P), () => ( _optionalChain([config, 'optionalAccess', _46 => _46.topP]))),
1505
- topK: _nullishCoalesce(parseOptionalNumber(process.env.BRASS_GOOGLE_TOP_K), () => ( _optionalChain([config, 'optionalAccess', _47 => _47.topK]))),
1506
- maxOutputTokens: _nullishCoalesce(parseOptionalNumber(process.env.BRASS_GOOGLE_MAX_OUTPUT_TOKENS), () => ( _optionalChain([config, 'optionalAccess', _48 => _48.maxOutputTokens])))
1498
+ model: process.env.BRASS_GOOGLE_MODEL ?? process.env.BRASS_LLM_MODEL ?? config?.model ?? "gemini-2.5-flash",
1499
+ apiVersion: process.env.BRASS_GOOGLE_API_VERSION ?? config?.apiVersion ?? "v1beta",
1500
+ baseUrl: process.env.BRASS_GOOGLE_BASE_URL ?? config?.baseUrl,
1501
+ endpoint: process.env.BRASS_GOOGLE_ENDPOINT ?? config?.endpoint,
1502
+ systemInstruction: process.env.BRASS_GOOGLE_SYSTEM_INSTRUCTION ?? config?.systemInstruction,
1503
+ temperature: parseOptionalNumber(process.env.BRASS_GOOGLE_TEMPERATURE) ?? config?.temperature,
1504
+ topP: parseOptionalNumber(process.env.BRASS_GOOGLE_TOP_P) ?? config?.topP,
1505
+ topK: parseOptionalNumber(process.env.BRASS_GOOGLE_TOP_K) ?? config?.topK,
1506
+ maxOutputTokens: parseOptionalNumber(process.env.BRASS_GOOGLE_MAX_OUTPUT_TOKENS) ?? config?.maxOutputTokens
1507
1507
  });
1508
1508
  };
1509
1509
  var makeOpenAICompatibleLLMFromEnv = (config) => {
1510
- const endpoint = _nullishCoalesce(process.env.BRASS_LLM_ENDPOINT, () => ( _optionalChain([config, 'optionalAccess', _49 => _49.endpoint])));
1511
- const apiKey = _nullishCoalesce(envByName(_optionalChain([config, 'optionalAccess', _50 => _50.apiKeyEnv])), () => ( process.env.BRASS_LLM_API_KEY));
1512
- const model = _nullishCoalesce(_nullishCoalesce(process.env.BRASS_LLM_MODEL, () => ( _optionalChain([config, 'optionalAccess', _51 => _51.model]))), () => ( "gpt-4.1"));
1510
+ const endpoint = process.env.BRASS_LLM_ENDPOINT ?? config?.endpoint;
1511
+ const apiKey = envByName(config?.apiKeyEnv) ?? process.env.BRASS_LLM_API_KEY;
1512
+ const model = process.env.BRASS_LLM_MODEL ?? config?.model ?? "gpt-4.1";
1513
1513
  if (!endpoint || !apiKey) return void 0;
1514
- return _chunkHRVX2IYWjs.makeOpenAICompatibleLLM.call(void 0, { endpoint, apiKey, model });
1514
+ return makeOpenAICompatibleLLM({ endpoint, apiKey, model });
1515
1515
  };
1516
1516
  var makeLLMFromEnv = (config) => {
1517
- const provider = _optionalChain([(_nullishCoalesce(process.env.BRASS_LLM_PROVIDER, () => ( _optionalChain([config, 'optionalAccess', _52 => _52.provider])))), 'optionalAccess', _53 => _53.trim, 'call', _54 => _54(), 'access', _55 => _55.toLowerCase, 'call', _56 => _56()]);
1518
- const fakeResponse = _nullishCoalesce(process.env.BRASS_FAKE_LLM_RESPONSE, () => ( _optionalChain([config, 'optionalAccess', _57 => _57.fakeResponse])));
1519
- if (provider === "fake") return _chunkHRVX2IYWjs.makeFakeLLM.call(void 0, { content: fakeResponse });
1517
+ const provider = (process.env.BRASS_LLM_PROVIDER ?? config?.provider)?.trim().toLowerCase();
1518
+ const fakeResponse = process.env.BRASS_FAKE_LLM_RESPONSE ?? config?.fakeResponse;
1519
+ if (provider === "fake") return makeFakeLLM({ content: fakeResponse });
1520
1520
  if (provider === "google" || provider === "gemini") {
1521
1521
  const google = makeGoogleLLMFromEnv(config);
1522
1522
  if (!google) {
@@ -1538,16 +1538,16 @@ var makeLLMFromEnv = (config) => {
1538
1538
  if (provider) {
1539
1539
  throw new Error(`Unsupported LLM provider: ${provider}`);
1540
1540
  }
1541
- return _nullishCoalesce(_nullishCoalesce(makeGoogleLLMFromEnv(config), () => ( makeOpenAICompatibleLLMFromEnv(config))), () => ( _chunkHRVX2IYWjs.makeFakeLLM.call(void 0, { content: fakeResponse })));
1541
+ return makeGoogleLLMFromEnv(config) ?? makeOpenAICompatibleLLMFromEnv(config) ?? makeFakeLLM({ content: fakeResponse });
1542
1542
  };
1543
1543
  var parseApprovalModeFromEnv = () => {
1544
- const raw = _optionalChain([process, 'access', _58 => _58.env, 'access', _59 => _59.BRASS_AGENT_APPROVAL, 'optionalAccess', _60 => _60.trim, 'call', _61 => _61(), 'access', _62 => _62.toLowerCase, 'call', _63 => _63()]);
1544
+ const raw = process.env.BRASS_AGENT_APPROVAL?.trim().toLowerCase();
1545
1545
  if (!raw) return void 0;
1546
1546
  if (isCliApprovalMode(raw)) return raw;
1547
1547
  throw new Error("BRASS_AGENT_APPROVAL must be one of: auto, interactive, approve, deny");
1548
1548
  };
1549
- var envTruthy = (value) => value === "1" || _optionalChain([value, 'optionalAccess', _64 => _64.toLowerCase, 'call', _65 => _65()]) === "true" || _optionalChain([value, 'optionalAccess', _66 => _66.toLowerCase, 'call', _67 => _67()]) === "yes";
1550
- var canPromptInteractively = () => Boolean(_optionalChain([process, 'access', _68 => _68.stdin, 'optionalAccess', _69 => _69.isTTY]) && (_nullishCoalesce(_optionalChain([process, 'access', _70 => _70.stderr, 'optionalAccess', _71 => _71.isTTY]), () => ( _optionalChain([process, 'access', _72 => _72.stdout, 'optionalAccess', _73 => _73.isTTY])))));
1549
+ var envTruthy = (value) => value === "1" || value?.toLowerCase() === "true" || value?.toLowerCase() === "yes";
1550
+ var canPromptInteractively = () => Boolean(process.stdin?.isTTY && (process.stderr?.isTTY ?? process.stdout?.isTTY));
1551
1551
  var resolveApprovalMode = (parsed) => {
1552
1552
  if (parsed.approvalSpecified && parsed.approval !== "auto") return parsed.approval;
1553
1553
  if (envTruthy(process.env.BRASS_AGENT_AUTO_APPROVE)) return "approve";
@@ -1561,9 +1561,9 @@ var makeApprovalServiceFromCli = (parsed) => {
1561
1561
  const mode = resolveApprovalMode(parsed);
1562
1562
  switch (mode) {
1563
1563
  case "approve":
1564
- return _chunkHRVX2IYWjs.autoApproveApprovals;
1564
+ return autoApproveApprovals;
1565
1565
  case "deny":
1566
- return _chunkHRVX2IYWjs.makeAutoDenyApprovals.call(void 0, "Approval rejected because the CLI is running without interactive input. Use --yes to auto-approve.");
1566
+ return makeAutoDenyApprovals("Approval rejected because the CLI is running without interactive input. Use --yes to auto-approve.");
1567
1567
  case "interactive":
1568
1568
  return makeCliApprovalService();
1569
1569
  }
@@ -1695,32 +1695,32 @@ var createHumanEventSink = (configPath) => ({
1695
1695
  console.log("");
1696
1696
  break;
1697
1697
  case "agent.action.started":
1698
- console.log(`\u2192 ${_chunkHRVX2IYWjs.summarizeAgentAction.call(void 0, event.action)}`);
1698
+ console.log(`\u2192 ${summarizeAgentAction(event.action)}`);
1699
1699
  break;
1700
1700
  case "agent.action.completed": {
1701
- const status = _chunkHRVX2IYWjs.observationStatus.call(void 0, event.observation);
1702
- console.log(`${statusIcon2(status)} ${_chunkHRVX2IYWjs.summarizeAgentObservation.call(void 0, event.observation)} ${formatDuration(event.durationMs)}`);
1701
+ const status = observationStatus(event.observation);
1702
+ console.log(`${statusIcon2(status)} ${summarizeAgentObservation(event.observation)} ${formatDuration(event.durationMs)}`);
1703
1703
  break;
1704
1704
  }
1705
1705
  case "agent.action.failed":
1706
1706
  if (event.error._tag !== "ToolTimeout" && event.error._tag !== "PermissionDenied" && event.error._tag !== "ApprovalRejected") {
1707
- console.log(`\u2717 ${_chunkHRVX2IYWjs.summarizeAgentAction.call(void 0, event.action)} failed with ${event.error._tag} ${formatDuration(event.durationMs)}`);
1707
+ console.log(`\u2717 ${summarizeAgentAction(event.action)} failed with ${event.error._tag} ${formatDuration(event.durationMs)}`);
1708
1708
  }
1709
1709
  break;
1710
1710
  case "agent.tool.timeout":
1711
- console.log(`! ${_chunkHRVX2IYWjs.summarizeAgentAction.call(void 0, event.action)} timed out after ${event.timeoutMs}ms`);
1711
+ console.log(`! ${summarizeAgentAction(event.action)} timed out after ${event.timeoutMs}ms`);
1712
1712
  break;
1713
1713
  case "agent.permission.denied":
1714
- console.log(`\u2717 ${_chunkHRVX2IYWjs.summarizeAgentAction.call(void 0, event.action)} denied: ${event.reason}`);
1714
+ console.log(`\u2717 ${summarizeAgentAction(event.action)} denied: ${event.reason}`);
1715
1715
  break;
1716
1716
  case "agent.approval.requested":
1717
- console.log(`? approval required for ${_chunkHRVX2IYWjs.summarizeAgentAction.call(void 0, event.action)} (${event.risk})`);
1717
+ console.log(`? approval required for ${summarizeAgentAction(event.action)} (${event.risk})`);
1718
1718
  break;
1719
1719
  case "agent.approval.resolved":
1720
1720
  if (event.approved) {
1721
- console.log(`\u2713 approval granted for ${_chunkHRVX2IYWjs.summarizeAgentAction.call(void 0, event.action)}`);
1721
+ console.log(`\u2713 approval granted for ${summarizeAgentAction(event.action)}`);
1722
1722
  } else {
1723
- console.log(`\u2717 approval rejected for ${_chunkHRVX2IYWjs.summarizeAgentAction.call(void 0, event.action)}${event.reason ? `: ${event.reason}` : ""}`);
1723
+ console.log(`\u2717 approval rejected for ${summarizeAgentAction(event.action)}${event.reason ? `: ${event.reason}` : ""}`);
1724
1724
  }
1725
1725
  break;
1726
1726
  case "agent.patch.applied":
@@ -1748,7 +1748,7 @@ var createProtocolEventSink = (options = {}) => ({
1748
1748
  });
1749
1749
  var safeFilePart = (value) => value.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "run";
1750
1750
  var markdownEscape = (value) => value.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
1751
- var writeRunArtifacts = _chunkTGOMLZ65js.async.call(void 0, state, outputDir, options) => {
1751
+ var writeRunArtifacts = async (state, outputDir, options) => {
1752
1752
  const nodePath = await dynamicImport2("node:path");
1753
1753
  const nodeFs = await dynamicImport2("node:fs/promises");
1754
1754
  const dir = nodePath.isAbsolute(outputDir) ? outputDir : nodePath.resolve(state.goal.cwd, outputDir);
@@ -1776,9 +1776,9 @@ var writeRunArtifacts = _chunkTGOMLZ65js.async.call(void 0, state, outputDir, op
1776
1776
  "",
1777
1777
  "## Summary",
1778
1778
  "",
1779
- _optionalChain([done, 'optionalAccess', _74 => _74.summary, 'optionalAccess', _75 => _75.trim, 'call', _76 => _76()]) || (error ? `Error: ${error.error._tag}` : "No summary recorded.")
1779
+ done?.summary?.trim() || (error ? `Error: ${error.error._tag}` : "No summary recorded.")
1780
1780
  ].filter(Boolean).join("\n"), "utf8");
1781
- if (_optionalChain([process, 'access', _77 => _77.stderr, 'optionalAccess', _78 => _78.isTTY])) {
1781
+ if (process.stderr?.isTTY) {
1782
1782
  console.error(`saved run artifacts: ${jsonPath} ${mdPath}`);
1783
1783
  }
1784
1784
  };
@@ -1825,13 +1825,13 @@ var printHumanFinalSummary = (state) => {
1825
1825
  };
1826
1826
  var makeEventsSink = (parsed, compactOptions) => parsed.output === "human" ? createHumanEventSink(parsed.resolvedConfigPath) : parsed.output === "events-json" ? createJsonEventSink(compactOptions) : parsed.output === "protocol-json" ? createProtocolEventSink(compactOptions) : void 0;
1827
1827
  var makeAgentEnv = (parsed, events) => {
1828
- const shell = _chunkHRVX2IYWjs.NodeShell;
1828
+ const shell = NodeShell;
1829
1829
  return {
1830
1830
  shell,
1831
- fs: _chunkHRVX2IYWjs.makeNodeFileSystem.call(void 0, shell),
1832
- patch: _chunkHRVX2IYWjs.makeNodePatchService.call(void 0, shell),
1831
+ fs: makeNodeFileSystem(shell),
1832
+ patch: makeNodePatchService(shell),
1833
1833
  llm: makeLLMFromEnv(parsed.config.llm),
1834
- permissions: _chunkHRVX2IYWjs.makeConfiguredPermissions.call(void 0, parsed.config.permissions),
1834
+ permissions: makeConfiguredPermissions(parsed.config.permissions),
1835
1835
  approvals: makeApprovalServiceFromCli(parsed),
1836
1836
  ...events ? { events } : {},
1837
1837
  ...parsed.config.tools ? { toolPolicies: parsed.config.tools } : {}
@@ -1846,12 +1846,12 @@ var singleRunFromParsed = (parsed) => ({
1846
1846
  ...parsed.patchFile ? { patchFile: parsed.patchFile } : {},
1847
1847
  ...parsed.saveRunDir ? { saveRunDir: parsed.saveRunDir } : {}
1848
1848
  });
1849
- var runCliAgent = _chunkTGOMLZ65js.async.call(void 0, parsed, run, compactOptions, events) => {
1849
+ var runCliAgent = async (parsed, run, compactOptions, events) => {
1850
1850
  const env = makeAgentEnv(parsed, events);
1851
- const runtime = new (0, _chunkTGOMLZ65js.Runtime)({ env });
1851
+ const runtime = new Runtime({ env });
1852
1852
  const initialPatch = run.patchFile ? await readPatchFile(run.cwd, run.patchFile) : void 0;
1853
1853
  const state = await runtime.toPromise(
1854
- _chunkHRVX2IYWjs.runAgent.call(void 0, runtime, {
1854
+ runAgent(runtime, {
1855
1855
  id: `agent-${Date.now()}-${run.index + 1}`,
1856
1856
  cwd: run.cwd,
1857
1857
  text: run.goalText,
@@ -1919,7 +1919,7 @@ var printWorkspaceWhere = (parsed) => {
1919
1919
  if (result.configPath) console.log(`config: ${result.configPath}`);
1920
1920
  if (result.envFiles.length > 0) console.log(`env: ${result.envFiles.join(", ")}`);
1921
1921
  };
1922
- var main = _chunkTGOMLZ65js.async.call(void 0, ) => {
1922
+ var main = async () => {
1923
1923
  const parsed = await resolveParsedConfig(parseCliArgs(process.argv.slice(2)));
1924
1924
  const isBatch = parsed.batchRuns.length > 0;
1925
1925
  if (parsed.showHelp) {