@agentconnect.md/daemon 1.0.0-rc.46 → 1.0.0-rc.48

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.
package/dist/index.js CHANGED
@@ -4,12 +4,12 @@ import { EventEmitter } from "node:events";
4
4
  import childProcess, { execFile, spawn } from "node:child_process";
5
5
  import * as sp from "node:path";
6
6
  import path, { delimiter, dirname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
7
- import fs, { accessSync, chmodSync, constants, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, stat, unlinkSync, unwatchFile, watch, watchFile, writeFileSync } from "node:fs";
7
+ import fs, { accessSync, chmodSync, constants, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, stat, unlinkSync, unwatchFile, watch, watchFile, writeFileSync } from "node:fs";
8
8
  import process$1 from "node:process";
9
9
  import { stripVTControlCharacters } from "node:util";
10
10
  import { fileURLToPath } from "node:url";
11
11
  import { createInterface } from "node:readline";
12
- import { cpus, freemem, homedir, hostname, totalmem, type } from "node:os";
12
+ import { cpus, freemem, homedir, hostname, tmpdir, totalmem, type } from "node:os";
13
13
  import { spawn as spawn$1 } from "child_process";
14
14
  import { Readable, Writable } from "node:stream";
15
15
  import { randomBytes, randomUUID } from "node:crypto";
@@ -3045,7 +3045,7 @@ var $ZodEncodeError = class extends Error {
3045
3045
  };
3046
3046
  (_a$2 = globalThis).__zod_globalConfig ?? (_a$2.__zod_globalConfig = {});
3047
3047
  const globalConfig = globalThis.__zod_globalConfig;
3048
- function config$1(newConfig) {
3048
+ function config(newConfig) {
3049
3049
  if (newConfig) Object.assign(globalConfig, newConfig);
3050
3050
  return globalConfig;
3051
3051
  }
@@ -3437,7 +3437,7 @@ const _parse = (_Err) => (schema, value, _ctx, _params) => {
3437
3437
  }, ctx);
3438
3438
  if (result instanceof Promise) throw new $ZodAsyncError();
3439
3439
  if (result.issues.length) {
3440
- const e = new ((_params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config$1())));
3440
+ const e = new ((_params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
3441
3441
  captureStackTrace(e, _params?.callee);
3442
3442
  throw e;
3443
3443
  }
@@ -3454,7 +3454,7 @@ const _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
3454
3454
  }, ctx);
3455
3455
  if (result instanceof Promise) result = await result;
3456
3456
  if (result.issues.length) {
3457
- const e = new ((params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config$1())));
3457
+ const e = new ((params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
3458
3458
  captureStackTrace(e, params?.callee);
3459
3459
  throw e;
3460
3460
  }
@@ -3472,7 +3472,7 @@ const _safeParse = (_Err) => (schema, value, _ctx) => {
3472
3472
  if (result instanceof Promise) throw new $ZodAsyncError();
3473
3473
  return result.issues.length ? {
3474
3474
  success: false,
3475
- error: new (_Err ?? $ZodError)(result.issues.map((iss) => finalizeIssue(iss, ctx, config$1())))
3475
+ error: new (_Err ?? $ZodError)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
3476
3476
  } : {
3477
3477
  success: true,
3478
3478
  data: result.value
@@ -3491,7 +3491,7 @@ const _safeParseAsync = (_Err) => async (schema, value, _ctx) => {
3491
3491
  if (result instanceof Promise) result = await result;
3492
3492
  return result.issues.length ? {
3493
3493
  success: false,
3494
- error: new _Err(result.issues.map((iss) => finalizeIssue(iss, ctx, config$1())))
3494
+ error: new _Err(result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
3495
3495
  } : {
3496
3496
  success: true,
3497
3497
  data: result.value
@@ -4732,7 +4732,7 @@ function handleUnionResults(results, final, inst, ctx) {
4732
4732
  code: "invalid_union",
4733
4733
  input: final.value,
4734
4734
  inst,
4735
- errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config$1())))
4735
+ errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
4736
4736
  });
4737
4737
  return final;
4738
4738
  }
@@ -4957,7 +4957,7 @@ const $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
4957
4957
  payload.issues.push({
4958
4958
  code: "invalid_key",
4959
4959
  origin: "record",
4960
- issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config$1())),
4960
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
4961
4961
  input: key,
4962
4962
  path: [key],
4963
4963
  inst
@@ -5012,7 +5012,7 @@ const $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
5012
5012
  else payload.issues.push({
5013
5013
  code: "invalid_key",
5014
5014
  origin: "record",
5015
- issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config$1())),
5015
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
5016
5016
  input: key,
5017
5017
  path: [key],
5018
5018
  inst
@@ -5209,7 +5209,7 @@ const $ZodCatch = /*@__PURE__*/ $constructor("$ZodCatch", (inst, def) => {
5209
5209
  if (result.issues.length) {
5210
5210
  payload.value = def.catchValue({
5211
5211
  ...payload,
5212
- error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config$1())) },
5212
+ error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config())) },
5213
5213
  input: payload.value
5214
5214
  });
5215
5215
  payload.issues = [];
@@ -5221,7 +5221,7 @@ const $ZodCatch = /*@__PURE__*/ $constructor("$ZodCatch", (inst, def) => {
5221
5221
  if (result.issues.length) {
5222
5222
  payload.value = def.catchValue({
5223
5223
  ...payload,
5224
- error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config$1())) },
5224
+ error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config())) },
5225
5225
  input: payload.value
5226
5226
  });
5227
5227
  payload.issues = [];
@@ -7529,7 +7529,7 @@ function toRuntimeDef(entry) {
7529
7529
  return null;
7530
7530
  }
7531
7531
  const REGISTRY_URL = "https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json";
7532
- const DEFAULT_TIMEOUT_MS = 4500;
7532
+ const DEFAULT_TIMEOUT_MS$1 = 4500;
7533
7533
  function readCachedDoc(root) {
7534
7534
  const file = registryPath(root);
7535
7535
  if (!existsSync(file)) return null;
@@ -7555,7 +7555,7 @@ async function fetchRegistry(root, opts = {}) {
7555
7555
  if (meta.etag) headers["If-None-Match"] = meta.etag;
7556
7556
  if (meta.lastModified) headers["If-Modified-Since"] = meta.lastModified;
7557
7557
  const ac = new AbortController();
7558
- const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
7558
+ const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? DEFAULT_TIMEOUT_MS$1);
7559
7559
  try {
7560
7560
  const res = await doFetch(REGISTRY_URL, {
7561
7561
  headers,
@@ -16891,6 +16891,21 @@ CLIENT_METHODS.session_update, CLIENT_METHODS.elicitation_complete;
16891
16891
  //#endregion
16892
16892
  //#region src/acp/acp-host.ts
16893
16893
  const PROTOCOL_VERSION = 1;
16894
+ /**
16895
+ * Extract the model selector from a session's `configOptions`. ACP models are an
16896
+ * (experimental) session config option tagged `category: "model"`, `type:
16897
+ * "select"`; the selectable values (optionally grouped) are the model list.
16898
+ * Returns null when the agent advertises no model selector.
16899
+ */
16900
+ function modelOptionsFrom(configOptions) {
16901
+ const model = configOptions?.find((o) => o.category === "model" && o.type === "select");
16902
+ if (!model || model.type !== "select") return null;
16903
+ const models = model.options.flatMap((o) => "group" in o ? o.options : [o]).map((o) => o.value);
16904
+ return {
16905
+ current: model.currentValue,
16906
+ models
16907
+ };
16908
+ }
16894
16909
  var AcpHost = class {
16895
16910
  runtime;
16896
16911
  opts;
@@ -16900,6 +16915,7 @@ var AcpHost = class {
16900
16915
  loadingSessions = /* @__PURE__ */ new Set();
16901
16916
  canLoad = false;
16902
16917
  promptCaps = {};
16918
+ lastModelOptions = null;
16903
16919
  constructor(runtime, opts) {
16904
16920
  this.runtime = runtime;
16905
16921
  this.opts = opts;
@@ -16953,9 +16969,15 @@ var AcpHost = class {
16953
16969
  cwd,
16954
16970
  mcpServers
16955
16971
  });
16972
+ this.lastModelOptions = modelOptionsFrom(res.configOptions);
16956
16973
  this.live.add(res.sessionId);
16957
16974
  return res.sessionId;
16958
16975
  }
16976
+ /** The model selector advertised by the most recent session/new, or null if the
16977
+ * agent exposed none. Used by the runtime probe to report available models. */
16978
+ modelOptions() {
16979
+ return this.lastModelOptions;
16980
+ }
16959
16981
  /** True iff THIS agent process created or loaded `sessionId` in its current lifetime. */
16960
16982
  hasSession(sessionId) {
16961
16983
  return this.live.has(sessionId);
@@ -81439,13 +81461,18 @@ var Scheduler = class {
81439
81461
  * only advertises genuinely-installed runtimes in `RegisterReq.capabilities`.
81440
81462
  *
81441
81463
  * Two layers:
81442
- * 1. A generic launcher check — is the runtime's `command` resolvable? Most
81443
- * agents ship as `npx`/`uvx` packages, which fetch on demand, so the launcher
81444
- * being present is enough for them.
81445
- * 2. Per-runtime custom probes (`CUSTOM_PROBES`) for the cases where (1) is too
81446
- * weak — almost every agent runs via `npx`, so "npx exists" is meaningless.
81447
- * For those we additionally look for the wrapped CLI's own config/state dir,
81448
- * which appears once the user has installed and run/initialized it.
81464
+ * 1. A generic launcher check — is the runtime's `command` resolvable? For a
81465
+ * runtime distributed as a real binary (`command` is the tool's own
81466
+ * executable) this is a meaningful signal: the binary on `$PATH` means it's
81467
+ * installed.
81468
+ * 2. For runtimes distributed via a package launcher (`npx`/`uvx`), (1) is
81469
+ * meaningless — the launcher fetches on demand, so "npx exists" is true on
81470
+ * virtually every dev host and tells us nothing about the wrapped agent. For
81471
+ * those we REQUIRE a per-runtime custom probe (`CUSTOM_PROBES`) that looks for
81472
+ * the wrapped CLI's own config/state dir, which appears once the user has
81473
+ * installed and run/initialized it. A launcher-distributed runtime with no
81474
+ * probe is treated as NOT installed — otherwise every npx/uvx agent in the
81475
+ * ACP registry would be falsely advertised just because `npx` is on `$PATH`.
81449
81476
  *
81450
81477
  * The custom probes test for the config *directory* (the "installed & initialized
81451
81478
  * on this host" signal). A stricter "is logged in" check would look for the auth
@@ -81511,11 +81538,18 @@ const CUSTOM_PROBES = {
81511
81538
  "factory-droid": (env) => pathExists(join(home(env), ".factory")),
81512
81539
  devin: (env) => anyExists(join(xdgConfigHome(env), "devin"), join(xdgDataHome(env), "devin"))
81513
81540
  };
81541
+ /**
81542
+ * Package launchers that fetch-and-run on demand. When a runtime is launched via
81543
+ * one of these, the launcher being on `$PATH` says nothing about whether the
81544
+ * wrapped agent is installed, so such runtimes require a custom probe to count.
81545
+ */
81546
+ const PACKAGE_LAUNCHERS = /* @__PURE__ */ new Set(["npx", "uvx"]);
81514
81547
  /** Is this runtime actually usable on this host? */
81515
81548
  function isRuntimeAvailable(id, rt, env = process.env) {
81516
81549
  if (!isCommandAvailable(rt.command, env)) return false;
81517
81550
  const custom = CUSTOM_PROBES[id];
81518
- return custom ? custom(env) : true;
81551
+ if (custom) return custom(env);
81552
+ return !PACKAGE_LAUNCHERS.has(rt.command);
81519
81553
  }
81520
81554
  /**
81521
81555
  * Filter a runtime map down to those installed on this host — what the daemon
@@ -81527,6 +81561,89 @@ function installedRuntimes(runtimes, env = process.env) {
81527
81561
  return out;
81528
81562
  }
81529
81563
  //#endregion
81564
+ //#region src/runtimes/runtime-prober.ts
81565
+ const DEFAULT_TIMEOUT_MS = 3e4;
81566
+ const DEFAULT_CONCURRENCY = 3;
81567
+ function makeHost(rt, log) {
81568
+ return new AcpHost(rt, {
81569
+ onUpdate: () => {},
81570
+ log
81571
+ });
81572
+ }
81573
+ /**
81574
+ * Probe one runtime. Never throws: any failure (spawn error, handshake failure,
81575
+ * timeout) is captured in `{ ok: false, error }`. On success, `models` reflects
81576
+ * whatever the agent advertised — an empty list is normal for agents that expose
81577
+ * no model selector, and is not a failure.
81578
+ */
81579
+ async function probeRuntime(id, rt, cwd, opts = {}) {
81580
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
81581
+ const host = (opts.hostFactory ?? ((r) => makeHost(r, opts.log)))(rt);
81582
+ let timer;
81583
+ const timeout = new Promise((_, reject) => {
81584
+ timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`probe timed out after ${timeoutMs}ms`)), timeoutMs);
81585
+ });
81586
+ const run = async () => {
81587
+ await host.start();
81588
+ await host.newSession(cwd);
81589
+ return host.modelOptions();
81590
+ };
81591
+ try {
81592
+ const models = await Promise.race([run(), timeout]);
81593
+ opts.log?.info(`probe: ${id} ok (models: ${models?.models.length ? models.models.join(", ") : "none advertised"})`);
81594
+ return {
81595
+ runtime: id,
81596
+ ok: true,
81597
+ models: models?.models ?? [],
81598
+ currentModel: models?.current
81599
+ };
81600
+ } catch (err) {
81601
+ const error = err.message;
81602
+ opts.log?.warn(`probe: ${id} failed — ${error}`);
81603
+ return {
81604
+ runtime: id,
81605
+ ok: false,
81606
+ models: [],
81607
+ error
81608
+ };
81609
+ } finally {
81610
+ if (timer) clearTimeout(timer);
81611
+ await host.stop().catch(() => {});
81612
+ }
81613
+ }
81614
+ /**
81615
+ * Probe every runtime with bounded concurrency. All probes share one temp cwd
81616
+ * (removed afterward). Result order is not meaningful — callers key by
81617
+ * `result.runtime`.
81618
+ */
81619
+ async function probeAllRuntimes(runtimes, opts = {}) {
81620
+ const ids = Object.keys(runtimes);
81621
+ if (ids.length === 0) return [];
81622
+ const cwd = mkdtempSync(join(tmpdir(), "ac-probe-"));
81623
+ const limit = Math.max(1, opts.concurrency ?? DEFAULT_CONCURRENCY);
81624
+ const results = [];
81625
+ let next = 0;
81626
+ const worker = async () => {
81627
+ for (let i = next++; i < ids.length; i = next++) {
81628
+ const id = ids[i];
81629
+ results.push(await probeRuntime(id, runtimes[id], cwd, opts));
81630
+ }
81631
+ };
81632
+ try {
81633
+ await Promise.all(Array.from({ length: Math.min(limit, ids.length) }, () => worker()));
81634
+ } finally {
81635
+ try {
81636
+ rmSync(cwd, {
81637
+ recursive: true,
81638
+ force: true
81639
+ });
81640
+ } catch (err) {
81641
+ opts.log?.debug(`probe: temp cwd cleanup failed for ${cwd}: ${err.message}`);
81642
+ }
81643
+ }
81644
+ return results;
81645
+ }
81646
+ //#endregion
81530
81647
  //#region src/log.ts
81531
81648
  const ORDER = {
81532
81649
  trace: 10,
@@ -81728,7 +81845,17 @@ var CpClient = class {
81728
81845
  this.heartbeatMs = ok.heartbeatSec > 0 ? ok.heartbeatSec * 1e3 : this.deps.heartbeatDefaultMs;
81729
81846
  this.armHeartbeat();
81730
81847
  this.deps.log.info(`cp: READY (epoch=${this.sessionEpoch}, routingEpoch=${this.routingEpoch})`);
81731
- for (const profile of this.deps.runtimeProfiles()) this.transport?.send(encode(buildEnvelope("facts/runtime-profile", profile)));
81848
+ for (const profile of this.deps.runtimeProfiles()) this.emitRuntimeProfile(profile);
81849
+ this.deps.onReady?.();
81850
+ }
81851
+ /**
81852
+ * Push a single runtime profile mid-session (D→C EVT, fire-and-forget). No-op
81853
+ * unless connected and READY/DRAINING — the CP only accepts control frames
81854
+ * there, and a reconnect's handshake re-emits the latest profiles anyway.
81855
+ */
81856
+ emitRuntimeProfile(profile) {
81857
+ if (this.state !== "READY" && this.state !== "DRAINING") return;
81858
+ this.transport?.send(encode(buildEnvelope("facts/runtime-profile", profile)));
81732
81859
  }
81733
81860
  request(type, payload) {
81734
81861
  const frame = buildEnvelope(type, payload);
@@ -82244,7 +82371,7 @@ function cpuTotals() {
82244
82371
  busy
82245
82372
  };
82246
82373
  }
82247
- var Daemon = class {
82374
+ var Daemon = class Daemon {
82248
82375
  opts;
82249
82376
  store;
82250
82377
  mcp;
@@ -82266,6 +82393,9 @@ var Daemon = class {
82266
82393
  runtimes = {};
82267
82394
  runtimeNames = {};
82268
82395
  runtimeVersions = {};
82396
+ runtimeModels = /* @__PURE__ */ new Map();
82397
+ probing = false;
82398
+ lastProbeAtMs = 0;
82269
82399
  cpClient;
82270
82400
  cpCrons;
82271
82401
  cpAgents;
@@ -83216,13 +83346,8 @@ var Daemon = class {
83216
83346
  acp: true,
83217
83347
  features: []
83218
83348
  }),
83219
- runtimeProfiles: () => Object.keys(this.runtimes).map((id) => ({
83220
- runtime: id,
83221
- version: this.runtimeVersions[id] ?? "",
83222
- models: [],
83223
- acpSupport: "full",
83224
- toolCalling: true
83225
- })),
83349
+ runtimeProfiles: () => Object.keys(this.runtimes).map((id) => this.runtimeProfileFor(id)),
83350
+ onReady: () => void this.probeRuntimesAndEmit(),
83226
83351
  localState: () => ({
83227
83352
  assignments: [],
83228
83353
  crons: this.cpCrons?.ids() ?? [],
@@ -83244,6 +83369,54 @@ var Daemon = class {
83244
83369
  this.cpClient.start();
83245
83370
  this.log.info(`cp: connecting to ${url}…`);
83246
83371
  }
83372
+ /** Build the current `facts/runtime-profile` for a runtime, folding in any
83373
+ * models learned by the probe sweep. */
83374
+ runtimeProfileFor(id) {
83375
+ return {
83376
+ runtime: id,
83377
+ version: this.runtimeVersions[id] ?? "",
83378
+ models: this.runtimeModels.get(id) ?? [],
83379
+ acpSupport: "full",
83380
+ toolCalling: true
83381
+ };
83382
+ }
83383
+ /** How long a completed probe sweep stays fresh — reconnects within this window
83384
+ * re-emit the cached profiles instead of re-spawning every agent. */
83385
+ static PROBE_TTL_MS = 5 * 6e4;
83386
+ /**
83387
+ * Probe every installed runtime in the background (launch → initialize →
83388
+ * session/new → read models → tear down), then emit a refreshed
83389
+ * `facts/runtime-profile` per runtime once the whole sweep completes.
83390
+ *
83391
+ * Triggered on each CP (re)connect. Deduped while in flight; skipped (with a
83392
+ * cached re-emit) when the last sweep is still fresh, so a reconnect storm can't
83393
+ * spawn a fleet of agent subprocesses. Never throws — probing is best-effort and
83394
+ * must not affect the CP connection.
83395
+ */
83396
+ async probeRuntimesAndEmit() {
83397
+ if (this.opts.hostFactory && !this.opts.probeRuntimes) return;
83398
+ const ids = Object.keys(this.runtimes);
83399
+ if (ids.length === 0) return;
83400
+ if (this.probing) return;
83401
+ if (this.lastProbeAtMs > 0 && Date.now() - this.lastProbeAtMs < Daemon.PROBE_TTL_MS) {
83402
+ for (const id of ids) this.cpClient?.emitRuntimeProfile(this.runtimeProfileFor(id));
83403
+ return;
83404
+ }
83405
+ this.probing = true;
83406
+ this.log.info(`probe: sweeping ${ids.length} runtime(s): ${ids.join(", ")}`);
83407
+ try {
83408
+ const results = await (this.opts.probeRuntimes ?? probeAllRuntimes)(this.runtimes, { log: this.log });
83409
+ for (const r of results) this.runtimeModels.set(r.runtime, r.ok ? r.models : []);
83410
+ this.lastProbeAtMs = Date.now();
83411
+ const okCount = results.filter((r) => r.ok).length;
83412
+ this.log.info(`probe: sweep complete — ${okCount}/${results.length} runtime(s) reachable`);
83413
+ for (const id of ids) this.cpClient?.emitRuntimeProfile(this.runtimeProfileFor(id));
83414
+ } catch (err) {
83415
+ this.log.warn(`probe: sweep failed: ${formatErr(err)}`);
83416
+ } finally {
83417
+ this.probing = false;
83418
+ }
83419
+ }
83247
83420
  async stop() {
83248
83421
  this.draining = true;
83249
83422
  clearTimeout(this.debounceTimer);
@@ -83527,7 +83700,7 @@ program.command("run").description("Run the daemon in the foreground").action(as
83527
83700
  }
83528
83701
  });
83529
83702
  program.command("mcp-bridge", { hidden: true }).description("internal: stdio MCP bridge to the running daemon").action(async () => {
83530
- const { runBridge } = await import("./bridge-hZMpl3k6.js");
83703
+ const { runBridge } = await import("./bridge-NDvTO1zB.js");
83531
83704
  await runBridge();
83532
83705
  });
83533
83706
  const controller = () => resolveController({ root: program.opts().root });
@@ -83629,20 +83802,20 @@ program.command("login").description("Interactive onboarding: test the Control P
83629
83802
  process.exit(1);
83630
83803
  }
83631
83804
  });
83632
- const config = program.command("config").description("Read / write / validate config.json");
83633
- const todo = (name) => () => {
83634
- console.log(`agentconnect: ${name} (not yet implemented)`);
83635
- };
83636
- config.command("get").action(todo("config get"));
83637
- config.command("set").action(todo("config set"));
83638
- config.command("validate").action(todo("config validate"));
83639
- config.command("path").action(todo("config path"));
83640
- const agent = program.command("agent").description("Manage local agent directories");
83641
- agent.command("list").action(todo("agent list"));
83642
- agent.command("add [id]").action(todo("agent add"));
83643
- agent.command("remove [id]").action(todo("agent remove"));
83644
- agent.command("enable [id]").action(todo("agent enable"));
83645
- agent.command("disable [id]").action(todo("agent disable"));
83805
+ program.command("agent").description("Inspect local agent directories").command("list").description("List agents discovered under --agents-dir (id, status, runtime, name, dir)").action(async () => {
83806
+ const opts = program.opts();
83807
+ try {
83808
+ const { runAgentList } = await import("./agent-list-CZbaXHPF.js");
83809
+ await runAgentList({
83810
+ agentsDir: opts.agentsDir,
83811
+ configPath: opts.config,
83812
+ root: opts.root
83813
+ });
83814
+ } catch (err) {
83815
+ console.error(`agentconnect agent list: ${err.message}`);
83816
+ process.exit(1);
83817
+ }
83818
+ });
83646
83819
  program.command("chat [message]").description("Discover an agent under --agents-dir (or --agent <name>) and chat over ACP").action(async (message) => {
83647
83820
  const opts = program.opts();
83648
83821
  try {
@@ -83661,6 +83834,6 @@ program.command("chat [message]").description("Discover an agent under --agents-
83661
83834
  });
83662
83835
  program.parse();
83663
83836
  //#endregion
83664
- export { __commonJSMin as C, safeParse$1 as S, record as _, _null as a, unknown as b, custom as c, literal as d, looseObject as f, preprocess as g, optional as h, _enum as i, discriminatedUnion as l, object as m, encodeFrame as n, array as o, number as p, DAEMON_VERSION as r, boolean as s, decodeFrames as t, intersection as u, string as v, __toESM as w, datetime as x, union as y };
83837
+ export { datetime as C, __toESM as E, unknown as S, __commonJSMin as T, optional as _, loadConfig as a, string as b, array as c, discriminatedUnion as d, intersection as f, object as g, number as h, discoverAgents as i, boolean as l, looseObject as m, encodeFrame as n, _enum as o, literal as p, DAEMON_VERSION as r, _null as s, decodeFrames as t, custom as u, preprocess as v, safeParse$1 as w, union as x, record as y };
83665
83838
 
83666
83839
  //# sourceMappingURL=index.js.map