@integrity-labs/agt-cli 0.28.64 → 0.28.65

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
@@ -37,7 +37,7 @@ import {
37
37
  success,
38
38
  table,
39
39
  warn
40
- } from "../chunk-JY3LAHBG.js";
40
+ } from "../chunk-PZ3TJOW4.js";
41
41
  import {
42
42
  CHANNEL_REGISTRY,
43
43
  DEPLOYMENT_TEMPLATES,
@@ -4777,7 +4777,7 @@ import { execFileSync, execSync } from "child_process";
4777
4777
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4778
4778
  import chalk18 from "chalk";
4779
4779
  import ora16 from "ora";
4780
- var cliVersion = true ? "0.28.64" : "dev";
4780
+ var cliVersion = true ? "0.28.65" : "dev";
4781
4781
  async function fetchLatestVersion() {
4782
4782
  const host2 = getHost();
4783
4783
  if (!host2) return null;
@@ -5791,7 +5791,7 @@ function handleError(err) {
5791
5791
  }
5792
5792
 
5793
5793
  // src/bin/agt.ts
5794
- var cliVersion2 = true ? "0.28.64" : "dev";
5794
+ var cliVersion2 = true ? "0.28.65" : "dev";
5795
5795
  var program = new Command();
5796
5796
  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");
5797
5797
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -7347,7 +7347,7 @@ function requireHost() {
7347
7347
  }
7348
7348
 
7349
7349
  // src/lib/api-client.ts
7350
- var agtCliVersion = true ? "0.28.64" : "dev";
7350
+ var agtCliVersion = true ? "0.28.65" : "dev";
7351
7351
  var lastConfigHash = null;
7352
7352
  function setConfigHash(hash) {
7353
7353
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -8643,4 +8643,4 @@ export {
8643
8643
  managerInstallSystemUnitCommand,
8644
8644
  managerUninstallSystemUnitCommand
8645
8645
  };
8646
- //# sourceMappingURL=chunk-JY3LAHBG.js.map
8646
+ //# sourceMappingURL=chunk-PZ3TJOW4.js.map
@@ -27,7 +27,7 @@ import {
27
27
  requireHost,
28
28
  safeWriteJsonAtomic,
29
29
  setConfigHash
30
- } from "../chunk-JY3LAHBG.js";
30
+ } from "../chunk-PZ3TJOW4.js";
31
31
  import {
32
32
  getProjectDir as getProjectDir2,
33
33
  getReadyTasks,
@@ -6734,7 +6734,7 @@ var cachedMaintenanceWindow = null;
6734
6734
  var lastVersionCheckAt = 0;
6735
6735
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6736
6736
  var lastResponsivenessProbeAt = 0;
6737
- var agtCliVersion = true ? "0.28.64" : "dev";
6737
+ var agtCliVersion = true ? "0.28.65" : "dev";
6738
6738
  function resolveBrewPath(execFileSync4) {
6739
6739
  try {
6740
6740
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
package/dist/mcp/index.js CHANGED
@@ -21078,6 +21078,129 @@ function writeAgentRestartFlag(codeName, reason, nowMs) {
21078
21078
  return path;
21079
21079
  }
21080
21080
 
21081
+ // src/approval-tools.ts
21082
+ function statusToOutcome(status) {
21083
+ switch (status) {
21084
+ case "active":
21085
+ case "auto_approve":
21086
+ return "approved";
21087
+ case "denied":
21088
+ case "hard_deny":
21089
+ return "denied";
21090
+ case "expired":
21091
+ return "timed_out";
21092
+ case "cancelled":
21093
+ case "revoked":
21094
+ return "cancelled";
21095
+ case "pending":
21096
+ return "pending";
21097
+ default:
21098
+ return "error";
21099
+ }
21100
+ }
21101
+ function render(result) {
21102
+ const lines = [result.note ?? "", JSON.stringify({
21103
+ request_id: result.request_id,
21104
+ outcome: result.outcome,
21105
+ ...result.reason ? { reason: result.reason } : {},
21106
+ ...result.result_payload != null ? { result_payload: result.result_payload } : {},
21107
+ ...result.expires_at ? { expires_at: result.expires_at } : {}
21108
+ })].filter(Boolean);
21109
+ return { content: [{ type: "text", text: lines.join("\n") }] };
21110
+ }
21111
+ function registerApprovalTools(server2, deps) {
21112
+ const { agentId, apiPost: apiPost2, apiGet: apiGet2 } = deps;
21113
+ server2.tool(
21114
+ "request_approval",
21115
+ "Ask a human (your Manager) to approve an action before you take it, then END YOUR TURN \u2014 this does NOT block your session. You get back a request_id; later call check_approval(request_id) to see the verdict (it survives a restart \u2014 re-attach by the same id). NOTIFY-ONLY: on approval the platform does nothing \u2014 YOU perform the action. Use for actions outside your standing authority where a person must sign off.",
21116
+ {
21117
+ summary: external_exports.string().min(1).max(280).describe('One line describing the action you want approved (shown to the approver). E.g. "Send the Q3 report to the external auditor".'),
21118
+ reason: external_exports.string().min(1).max(280).describe("Why you need it / context for the approver. Keep it specific."),
21119
+ idempotency_key: external_exports.string().min(1).max(200).describe("A stable exactly-once key YOU choose for this ask (e.g. a task id + action). Retrying with the same key + same details re-attaches to the same request instead of filing a duplicate."),
21120
+ detail: external_exports.record(external_exports.unknown()).optional().describe("Optional structured context for the approver (display + audit only; never executed)."),
21121
+ ttl_seconds: external_exports.number().int().optional().describe("How long the request stays open before it times out (default 3600; clamped to [60, 86400]).")
21122
+ },
21123
+ async (params) => {
21124
+ try {
21125
+ const resp = await apiPost2("/approvals", {
21126
+ agent_id: agentId,
21127
+ summary: params.summary,
21128
+ reason: params.reason,
21129
+ idempotency_key: params.idempotency_key,
21130
+ detail: params.detail,
21131
+ ttl_seconds: params.ttl_seconds
21132
+ });
21133
+ const outcome = resp.outcome ?? statusToOutcome(resp.status);
21134
+ const note = resp.duplicate ? `An open request for this idempotency_key already exists \u2014 re-attached to it (request_id ${resp.request_id}). Poll it with check_approval.` : resp.notification_status === "failed" ? `Approval filed (request_id ${resp.request_id}) but the Manager notification failed (${resp.notification_failure_reason ?? "unknown"}) \u2014 tell your operator. Poll with check_approval.` : `Approval requested (request_id ${resp.request_id}). Your Manager was notified. End your turn; poll with check_approval later.`;
21135
+ return render({ request_id: resp.request_id, outcome, expires_at: resp.expires_at ?? null, note });
21136
+ } catch (err) {
21137
+ const msg = err instanceof Error ? err.message : String(err);
21138
+ return {
21139
+ content: [
21140
+ {
21141
+ type: "text",
21142
+ text: `Could not file the approval request: ${msg}
21143
+ ` + JSON.stringify({ request_id: "", outcome: "error", reason: msg })
21144
+ }
21145
+ ],
21146
+ isError: true
21147
+ };
21148
+ }
21149
+ }
21150
+ );
21151
+ server2.tool(
21152
+ "check_approval",
21153
+ "Check the verdict on an approval you requested earlier (by request_id from request_approval). Returns one of: approved | denied | timed_out | cancelled | pending | error. While 'pending', do nothing and check again later. Safe to call after a restart \u2014 the request is durable and you re-attach by id.",
21154
+ {
21155
+ request_id: external_exports.string().min(1).describe("The request_id returned by request_approval.")
21156
+ },
21157
+ async (params) => {
21158
+ try {
21159
+ const resp = await apiGet2(
21160
+ `/approvals/${encodeURIComponent(params.request_id)}?agent_id=${encodeURIComponent(agentId)}`
21161
+ );
21162
+ return render({
21163
+ request_id: resp.request_id,
21164
+ outcome: resp.outcome,
21165
+ reason: resp.reason,
21166
+ result_payload: resp.result_payload,
21167
+ expires_at: resp.expires_at
21168
+ });
21169
+ } catch (err) {
21170
+ const msg = err instanceof Error ? err.message : String(err);
21171
+ return {
21172
+ content: [{ type: "text", text: `Could not check approval ${params.request_id}: ${msg}` }],
21173
+ isError: true
21174
+ };
21175
+ }
21176
+ }
21177
+ );
21178
+ server2.tool(
21179
+ "cancel_approval",
21180
+ "Withdraw an approval request you no longer need (only works while it is still pending). The Manager stops being asked. Use when the underlying need went away.",
21181
+ {
21182
+ request_id: external_exports.string().min(1).describe("The request_id to withdraw."),
21183
+ reason: external_exports.string().max(280).optional().describe("Optional short note on why you are withdrawing.")
21184
+ },
21185
+ async (params) => {
21186
+ try {
21187
+ const resp = await apiPost2(
21188
+ `/approvals/${encodeURIComponent(params.request_id)}/cancel`,
21189
+ { agent_id: agentId, reason: params.reason ?? "" }
21190
+ );
21191
+ const note = resp.outcome === "cancelled" ? `Withdrew approval request ${resp.request_id}.` : `Could not withdraw \u2014 the request is already ${resp.status}.`;
21192
+ return render({ request_id: resp.request_id, outcome: resp.outcome, note });
21193
+ } catch (err) {
21194
+ const msg = err instanceof Error ? err.message : String(err);
21195
+ return {
21196
+ content: [{ type: "text", text: `Could not cancel approval ${params.request_id}: ${msg}` }],
21197
+ isError: true
21198
+ };
21199
+ }
21200
+ }
21201
+ );
21202
+ }
21203
+
21081
21204
  // src/index.ts
21082
21205
  import { spawn } from "child_process";
21083
21206
  var DeliveryTargetSchema = external_exports.union([
@@ -21198,10 +21321,47 @@ async function apiPost(path, body, retried = false, timeoutMs = 15e3) {
21198
21321
  clearTimeout(timeout);
21199
21322
  }
21200
21323
  }
21324
+ async function apiGet(path, retried = false, timeoutMs = 15e3) {
21325
+ const token = await getToken();
21326
+ const controller = new AbortController();
21327
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
21328
+ try {
21329
+ const res = await fetch(`${AGT_HOST}${path}`, {
21330
+ method: "GET",
21331
+ headers: { Authorization: `Bearer ${token}` },
21332
+ signal: controller.signal
21333
+ });
21334
+ if (res.status === 401 && AGT_API_KEY && !AGT_AGENT_SESSION_TOKEN && !retried) {
21335
+ clearTimeout(timeout);
21336
+ tokenExpiresAt = 0;
21337
+ return apiGet(path, true, timeoutMs);
21338
+ }
21339
+ if (!res.ok) {
21340
+ const text = await res.text().catch(() => res.statusText);
21341
+ if (res.status === 401 && AGT_AGENT_SESSION_TOKEN) {
21342
+ throw new Error(
21343
+ `API ${path} returned 401: agent-session rejected (expired or revoked). Re-run \`agt impersonate connect\` to mint a fresh session. (${text})`
21344
+ );
21345
+ }
21346
+ throw new Error(`API ${path} returned ${res.status}: ${text}`);
21347
+ }
21348
+ return await res.json();
21349
+ } catch (err) {
21350
+ if (err instanceof DOMException && err.name === "AbortError") {
21351
+ throw new Error(`API ${path} timed out after ${timeoutMs}ms`);
21352
+ }
21353
+ throw err;
21354
+ } finally {
21355
+ clearTimeout(timeout);
21356
+ }
21357
+ }
21201
21358
  var server = new McpServer({
21202
21359
  name: "augmented",
21203
21360
  version: "0.1.0"
21204
21361
  });
21362
+ if (AGT_AGENT_ID) {
21363
+ registerApprovalTools(server, { agentId: AGT_AGENT_ID, apiPost, apiGet });
21364
+ }
21205
21365
  server.tool(
21206
21366
  "kanban_list",
21207
21367
  'List kanban board items for this agent. Returns active items plus only the most recently completed work (last 24h). This is a NARROW, recency-windowed view \u2014 older done cards are NOT here (only done cards are windowed; failed and active cards always show). Before telling anyone you have "no record" of past work, use kanban_search, which covers your full history.',
@@ -22387,6 +22547,10 @@ async function forwardToolCall(toolName, args) {
22387
22547
  );
22388
22548
  }
22389
22549
  var LOCAL_TOOL_NAMES = /* @__PURE__ */ new Set([
22550
+ // ENG-6452: generic agent-approval seam (always registered locally).
22551
+ "request_approval",
22552
+ "check_approval",
22553
+ "cancel_approval",
22390
22554
  "kanban_list",
22391
22555
  "kanban_search",
22392
22556
  "kanban_add",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.64",
3
+ "version": "0.28.65",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {