@integrity-labs/agt-cli 0.28.522 → 0.28.523

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.
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-5GMZKV37.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-OT66RBK5.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-7W7LSW73.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-KEG2LDMH.js.map
@@ -53,7 +53,7 @@ import {
53
53
  safeWriteJsonAtomic,
54
54
  setConfigHash,
55
55
  tripClass
56
- } from "../chunk-WIQCLSZY.js";
56
+ } from "../chunk-HERASX7X.js";
57
57
  import {
58
58
  getProjectDir as getProjectDir2,
59
59
  getReadyTasks,
@@ -177,7 +177,7 @@ import {
177
177
  toOpencodeModel,
178
178
  transcriptActivityAgeSeconds,
179
179
  writeEgressAllowlist
180
- } from "../chunk-4GTDD2I5.js";
180
+ } from "../chunk-LBSV575W.js";
181
181
  import {
182
182
  reapOrphanChannelMcps
183
183
  } from "../chunk-XWVM4KPK.js";
@@ -10106,7 +10106,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
10106
10106
  var lastVersionCheckAt = 0;
10107
10107
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10108
10108
  var lastResponsivenessProbeAt = 0;
10109
- var agtCliVersion = true ? "0.28.522" : "dev";
10109
+ var agtCliVersion = true ? "0.28.523" : "dev";
10110
10110
  function resolveBrewPath(execFileSync2) {
10111
10111
  try {
10112
10112
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -11314,7 +11314,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
11314
11314
  if (codeNames.length === 0) return;
11315
11315
  void (async () => {
11316
11316
  try {
11317
- const { collectDiagnostics } = await import("../persistent-session-5GMZKV37.js");
11317
+ const { collectDiagnostics } = await import("../persistent-session-OT66RBK5.js");
11318
11318
  await api.post("/host/heartbeat", {
11319
11319
  host_id: hostId,
11320
11320
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11421,7 +11421,7 @@ async function pollCycle() {
11421
11421
  }
11422
11422
  try {
11423
11423
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11424
- const { collectDiagnostics } = await import("../persistent-session-5GMZKV37.js");
11424
+ const { collectDiagnostics } = await import("../persistent-session-OT66RBK5.js");
11425
11425
  const diagCodeNames = [...agentState.persistentSessionAgents];
11426
11426
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11427
11427
  let tailscaleHostname;
@@ -11536,7 +11536,7 @@ async function pollCycle() {
11536
11536
  collectResponsivenessProbes,
11537
11537
  collectPanelessActivityProbes,
11538
11538
  getResponsivenessIntervalMs
11539
- } = await import("../responsiveness-probe-52IZOP2M.js");
11539
+ } = await import("../responsiveness-probe-KW7KQJUY.js");
11540
11540
  const probeIntervalMs = getResponsivenessIntervalMs();
11541
11541
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11542
11542
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11600,7 +11600,7 @@ async function pollCycle() {
11600
11600
  collectResponsivenessProbes,
11601
11601
  livePendingInboundOldestAgeSeconds,
11602
11602
  parkPendingInbound
11603
- } = await import("../responsiveness-probe-52IZOP2M.js");
11603
+ } = await import("../responsiveness-probe-KW7KQJUY.js");
11604
11604
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11605
11605
  const wedgeNow = /* @__PURE__ */ new Date();
11606
11606
  const liveAgents = agentState.persistentSessionAgents;
@@ -15108,7 +15108,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
15108
15108
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
15109
15109
  void (async () => {
15110
15110
  try {
15111
- const { collectDiagnostics } = await import("../persistent-session-5GMZKV37.js");
15111
+ const { collectDiagnostics } = await import("../persistent-session-OT66RBK5.js");
15112
15112
  await api.post("/host/heartbeat", {
15113
15113
  host_id: hostId,
15114
15114
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15158,7 +15158,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
15158
15158
  }
15159
15159
  try {
15160
15160
  const hostId = await getHostId();
15161
- const { collectDiagnostics } = await import("../persistent-session-5GMZKV37.js");
15161
+ const { collectDiagnostics } = await import("../persistent-session-OT66RBK5.js");
15162
15162
  await api.post("/host/heartbeat", {
15163
15163
  host_id: hostId,
15164
15164
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15676,7 +15676,7 @@ async function processClaudePairSessions(agents) {
15676
15676
  killPairSession,
15677
15677
  pairTmuxSession,
15678
15678
  finalizeClaudePairOnboarding
15679
- } = await import("../claude-pair-runtime-7W7LSW73.js");
15679
+ } = await import("../claude-pair-runtime-KEG2LDMH.js");
15680
15680
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15681
15681
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15682
15682
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -32596,7 +32596,14 @@ var REMOTE_MCP_PROXY_ENV = {
32596
32596
  authHeader: "AGT_REMOTE_MCP_AUTH_HEADER",
32597
32597
  extraHeaders: "AGT_REMOTE_MCP_EXTRA_HEADERS",
32598
32598
  toolAllowlist: "AGT_REMOTE_MCP_TOOL_ALLOWLIST",
32599
- preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS"
32599
+ preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS",
32600
+ // ENG-8512: per-provider argument rules. A `tools/call` carrying a value we
32601
+ // KNOW the remote accepts and silently ignores is refused before it is
32602
+ // forwarded, rather than returning a 200 that every layer above records as
32603
+ // success. Deliberately NOT in REMOTE_MCP_AUTH_ENV_KEYS: it shapes which calls
32604
+ // we forward, not what an outbound request looks like, so the probe (which
32605
+ // never issues a tools/call) has nothing to reconstruct from it.
32606
+ argRejects: "AGT_REMOTE_MCP_ARG_REJECTS"
32600
32607
  };
32601
32608
  var REMOTE_MCP_AUTH_ENV_KEYS = [
32602
32609
  REMOTE_MCP_PROXY_ENV.tokenVar,
@@ -38934,7 +38934,14 @@ var REMOTE_MCP_PROXY_ENV = {
38934
38934
  authHeader: "AGT_REMOTE_MCP_AUTH_HEADER",
38935
38935
  extraHeaders: "AGT_REMOTE_MCP_EXTRA_HEADERS",
38936
38936
  toolAllowlist: "AGT_REMOTE_MCP_TOOL_ALLOWLIST",
38937
- preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS"
38937
+ preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS",
38938
+ // ENG-8512: per-provider argument rules. A `tools/call` carrying a value we
38939
+ // KNOW the remote accepts and silently ignores is refused before it is
38940
+ // forwarded, rather than returning a 200 that every layer above records as
38941
+ // success. Deliberately NOT in REMOTE_MCP_AUTH_ENV_KEYS: it shapes which calls
38942
+ // we forward, not what an outbound request looks like, so the probe (which
38943
+ // never issues a tools/call) has nothing to reconstruct from it.
38944
+ argRejects: "AGT_REMOTE_MCP_ARG_REJECTS"
38938
38945
  };
38939
38946
  var REMOTE_MCP_AUTH_ENV_KEYS = [
38940
38947
  REMOTE_MCP_PROXY_ENV.tokenVar,
@@ -17,7 +17,14 @@ var REMOTE_MCP_PROXY_ENV = {
17
17
  authHeader: "AGT_REMOTE_MCP_AUTH_HEADER",
18
18
  extraHeaders: "AGT_REMOTE_MCP_EXTRA_HEADERS",
19
19
  toolAllowlist: "AGT_REMOTE_MCP_TOOL_ALLOWLIST",
20
- preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS"
20
+ preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS",
21
+ // ENG-8512: per-provider argument rules. A `tools/call` carrying a value we
22
+ // KNOW the remote accepts and silently ignores is refused before it is
23
+ // forwarded, rather than returning a 200 that every layer above records as
24
+ // success. Deliberately NOT in REMOTE_MCP_AUTH_ENV_KEYS: it shapes which calls
25
+ // we forward, not what an outbound request looks like, so the probe (which
26
+ // never issues a tools/call) has nothing to reconstruct from it.
27
+ argRejects: "AGT_REMOTE_MCP_ARG_REJECTS"
21
28
  };
22
29
  var REMOTE_MCP_AUTH_ENV_KEYS = [
23
30
  REMOTE_MCP_PROXY_ENV.tokenVar,
@@ -67,6 +74,7 @@ var TOKEN_FILE_ENV = REMOTE_MCP_PROXY_ENV.tokenFile;
67
74
  var TOKEN_VAR_ENV = REMOTE_MCP_PROXY_ENV.tokenVar;
68
75
  var ALLOWLIST_ENV = REMOTE_MCP_PROXY_ENV.toolAllowlist;
69
76
  var PREENABLE_ENV = REMOTE_MCP_PROXY_ENV.preEnableToolsets;
77
+ var ARG_REJECTS_ENV = REMOTE_MCP_PROXY_ENV.argRejects;
70
78
  var REMOTE_FETCH_TIMEOUT_MS = 3e4;
71
79
  var remoteUrl = process.env[URL_ENV] ?? "";
72
80
  var tokenFile = process.env[TOKEN_FILE_ENV] ?? "";
@@ -74,6 +82,7 @@ var tokenVar = process.env[TOKEN_VAR_ENV] ?? "";
74
82
  var label = process.env[REMOTE_MCP_PROXY_ENV.label] || tokenVar || "remote-oauth";
75
83
  var toolAllowlist = parseToolAllowlist(process.env[ALLOWLIST_ENV] ?? "");
76
84
  var preEnableToolsets = parsePreEnableToolsets(process.env[PREENABLE_ENV] ?? "");
85
+ var argRejects = parseArgRejects(process.env[ARG_REJECTS_ENV] ?? "");
77
86
  var { authHeader: authHeaderName, extras: extraHeaderSpecs } = readRemoteMcpAuthConfig(process.env);
78
87
  function logErr(msg) {
79
88
  process.stderr.write(`[remote-oauth-proxy:${label}] ${msg}
@@ -183,6 +192,70 @@ function isToolCallBlocked(method, params, allow) {
183
192
  if (name && !allow.has(name)) return { blocked: true, name };
184
193
  return { blocked: false, name };
185
194
  }
195
+ function parseArgRejects(raw) {
196
+ if (!raw || !raw.trim()) return [];
197
+ let parsed;
198
+ try {
199
+ parsed = JSON.parse(raw);
200
+ } catch {
201
+ return [];
202
+ }
203
+ if (!Array.isArray(parsed)) return [];
204
+ const out = [];
205
+ for (const entry of parsed) {
206
+ if (!entry || typeof entry !== "object") continue;
207
+ const e = entry;
208
+ const tool = typeof e["tool"] === "string" ? e["tool"] : "";
209
+ const field = typeof e["field"] === "string" ? e["field"] : "";
210
+ const pattern = typeof e["pattern"] === "string" ? e["pattern"] : "";
211
+ const message = typeof e["message"] === "string" ? e["message"] : "";
212
+ if (!tool || !field || !pattern || !message) continue;
213
+ try {
214
+ out.push({ tool, field, re: new RegExp(pattern), message });
215
+ } catch {
216
+ }
217
+ }
218
+ return out;
219
+ }
220
+ function isToolArgRejected(method, params, rules) {
221
+ const none = { rejected: false, name: "", field: "", message: "" };
222
+ if (rules.length === 0 || method !== "tools/call") return none;
223
+ if (!params || typeof params !== "object") return none;
224
+ const p = params;
225
+ const name = typeof p.name === "string" ? p.name : "";
226
+ if (!name) return none;
227
+ const args = p.arguments;
228
+ if (!args || typeof args !== "object") return none;
229
+ const bag = args;
230
+ for (const rule of rules) {
231
+ if (rule.tool !== name) continue;
232
+ const value = bag[rule.field];
233
+ if (typeof value !== "string") continue;
234
+ if (rule.re.test(value)) {
235
+ return { rejected: true, name, field: rule.field, message: rule.message };
236
+ }
237
+ }
238
+ return none;
239
+ }
240
+ function callRefusal(method, params, allow, rules, label2) {
241
+ const block = isToolCallBlocked(method, params, allow);
242
+ if (block.blocked) {
243
+ return {
244
+ log: `blocked tools/call to non-allowlisted tool "${block.name}"`,
245
+ code: -32601,
246
+ message: `${label2}: tool "${block.name}" is not enabled for this integration`
247
+ };
248
+ }
249
+ const argReject = isToolArgRejected(method, params, rules);
250
+ if (argReject.rejected) {
251
+ return {
252
+ log: `rejected tools/call "${argReject.name}": argument "${argReject.field}" would be silently ignored by the remote`,
253
+ code: -32602,
254
+ message: `${label2}: ${argReject.name} refused - ${argReject.message}`
255
+ };
256
+ }
257
+ return null;
258
+ }
186
259
  function readCurrentToken(file, varName) {
187
260
  let raw;
188
261
  try {
@@ -426,17 +499,16 @@ async function main() {
426
499
  }
427
500
  const isNotification = !("id" in parsed);
428
501
  const id = parsed.id;
429
- if (!isNotification) {
430
- const block = isToolCallBlocked(parsed.method, parsed.params, toolAllowlist);
431
- if (block.blocked) {
432
- logErr(`blocked tools/call to non-allowlisted tool "${block.name}"`);
433
- const task2 = writeReplies([
434
- jsonRpcError(id, -32601, `${label}: tool "${block.name}" is not enabled for this integration`)
435
- ]).catch((err) => logErr(`handler error: ${err.message}`));
436
- inflight.add(task2);
437
- void task2.finally(() => inflight.delete(task2));
438
- return;
439
- }
502
+ const refusal = callRefusal(parsed.method, parsed.params, toolAllowlist, argRejects, label);
503
+ if (refusal) {
504
+ logErr(isNotification ? `${refusal.log} (notification, no reply sent)` : refusal.log);
505
+ if (isNotification) return;
506
+ const task2 = writeReplies([jsonRpcError(id, refusal.code, refusal.message)]).catch(
507
+ (err) => logErr(`handler error: ${err.message}`)
508
+ );
509
+ inflight.add(task2);
510
+ void task2.finally(() => inflight.delete(task2));
511
+ return;
440
512
  }
441
513
  const task = forward(text, id, isNotification, parsed.method, parsed.params).then(writeReplies).catch((err) => {
442
514
  logErr(`handler error: ${err.message}`);
@@ -466,13 +538,16 @@ export {
466
538
  buildEnableToolsetRequest,
467
539
  buildForwardHeaders,
468
540
  buildToolsListRequest,
541
+ callRefusal,
469
542
  extractJsonRpcMessages,
470
543
  extractToolsArray,
471
544
  filterToolsListMessage,
472
545
  forward,
473
546
  isManagedActivationCall,
547
+ isToolArgRejected,
474
548
  isToolCallBlocked,
475
549
  main,
550
+ parseArgRejects,
476
551
  parseEnableToolsetResponse,
477
552
  parseExtraHeaders,
478
553
  parsePreEnableToolsets,
@@ -32818,7 +32818,14 @@ var REMOTE_MCP_PROXY_ENV = {
32818
32818
  authHeader: "AGT_REMOTE_MCP_AUTH_HEADER",
32819
32819
  extraHeaders: "AGT_REMOTE_MCP_EXTRA_HEADERS",
32820
32820
  toolAllowlist: "AGT_REMOTE_MCP_TOOL_ALLOWLIST",
32821
- preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS"
32821
+ preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS",
32822
+ // ENG-8512: per-provider argument rules. A `tools/call` carrying a value we
32823
+ // KNOW the remote accepts and silently ignores is refused before it is
32824
+ // forwarded, rather than returning a 200 that every layer above records as
32825
+ // success. Deliberately NOT in REMOTE_MCP_AUTH_ENV_KEYS: it shapes which calls
32826
+ // we forward, not what an outbound request looks like, so the probe (which
32827
+ // never issues a tools/call) has nothing to reconstruct from it.
32828
+ argRejects: "AGT_REMOTE_MCP_ARG_REJECTS"
32822
32829
  };
32823
32830
  var REMOTE_MCP_AUTH_ENV_KEYS = [
32824
32831
  REMOTE_MCP_PROXY_ENV.tokenVar,
@@ -33144,7 +33144,14 @@ var REMOTE_MCP_PROXY_ENV = {
33144
33144
  authHeader: "AGT_REMOTE_MCP_AUTH_HEADER",
33145
33145
  extraHeaders: "AGT_REMOTE_MCP_EXTRA_HEADERS",
33146
33146
  toolAllowlist: "AGT_REMOTE_MCP_TOOL_ALLOWLIST",
33147
- preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS"
33147
+ preEnableToolsets: "AGT_REMOTE_MCP_PREENABLE_TOOLSETS",
33148
+ // ENG-8512: per-provider argument rules. A `tools/call` carrying a value we
33149
+ // KNOW the remote accepts and silently ignores is refused before it is
33150
+ // forwarded, rather than returning a 200 that every layer above records as
33151
+ // success. Deliberately NOT in REMOTE_MCP_AUTH_ENV_KEYS: it shapes which calls
33152
+ // we forward, not what an outbound request looks like, so the probe (which
33153
+ // never issues a tools/call) has nothing to reconstruct from it.
33154
+ argRejects: "AGT_REMOTE_MCP_ARG_REJECTS"
33148
33155
  };
33149
33156
  var REMOTE_MCP_AUTH_ENV_KEYS = [
33150
33157
  REMOTE_MCP_PROXY_ENV.tokenVar,
@@ -37,7 +37,7 @@ import {
37
37
  writeDirectChatSessionState,
38
38
  writeEgressAllowlist,
39
39
  writePersistentClaudeWrapper
40
- } from "./chunk-4GTDD2I5.js";
40
+ } from "./chunk-LBSV575W.js";
41
41
  import "./chunk-XWVM4KPK.js";
42
42
  export {
43
43
  EGRESS_BASELINE_DOMAINS,
@@ -79,4 +79,4 @@ export {
79
79
  writeEgressAllowlist,
80
80
  writePersistentClaudeWrapper
81
81
  };
82
- //# sourceMappingURL=persistent-session-5GMZKV37.js.map
82
+ //# sourceMappingURL=persistent-session-OT66RBK5.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-4GTDD2I5.js";
3
+ } from "./chunk-LBSV575W.js";
4
4
  import "./chunk-XWVM4KPK.js";
5
5
 
6
6
  // src/lib/responsiveness-probe.ts
@@ -662,4 +662,4 @@ export {
662
662
  readAndResetSlackReplyBindingClassifications,
663
663
  readAndResetSlackReplyTargetClassifications
664
664
  };
665
- //# sourceMappingURL=responsiveness-probe-52IZOP2M.js.map
665
+ //# sourceMappingURL=responsiveness-probe-KW7KQJUY.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.522",
3
+ "version": "0.28.523",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {