@integrity-labs/agt-cli 0.28.573 → 0.28.575

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/mcp/index.js CHANGED
@@ -21045,6 +21045,112 @@ function jsonSchemaPropertyToZod(prop) {
21045
21045
  return external_exports.unknown();
21046
21046
  }
21047
21047
 
21048
+ // src/mutation-commit-state.ts
21049
+ var API_GATEWAY_INTEGRATION_TIMEOUT_MS = 29e3;
21050
+ var GATEWAY_TIMEOUT_MARGIN_MS = 3e3;
21051
+ var FORWARD_TOOL_CALL_TIMEOUT_MS = API_GATEWAY_INTEGRATION_TIMEOUT_MS - GATEWAY_TIMEOUT_MARGIN_MS;
21052
+ function isGatewayShapedBody(body) {
21053
+ if (!body) return false;
21054
+ let parsed;
21055
+ try {
21056
+ parsed = JSON.parse(body);
21057
+ } catch {
21058
+ return false;
21059
+ }
21060
+ if (typeof parsed !== "object" || parsed === null) return false;
21061
+ const obj = parsed;
21062
+ return typeof obj["message"] === "string" && !("error" in obj);
21063
+ }
21064
+ function classifyMutationCommitState(input) {
21065
+ const { status, body, aborted: aborted2 } = input;
21066
+ if (aborted2) return "indeterminate";
21067
+ if (status === null) return "indeterminate";
21068
+ if (status >= 200 && status < 300) return "committed";
21069
+ if (isGatewayShapedBody(body)) return "indeterminate";
21070
+ if (status === 401 || status === 403) return "not_committed";
21071
+ if (status >= 400 && status < 500) {
21072
+ return isOurErrorEnvelope(body) ? "not_committed" : "indeterminate";
21073
+ }
21074
+ return "indeterminate";
21075
+ }
21076
+ function isOurErrorEnvelope(body) {
21077
+ if (!body) return false;
21078
+ try {
21079
+ const parsed = JSON.parse(body);
21080
+ if (typeof parsed !== "object" || parsed === null) return false;
21081
+ return typeof parsed["error"] === "string";
21082
+ } catch {
21083
+ return false;
21084
+ }
21085
+ }
21086
+ var READONLY_VERB_TOKENS = ["LIST", "GET", "FIND", "SEARCH", "FETCH", "COUNT", "RETRIEVE"];
21087
+ var MUTATING_VERB_TOKENS = [
21088
+ "CREATE",
21089
+ "ADD",
21090
+ "UPDATE",
21091
+ "PATCH",
21092
+ "SET",
21093
+ "EDIT",
21094
+ "WRITE",
21095
+ "PUT",
21096
+ "POST",
21097
+ "DELETE",
21098
+ "REMOVE",
21099
+ "CLEAR",
21100
+ "ARCHIVE",
21101
+ "PURGE",
21102
+ "DROP",
21103
+ "SEND",
21104
+ "REPLY",
21105
+ "PUBLISH",
21106
+ "UPLOAD",
21107
+ "EMAIL",
21108
+ "NOTIFY",
21109
+ "INVITE",
21110
+ "MOVE",
21111
+ "ASSIGN",
21112
+ "REASSIGN",
21113
+ "MARK",
21114
+ "CLOSE",
21115
+ "OPEN",
21116
+ "START",
21117
+ "STOP",
21118
+ "CANCEL",
21119
+ "APPROVE",
21120
+ "REJECT",
21121
+ "MERGE",
21122
+ "RESTART",
21123
+ "RECALL",
21124
+ "PROPOSE"
21125
+ ];
21126
+ function mayMutate(toolName) {
21127
+ if (!toolName) return true;
21128
+ const tokens = toolName.toUpperCase().split(/[^A-Z0-9]+/).filter(Boolean);
21129
+ if (tokens.length === 0) return true;
21130
+ if (tokens.some((t) => MUTATING_VERB_TOKENS.includes(t))) return true;
21131
+ const verbCandidates = [tokens[0], tokens[1]].filter((t) => Boolean(t));
21132
+ return !verbCandidates.some((t) => READONLY_VERB_TOKENS.includes(t));
21133
+ }
21134
+ function describeToolCallFailure(params) {
21135
+ const { path, toolName, readOnly, state, status, body, aborted: aborted2, timeoutMs } = params;
21136
+ const what = aborted2 ? `API ${path} did not respond within ${timeoutMs}ms` : `API ${path} returned ${status}`;
21137
+ const detail = body ? `: ${truncate(body, 400)}` : "";
21138
+ if (state === "not_committed") {
21139
+ return `${what}${detail} \u2014 the request was rejected before it took effect, so nothing changed. Safe to retry once the cause is fixed.`;
21140
+ }
21141
+ if (state === "committed") {
21142
+ return `${what}${detail} \u2014 the server ACCEPTED this operation (it responded successfully); only the reply could not be read. The effect has landed, so do NOT retry \u2014 re-read the state if you need the result.`;
21143
+ }
21144
+ const tool = toolName ? `'${toolName}'` : "this call";
21145
+ if (!readOnly && mayMutate(toolName)) {
21146
+ return `${what}${detail} \u2014 INDETERMINATE: the server may have completed this operation before the failure. ${tool} is not a read-only tool, so retrying it could duplicate the effect (a second write, a second send). Re-read the relevant state to establish what actually happened BEFORE retrying. An error from this bridge is not evidence the operation did not occur.`;
21147
+ }
21148
+ return `${what}${detail} \u2014 INDETERMINATE: the server may have completed this operation before the failure. ${tool} is read-only, so retrying is safe.`;
21149
+ }
21150
+ function truncate(text, max) {
21151
+ return text.length > max ? `${text.slice(0, max)}\u2026` : text;
21152
+ }
21153
+
21048
21154
  // src/kanban-list-render.ts
21049
21155
  var KANBAN_LIST_DISPLAY_ORDER = [
21050
21156
  "in_progress",
@@ -21980,7 +22086,7 @@ async function getToken() {
21980
22086
  }
21981
22087
  return AGT_TOKEN;
21982
22088
  }
21983
- async function apiPost(path, body, retried = false, timeoutMs = 15e3) {
22089
+ async function apiPost(path, body, retried = false, timeoutMs = 15e3, toolName, readOnly = false) {
21984
22090
  const token = await getToken();
21985
22091
  const controller = new AbortController();
21986
22092
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
@@ -21997,7 +22103,7 @@ async function apiPost(path, body, retried = false, timeoutMs = 15e3) {
21997
22103
  if (res.status === 401 && AGT_API_KEY && !AGT_AGENT_SESSION_TOKEN && !retried) {
21998
22104
  clearTimeout(timeout);
21999
22105
  tokenExpiresAt = 0;
22000
- return apiPost(path, body, true, timeoutMs);
22106
+ return apiPost(path, body, true, timeoutMs, toolName, readOnly);
22001
22107
  }
22002
22108
  if (!res.ok) {
22003
22109
  const text = await res.text().catch(() => res.statusText);
@@ -22006,12 +22112,55 @@ async function apiPost(path, body, retried = false, timeoutMs = 15e3) {
22006
22112
  `API ${path} returned 401: agent-session rejected (expired or revoked). Re-run \`agt impersonate connect\` to mint a fresh session. (${text})`
22007
22113
  );
22008
22114
  }
22009
- throw new Error(`API ${path} returned ${res.status}: ${text}`);
22115
+ throw new Error(
22116
+ describeToolCallFailure({
22117
+ path,
22118
+ toolName,
22119
+ readOnly,
22120
+ state: classifyMutationCommitState({ status: res.status, body: text }),
22121
+ status: res.status,
22122
+ body: text
22123
+ })
22124
+ );
22125
+ }
22126
+ try {
22127
+ return await res.json();
22128
+ } catch {
22129
+ throw new Error(
22130
+ describeToolCallFailure({
22131
+ path,
22132
+ toolName,
22133
+ state: "committed",
22134
+ status: res.status,
22135
+ body: "response body was not valid JSON"
22136
+ })
22137
+ );
22010
22138
  }
22011
- return await res.json();
22012
22139
  } catch (err) {
22013
22140
  if (err instanceof DOMException && err.name === "AbortError") {
22014
- throw new Error(`API ${path} timed out after ${timeoutMs}ms`);
22141
+ throw new Error(
22142
+ describeToolCallFailure({
22143
+ path,
22144
+ toolName,
22145
+ readOnly,
22146
+ state: "indeterminate",
22147
+ status: null,
22148
+ aborted: true,
22149
+ timeoutMs
22150
+ })
22151
+ );
22152
+ }
22153
+ if (err instanceof Error && !/^API /.test(err.message)) {
22154
+ throw new Error(
22155
+ describeToolCallFailure({
22156
+ path,
22157
+ toolName,
22158
+ readOnly,
22159
+ state: classifyMutationCommitState({ status: null }),
22160
+ status: null,
22161
+ body: err.message
22162
+ })
22163
+ );
22015
22164
  }
22016
22165
  throw err;
22017
22166
  } finally {
@@ -24196,7 +24345,6 @@ async function discoverApiTools() {
24196
24345
  return [];
24197
24346
  }
24198
24347
  }
24199
- var FORWARD_TOOL_CALL_TIMEOUT_MS = 35e3;
24200
24348
  async function forwardToolCall(toolName, args) {
24201
24349
  if (!AGT_AGENT_ID) {
24202
24350
  throw new Error("Cannot forward tool call: AGT_AGENT_ID is not set");
@@ -24210,7 +24358,8 @@ async function forwardToolCall(toolName, args) {
24210
24358
  run_id: AGT_RUN_ID ?? null
24211
24359
  },
24212
24360
  false,
24213
- FORWARD_TOOL_CALL_TIMEOUT_MS
24361
+ FORWARD_TOOL_CALL_TIMEOUT_MS,
24362
+ toolName
24214
24363
  );
24215
24364
  }
24216
24365
  var LOCAL_TOOL_NAMES = /* @__PURE__ */ new Set([
@@ -41,7 +41,7 @@ import {
41
41
  writeDirectChatSessionState,
42
42
  writeEgressAllowlist,
43
43
  writePersistentClaudeWrapper
44
- } from "./chunk-5Z6RJ3RX.js";
44
+ } from "./chunk-E3KBX3UW.js";
45
45
  import "./chunk-XWVM4KPK.js";
46
46
  export {
47
47
  EGRESS_BASELINE_DOMAINS,
@@ -87,4 +87,4 @@ export {
87
87
  writeEgressAllowlist,
88
88
  writePersistentClaudeWrapper
89
89
  };
90
- //# sourceMappingURL=persistent-session-6UGFGI6J.js.map
90
+ //# sourceMappingURL=persistent-session-2ESCLFCK.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-5Z6RJ3RX.js";
3
+ } from "./chunk-E3KBX3UW.js";
4
4
  import "./chunk-XWVM4KPK.js";
5
5
 
6
6
  // src/lib/responsiveness-probe.ts
@@ -689,4 +689,4 @@ export {
689
689
  readAndResetSlackReplyBindingClassifications,
690
690
  readAndResetSlackReplyTargetClassifications
691
691
  };
692
- //# sourceMappingURL=responsiveness-probe-O7AVC73R.js.map
692
+ //# sourceMappingURL=responsiveness-probe-YCUDUCAS.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.573",
3
+ "version": "0.28.575",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {