@integrity-labs/agt-cli 0.28.574 → 0.28.576

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/bin/agt.js CHANGED
@@ -40,7 +40,7 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-PKBAJMBG.js";
43
+ } from "../chunk-P2LAQMRN.js";
44
44
  import {
45
45
  AnchorSessionClient,
46
46
  CHANNEL_REGISTRY,
@@ -4853,7 +4853,7 @@ import { execFileSync, execSync } from "child_process";
4853
4853
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4854
4854
  import chalk18 from "chalk";
4855
4855
  import ora16 from "ora";
4856
- var cliVersion = true ? "0.28.574" : "dev";
4856
+ var cliVersion = true ? "0.28.576" : "dev";
4857
4857
  async function fetchLatestVersion() {
4858
4858
  const host2 = getHost();
4859
4859
  if (!host2) return null;
@@ -6031,7 +6031,7 @@ function handleError(err) {
6031
6031
  }
6032
6032
 
6033
6033
  // src/bin/agt.ts
6034
- var cliVersion2 = true ? "0.28.574" : "dev";
6034
+ var cliVersion2 = true ? "0.28.576" : "dev";
6035
6035
  var program = new Command();
6036
6036
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
6037
6037
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -5646,7 +5646,7 @@ function exchangeFailureKind(err) {
5646
5646
  }
5647
5647
 
5648
5648
  // src/lib/api-client.ts
5649
- var agtCliVersion = true ? "0.28.574" : "dev";
5649
+ var agtCliVersion = true ? "0.28.576" : "dev";
5650
5650
  var lastConfigHash = null;
5651
5651
  function setConfigHash(hash) {
5652
5652
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -9015,4 +9015,4 @@ export {
9015
9015
  managerInstallSystemUnitCommand,
9016
9016
  managerUninstallSystemUnitCommand
9017
9017
  };
9018
- //# sourceMappingURL=chunk-PKBAJMBG.js.map
9018
+ //# sourceMappingURL=chunk-P2LAQMRN.js.map
@@ -53,7 +53,7 @@ import {
53
53
  safeWriteJsonAtomic,
54
54
  setConfigHash,
55
55
  tripClass
56
- } from "../chunk-PKBAJMBG.js";
56
+ } from "../chunk-P2LAQMRN.js";
57
57
  import {
58
58
  getProjectDir as getProjectDir2,
59
59
  getReadyTasks,
@@ -11596,7 +11596,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
11596
11596
  var lastVersionCheckAt = 0;
11597
11597
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
11598
11598
  var lastResponsivenessProbeAt = 0;
11599
- var agtCliVersion = true ? "0.28.574" : "dev";
11599
+ var agtCliVersion = true ? "0.28.576" : "dev";
11600
11600
  function resolveBrewPath(execFileSync2) {
11601
11601
  try {
11602
11602
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
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([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.574",
3
+ "version": "0.28.576",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {