@integrity-labs/agt-cli 0.28.7 → 0.28.8

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
@@ -33,7 +33,7 @@ import {
33
33
  success,
34
34
  table,
35
35
  warn
36
- } from "../chunk-QHW6NHCZ.js";
36
+ } from "../chunk-CJSEB2LS.js";
37
37
  import {
38
38
  CHANNEL_REGISTRY,
39
39
  DEPLOYMENT_TEMPLATES,
@@ -4773,7 +4773,7 @@ import { execFileSync, execSync } from "child_process";
4773
4773
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4774
4774
  import chalk18 from "chalk";
4775
4775
  import ora16 from "ora";
4776
- var cliVersion = true ? "0.28.7" : "dev";
4776
+ var cliVersion = true ? "0.28.8" : "dev";
4777
4777
  async function fetchLatestVersion() {
4778
4778
  const host2 = getHost();
4779
4779
  if (!host2) return null;
@@ -5696,7 +5696,7 @@ function handleError(err) {
5696
5696
  }
5697
5697
 
5698
5698
  // src/bin/agt.ts
5699
- var cliVersion2 = true ? "0.28.7" : "dev";
5699
+ var cliVersion2 = true ? "0.28.8" : "dev";
5700
5700
  var program = new Command();
5701
5701
  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");
5702
5702
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -8275,4 +8275,4 @@ export {
8275
8275
  managerInstallSystemUnitCommand,
8276
8276
  managerUninstallSystemUnitCommand
8277
8277
  };
8278
- //# sourceMappingURL=chunk-QHW6NHCZ.js.map
8278
+ //# sourceMappingURL=chunk-CJSEB2LS.js.map
@@ -22,7 +22,7 @@ import {
22
22
  provisionStopHook,
23
23
  requireHost,
24
24
  safeWriteJsonAtomic
25
- } from "../chunk-QHW6NHCZ.js";
25
+ } from "../chunk-CJSEB2LS.js";
26
26
  import {
27
27
  getProjectDir as getProjectDir2,
28
28
  getReadyTasks,
@@ -5083,7 +5083,7 @@ var cachedMaintenanceWindow = null;
5083
5083
  var lastVersionCheckAt = 0;
5084
5084
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
5085
5085
  var lastResponsivenessProbeAt = 0;
5086
- var agtCliVersion = true ? "0.28.7" : "dev";
5086
+ var agtCliVersion = true ? "0.28.8" : "dev";
5087
5087
  function resolveBrewPath(execFileSync4) {
5088
5088
  try {
5089
5089
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -13971,9 +13971,49 @@ function buildImpersonationRefusal(toolName) {
13971
13971
  // src/channel-egress-tools.ts
13972
13972
  var DIRECT_CHAT_EGRESS_TOOLS = /* @__PURE__ */ new Set([
13973
13973
  "direct_chat.reply",
13974
+ "direct_chat.consume",
13974
13975
  "channel_request_input"
13975
13976
  ]);
13976
13977
 
13978
+ // src/direct-chat-claim-tracker.ts
13979
+ var DirectChatClaimTracker = class {
13980
+ bySession = /* @__PURE__ */ new Map();
13981
+ /** Record that `messageId` was claimed for `sessionId` (idempotent). */
13982
+ track(sessionId, messageId) {
13983
+ let set = this.bySession.get(sessionId);
13984
+ if (!set) {
13985
+ set = /* @__PURE__ */ new Set();
13986
+ this.bySession.set(sessionId, set);
13987
+ }
13988
+ set.add(messageId);
13989
+ }
13990
+ /**
13991
+ * The claimed-but-unconsumed message ids for a session, WITHOUT clearing them.
13992
+ * Peek-then-clear-on-success (rather than drain-up-front) so a failed
13993
+ * reply/consume POST doesn't lose the ids — they stay tracked for the retry.
13994
+ */
13995
+ peek(sessionId) {
13996
+ return [...this.bySession.get(sessionId) ?? []];
13997
+ }
13998
+ /**
13999
+ * Clear exactly the given ids for a session (call after a successful
14000
+ * reply/consume). Only the ids actually sent are cleared, so any message
14001
+ * claimed between peek and clear stays tracked for the next turn.
14002
+ */
14003
+ clear(sessionId, ids) {
14004
+ const set = this.bySession.get(sessionId);
14005
+ if (!set) return;
14006
+ for (const id of ids) set.delete(id);
14007
+ if (set.size === 0) this.bySession.delete(sessionId);
14008
+ }
14009
+ /** Total tracked message ids across all sessions (for bounding / diagnostics). */
14010
+ get size() {
14011
+ let n = 0;
14012
+ for (const set of this.bySession.values()) n += set.size;
14013
+ return n;
14014
+ }
14015
+ };
14016
+
13977
14017
  // src/mcp-spawn-lock.ts
13978
14018
  import {
13979
14019
  existsSync,
@@ -14165,10 +14205,12 @@ var mcp = new Server(
14165
14205
  'Messages from the webapp Direct Chat arrive as <channel source="direct-chat" session_id="..." user="...">.',
14166
14206
  "Reply using the direct_chat.reply tool, passing the session_id from the tag.",
14167
14207
  "Always reply to every direct chat message \u2014 the user is waiting in the webapp.",
14208
+ "In the rare case you deliberately handle a message without replying (e.g. an internal command), call direct_chat.consume with the session_id so it is not treated as undelivered and redelivered.",
14168
14209
  "Keep replies concise and helpful. You have full access to all your MCP tools."
14169
14210
  ].join(" ")
14170
14211
  }
14171
14212
  );
14213
+ var claimTracker = new DirectChatClaimTracker();
14172
14214
  mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
14173
14215
  tools: [
14174
14216
  {
@@ -14225,6 +14267,20 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
14225
14267
  },
14226
14268
  required: ["session_id", "content"]
14227
14269
  }
14270
+ },
14271
+ {
14272
+ name: "direct_chat.consume",
14273
+ description: "Acknowledge direct-chat message(s) you handled WITHOUT sending a reply (e.g. a command that only updated state, or a message you deliberately ignored). Pass the session_id from the <channel> tag. If you send a direct_chat.reply you do NOT also need to consume \u2014 the reply already acknowledges the message. Without one of the two, a silently-handled message is treated as undelivered and may be redelivered.",
14274
+ inputSchema: {
14275
+ type: "object",
14276
+ properties: {
14277
+ session_id: {
14278
+ type: "string",
14279
+ description: "Session ID (from the session_id attribute in the <channel> tag)"
14280
+ }
14281
+ },
14282
+ required: ["session_id"]
14283
+ }
14228
14284
  }
14229
14285
  ]
14230
14286
  }));
@@ -14246,11 +14302,13 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
14246
14302
  }
14247
14303
  if (name === "direct_chat.reply") {
14248
14304
  const { session_id, content } = args;
14305
+ const message_ids = claimTracker.peek(session_id);
14249
14306
  try {
14250
14307
  const res = await apiPost("/host/direct-chat/reply", {
14251
14308
  agent_id: AGT_AGENT_ID,
14252
14309
  session_id,
14253
- content
14310
+ content,
14311
+ message_ids
14254
14312
  });
14255
14313
  const data = await res.json();
14256
14314
  if (!res.ok || data.error) {
@@ -14259,6 +14317,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
14259
14317
  isError: true
14260
14318
  };
14261
14319
  }
14320
+ claimTracker.clear(session_id, message_ids);
14262
14321
  return { content: [{ type: "text", text: "sent" }] };
14263
14322
  } catch (err) {
14264
14323
  return {
@@ -14267,6 +14326,34 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
14267
14326
  };
14268
14327
  }
14269
14328
  }
14329
+ if (name === "direct_chat.consume") {
14330
+ const { session_id } = args;
14331
+ const message_ids = claimTracker.peek(session_id);
14332
+ if (message_ids.length === 0) {
14333
+ return { content: [{ type: "text", text: "nothing to consume" }] };
14334
+ }
14335
+ try {
14336
+ const res = await apiPost("/host/direct-chat/consume", {
14337
+ agent_id: AGT_AGENT_ID,
14338
+ session_id,
14339
+ message_ids
14340
+ });
14341
+ const data = await res.json();
14342
+ if (!res.ok || data.error) {
14343
+ return {
14344
+ content: [{ type: "text", text: `Consume failed: ${data.error ?? res.statusText}` }],
14345
+ isError: true
14346
+ };
14347
+ }
14348
+ claimTracker.clear(session_id, message_ids);
14349
+ return { content: [{ type: "text", text: "consumed" }] };
14350
+ } catch (err) {
14351
+ return {
14352
+ content: [{ type: "text", text: `Failed: ${err.message}` }],
14353
+ isError: true
14354
+ };
14355
+ }
14356
+ }
14270
14357
  throw new Error(`Unknown tool: ${name}`);
14271
14358
  });
14272
14359
  await mcp.connect(new StdioServerTransport());
@@ -14285,6 +14372,7 @@ async function pollForMessages() {
14285
14372
  const ids = [...processedIds];
14286
14373
  for (let i = 0; i < 250; i++) processedIds.delete(ids[i]);
14287
14374
  }
14375
+ claimTracker.track(msg.session_id, msg.id);
14288
14376
  await mcp.notification({
14289
14377
  method: "notifications/claude/channel",
14290
14378
  params: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.7",
3
+ "version": "0.28.8",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {