@livx.cc/agentx 0.99.4 → 0.99.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,5 +1,5 @@
1
1
  import { IFilesystem } from '@livx.cc/wcli/core';
2
- import { M as Message, H as HostBridge, A as AgentTool, C as ChatLike, e as MessageContent } from './tools-CrsRHvvl.js';
2
+ import { M as Message, H as HostBridge, A as AgentTool, C as ChatLike, e as MessageContent } from './tools-DKf3hN4M.js';
3
3
 
4
4
  /**
5
5
  * Hooks — deterministic interception points around tool execution, run by the
package/dist/cli.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
- import { H as Hooks, h as RunResult, R as ReasoningEffort, A as Agent } from './Agent-BPEXD7n7.js';
2
+ import { H as Hooks, h as RunResult, R as ReasoningEffort, A as Agent } from './Agent-DYMSg21f.js';
3
3
  import { IFilesystem } from '@livx.cc/wcli/core';
4
- import { M as Message, c as ContentPart, e as MessageContent } from './tools-CrsRHvvl.js';
4
+ import { M as Message, H as HostBridge, c as ContentPart, e as MessageContent } from './tools-DKf3hN4M.js';
5
5
 
6
6
  /**
7
7
  * On-disk session store for the CLI: each conversation is one JSON file at
@@ -146,6 +146,11 @@ interface Args {
146
146
  update?: boolean;
147
147
  }
148
148
  declare function parseArgs(argv: string[]): Args;
149
+ declare function makeHost(format?: 'text' | 'json' | 'stream-json', opts?: {
150
+ stream?: boolean;
151
+ }): HostBridge & {
152
+ flushText: () => void;
153
+ };
149
154
  /** Hooks that render tool activity to stderr: a preToolUse header, and for edits a colorized diff.
150
155
  * `opts.background` marks the agent as a BACKGROUND one (duplex workers): its chrome lands async on
151
156
  * top of a live prompt, so it must never drive the foreground spinner (the 'agentx › '/'⠹ thinking…'
@@ -293,4 +298,4 @@ declare function runTurn(agent: Agent, store: SessionStore, session: SessionData
293
298
  res?: RunResult;
294
299
  }>;
295
300
 
296
- export { type PermMode, abortActiveTurn, appendMemoryNote, cacheMultipliers, condenseReplay, costOf, estimateTranscriptTokens, expandMentions, exportMarkdown, fmtUsd, formatHistory, formatStatus, formatTranscriptFull, jsonResult, mcpMentionResolver, mentionRefs, parseArgs, pastePathClassifier, readImageParts, readMultiline, resolvePermMode, runShellLine, runTurn, setMcpMentionResolver, summarizeResult };
301
+ export { type PermMode, abortActiveTurn, appendMemoryNote, cacheMultipliers, condenseReplay, costOf, estimateTranscriptTokens, expandMentions, exportMarkdown, fmtUsd, formatHistory, formatStatus, formatTranscriptFull, jsonResult, makeHost, mcpMentionResolver, mentionRefs, parseArgs, pastePathClassifier, readImageParts, readMultiline, resolvePermMode, runShellLine, runTurn, setMcpMentionResolver, summarizeResult };
package/dist/cli.js CHANGED
@@ -1959,7 +1959,7 @@ var init_tools_shell = __esm({
1959
1959
  // cli/cli.ts
1960
1960
  import { createInterface } from "readline/promises";
1961
1961
  import { existsSync as existsSync9, readFileSync as readFileSync8, appendFileSync, mkdirSync as mkdirSync11, writeFileSync as writeFileSync9, readdirSync as readdirSync4, statSync as statSync4, unlinkSync as unlinkSync5 } from "fs";
1962
- import { homedir as homedir9, tmpdir as tmpdir3 } from "os";
1962
+ import { homedir as homedir10, tmpdir as tmpdir3 } from "os";
1963
1963
  import { spawnSync as spawnSync6 } from "child_process";
1964
1964
 
1965
1965
  // cli/clipboard.ts
@@ -3684,7 +3684,7 @@ var Agent = class _Agent {
3684
3684
  if (chunk.toolActivity) {
3685
3685
  const a = chunk.toolActivity;
3686
3686
  const verb = a.status === "error" ? "\u2717" : a.status === "completed" ? "\u2713" : "\u2192";
3687
- this.options.host.notify({ kind: "tool_activity", id: a.id, name: a.name, input: a.input, status: a.status, message: `${verb} ${a.name}` });
3687
+ this.options.host.notify({ kind: "tool_activity", id: a.id, name: a.name, input: a.input, output: a.output, status: a.status, truncated: a.truncated, message: `${verb} ${a.name}` });
3688
3688
  }
3689
3689
  if (chunk.content) {
3690
3690
  content += chunk.content;
@@ -8433,22 +8433,29 @@ ${formatDiff(ops)}`);
8433
8433
  import { execFile as execFile3 } from "child_process";
8434
8434
  import { promisify } from "util";
8435
8435
  import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync7 } from "fs";
8436
- import { join as join9, resolve as resolve2, sep as sep2 } from "path";
8436
+ import { homedir as homedir6 } from "os";
8437
+ import { join as join9, resolve as resolve2, sep as sep2, parse as parsePath } from "path";
8437
8438
  var log20 = forComponent("checkpoints");
8438
8439
  var exec = promisify(execFile3);
8439
8440
  var DEFAULT_EXCLUDE = [".agent/", ".git/", "node_modules/", "dist/", "build/", ".next/", "target/", ".venv/", "__pycache__/", "*.log"];
8441
+ function isBroadRoot(p) {
8442
+ const abs = resolve2(p);
8443
+ return abs === resolve2(homedir6()) || abs === parsePath(abs).root;
8444
+ }
8440
8445
  var ShadowRepo = class {
8441
8446
  // undefined = unprobed; false = git/this root unusable
8442
- constructor(workTree, gitDir, exclude, git2) {
8447
+ constructor(workTree, gitDir, exclude, git2, timeoutMs) {
8443
8448
  this.workTree = workTree;
8444
8449
  this.gitDir = gitDir;
8445
8450
  this.exclude = exclude;
8446
8451
  this.git = git2;
8452
+ this.timeoutMs = timeoutMs;
8447
8453
  }
8448
8454
  workTree;
8449
8455
  gitDir;
8450
8456
  exclude;
8451
8457
  git;
8458
+ timeoutMs;
8452
8459
  ready;
8453
8460
  /** Absolute work-tree root — used to route force-tracked paths to the repo that contains them. */
8454
8461
  get root() {
@@ -8457,7 +8464,9 @@ var ShadowRepo = class {
8457
8464
  async run(...args) {
8458
8465
  const { stdout } = await exec(this.git, ["-c", "core.hooksPath=/dev/null", ...args], {
8459
8466
  env: { ...process.env, GIT_DIR: this.gitDir, GIT_WORK_TREE: this.workTree },
8460
- maxBuffer: 64 * 1024 * 1024
8467
+ maxBuffer: 64 * 1024 * 1024,
8468
+ timeout: this.timeoutMs,
8469
+ killSignal: "SIGKILL"
8461
8470
  });
8462
8471
  return stdout;
8463
8472
  }
@@ -8570,7 +8579,7 @@ var GitCheckpoints = class {
8570
8579
  constructor(options) {
8571
8580
  this.options = { ...new GitCheckpointsOptions(), ...options };
8572
8581
  this.session = this.options.sessionId;
8573
- this.repos = this.roots().map((r) => new ShadowRepo(r.workTree, r.gitDir, this.options.exclude, this.options.git));
8582
+ this.repos = this.roots().map((r) => new ShadowRepo(r.workTree, r.gitDir, this.options.exclude, this.options.git, this.options.opTimeoutMs));
8574
8583
  this.caches = this.repos.map(() => []);
8575
8584
  }
8576
8585
  ref() {
@@ -8595,14 +8604,23 @@ var GitCheckpoints = class {
8595
8604
  const usable = [];
8596
8605
  const caches = [];
8597
8606
  const cutoff = Math.floor(Date.now() / 1e3) - this.options.retainDays * 86400;
8607
+ let gitFailed = false;
8598
8608
  for (const r of this.repos) {
8599
- if (!await r.init()) continue;
8609
+ if (isBroadRoot(r.root)) {
8610
+ process.stderr.write(`\x1B[2m checkpoints: '${r.root}' is too broad (home/root) \u2014 file rewind disabled here\x1B[0m
8611
+ `);
8612
+ continue;
8613
+ }
8614
+ if (!await r.init()) {
8615
+ gitFailed = true;
8616
+ continue;
8617
+ }
8600
8618
  await r.point(this.ref());
8601
8619
  await r.prune(cutoff, this.ref());
8602
8620
  usable.push(r);
8603
8621
  caches.push([]);
8604
8622
  }
8605
- if (!usable.length && this.repos.length)
8623
+ if (!usable.length && gitFailed)
8606
8624
  process.stderr.write("\x1B[2m checkpoints: git unavailable \u2014 file rewind disabled (conversation rewind still works)\x1B[0m\n");
8607
8625
  this.repos = usable;
8608
8626
  this.caches = caches;
@@ -8618,15 +8636,28 @@ var GitCheckpoints = class {
8618
8636
  const msg = sanitizeLabel(label, 72) || "(turn)";
8619
8637
  let slow;
8620
8638
  if (!this.snapshotted) slow = setTimeout(() => process.stderr.write("\x1B[2m checkpointing initial workspace snapshot\u2026\x1B[0m\n"), 1500);
8639
+ const survivors = [], survivorCaches = [];
8621
8640
  for (let i = 0; i < this.repos.length; i++) {
8622
8641
  const forced = [...this.forced].filter((p) => this.repoIndexFor(p) === i);
8623
8642
  try {
8624
8643
  await this.repos[i].commit(msg, forced);
8644
+ survivors.push(this.repos[i]);
8645
+ survivorCaches.push(this.caches[i] ?? []);
8625
8646
  } catch (e) {
8626
- log20.debug("checkpoint commit failed", e);
8647
+ const timedOut = e?.killed;
8648
+ if (!this.snapshotted && timedOut) {
8649
+ process.stderr.write(`\x1B[2m checkpoints: '${this.repos[i].root}' too large to snapshot in ${Math.round(this.options.opTimeoutMs / 1e3)}s \u2014 file rewind disabled here\x1B[0m
8650
+ `);
8651
+ } else {
8652
+ log20.debug("checkpoint commit failed", e);
8653
+ survivors.push(this.repos[i]);
8654
+ survivorCaches.push(this.caches[i] ?? []);
8655
+ }
8627
8656
  }
8628
8657
  }
8629
8658
  if (slow) clearTimeout(slow);
8659
+ this.repos = survivors;
8660
+ this.caches = survivorCaches;
8630
8661
  this.snapshotted = true;
8631
8662
  }
8632
8663
  /** Index of the repo whose work-tree contains `abs` (longest-prefix wins for nested roots); -1 if none. */
@@ -8714,13 +8745,15 @@ var GitCheckpointsOptions = class {
8714
8745
  retainDays = 30;
8715
8746
  /** Paths the shadow repos always ignore (heavy/derived/VCS), beyond the user's own .gitignore. */
8716
8747
  exclude = [...DEFAULT_EXCLUDE];
8748
+ /** Per-git-op wall-clock cap (ms). A root that can't snapshot within this is dropped, not left to hang. */
8749
+ opTimeoutMs = 3e4;
8717
8750
  /** git executable. */
8718
8751
  git = "git";
8719
8752
  };
8720
8753
 
8721
8754
  // cli/permissions.ts
8722
8755
  import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "fs";
8723
- import { homedir as homedir6 } from "os";
8756
+ import { homedir as homedir7 } from "os";
8724
8757
  import { join as join10 } from "path";
8725
8758
  var RULE_RE = /^(\w+)(?:\((.+)\))?$/;
8726
8759
  function parseOne(raw, decision) {
@@ -8748,7 +8781,7 @@ function loadPersistedRules(cwd) {
8748
8781
  const j = readJsonFile(PERM_FILE(cwd), null);
8749
8782
  return j ? { allow: j.allow ?? [], ask: j.ask ?? [], deny: j.deny ?? [] } : {};
8750
8783
  }
8751
- function loadClaudeSettings(cwd, home = homedir6()) {
8784
+ function loadClaudeSettings(cwd, home = homedir7()) {
8752
8785
  const files = [join10(home, ".claude", "settings.json"), join10(cwd, ".claude", "settings.json"), join10(cwd, ".claude", "settings.local.json")];
8753
8786
  let out = {};
8754
8787
  for (const p of files) {
@@ -8776,7 +8809,7 @@ function mergePerms(a, b) {
8776
8809
  }
8777
8810
  return Object.keys(out).length ? out : void 0;
8778
8811
  }
8779
- var TRUST_FILE = join10(homedir6(), ".agent", "trusted.json");
8812
+ var TRUST_FILE = join10(homedir7(), ".agent", "trusted.json");
8780
8813
  function isTrusted(cwd, file = TRUST_FILE) {
8781
8814
  const list = readJsonFile(file, []);
8782
8815
  return Array.isArray(list) && list.includes(cwd);
@@ -9056,6 +9089,17 @@ function renderMdLine(line, inFence, p, cols = 80, fenceLang) {
9056
9089
  if (b) return { out: b[1] + p.cyan("\u2022") + " " + mdInline(vis(b[2]), p), inFence };
9057
9090
  return { out: mdInline(vis(line), p), inFence };
9058
9091
  }
9092
+ function renderMdBlock(text, p, cols = 80) {
9093
+ let inFence = false, fenceLang;
9094
+ const out = [];
9095
+ for (const line of text.split("\n")) {
9096
+ const r = renderMdLine(line, inFence, p, cols, fenceLang);
9097
+ inFence = r.inFence;
9098
+ fenceLang = r.fenceLang;
9099
+ out.push(r.inFence || /^\s*```/.test(line) ? r.out : wrapAnsi(r.out, cols, hangIndent(line)));
9100
+ }
9101
+ return out.join("\n");
9102
+ }
9059
9103
  function isTableRow(line) {
9060
9104
  return /^\s*\|.*\|\s*$/.test(line);
9061
9105
  }
@@ -10357,7 +10401,7 @@ function readPlainLine() {
10357
10401
  // cli/osScheduler.ts
10358
10402
  import { spawnSync as spawnSync5 } from "child_process";
10359
10403
  import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, readdirSync as readdirSync2, unlinkSync as unlinkSync3, chmodSync, existsSync as existsSync7 } from "fs";
10360
- import { homedir as homedir7 } from "os";
10404
+ import { homedir as homedir8 } from "os";
10361
10405
  import { join as join12 } from "path";
10362
10406
  var log21 = forComponent("os-sched");
10363
10407
  var OsScheduler = class {
@@ -10514,7 +10558,7 @@ ${expr} /bin/sh ${script} # agentx-sched-${spec.id}
10514
10558
  };
10515
10559
  var OsSchedulerOptions = class {
10516
10560
  platform = process.platform;
10517
- home = homedir7();
10561
+ home = homedir8();
10518
10562
  /** How the fired job invokes the CLI — a RAW shell snippet (may be `bun /path/cli.ts`). Default: `agentx` on PATH. */
10519
10563
  agentx = "agentx";
10520
10564
  /** Injectable executor for tests. Returns stdout+stderr merged — `at` reports "job N" on STDERR,
@@ -10536,10 +10580,10 @@ function routeTrigger(trigger, backendHint, now5 = Date.now()) {
10536
10580
  import { createServer as createServer2, createConnection } from "net";
10537
10581
  import { spawn as spawn3 } from "child_process";
10538
10582
  import { existsSync as existsSync8, mkdirSync as mkdirSync10, unlinkSync as unlinkSync4, readdirSync as readdirSync3 } from "fs";
10539
- import { homedir as homedir8 } from "os";
10583
+ import { homedir as homedir9 } from "os";
10540
10584
  import { join as join13 } from "path";
10541
10585
  var log22 = forComponent("remote-trigger");
10542
- var TRIGGER_DIR = () => join13(homedir8(), ".agent", "triggers");
10586
+ var TRIGGER_DIR = () => join13(homedir9(), ".agent", "triggers");
10543
10587
  var sockPath = (sessionId, dir = TRIGGER_DIR()) => join13(dir, `${sessionId}.sock`);
10544
10588
  var TriggerServer = class {
10545
10589
  constructor(onTrigger) {
@@ -10702,6 +10746,7 @@ var yellow = C("33");
10702
10746
  var italic = C("3");
10703
10747
  var strike = C("9");
10704
10748
  var link = (text, url) => useColor ? `\x1B]8;;${url}\x1B\\${cyan(text)}\x1B]8;;\x1B\\` : `${text} (${url})`;
10749
+ var mdPalette = { bold, dim, cyan, italic, strike, green, link };
10705
10750
  var err = (s) => process.stderr.write(s);
10706
10751
  var log23 = forComponent("cli");
10707
10752
  var VERSION = (() => {
@@ -10968,7 +11013,7 @@ function loadInstallEnv() {
10968
11013
  for (let i = 0; i < 5 && !existsSync9(join14(dir, "package.json")); i++) dir = dirname4(dir);
10969
11014
  for (const name of [".env", ".env.local"]) {
10970
11015
  loadEnvFile(join14(dir, name));
10971
- loadEnvFile(join14(homedir9(), ".agent", name));
11016
+ loadEnvFile(join14(homedir10(), ".agent", name));
10972
11017
  }
10973
11018
  }
10974
11019
  async function loadBodifySecrets() {
@@ -11005,7 +11050,7 @@ function apiKeysFromEnv() {
11005
11050
  function makeHost(format = "text", opts) {
11006
11051
  const streamJson = format === "stream-json";
11007
11052
  const cleanStdout = format === "json";
11008
- const md = format === "text" && useColor && opts?.stream ? new MarkdownStream({ bold, dim, cyan, italic, strike, green, link }, process.stdout.columns ?? 80) : null;
11053
+ const md = format === "text" && useColor && opts?.stream ? new MarkdownStream(mdPalette, process.stdout.columns ?? 80) : null;
11009
11054
  if (md) process.on("SIGWINCH", () => md.resize(process.stdout.columns ?? 80));
11010
11055
  const flushText = () => {
11011
11056
  if (md && md.pending()) process.stdout.write(md.commit());
@@ -11017,10 +11062,14 @@ function makeHost(format = "text", opts) {
11017
11062
  openReasonLine = false;
11018
11063
  }
11019
11064
  };
11065
+ const activitySeen = /* @__PURE__ */ new Set();
11020
11066
  return {
11021
11067
  flushText,
11022
11068
  notify(e) {
11023
- if (e.kind === "turn_start") return;
11069
+ if (e.kind === "turn_start") {
11070
+ activitySeen.clear();
11071
+ return;
11072
+ }
11024
11073
  spinner.stop();
11025
11074
  if (e.kind === "text_delta") {
11026
11075
  flushLookupGroup();
@@ -11044,6 +11093,43 @@ function makeHost(format = "text", opts) {
11044
11093
  }
11045
11094
  return;
11046
11095
  }
11096
+ if (e.kind === "tool_activity") {
11097
+ const a = e;
11098
+ flushLookupGroup();
11099
+ closeReasonLine();
11100
+ flushText();
11101
+ if (streamJson) {
11102
+ process.stdout.write(JSON.stringify({ type: "tool_activity", id: a.id, name: a.name, input: a.input, output: a.output, status: a.status }) + "\n");
11103
+ return;
11104
+ }
11105
+ const clip = (s) => s.length > 200 ? s.slice(0, 200) + "\u2026" : s;
11106
+ const terminal = a.status === "completed" || a.status === "error";
11107
+ if (!terminal || !a.id || !activitySeen.has(a.id)) {
11108
+ if (a.id) activitySeen.add(a.id);
11109
+ const argHint = summarizeCall(a.name, a.input) + (a.truncated?.args ? " \u2026" : "");
11110
+ err(cyan(` \u2699 ${a.name}`) + (argHint ? dim(" " + argHint) : "") + "\n");
11111
+ }
11112
+ if (terminal) {
11113
+ if (a.id) activitySeen.delete(a.id);
11114
+ const raw = a.output == null ? "" : typeof a.output === "string" ? a.output : JSON.stringify(a.output);
11115
+ const text = raw.replace(/\s+$/, "");
11116
+ const paint = a.status === "error" ? red : dim;
11117
+ if (!text) {
11118
+ if (a.status === "error") err(paint(" \u23BF (error)\n"));
11119
+ spinner.start();
11120
+ return;
11121
+ }
11122
+ const lines = text.split("\n");
11123
+ const shown = lines.slice(0, previewLines());
11124
+ err(paint(" \u23BF " + clip(shown[0])) + "\n");
11125
+ for (const ln of shown.slice(1)) err(dim(" " + clip(ln)) + "\n");
11126
+ const more = lines.length - shown.length;
11127
+ if (more > 0 || a.truncated?.result) err(dim(` \u2026 (${more > 0 ? `+${more} more line${more > 1 ? "s" : ""}` : "truncated by backend"}${a.truncated?.result && more > 0 ? ", truncated" : ""} \xB7 ctrl+o expands)
11128
+ `));
11129
+ }
11130
+ spinner.start();
11131
+ return;
11132
+ }
11047
11133
  if (!("message" in e)) return;
11048
11134
  flushLookupGroup();
11049
11135
  closeReasonLine();
@@ -11224,7 +11310,7 @@ function formatHistory(messages) {
11224
11310
  if (t) out.push("\n" + bold(cyan(" \u203A ")) + (t.length > 1500 ? clipReplay(t, 1500) + dim(" \u2026") : t) + "\n");
11225
11311
  } else if (m.role === "assistant") {
11226
11312
  const at = contentText(m.content);
11227
- if (at.trim()) out.push(dim(" ") + at.trim() + "\n");
11313
+ if (at.trim()) out.push(renderMdBlock(at.trim(), mdPalette, (process.stderr.columns ?? 80) - 2).replace(/^/gm, " ") + "\n");
11228
11314
  for (const tc of m.tool_calls ?? []) {
11229
11315
  let args = {};
11230
11316
  try {
@@ -11260,7 +11346,7 @@ function formatTranscriptFull(messages, opts) {
11260
11346
  if (t) out.push("\n" + bold(cyan(" \u203A ")) + t.replace(/\n/g, "\n ") + "\n");
11261
11347
  } else if (m.role === "assistant") {
11262
11348
  const at = contentText(m.content).trim();
11263
- if (at) out.push(" " + at.replace(/\n/g, "\n ") + "\n");
11349
+ if (at) out.push(renderMdBlock(at, mdPalette, (process.stderr.columns ?? 80) - 2).replace(/^/gm, " ") + "\n");
11264
11350
  for (const tc of m.tool_calls ?? []) {
11265
11351
  let args = {};
11266
11352
  try {
@@ -11583,7 +11669,7 @@ var IMG_EXT = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg"
11583
11669
  function mentionRefs(line) {
11584
11670
  return [...line.matchAll(/(?:^|\s)@(?:"([^"]+)"|(\S+))/g)].map((m) => m[1] ?? m[2].replace(/[?!.,;:)\]}'">]+$/, "")).filter(Boolean);
11585
11671
  }
11586
- var untilde = (p) => p.startsWith("~/") ? join14(homedir9(), p.slice(2)) : p;
11672
+ var untilde = (p) => p.startsWith("~/") ? join14(homedir10(), p.slice(2)) : p;
11587
11673
  function readImageParts(cwd, line) {
11588
11674
  const refs = mentionRefs(line);
11589
11675
  const parts = [];
@@ -12682,7 +12768,7 @@ ${task}`;
12682
12768
  }
12683
12769
  const info = getModelInfo(work.model);
12684
12770
  info?.pricing ? ok(`model ${work.model} \u2014 priced (${info.pricing.inputCostPer1K}/${info.pricing.outputCostPer1K} per 1k in/out)`) : warn(`model ${work.model} \u2014 no pricing in the catalog (costs will show ~$0; verify the id)`);
12685
- const cfgFiles = ["ts", "js", "json"].flatMap((e) => [`${cwd}/.agent/config.${e}`, `${homedir9()}/.agent/config.${e}`]).filter((p) => existsSync9(p));
12771
+ const cfgFiles = ["ts", "js", "json"].flatMap((e) => [`${cwd}/.agent/config.${e}`, `${homedir10()}/.agent/config.${e}`]).filter((p) => existsSync9(p));
12686
12772
  cfgFiles.length ? ok(`config: ${cfgFiles.join(", ")}`) : warn("no .agent/config.* found (project or ~) \u2014 running on defaults");
12687
12773
  try {
12688
12774
  const probe = `${cwd}/.agent/sessions/.doctor-probe`;
@@ -14140,6 +14226,7 @@ export {
14140
14226
  formatStatus,
14141
14227
  formatTranscriptFull,
14142
14228
  jsonResult,
14229
+ makeHost,
14143
14230
  mcpMentionResolver,
14144
14231
  mentionRefs,
14145
14232
  parseArgs,