@integrity-labs/agt-cli 0.28.238 → 0.28.239

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.
@@ -18,7 +18,7 @@ import {
18
18
  resolveConnectivityProbe,
19
19
  worseConnectivityOutcome,
20
20
  wrapScheduledTaskPrompt
21
- } from "./chunk-P7TUBBQL.js";
21
+ } from "./chunk-GO4VMK2P.js";
22
22
  import {
23
23
  parsePsRows
24
24
  } from "./chunk-XWVM4KPK.js";
@@ -4203,6 +4203,21 @@ function buildMcpJson(input) {
4203
4203
  }
4204
4204
  };
4205
4205
  }
4206
+ const origamiIntegration = input.integrations?.find((i) => i.definition_id === "origami");
4207
+ if (origamiIntegration?.stdioMcp === true && origamiIntegration.id) {
4208
+ const localOrigamiMcpPath = join2(getHomeDir(), ".augmented", "_mcp", "origami.js");
4209
+ mcpServers["origami"] = {
4210
+ command: "node",
4211
+ args: [localOrigamiMcpPath],
4212
+ env: {
4213
+ AGT_HOST: "${AGT_HOST}",
4214
+ AGT_TOKEN: "${AGT_TOKEN}",
4215
+ AGT_API_KEY: "${AGT_API_KEY}",
4216
+ AGT_AGENT_ID: input.agent.agent_id,
4217
+ AGT_INTEGRATION_ID: origamiIntegration.id
4218
+ }
4219
+ };
4220
+ }
4206
4221
  return { mcpServers };
4207
4222
  }
4208
4223
  function parseIntervalMinutes(scheduleEvery) {
@@ -5342,6 +5357,23 @@ ${sections}`
5342
5357
  }
5343
5358
  });
5344
5359
  }
5360
+ const origamiStdio = integrations.find((i) => i.definition_id === "origami");
5361
+ const origamiStdioAgentId = resolveBrokerAgentId(codeName) ?? agentId;
5362
+ const origamiStdioExpected = Boolean(origamiStdio?.stdioMcp === true && origamiStdio.id);
5363
+ if (origamiStdioExpected && origamiStdioAgentId) {
5364
+ const localOrigamiMcpPath = join2(getHomeDir(), ".augmented", "_mcp", "origami.js");
5365
+ this.writeMcpServer(codeName, "origami", {
5366
+ command: "node",
5367
+ args: [localOrigamiMcpPath],
5368
+ env: {
5369
+ AGT_HOST: "${AGT_HOST}",
5370
+ AGT_TOKEN: "${AGT_TOKEN}",
5371
+ AGT_API_KEY: "${AGT_API_KEY}",
5372
+ AGT_AGENT_ID: origamiStdioAgentId,
5373
+ AGT_INTEGRATION_ID: origamiStdio.id
5374
+ }
5375
+ });
5376
+ }
5345
5377
  if (this.removeMcpServer) {
5346
5378
  const nativeMcpKeys = INTEGRATION_REGISTRY.filter((d) => d.nativeMcp !== void 0).map((d) => d.nativeMcp.key ?? d.id);
5347
5379
  const integrationDerivedKeys = /* @__PURE__ */ new Set([
@@ -5351,6 +5383,10 @@ ${sections}`
5351
5383
  "xero-broker",
5352
5384
  "augmented-admin",
5353
5385
  "augmented-support",
5386
+ // ENG-7358: the dedicated origami stdio server. In the universe so
5387
+ // that removing the integration OR flipping the catalog stdio_mcp
5388
+ // flag back (rollback) prunes the entry symmetrically.
5389
+ "origami",
5354
5390
  ...nativeMcpKeys,
5355
5391
  ...Object.entries(OAUTH_PROVIDERS).filter(([, provider]) => Boolean(provider.mcpUrl)).map(([id]) => id)
5356
5392
  ]);
@@ -5367,6 +5403,8 @@ ${sections}`
5367
5403
  expectedKeys.add("augmented-admin");
5368
5404
  if (hasSupport)
5369
5405
  expectedKeys.add("augmented-support");
5406
+ if (origamiStdioExpected)
5407
+ expectedKeys.add("origami");
5370
5408
  for (const integration of integrations) {
5371
5409
  const def = INTEGRATION_REGISTRY.find((d) => d.id === integration.definition_id);
5372
5410
  if (def?.nativeMcp) {
@@ -5794,7 +5832,7 @@ function requireHost() {
5794
5832
  }
5795
5833
 
5796
5834
  // src/lib/api-client.ts
5797
- var agtCliVersion = true ? "0.28.238" : "dev";
5835
+ var agtCliVersion = true ? "0.28.239" : "dev";
5798
5836
  var lastConfigHash = null;
5799
5837
  function setConfigHash(hash) {
5800
5838
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -6748,11 +6786,130 @@ function reapMissingMcpSessions(args) {
6748
6786
  import { join as join5 } from "path";
6749
6787
  import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
6750
6788
 
6789
+ // src/lib/mcp-stdio-probe.ts
6790
+ import { spawn } from "child_process";
6791
+ var DEFAULT_TIMEOUT_MS = 15e3;
6792
+ async function probeMcpStdio(config) {
6793
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
6794
+ const child = spawn(config.command, config.args ?? [], {
6795
+ // Faithful reproduction of the real spawn: the child inherits the manager's
6796
+ // process env (PATH/HOME so `node`/`npx` resolve) with the entry's env
6797
+ // overlaid, exactly as Claude Code spawns it.
6798
+ env: { ...process.env, ...config.env ?? {} },
6799
+ cwd: config.cwd,
6800
+ stdio: ["pipe", "pipe", "pipe"]
6801
+ });
6802
+ let stdout = "";
6803
+ let stderrTail = "";
6804
+ const pending = /* @__PURE__ */ new Map();
6805
+ return await new Promise((resolve) => {
6806
+ let done = false;
6807
+ const finish = (outcome) => {
6808
+ if (done) return;
6809
+ done = true;
6810
+ clearTimeout(timer);
6811
+ child.stdout.removeAllListeners();
6812
+ try {
6813
+ child.kill("SIGKILL");
6814
+ } catch {
6815
+ }
6816
+ resolve(outcome);
6817
+ };
6818
+ const timer = setTimeout(() => {
6819
+ finish({ status: "transient_error", message: `MCP stdio handshake timed out after ${timeoutMs / 1e3}s` });
6820
+ }, timeoutMs);
6821
+ if (typeof timer.unref === "function") timer.unref();
6822
+ child.on("error", (err) => {
6823
+ finish({ status: "down", message: `MCP server failed to spawn: ${err.message}` });
6824
+ });
6825
+ child.on("exit", (code) => {
6826
+ if (!done) {
6827
+ finish({
6828
+ status: "down",
6829
+ message: `MCP server exited (code ${code ?? "null"})${stderrTail ? `: ${stderrTail.trim().slice(-200)}` : ""}`
6830
+ });
6831
+ }
6832
+ });
6833
+ child.stdin.on("error", () => {
6834
+ });
6835
+ child.stderr.on("data", (d) => {
6836
+ stderrTail = (stderrTail + d.toString()).slice(-500);
6837
+ });
6838
+ child.stdout.on("data", (d) => {
6839
+ stdout += d.toString();
6840
+ let nl;
6841
+ while ((nl = stdout.indexOf("\n")) >= 0) {
6842
+ const line = stdout.slice(0, nl).trim();
6843
+ stdout = stdout.slice(nl + 1);
6844
+ if (!line) continue;
6845
+ let msg = null;
6846
+ try {
6847
+ msg = JSON.parse(line);
6848
+ } catch {
6849
+ continue;
6850
+ }
6851
+ if (msg && typeof msg.id === "number" && pending.has(msg.id)) {
6852
+ const cb = pending.get(msg.id);
6853
+ pending.delete(msg.id);
6854
+ cb(msg);
6855
+ }
6856
+ }
6857
+ });
6858
+ const send = (msg) => child.stdin.write(`${JSON.stringify(msg)}
6859
+ `);
6860
+ const request = (id, method, params) => new Promise((res) => {
6861
+ pending.set(id, res);
6862
+ send({ jsonrpc: "2.0", id, method, ...params ? { params } : {} });
6863
+ });
6864
+ void (async () => {
6865
+ const init = await request(1, "initialize", {
6866
+ protocolVersion: "2025-03-26",
6867
+ capabilities: {},
6868
+ clientInfo: { name: "augmented-connectivity-probe", version: "1.0.0" }
6869
+ });
6870
+ if (done) return;
6871
+ if (init.error) return finish({ status: "down", message: `MCP initialize error: ${init.error.message ?? "unknown"}` });
6872
+ send({ jsonrpc: "2.0", method: "notifications/initialized" });
6873
+ const list = await request(2, "tools/list");
6874
+ if (done) return;
6875
+ if (list.error) return finish({ status: "down", message: `MCP tools/list error: ${list.error.message ?? "unknown"}` });
6876
+ const toolCount = Array.isArray(list.result?.tools) ? list.result.tools.length : void 0;
6877
+ const testTool = config.connectivityTest?.tool;
6878
+ if (testTool) {
6879
+ const rawArgs = config.connectivityTest?.args;
6880
+ if (Array.isArray(rawArgs)) {
6881
+ return finish({
6882
+ status: "down",
6883
+ message: `connectivity_test.args for ${testTool} must be an object (got a string[])`
6884
+ });
6885
+ }
6886
+ const toolArgs = rawArgs ?? {};
6887
+ const call = await request(3, "tools/call", { name: testTool, arguments: toolArgs });
6888
+ if (done) return;
6889
+ if (call.error) return finish({ status: "down", message: `MCP tools/call ${testTool} error: ${call.error.message ?? "unknown"}` });
6890
+ if (call.result?.isError === true) {
6891
+ return finish({ status: "down", message: `MCP tool ${testTool} returned an error result` });
6892
+ }
6893
+ return finish({
6894
+ status: "ok",
6895
+ message: `${testTool} succeeded`,
6896
+ details: { ...toolCount !== void 0 ? { toolCount } : {}, testTool }
6897
+ });
6898
+ }
6899
+ finish({
6900
+ status: "ok",
6901
+ message: toolCount !== void 0 ? `${toolCount} tools` : "reachable",
6902
+ ...toolCount !== void 0 ? { details: { toolCount } } : {}
6903
+ });
6904
+ })();
6905
+ });
6906
+ }
6907
+
6751
6908
  // src/lib/cli-probe.ts
6752
6909
  import { execFile as execFile2 } from "child_process";
6753
- var DEFAULT_TIMEOUT_MS = 8e3;
6910
+ var DEFAULT_TIMEOUT_MS2 = 8e3;
6754
6911
  function runCliProbe(binary, args, opts = {}) {
6755
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
6912
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
6756
6913
  return new Promise((resolve) => {
6757
6914
  execFile2(
6758
6915
  binary,
@@ -6814,6 +6971,31 @@ function readMcpHttpServerConfig(projectDir, serverKey, env) {
6814
6971
  return null;
6815
6972
  }
6816
6973
  }
6974
+ function readMcpStdioServerConfig(projectDir, serverKey, env) {
6975
+ try {
6976
+ const raw = readFileSync6(join5(projectDir, ".mcp.json"), "utf-8");
6977
+ const servers = JSON.parse(raw).mcpServers ?? {};
6978
+ const entry = servers[serverKey];
6979
+ if (!entry || typeof entry.command !== "string") return null;
6980
+ const unresolved = /* @__PURE__ */ new Set();
6981
+ const sub = (value) => {
6982
+ if (!env) return value;
6983
+ const r = expandTemplateVars(value, env);
6984
+ for (const name of r.unresolved) unresolved.add(name);
6985
+ return r.value;
6986
+ };
6987
+ const resolvedEnv = {};
6988
+ for (const [k, v] of Object.entries(entry.env ?? {})) resolvedEnv[k] = sub(v);
6989
+ return {
6990
+ command: entry.command,
6991
+ args: (entry.args ?? []).map(sub),
6992
+ env: resolvedEnv,
6993
+ unresolved: [...unresolved]
6994
+ };
6995
+ } catch {
6996
+ return null;
6997
+ }
6998
+ }
6817
6999
  function deriveMcpServerKey(input) {
6818
7000
  const kind = resolveConnectivityProbe({
6819
7001
  definitionId: input.definitionId,
@@ -6852,6 +7034,31 @@ function buildConnectivityProbeDeps(projectDir, probeEnv) {
6852
7034
  }
6853
7035
  return probeMcpHttp(cfg);
6854
7036
  },
7037
+ // ENG-7405: local-STDIO MCP probe. Spawns the toolkit's bundled server with
7038
+ // the agent's env (the exact command/args/env from `.mcp.json`), handshakes,
7039
+ // and calls the read-only `connectivity_test` tool when the descriptor set
7040
+ // one (threaded via target.toolName). An unresolvable `${VAR}` in the spawn
7041
+ // env → skip as non-escalating, never spawn a doomed server. A missing
7042
+ // server entry is a real `down` — the tools aren't wired.
7043
+ mcpStdioProbe: async (target) => {
7044
+ const cfg = readMcpStdioServerConfig(projectDir, target.serverKey, probeEnv);
7045
+ if (!cfg) {
7046
+ return { status: "down", message: `MCP stdio server '${target.serverKey}' not wired in .mcp.json` };
7047
+ }
7048
+ if (cfg.unresolved.length > 0) {
7049
+ return {
7050
+ status: "transient_error",
7051
+ message: `MCP stdio '${target.serverKey}' env unresolved: ${cfg.unresolved.join(", ")}`
7052
+ };
7053
+ }
7054
+ return probeMcpStdio({
7055
+ command: cfg.command,
7056
+ args: cfg.args,
7057
+ env: cfg.env,
7058
+ cwd: projectDir,
7059
+ connectivityTest: target.toolName ? { tool: target.toolName, args: target.toolArgs ?? null } : null
7060
+ });
7061
+ },
6855
7062
  // ENG-6139: connected-account binding check for managed (Composio) toolkits.
6856
7063
  // The MCP handshake reads green on a dead/mis-bound account, so the managed
6857
7064
  // probe also verifies the account is ACTIVE + bound to the entity the agent
@@ -7147,12 +7354,12 @@ import chalk3 from "chalk";
7147
7354
  import { existsSync as existsSync8, realpathSync } from "fs";
7148
7355
  import { join as join8 } from "path";
7149
7356
  import { homedir as homedir4, userInfo } from "os";
7150
- import { spawn as spawn2 } from "child_process";
7357
+ import { spawn as spawn3 } from "child_process";
7151
7358
 
7152
7359
  // src/lib/watchdog.ts
7153
7360
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, unlinkSync as unlinkSync3, existsSync as existsSync7, mkdirSync as mkdirSync5, openSync as openSync2, closeSync as closeSync2, chmodSync as chmodSync4 } from "fs";
7154
7361
  import { join as join7 } from "path";
7155
- import { spawn, execFileSync as execFileSync3 } from "child_process";
7362
+ import { spawn as spawn2, execFileSync as execFileSync3 } from "child_process";
7156
7363
  var DEFAULT_CONFIG_DIR = join7(process.env["HOME"] ?? "/tmp", ".augmented");
7157
7364
  function getManagerPaths(configDir) {
7158
7365
  return {
@@ -7248,7 +7455,7 @@ function startWatchdog(opts) {
7248
7455
  } catch {
7249
7456
  }
7250
7457
  const intervalSec = String(Math.max(Math.floor(opts.intervalMs / 1e3), 5));
7251
- const child = spawn(
7458
+ const child = spawn2(
7252
7459
  process.execPath,
7253
7460
  [process.argv[1], "manager", "start", "--interval", intervalSec, "--config-dir", configDir, "--supervise"],
7254
7461
  {
@@ -7449,7 +7656,7 @@ function runSupervisorLoop(intervalSec, configDir) {
7449
7656
  process.on("SIGINT", forwardOrExit("SIGINT"));
7450
7657
  const runOne = () => {
7451
7658
  respawnTimer = null;
7452
- currentChild = spawn2(
7659
+ currentChild = spawn3(
7453
7660
  process.execPath,
7454
7661
  [process.argv[1], "manager", "start", "--interval", String(intervalSec), "--config-dir", configDir],
7455
7662
  { stdio: "inherit", env: process.env }
@@ -7810,6 +8017,14 @@ async function executeConnectivityProbe(target, deps = {}) {
7810
8017
  serverKey: target.mcpServerKey ?? target.definitionId,
7811
8018
  definitionId: target.definitionId
7812
8019
  });
8020
+ case "mcp_stdio":
8021
+ if (!deps.mcpStdioProbe) return null;
8022
+ return deps.mcpStdioProbe({
8023
+ serverKey: target.mcpServerKey ?? target.definitionId,
8024
+ definitionId: target.definitionId,
8025
+ toolName: descriptor.probeTool ?? null,
8026
+ toolArgs: descriptor.probeArgs ?? null
8027
+ });
7813
8028
  case "cli_command":
7814
8029
  if (!deps.runCli) return null;
7815
8030
  return deps.runCli(target.cliBinary ?? target.definitionId, descriptor.cliArgs ?? ["--version"]);
@@ -7887,4 +8102,4 @@ export {
7887
8102
  managerInstallSystemUnitCommand,
7888
8103
  managerUninstallSystemUnitCommand
7889
8104
  };
7890
- //# sourceMappingURL=chunk-D4HUKRER.js.map
8105
+ //# sourceMappingURL=chunk-O3MVFYYC.js.map