@integrity-labs/agt-cli 0.28.40 → 0.28.42

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.
@@ -3,6 +3,7 @@ import {
3
3
  DEFAULT_MODELS,
4
4
  OAUTH_PROVIDERS,
5
5
  coerceEnvValue,
6
+ expandTemplateVars,
6
7
  formatForOpenClawCli,
7
8
  getChannel,
8
9
  getFlagDefinition,
@@ -11,10 +12,17 @@ import {
11
12
  listFlagDefinitions,
12
13
  normalizeFlagValue,
13
14
  parseDeliveryTarget,
15
+ parseEnvIntegrations,
16
+ probeComposioAccount,
17
+ probeComposioMcpToolCall,
18
+ probeHttpProvider,
19
+ probeMcpHttp,
14
20
  registerFramework,
15
21
  resolveAvatarEnvUrl,
22
+ resolveConnectivityProbe,
23
+ worseConnectivityOutcome,
16
24
  wrapScheduledTaskPrompt
17
- } from "./chunk-X5E2Q3W2.js";
25
+ } from "./chunk-SJUD2BWU.js";
18
26
 
19
27
  // ../../packages/core/dist/integrations/registry.js
20
28
  var INTEGRATION_REGISTRY = [
@@ -3390,43 +3398,32 @@ acknowledge before you start.
3390
3398
  - **FAST (< 60s):** handle inline. Reply via the channel tool
3391
3399
  (slack.reply / telegram.reply / directchat.reply) and end your turn.
3392
3400
 
3393
- - **SLOW (\u2265 60s):** acknowledge, dispatch to background, stay responsive.
3401
+ - **SLOW (\u2265 60s):** acknowledge first, then handle inline.
3394
3402
  1. Send a one-line acknowledgement via the channel tool \u2014 short, warm,
3395
3403
  and tell the user you'll come back. Example shape (don't copy verbatim,
3396
3404
  match your voice): "On it \u2014 this'll take a minute or two, I'll ping
3397
3405
  when it's done."
3398
- 2. Dispatch the work to a background sub-agent: the Agent tool with
3399
- \`subagent_type: general-purpose\` AND \`run_in_background: true\`.
3400
- Put EVERYTHING the worker needs in the dispatch prompt \u2014 the user's
3401
- full request, relevant thread context, which integrations/tools to
3402
- use, and the exact shape of result you want back. The worker inherits
3403
- your full MCP tool surface but NOT your conversation context.
3404
- 3. End your turn after dispatching. This is the point: you stay free to
3405
- answer other messages while the worker grinds. Do NOT wait, poll, or
3406
- dispatch the same work synchronously \u2014 a synchronous dispatch blocks
3407
- your turn and defeats the purpose.
3408
- 4. When the worker's completion notification arrives (it lands
3409
- automatically as a system message), read its result and reply via the
3410
- channel tool (\`slack.reply\` / \`telegram.reply\` / \`directchat.reply\`)
3411
- to the same thread / chat / conversation you acknowledged in step 1.
3412
- **You post the substantive reply \u2014 the worker has no channel tools.**
3413
- 5. If the completion notification reports a failure or an unusable
3414
- result, tell the user what happened and either re-dispatch with a
3415
- better prompt or handle it inline \u2014 never go silent.
3416
-
3417
- > **Why background dispatch (and why \`general-purpose\`):** validated
3418
- > 2026-06-10 on Claude Code 2.1.170 (ENG-6274 spike,
3419
- > \`docs/spikes/ENG-6274-run-in-background-dispatch.md\`): background
3420
- > dispatch returns immediately, your turn ends, inbound messages get
3421
- > answered in seconds while the worker runs, and the completion arrives
3422
- > as a notification you handle like any other turn. Use
3423
- > \`subagent_type: general-purpose\` (inherit-all tools) \u2014 NOT
3424
- > \`channel-message-handler\` or \`augmented-worker\` \u2014 until ENG-6273
3425
- > re-verifies on this host that the upstream allowlist bug
3426
- > ([anthropics/claude-code#64909](https://github.com/anthropics/claude-code/issues/64909),
3427
- > empirically 0/6 MCP tools in named sub-agents on 2026-06-03) is fixed
3428
- > at the fleet's pinned Claude Code version. \`general-purpose\` escapes
3429
- > that bug by construction either way.
3406
+ 2. Do the work yourself in this same session. Use whatever tools you
3407
+ need (MCP, skills, file reads, etc.) \u2014 your parent session has the
3408
+ full MCP surface bound.
3409
+ 3. Reply with the result via the channel tool (\`slack.reply\` /
3410
+ \`telegram.reply\` / \`directchat.reply\`), addressing the same thread
3411
+ / chat / conversation you acknowledged in step 1.
3412
+
3413
+ > **Why inline and not sub-agent dispatch right now:** there is an
3414
+ > upstream Claude Code bug
3415
+ > ([anthropics/claude-code#64909](https://github.com/anthropics/claude-code/issues/64909))
3416
+ > where sub-agents dispatched via the Task tool with an explicit
3417
+ > \`tools:\` allowlist (which is the shape \`channel-message-handler\`
3418
+ > uses) get an **empty MCP tool registry** \u2014 every \`mcp__*\` call
3419
+ > returns "No such tool available", including the channel reply tools.
3420
+ > Dispatching a slow channel reply to \`channel-message-handler\` will
3421
+ > therefore silently fail to land: you'd post the one-line ack, the
3422
+ > sub-agent would do the analysis fine, but its \`slack.reply\` call
3423
+ > would error and the user would never see the substantive reply.
3424
+ > Empirically confirmed 2026-06-03 with a 6-tool probe: 0/6 MCP tools
3425
+ > bound inside \`channel-message-handler\`. Until Anthropic ships the
3426
+ > fix, handling slow channel replies inline is the only working path.
3430
3427
 
3431
3428
  **Why this triage decision still matters more than any other instruction
3432
3429
  below:** if you skip the acknowledgement and just dive into slow work
@@ -3448,29 +3445,25 @@ For background tool work that **isn't** a channel reply \u2014 multi-step data
3448
3445
  pulls, CRM enrichments, research workflows, cross-MCP orchestration \u2014 use
3449
3446
  \`subagent_type: general-purpose\` (Anthropic's built-in). It inherits the
3450
3447
  full MCP tool surface from this session and reliably binds every
3451
- \`mcp__*\` server you have available. For anything expected to take more
3452
- than a minute, add \`run_in_background: true\` so your turn ends and you
3453
- stay responsive; the completion notification brings you the result.
3454
- Don't background-dispatch trivial work \u2014 each dispatch is a fresh
3455
- context and costs real tokens.
3448
+ \`mcp__*\` server you have available.
3456
3449
 
3457
3450
  **Why not \`augmented-worker\` for now:** there is an upstream Claude Code
3458
3451
  bug ([anthropics/claude-code#64909](https://github.com/anthropics/claude-code/issues/64909))
3459
3452
  where sub-agents with an explicit \`tools:\` allowlist get an empty MCP
3460
3453
  tool registry \u2014 every \`mcp__*\` call returns "No such tool available."
3461
3454
  \`general-purpose\` uses \`tools: *\` (inherit-all) and escapes the bug.
3462
- The fix appears to have shipped upstream (verified locally on Claude Code
3463
- 2.1.170, 2026-06-10 \u2014 ENG-6269 spike); once ENG-6273 re-verifies it on
3464
- this host's pinned version, \`augmented-worker\` becomes preferred again
3465
- (restricted tool surface for safety + working MCP binding) and
3466
- \`channel-message-handler\` returns as a dispatch target. Until then,
3467
- \`general-purpose\` only.
3455
+ Once Anthropic ships the fix, \`augmented-worker\` becomes preferred again
3456
+ (restricted tool surface for safety + working MCP binding); the dispatch
3457
+ recommendation here will flip back automatically.
3468
3458
 
3469
3459
  For slow **channel** replies, see \xA7 FIRST ACTION above \u2014 those are
3470
- dispatched as background \`general-purpose\` workers and **you** post the
3471
- result back to the channel when the completion notification arrives
3472
- (\`channel-message-handler\` is not yet the dispatch target for the same
3473
- ENG-6273-pending reason).
3460
+ currently handled inline (not dispatched) because \`channel-message-handler\`
3461
+ shares the explicit-allowlist shape and so suffers the same upstream
3462
+ bug. Empirically confirmed 2026-06-03 on agt-aws-1 with a 6-tool probe:
3463
+ 0/6 MCP tools bound inside \`channel-message-handler\` (matching the
3464
+ \`augmented-worker\` result). When Anthropic ships the upstream fix, both
3465
+ named sub-agents will work again and the FIRST ACTION triage will switch
3466
+ back to dispatch.
3474
3467
 
3475
3468
  ${activeTasksSection}${personalitySection}## Identity
3476
3469
 
@@ -5816,9 +5809,9 @@ ${sections}`
5816
5809
  // so ensureGatewayRunning() returns early with running=false
5817
5810
  async getVersion() {
5818
5811
  try {
5819
- const { execFile: execFile4 } = await import("child_process");
5812
+ const { execFile: execFile5 } = await import("child_process");
5820
5813
  return new Promise((resolve3) => {
5821
- execFile4("claude", ["--version"], { timeout: 5e3 }, (err, stdout) => {
5814
+ execFile5("claude", ["--version"], { timeout: 5e3 }, (err, stdout) => {
5822
5815
  if (err) {
5823
5816
  resolve3(null);
5824
5817
  return;
@@ -7266,7 +7259,7 @@ function requireHost() {
7266
7259
  }
7267
7260
 
7268
7261
  // src/lib/api-client.ts
7269
- var agtCliVersion = true ? "0.28.40" : "dev";
7262
+ var agtCliVersion = true ? "0.28.42" : "dev";
7270
7263
  var lastConfigHash = null;
7271
7264
  function setConfigHash(hash) {
7272
7265
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -7662,27 +7655,177 @@ function provision(input, frameworkId = "openclaw") {
7662
7655
  };
7663
7656
  }
7664
7657
 
7658
+ // src/lib/connectivity-probe-context.ts
7659
+ import { join as join8 } from "path";
7660
+ import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
7661
+
7662
+ // src/lib/cli-probe.ts
7663
+ import { execFile as execFile4 } from "child_process";
7664
+ var DEFAULT_TIMEOUT_MS = 8e3;
7665
+ function runCliProbe(binary, args, opts = {}) {
7666
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
7667
+ return new Promise((resolve3) => {
7668
+ execFile4(
7669
+ binary,
7670
+ args,
7671
+ { timeout: timeoutMs, env: opts.env ?? process.env, windowsHide: true },
7672
+ (err, stdout) => {
7673
+ if (!err) {
7674
+ const firstLine = String(stdout).split(/\r?\n/, 1)[0]?.trim();
7675
+ resolve3({ status: "ok", message: firstLine ? `${binary}: ${firstLine}` : `${binary}: ok` });
7676
+ return;
7677
+ }
7678
+ const e = err;
7679
+ if (e.code === "ENOENT") {
7680
+ resolve3({ status: "down", message: `${binary} not found on PATH (not installed)` });
7681
+ return;
7682
+ }
7683
+ if (e.killed || e.signal === "SIGTERM") {
7684
+ resolve3({ status: "transient_error", message: `${binary} probe timed out after ${timeoutMs / 1e3}s` });
7685
+ return;
7686
+ }
7687
+ resolve3({ status: "down", message: `${binary} exited non-zero: ${e.message}` });
7688
+ }
7689
+ );
7690
+ });
7691
+ }
7692
+
7693
+ // src/lib/connectivity-probe-context.ts
7694
+ function readMcpHttpServerConfig(projectDir, serverKey, env) {
7695
+ try {
7696
+ const raw = readFileSync8(join8(projectDir, ".mcp.json"), "utf-8");
7697
+ const servers = JSON.parse(raw).mcpServers ?? {};
7698
+ const entry = servers[serverKey];
7699
+ if (entry && typeof entry.url === "string" && (entry.type === "http" || entry.type === void 0)) {
7700
+ const unresolved = /* @__PURE__ */ new Set();
7701
+ const sub = (value) => {
7702
+ if (!env) return value;
7703
+ const r = expandTemplateVars(value, env);
7704
+ for (const name of r.unresolved) unresolved.add(name);
7705
+ return r.value;
7706
+ };
7707
+ const url = sub(entry.url);
7708
+ let headers;
7709
+ if (entry.headers) {
7710
+ headers = {};
7711
+ for (const [k, v] of Object.entries(entry.headers)) headers[k] = sub(v);
7712
+ }
7713
+ return { url, ...headers ? { headers } : {}, unresolved: [...unresolved] };
7714
+ }
7715
+ return null;
7716
+ } catch {
7717
+ return null;
7718
+ }
7719
+ }
7720
+ function deriveMcpServerKey(input) {
7721
+ const kind = resolveConnectivityProbe({
7722
+ definitionId: input.definitionId,
7723
+ sourceType: input.sourceType,
7724
+ authType: input.authType,
7725
+ connectivityTest: input.connectivityTest ?? null
7726
+ }).kind;
7727
+ if (kind !== "mcp_tools_list" && kind !== "managed_composite") return void 0;
7728
+ return input.definitionId.replace(/[^a-z0-9]/gi, "_").toLowerCase();
7729
+ }
7730
+ function buildProbeEnv(projectDir) {
7731
+ const probeEnv = { ...process.env };
7732
+ try {
7733
+ const envIntPath = join8(projectDir, ".env.integrations");
7734
+ if (existsSync8(envIntPath)) {
7735
+ Object.assign(probeEnv, parseEnvIntegrations(readFileSync8(envIntPath, "utf-8")));
7736
+ }
7737
+ } catch {
7738
+ }
7739
+ return probeEnv;
7740
+ }
7741
+ function buildConnectivityProbeDeps(projectDir, probeEnv) {
7742
+ return {
7743
+ fetchImpl: fetch,
7744
+ runCli: (binary, args) => runCliProbe(binary, args, { env: probeEnv }),
7745
+ mcpProbe: async (target) => {
7746
+ const cfg = readMcpHttpServerConfig(projectDir, target.serverKey, probeEnv);
7747
+ if (!cfg) {
7748
+ return { status: "transient_error", message: `MCP server '${target.serverKey}' not resolvable from .mcp.json` };
7749
+ }
7750
+ if (cfg.unresolved.length > 0) {
7751
+ return {
7752
+ status: "transient_error",
7753
+ message: `MCP '${target.serverKey}' auth unresolved: ${cfg.unresolved.join(", ")}`
7754
+ };
7755
+ }
7756
+ return probeMcpHttp(cfg);
7757
+ },
7758
+ // ENG-6139: connected-account binding check for managed (Composio) toolkits.
7759
+ // The MCP handshake reads green on a dead/mis-bound account, so the managed
7760
+ // probe also verifies the account is ACTIVE + bound to the entity the agent
7761
+ // queries with. Inputs come from the agent's OWN wired MCP server: the
7762
+ // `x-api-key` header and the `user_id` query param (the agent already
7763
+ // authenticates with these), plus the recorded connected_account_id.
7764
+ composioProbe: async (definitionId, credentials) => {
7765
+ const serverKey = definitionId.replace(/[^a-z0-9]/gi, "_").toLowerCase();
7766
+ const cfg = readMcpHttpServerConfig(projectDir, serverKey, probeEnv);
7767
+ if (!cfg) {
7768
+ return { status: "transient_error", message: `MCP server '${serverKey}' not resolvable from .mcp.json` };
7769
+ }
7770
+ if (cfg.unresolved.length > 0) {
7771
+ return {
7772
+ status: "transient_error",
7773
+ message: `MCP '${serverKey}' auth unresolved: ${cfg.unresolved.join(", ")}`
7774
+ };
7775
+ }
7776
+ const apiKey = Object.entries(cfg.headers ?? {}).find(([k]) => k.toLowerCase() === "x-api-key")?.[1] ?? "";
7777
+ let expectedUserId = "";
7778
+ let serverId;
7779
+ try {
7780
+ const u = new URL(cfg.url);
7781
+ expectedUserId = u.searchParams.get("user_id") ?? "";
7782
+ const m = u.pathname.match(/\/v3\/mcp\/([^/]+)\/mcp/);
7783
+ serverId = m?.[1] ? decodeURIComponent(m[1]) : void 0;
7784
+ } catch {
7785
+ expectedUserId = "";
7786
+ }
7787
+ const connectedAccountId = typeof credentials?.["connected_account_id"] === "string" ? credentials["connected_account_id"] : "";
7788
+ return probeComposioAccount({ connectedAccountId, apiKey, expectedUserId, serverId });
7789
+ },
7790
+ // ENG-6157 (Phase 2): the live tool-call leg. Uses the agent's OWN wired MCP
7791
+ // URL + headers (the exact path tool calls take), so a broken auth_config
7792
+ // linkage surfaces as a real `No connected account found` instead of a
7793
+ // green handshake. Skips (`null`) when no safe read-only tool is callable.
7794
+ composioToolCallProbe: async (target) => {
7795
+ const cfg = readMcpHttpServerConfig(projectDir, target.serverKey, probeEnv);
7796
+ if (!cfg) return null;
7797
+ if (cfg.unresolved.length > 0) return null;
7798
+ return probeComposioMcpToolCall({
7799
+ url: cfg.url,
7800
+ headers: cfg.headers,
7801
+ toolName: target.toolName,
7802
+ toolArgs: target.toolArgs
7803
+ });
7804
+ }
7805
+ };
7806
+ }
7807
+
7665
7808
  // src/commands/manager.ts
7666
7809
  import chalk3 from "chalk";
7667
- import { existsSync as existsSync9, realpathSync } from "fs";
7668
- import { join as join9 } from "path";
7810
+ import { existsSync as existsSync10, realpathSync } from "fs";
7811
+ import { join as join10 } from "path";
7669
7812
  import { homedir as homedir6, userInfo } from "os";
7670
7813
  import { spawn as spawn3 } from "child_process";
7671
7814
 
7672
7815
  // src/lib/watchdog.ts
7673
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, existsSync as existsSync8, mkdirSync as mkdirSync7, openSync as openSync2, closeSync as closeSync2, chmodSync as chmodSync6 } from "fs";
7674
- import { join as join8 } from "path";
7816
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, existsSync as existsSync9, mkdirSync as mkdirSync7, openSync as openSync2, closeSync as closeSync2, chmodSync as chmodSync6 } from "fs";
7817
+ import { join as join9 } from "path";
7675
7818
  import { spawn as spawn2, execFileSync } from "child_process";
7676
- var DEFAULT_CONFIG_DIR = join8(process.env["HOME"] ?? "/tmp", ".augmented");
7819
+ var DEFAULT_CONFIG_DIR = join9(process.env["HOME"] ?? "/tmp", ".augmented");
7677
7820
  function getManagerPaths(configDir) {
7678
7821
  return {
7679
- pidFile: join8(configDir, "manager.pid"),
7680
- stateFile: join8(configDir, "manager-state.json"),
7681
- logFile: join8(configDir, "manager.log")
7822
+ pidFile: join9(configDir, "manager.pid"),
7823
+ stateFile: join9(configDir, "manager-state.json"),
7824
+ logFile: join9(configDir, "manager.log")
7682
7825
  };
7683
7826
  }
7684
7827
  function ensureDir2(configDir) {
7685
- if (!existsSync8(configDir)) {
7828
+ if (!existsSync9(configDir)) {
7686
7829
  mkdirSync7(configDir, { recursive: true });
7687
7830
  }
7688
7831
  }
@@ -7692,7 +7835,7 @@ function writePidFile(configDir, pid) {
7692
7835
  }
7693
7836
  function readPidFile(configDir) {
7694
7837
  try {
7695
- const raw = readFileSync8(getManagerPaths(configDir).pidFile, "utf-8").trim();
7838
+ const raw = readFileSync9(getManagerPaths(configDir).pidFile, "utf-8").trim();
7696
7839
  const pid = parseInt(raw, 10);
7697
7840
  return isNaN(pid) ? null : pid;
7698
7841
  } catch {
@@ -7730,7 +7873,7 @@ function defaultPgrep() {
7730
7873
  }
7731
7874
  function readStateFile(configDir) {
7732
7875
  try {
7733
- const raw = readFileSync8(getManagerPaths(configDir).stateFile, "utf-8");
7876
+ const raw = readFileSync9(getManagerPaths(configDir).stateFile, "utf-8");
7734
7877
  return JSON.parse(raw);
7735
7878
  } catch {
7736
7879
  return null;
@@ -7786,7 +7929,7 @@ function startWatchdog(opts) {
7786
7929
  const deadline = Date.now() + 5e3;
7787
7930
  const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
7788
7931
  while (Date.now() < deadline) {
7789
- if (existsSync8(pidFile)) {
7932
+ if (existsSync9(pidFile)) {
7790
7933
  return { pid: child.pid };
7791
7934
  }
7792
7935
  if (child.exitCode !== null) {
@@ -7914,7 +8057,7 @@ function managerStartCommand(opts) {
7914
8057
  process.exitCode = 1;
7915
8058
  return;
7916
8059
  }
7917
- const configDir = opts.configDir ?? join9(homedir6(), ".augmented");
8060
+ const configDir = opts.configDir ?? join10(homedir6(), ".augmented");
7918
8061
  if (opts.supervise) {
7919
8062
  if (json) {
7920
8063
  jsonOutput({ ok: false, error: "--supervise is not supported with --json" });
@@ -8010,7 +8153,7 @@ function runSupervisorLoop(intervalSec, configDir) {
8010
8153
  }
8011
8154
  async function managerStopCommand(opts = {}) {
8012
8155
  const json = isJsonMode();
8013
- const configDir = opts.configDir ?? join9(homedir6(), ".augmented");
8156
+ const configDir = opts.configDir ?? join10(homedir6(), ".augmented");
8014
8157
  try {
8015
8158
  const result = await stopWatchdog(configDir);
8016
8159
  if (!result.stopped && !result.pid) {
@@ -8038,7 +8181,7 @@ async function managerStopCommand(opts = {}) {
8038
8181
  }
8039
8182
  function managerStatusCommand(opts = {}) {
8040
8183
  const json = isJsonMode();
8041
- const configDir = opts.configDir ?? join9(homedir6(), ".augmented");
8184
+ const configDir = opts.configDir ?? join10(homedir6(), ".augmented");
8042
8185
  const status = getManagerStatus(configDir);
8043
8186
  if (!status) {
8044
8187
  if (json) {
@@ -8110,7 +8253,7 @@ function resolveStableAgtBin(rawPath) {
8110
8253
  if (!prefix || !formula) return rawPath;
8111
8254
  const candidates = [`${prefix}/bin/${formula}`, `${prefix}/bin/agt`];
8112
8255
  for (const candidate of candidates) {
8113
- if (!existsSync9(candidate)) continue;
8256
+ if (!existsSync10(candidate)) continue;
8114
8257
  try {
8115
8258
  realpathSync(candidate);
8116
8259
  return candidate;
@@ -8130,7 +8273,7 @@ async function managerInstallCommand(opts = {}) {
8130
8273
  process.exitCode = 1;
8131
8274
  return;
8132
8275
  }
8133
- const configDir = opts.configDir ?? join9(homedir6(), ".augmented");
8276
+ const configDir = opts.configDir ?? join10(homedir6(), ".augmented");
8134
8277
  const rawAgtBin = process.argv[1];
8135
8278
  if (!rawAgtBin) {
8136
8279
  const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
@@ -8143,7 +8286,7 @@ async function managerInstallCommand(opts = {}) {
8143
8286
  if (process.platform === "darwin") {
8144
8287
  const home = homedir6();
8145
8288
  const protectedRoots = ["Documents", "Downloads", "Desktop", "Movies", "Music", "Pictures"];
8146
- const offending = protectedRoots.map((r) => join9(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
8289
+ const offending = protectedRoots.map((r) => join10(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
8147
8290
  if (offending) {
8148
8291
  const msg = `agt binary at ${agtBin} sits inside a macOS TCC-protected folder (${offending}). launchd-spawned processes cannot read files there and the manager would EPERM on startup. Either install agt globally (\`npm install -g @integrity-labs/agt-cli\`) or copy the dist outside protected folders before running this command.`;
8149
8292
  if (json) jsonOutput({ ok: false, error: msg });
@@ -8211,7 +8354,7 @@ async function managerInstallSystemUnitCommand(opts = {}) {
8211
8354
  return;
8212
8355
  }
8213
8356
  const user = opts.user ?? "root";
8214
- const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" : join9("/home", user, ".augmented"));
8357
+ const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" : join10("/home", user, ".augmented"));
8215
8358
  const rawAgtBin = process.argv[1];
8216
8359
  if (!rawAgtBin) {
8217
8360
  const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
@@ -8274,6 +8417,73 @@ async function managerUninstallSystemUnitCommand() {
8274
8417
  }
8275
8418
  }
8276
8419
 
8420
+ // src/lib/connectivity-probe-executor.ts
8421
+ async function executeConnectivityProbe(target, deps = {}) {
8422
+ const descriptor = resolveConnectivityProbe({
8423
+ definitionId: target.definitionId,
8424
+ sourceType: target.sourceType,
8425
+ authType: target.authType,
8426
+ // ENG-6242: carry the toolkit's connectivity_test override so a managed
8427
+ // descriptor surfaces `probeTool`/`probeArgs` (the prescribed read-only tool)
8428
+ // — without this the hourly probe auto-picked a different tool than the Test
8429
+ // path, the false-RED that flagged every managed Linear install "unreachable".
8430
+ connectivityTest: target.connectivityTest ?? null
8431
+ });
8432
+ if (!descriptor.readOnly) {
8433
+ throw new Error(`Refusing non-read-only probe for ${target.definitionId}`);
8434
+ }
8435
+ switch (descriptor.kind) {
8436
+ case "http_provider":
8437
+ return probeHttpProvider(target.definitionId, target.credentials, deps.fetchImpl ?? fetch);
8438
+ case "composio_account":
8439
+ if (!deps.composioProbe) return null;
8440
+ return deps.composioProbe(target.definitionId, target.credentials);
8441
+ case "managed_composite": {
8442
+ const outcomes = [];
8443
+ if (deps.mcpProbe) {
8444
+ outcomes.push(
8445
+ await deps.mcpProbe({
8446
+ serverKey: target.mcpServerKey ?? target.definitionId,
8447
+ definitionId: target.definitionId
8448
+ })
8449
+ );
8450
+ }
8451
+ if (deps.composioProbe) {
8452
+ outcomes.push(await deps.composioProbe(target.definitionId, target.credentials));
8453
+ }
8454
+ if (deps.composioToolCallProbe) {
8455
+ const toolCall = await deps.composioToolCallProbe({
8456
+ serverKey: target.mcpServerKey ?? target.definitionId,
8457
+ definitionId: target.definitionId,
8458
+ // ENG-6242: thread the prescribed tool through to the live tool-call
8459
+ // leg. resolveConnectivityProbe only sets these for managed toolkits
8460
+ // with a stored override; the probe re-validates read-only and falls
8461
+ // back to auto-pick on drift, so a missing/invalid override is safe.
8462
+ toolName: descriptor.probeTool ?? null,
8463
+ toolArgs: descriptor.probeArgs ?? null
8464
+ });
8465
+ if (toolCall) outcomes.push(toolCall);
8466
+ }
8467
+ if (outcomes.length === 0) return null;
8468
+ return outcomes.reduce((acc, o) => worseConnectivityOutcome(acc, o));
8469
+ }
8470
+ case "mcp_tools_list":
8471
+ if (!deps.mcpProbe) return null;
8472
+ return deps.mcpProbe({
8473
+ serverKey: target.mcpServerKey ?? target.definitionId,
8474
+ definitionId: target.definitionId
8475
+ });
8476
+ case "cli_command":
8477
+ if (!deps.runCli) return null;
8478
+ return deps.runCli(target.cliBinary ?? target.definitionId, descriptor.cliArgs ?? ["--version"]);
8479
+ case "builtin":
8480
+ return { status: "ok", message: `${target.definitionId}: built-in` };
8481
+ case "unsupported":
8482
+ default:
8483
+ return null;
8484
+ }
8485
+ }
8486
+
8277
8487
  export {
8278
8488
  getIntegration,
8279
8489
  extractCommandNotFound,
@@ -8315,6 +8525,10 @@ export {
8315
8525
  resolveAllFlags,
8316
8526
  HostFlagStore,
8317
8527
  provision,
8528
+ executeConnectivityProbe,
8529
+ deriveMcpServerKey,
8530
+ buildProbeEnv,
8531
+ buildConnectivityProbeDeps,
8318
8532
  getManagerPaths,
8319
8533
  startWatchdog,
8320
8534
  managerStartCommand,
@@ -8326,4 +8540,4 @@ export {
8326
8540
  managerInstallSystemUnitCommand,
8327
8541
  managerUninstallSystemUnitCommand
8328
8542
  };
8329
- //# sourceMappingURL=chunk-DA776TZO.js.map
8543
+ //# sourceMappingURL=chunk-3QK6QLQW.js.map