@integrity-labs/agt-cli 0.28.140 → 0.28.142

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.
@@ -22,7 +22,7 @@ import {
22
22
  resolveConnectivityProbe,
23
23
  worseConnectivityOutcome,
24
24
  wrapScheduledTaskPrompt
25
- } from "./chunk-WI6HYZ7K.js";
25
+ } from "./chunk-HKKV7NJD.js";
26
26
 
27
27
  // ../../packages/core/dist/integrations/registry.js
28
28
  var INTEGRATION_REGISTRY = [
@@ -7746,7 +7746,7 @@ function requireHost() {
7746
7746
  }
7747
7747
 
7748
7748
  // src/lib/api-client.ts
7749
- var agtCliVersion = true ? "0.28.140" : "dev";
7749
+ var agtCliVersion = true ? "0.28.142" : "dev";
7750
7750
  var lastConfigHash = null;
7751
7751
  function setConfigHash(hash) {
7752
7752
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -9043,4 +9043,4 @@ export {
9043
9043
  managerInstallSystemUnitCommand,
9044
9044
  managerUninstallSystemUnitCommand
9045
9045
  };
9046
- //# sourceMappingURL=chunk-3R2XOKXQ.js.map
9046
+ //# sourceMappingURL=chunk-OXKVXJRT.js.map
@@ -3,7 +3,7 @@ import {
3
3
  formatMissingVar,
4
4
  isClaudeFastMode,
5
5
  probeMcpEnvSubstitution
6
- } from "./chunk-WI6HYZ7K.js";
6
+ } from "./chunk-HKKV7NJD.js";
7
7
  import {
8
8
  reapOrphanChannelMcps
9
9
  } from "./chunk-XWVM4KPK.js";
@@ -1589,4 +1589,4 @@ export {
1589
1589
  stopAllSessionsAndWait,
1590
1590
  getProjectDir
1591
1591
  };
1592
- //# sourceMappingURL=chunk-6GNDRA3F.js.map
1592
+ //# sourceMappingURL=chunk-UVCPJVEF.js.map
@@ -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-BRGQGGZY.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-N4KR5IFC.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-CSTESL6B.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-SBATMO4Y.js.map
@@ -28,7 +28,7 @@ import {
28
28
  requireHost,
29
29
  safeWriteJsonAtomic,
30
30
  setConfigHash
31
- } from "../chunk-3R2XOKXQ.js";
31
+ } from "../chunk-OXKVXJRT.js";
32
32
  import {
33
33
  getProjectDir as getProjectDir2,
34
34
  getReadyTasks,
@@ -72,7 +72,7 @@ import {
72
72
  takeZombieDetection,
73
73
  transcriptActivityAgeSeconds,
74
74
  writeEgressAllowlist
75
- } from "../chunk-6GNDRA3F.js";
75
+ } from "../chunk-UVCPJVEF.js";
76
76
  import {
77
77
  FLAGS_SCHEMA_VERSION,
78
78
  FLAG_REGISTRY,
@@ -110,7 +110,7 @@ import {
110
110
  resolveDmTarget,
111
111
  sumTranscriptUsageInWindow,
112
112
  wrapScheduledTaskPrompt
113
- } from "../chunk-WI6HYZ7K.js";
113
+ } from "../chunk-HKKV7NJD.js";
114
114
  import {
115
115
  parsePsRows,
116
116
  reapOrphanChannelMcps
@@ -7092,7 +7092,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
7092
7092
  var lastVersionCheckAt = 0;
7093
7093
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
7094
7094
  var lastResponsivenessProbeAt = 0;
7095
- var agtCliVersion = true ? "0.28.140" : "dev";
7095
+ var agtCliVersion = true ? "0.28.142" : "dev";
7096
7096
  function resolveBrewPath(execFileSync4) {
7097
7097
  try {
7098
7098
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -8225,7 +8225,7 @@ async function pollCycle() {
8225
8225
  }
8226
8226
  try {
8227
8227
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
8228
- const { collectDiagnostics } = await import("../persistent-session-BRGQGGZY.js");
8228
+ const { collectDiagnostics } = await import("../persistent-session-N4KR5IFC.js");
8229
8229
  const diagCodeNames = [...agentState.persistentSessionAgents];
8230
8230
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
8231
8231
  let tailscaleHostname;
@@ -8373,7 +8373,7 @@ async function pollCycle() {
8373
8373
  const {
8374
8374
  collectResponsivenessProbes,
8375
8375
  getResponsivenessIntervalMs
8376
- } = await import("../responsiveness-probe-RZYQMCM3.js");
8376
+ } = await import("../responsiveness-probe-MYFNFOB7.js");
8377
8377
  const probeIntervalMs = getResponsivenessIntervalMs();
8378
8378
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
8379
8379
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -8405,7 +8405,7 @@ async function pollCycle() {
8405
8405
  collectResponsivenessProbes,
8406
8406
  livePendingInboundOldestAgeSeconds,
8407
8407
  parkPendingInbound
8408
- } = await import("../responsiveness-probe-RZYQMCM3.js");
8408
+ } = await import("../responsiveness-probe-MYFNFOB7.js");
8409
8409
  const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
8410
8410
  const wedgeNow = /* @__PURE__ */ new Date();
8411
8411
  const liveAgents = agentState.persistentSessionAgents;
@@ -11993,7 +11993,7 @@ async function processClaudePairSessions(agents) {
11993
11993
  killPairSession,
11994
11994
  pairTmuxSession,
11995
11995
  finalizeClaudePairOnboarding
11996
- } = await import("../claude-pair-runtime-CSTESL6B.js");
11996
+ } = await import("../claude-pair-runtime-SBATMO4Y.js");
11997
11997
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
11998
11998
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
11999
11999
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -13975,6 +13975,64 @@ var DIRECT_CHAT_EGRESS_TOOLS = /* @__PURE__ */ new Set([
13975
13975
  "channel_request_input"
13976
13976
  ]);
13977
13977
 
13978
+ // src/strip-repost-preamble.ts
13979
+ var PRIOR_ATTEMPT_CUE = /\b(a moment ago|just now|a second ago|earlier|moments ago|previously|last (?:time|attempt)|drafted|dialled|dialed|typed|composed|wrote|sent) (?:this|that|it)?\b|\b(?:drafted|dialled|dialed|typed|composed)\b/i;
13980
+ var FAILURE_CUE = /\b(?:did(?:n['’]t| not)|could(?:n['’]t| not)|would(?:n['’]t| not)|wasn['’]t|fail(?:ed)?|never)\b[^.!?\n]*?\b(?:parse[d]?|send|sent|go through|went through|land|deliver(?:ed)?|post(?:ed)?|come through|came through)\b/i;
13981
+ var REPOST_CUE = /\b(?:re-?post(?:ing)?|re-?send(?:ing)?|re-?sending|post(?:ing)?|send(?:ing)?|trying|sharing)\b[^.!?\n]*?\b(?:it|this|that|again|now|once more)\b|\bhere(?:['’]s| it is| is the)[^.!?\n]*?\bagain\b/i;
13982
+ function isRepostPreamble(fragment) {
13983
+ const hasRepost = REPOST_CUE.test(fragment);
13984
+ if (!hasRepost) return false;
13985
+ return FAILURE_CUE.test(fragment) || PRIOR_ATTEMPT_CUE.test(fragment);
13986
+ }
13987
+ function trimLeadingSeparators(s) {
13988
+ return s.replace(/^[\s]*[—–\-:.,;]+[\s]*/, "").replace(/^\s+/, "");
13989
+ }
13990
+ function stripRepostPreambleWithMeta(text) {
13991
+ if (!text) return { text, stripped: false, shape: null };
13992
+ const leading = text.replace(/^\s+/, "");
13993
+ if (leading.startsWith("(")) {
13994
+ const close = leading.indexOf(")");
13995
+ if (close > 0) {
13996
+ const inner = leading.slice(1, close);
13997
+ if (isRepostPreamble(inner)) {
13998
+ const rest = trimLeadingSeparators(leading.slice(close + 1));
13999
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "parenthetical" };
14000
+ }
14001
+ }
14002
+ }
14003
+ const runOn = leading.match(
14004
+ /^([^.!?\n]*?\b(?:again|now|once more)\b)[\s—–\-:.,;]+/i
14005
+ );
14006
+ if (runOn?.[1] && isRepostPreamble(runOn[1])) {
14007
+ const rest = trimLeadingSeparators(leading.slice(runOn[0].length));
14008
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "sentence" };
14009
+ }
14010
+ const boundary = leading.search(/[.!?\n]/);
14011
+ if (boundary > 0) {
14012
+ const fragment = leading.slice(0, boundary + 1);
14013
+ if (isRepostPreamble(fragment)) {
14014
+ const rest = trimLeadingSeparators(leading.slice(boundary + 1));
14015
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "sentence" };
14016
+ }
14017
+ }
14018
+ return { text, stripped: false, shape: null };
14019
+ }
14020
+ function emitPreambleStripTelemetry(channel, shape) {
14021
+ if (!shape) return;
14022
+ const agentCode = process.env.AGT_AGENT_CODE_NAME ?? "unknown";
14023
+ try {
14024
+ process.stderr.write(
14025
+ `agt.egress.preamble_stripped ${JSON.stringify({
14026
+ channel,
14027
+ agent_code: agentCode,
14028
+ shape
14029
+ })}
14030
+ `
14031
+ );
14032
+ } catch {
14033
+ }
14034
+ }
14035
+
13978
14036
  // src/direct-chat-claim-tracker.ts
13979
14037
  var DirectChatClaimTracker = class {
13980
14038
  bySession = /* @__PURE__ */ new Map();
@@ -14465,7 +14523,10 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
14465
14523
  };
14466
14524
  }
14467
14525
  if (name === "direct_chat.reply") {
14468
- const { session_id, content } = args;
14526
+ const { session_id, content: rawContent } = args;
14527
+ const sanitizedReply = stripRepostPreambleWithMeta(rawContent);
14528
+ if (sanitizedReply.stripped) emitPreambleStripTelemetry("direct_chat", sanitizedReply.shape);
14529
+ const content = sanitizedReply.text;
14469
14530
  const message_ids = claimTracker.peek(session_id);
14470
14531
  const streamEnabled = resolveHostBooleanFlag({
14471
14532
  key: "direct-chat-stream-reply",
package/dist/mcp/index.js CHANGED
@@ -23058,6 +23058,7 @@ var LOCAL_TOOL_NAMES = /* @__PURE__ */ new Set([
23058
23058
  "artefacts_get",
23059
23059
  "artefacts_get_source_chunk",
23060
23060
  "artefacts_download",
23061
+ "artefacts_resolve",
23061
23062
  // ADR-0017 Projects container (the reclaimed projects_* namespace). Read tools
23062
23063
  // shipped in v1; ENG-6769 adds agent-initiated create + post-creation tagging
23063
23064
  // of artefacts/tasks to a project. No projects_get_source_chunk — a project is
@@ -23285,6 +23286,32 @@ server.tool(
23285
23286
  content: [{ type: "text", text: await downloadArtefactText(params) }]
23286
23287
  })
23287
23288
  );
23289
+ async function resolveArtefactText(url) {
23290
+ const data = await apiPost("/host/artefact/resolve", {
23291
+ agent_id: AGT_AGENT_ID,
23292
+ url
23293
+ });
23294
+ const a = data.artefact;
23295
+ return [
23296
+ `Resolved to artefact ${a.id}`,
23297
+ `Slug: ${a.publisher_resource_id}`,
23298
+ a.title ? `Title: ${a.title}` : null,
23299
+ `Kind: ${a.kind} [${a.status}]`,
23300
+ a.project_id ? `Project: ${a.project_id}` : null,
23301
+ a.live_url ? `URL: ${a.live_url}` : null,
23302
+ "Use this id with artefacts_get, artefacts_download, or artefacts_assign_project."
23303
+ ].filter((s) => s !== null).join("\n");
23304
+ }
23305
+ server.tool(
23306
+ "artefacts_resolve",
23307
+ "Resolve an Augmented Live URL (e.g. https://live.augmented.team/<slug>) or a bare slug to the internal artefact id, so you can act on a link someone shared. Returns the id plus title, kind, status, and project. Only resolves your own published artefacts.",
23308
+ {
23309
+ url: external_exports.string().min(1).describe("An Augmented Live URL or the bare slug from one (the last path segment)")
23310
+ },
23311
+ async (params) => ({
23312
+ content: [{ type: "text", text: await resolveArtefactText(params.url) }]
23313
+ })
23314
+ );
23288
23315
  async function listProjectsText(params) {
23289
23316
  const data = await apiPost("/host/my-projects", {
23290
23317
  agent_id: AGT_AGENT_ID,
@@ -15265,6 +15265,64 @@ var SLACK_EGRESS_TOOLS = /* @__PURE__ */ new Set([
15265
15265
  "slack.upload_file"
15266
15266
  ]);
15267
15267
 
15268
+ // src/strip-repost-preamble.ts
15269
+ var PRIOR_ATTEMPT_CUE = /\b(a moment ago|just now|a second ago|earlier|moments ago|previously|last (?:time|attempt)|drafted|dialled|dialed|typed|composed|wrote|sent) (?:this|that|it)?\b|\b(?:drafted|dialled|dialed|typed|composed)\b/i;
15270
+ var FAILURE_CUE = /\b(?:did(?:n['’]t| not)|could(?:n['’]t| not)|would(?:n['’]t| not)|wasn['’]t|fail(?:ed)?|never)\b[^.!?\n]*?\b(?:parse[d]?|send|sent|go through|went through|land|deliver(?:ed)?|post(?:ed)?|come through|came through)\b/i;
15271
+ var REPOST_CUE = /\b(?:re-?post(?:ing)?|re-?send(?:ing)?|re-?sending|post(?:ing)?|send(?:ing)?|trying|sharing)\b[^.!?\n]*?\b(?:it|this|that|again|now|once more)\b|\bhere(?:['’]s| it is| is the)[^.!?\n]*?\bagain\b/i;
15272
+ function isRepostPreamble(fragment) {
15273
+ const hasRepost = REPOST_CUE.test(fragment);
15274
+ if (!hasRepost) return false;
15275
+ return FAILURE_CUE.test(fragment) || PRIOR_ATTEMPT_CUE.test(fragment);
15276
+ }
15277
+ function trimLeadingSeparators(s) {
15278
+ return s.replace(/^[\s]*[—–\-:.,;]+[\s]*/, "").replace(/^\s+/, "");
15279
+ }
15280
+ function stripRepostPreambleWithMeta(text) {
15281
+ if (!text) return { text, stripped: false, shape: null };
15282
+ const leading = text.replace(/^\s+/, "");
15283
+ if (leading.startsWith("(")) {
15284
+ const close = leading.indexOf(")");
15285
+ if (close > 0) {
15286
+ const inner = leading.slice(1, close);
15287
+ if (isRepostPreamble(inner)) {
15288
+ const rest = trimLeadingSeparators(leading.slice(close + 1));
15289
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "parenthetical" };
15290
+ }
15291
+ }
15292
+ }
15293
+ const runOn = leading.match(
15294
+ /^([^.!?\n]*?\b(?:again|now|once more)\b)[\s—–\-:.,;]+/i
15295
+ );
15296
+ if (runOn?.[1] && isRepostPreamble(runOn[1])) {
15297
+ const rest = trimLeadingSeparators(leading.slice(runOn[0].length));
15298
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "sentence" };
15299
+ }
15300
+ const boundary = leading.search(/[.!?\n]/);
15301
+ if (boundary > 0) {
15302
+ const fragment = leading.slice(0, boundary + 1);
15303
+ if (isRepostPreamble(fragment)) {
15304
+ const rest = trimLeadingSeparators(leading.slice(boundary + 1));
15305
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "sentence" };
15306
+ }
15307
+ }
15308
+ return { text, stripped: false, shape: null };
15309
+ }
15310
+ function emitPreambleStripTelemetry(channel, shape) {
15311
+ if (!shape) return;
15312
+ const agentCode = process.env.AGT_AGENT_CODE_NAME ?? "unknown";
15313
+ try {
15314
+ process.stderr.write(
15315
+ `agt.egress.preamble_stripped ${JSON.stringify({
15316
+ channel,
15317
+ agent_code: agentCode,
15318
+ shape
15319
+ })}
15320
+ `
15321
+ );
15322
+ } catch {
15323
+ }
15324
+ }
15325
+
15268
15326
  // src/slack-pending-inbound-cleanup.ts
15269
15327
  import { existsSync as existsSync3, readdirSync as readdirSync2, statSync, unlinkSync } from "fs";
15270
15328
  import { join as join5 } from "path";
@@ -17446,9 +17504,9 @@ async function processSlackRecoveryOutboxFile(filename) {
17446
17504
  }
17447
17505
  return;
17448
17506
  }
17449
- const text = `_(I drafted this a moment ago but it didn't send \u2014 posting it now.)_
17450
-
17451
- ${payload.text}`;
17507
+ const recovered = stripRepostPreambleWithMeta(payload.text);
17508
+ if (recovered.stripped) emitPreambleStripTelemetry("slack", recovered.shape);
17509
+ const text = recovered.text;
17452
17510
  let sendSucceeded = false;
17453
17511
  const controller = new AbortController();
17454
17512
  const timeoutId = setTimeout(() => controller.abort(), 15e3);
@@ -19270,6 +19328,8 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
19270
19328
  clearOldestSlackPendingMarkerInChannel2(channel);
19271
19329
  }
19272
19330
  };
19331
+ const sanitized = stripRepostPreambleWithMeta(text);
19332
+ if (sanitized.stripped) emitPreambleStripTelemetry("slack", sanitized.shape);
19273
19333
  try {
19274
19334
  const res = await fetch("https://slack.com/api/chat.postMessage", {
19275
19335
  method: "POST",
@@ -19279,7 +19339,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
19279
19339
  },
19280
19340
  body: JSON.stringify({
19281
19341
  channel,
19282
- text,
19342
+ text: sanitized.text,
19283
19343
  ...effectiveThreadTs ? { thread_ts: effectiveThreadTs } : {},
19284
19344
  ...buildAugmentedSlackMetadata() ? { metadata: buildAugmentedSlackMetadata() } : {}
19285
19345
  // ↑ Labels this message as Augmented-agent-originated so peer agents
@@ -14034,6 +14034,64 @@ function resolveSandboxedPath(filePath, projectDir) {
14034
14034
  return { ok: true, resolved };
14035
14035
  }
14036
14036
 
14037
+ // src/strip-repost-preamble.ts
14038
+ var PRIOR_ATTEMPT_CUE = /\b(a moment ago|just now|a second ago|earlier|moments ago|previously|last (?:time|attempt)|drafted|dialled|dialed|typed|composed|wrote|sent) (?:this|that|it)?\b|\b(?:drafted|dialled|dialed|typed|composed)\b/i;
14039
+ var FAILURE_CUE = /\b(?:did(?:n['’]t| not)|could(?:n['’]t| not)|would(?:n['’]t| not)|wasn['’]t|fail(?:ed)?|never)\b[^.!?\n]*?\b(?:parse[d]?|send|sent|go through|went through|land|deliver(?:ed)?|post(?:ed)?|come through|came through)\b/i;
14040
+ var REPOST_CUE = /\b(?:re-?post(?:ing)?|re-?send(?:ing)?|re-?sending|post(?:ing)?|send(?:ing)?|trying|sharing)\b[^.!?\n]*?\b(?:it|this|that|again|now|once more)\b|\bhere(?:['’]s| it is| is the)[^.!?\n]*?\bagain\b/i;
14041
+ function isRepostPreamble(fragment) {
14042
+ const hasRepost = REPOST_CUE.test(fragment);
14043
+ if (!hasRepost) return false;
14044
+ return FAILURE_CUE.test(fragment) || PRIOR_ATTEMPT_CUE.test(fragment);
14045
+ }
14046
+ function trimLeadingSeparators(s) {
14047
+ return s.replace(/^[\s]*[—–\-:.,;]+[\s]*/, "").replace(/^\s+/, "");
14048
+ }
14049
+ function stripRepostPreambleWithMeta(text) {
14050
+ if (!text) return { text, stripped: false, shape: null };
14051
+ const leading = text.replace(/^\s+/, "");
14052
+ if (leading.startsWith("(")) {
14053
+ const close = leading.indexOf(")");
14054
+ if (close > 0) {
14055
+ const inner = leading.slice(1, close);
14056
+ if (isRepostPreamble(inner)) {
14057
+ const rest = trimLeadingSeparators(leading.slice(close + 1));
14058
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "parenthetical" };
14059
+ }
14060
+ }
14061
+ }
14062
+ const runOn = leading.match(
14063
+ /^([^.!?\n]*?\b(?:again|now|once more)\b)[\s—–\-:.,;]+/i
14064
+ );
14065
+ if (runOn?.[1] && isRepostPreamble(runOn[1])) {
14066
+ const rest = trimLeadingSeparators(leading.slice(runOn[0].length));
14067
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "sentence" };
14068
+ }
14069
+ const boundary = leading.search(/[.!?\n]/);
14070
+ if (boundary > 0) {
14071
+ const fragment = leading.slice(0, boundary + 1);
14072
+ if (isRepostPreamble(fragment)) {
14073
+ const rest = trimLeadingSeparators(leading.slice(boundary + 1));
14074
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "sentence" };
14075
+ }
14076
+ }
14077
+ return { text, stripped: false, shape: null };
14078
+ }
14079
+ function emitPreambleStripTelemetry(channel, shape) {
14080
+ if (!shape) return;
14081
+ const agentCode = process.env.AGT_AGENT_CODE_NAME ?? "unknown";
14082
+ try {
14083
+ process.stderr.write(
14084
+ `agt.egress.preamble_stripped ${JSON.stringify({
14085
+ channel,
14086
+ agent_code: agentCode,
14087
+ shape
14088
+ })}
14089
+ `
14090
+ );
14091
+ } catch {
14092
+ }
14093
+ }
14094
+
14037
14095
  // src/msteams-inbound-puller.ts
14038
14096
  import { existsSync, mkdirSync, readdirSync, utimesSync, writeFileSync } from "fs";
14039
14097
  import { join } from "path";
@@ -15403,10 +15461,12 @@ async function handleReply(args) {
15403
15461
  )}s (threshold ${throttleCfg.threshold}). Stop attempting to reply until a human posts.`
15404
15462
  );
15405
15463
  }
15464
+ const sanitized = stripRepostPreambleWithMeta(text);
15465
+ if (sanitized.stripped) emitPreambleStripTelemetry("teams", sanitized.shape);
15406
15466
  try {
15407
15467
  const result = await sendActivity(serviceUrl, conversationId, {
15408
15468
  type: "message",
15409
- text,
15469
+ text: sanitized.text,
15410
15470
  textFormat: "markdown",
15411
15471
  ...replyToId ? { replyToId } : {}
15412
15472
  });
@@ -15962,10 +16022,12 @@ async function processRecoveryFile(filename) {
15962
16022
  }
15963
16023
  return;
15964
16024
  }
16025
+ const recovered = stripRepostPreambleWithMeta(payload.text);
16026
+ if (recovered.stripped) emitPreambleStripTelemetry("teams", recovered.shape);
15965
16027
  try {
15966
16028
  await sendActivity(payload.service_url, payload.conversation_id, {
15967
16029
  type: "message",
15968
- text: payload.text,
16030
+ text: recovered.text,
15969
16031
  ...payload.reply_to_id ? { replyToId: payload.reply_to_id } : {}
15970
16032
  });
15971
16033
  try {
@@ -16335,6 +16335,64 @@ var TELEGRAM_EGRESS_TOOLS = /* @__PURE__ */ new Set([
16335
16335
  "channel_request_input"
16336
16336
  ]);
16337
16337
 
16338
+ // src/strip-repost-preamble.ts
16339
+ var PRIOR_ATTEMPT_CUE = /\b(a moment ago|just now|a second ago|earlier|moments ago|previously|last (?:time|attempt)|drafted|dialled|dialed|typed|composed|wrote|sent) (?:this|that|it)?\b|\b(?:drafted|dialled|dialed|typed|composed)\b/i;
16340
+ var FAILURE_CUE = /\b(?:did(?:n['’]t| not)|could(?:n['’]t| not)|would(?:n['’]t| not)|wasn['’]t|fail(?:ed)?|never)\b[^.!?\n]*?\b(?:parse[d]?|send|sent|go through|went through|land|deliver(?:ed)?|post(?:ed)?|come through|came through)\b/i;
16341
+ var REPOST_CUE = /\b(?:re-?post(?:ing)?|re-?send(?:ing)?|re-?sending|post(?:ing)?|send(?:ing)?|trying|sharing)\b[^.!?\n]*?\b(?:it|this|that|again|now|once more)\b|\bhere(?:['’]s| it is| is the)[^.!?\n]*?\bagain\b/i;
16342
+ function isRepostPreamble(fragment) {
16343
+ const hasRepost = REPOST_CUE.test(fragment);
16344
+ if (!hasRepost) return false;
16345
+ return FAILURE_CUE.test(fragment) || PRIOR_ATTEMPT_CUE.test(fragment);
16346
+ }
16347
+ function trimLeadingSeparators(s) {
16348
+ return s.replace(/^[\s]*[—–\-:.,;]+[\s]*/, "").replace(/^\s+/, "");
16349
+ }
16350
+ function stripRepostPreambleWithMeta(text) {
16351
+ if (!text) return { text, stripped: false, shape: null };
16352
+ const leading = text.replace(/^\s+/, "");
16353
+ if (leading.startsWith("(")) {
16354
+ const close = leading.indexOf(")");
16355
+ if (close > 0) {
16356
+ const inner = leading.slice(1, close);
16357
+ if (isRepostPreamble(inner)) {
16358
+ const rest = trimLeadingSeparators(leading.slice(close + 1));
16359
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "parenthetical" };
16360
+ }
16361
+ }
16362
+ }
16363
+ const runOn = leading.match(
16364
+ /^([^.!?\n]*?\b(?:again|now|once more)\b)[\s—–\-:.,;]+/i
16365
+ );
16366
+ if (runOn?.[1] && isRepostPreamble(runOn[1])) {
16367
+ const rest = trimLeadingSeparators(leading.slice(runOn[0].length));
16368
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "sentence" };
16369
+ }
16370
+ const boundary = leading.search(/[.!?\n]/);
16371
+ if (boundary > 0) {
16372
+ const fragment = leading.slice(0, boundary + 1);
16373
+ if (isRepostPreamble(fragment)) {
16374
+ const rest = trimLeadingSeparators(leading.slice(boundary + 1));
16375
+ if (rest.length > 0) return { text: rest, stripped: true, shape: "sentence" };
16376
+ }
16377
+ }
16378
+ return { text, stripped: false, shape: null };
16379
+ }
16380
+ function emitPreambleStripTelemetry(channel, shape) {
16381
+ if (!shape) return;
16382
+ const agentCode = process.env.AGT_AGENT_CODE_NAME ?? "unknown";
16383
+ try {
16384
+ process.stderr.write(
16385
+ `agt.egress.preamble_stripped ${JSON.stringify({
16386
+ channel,
16387
+ agent_code: agentCode,
16388
+ shape
16389
+ })}
16390
+ `
16391
+ );
16392
+ } catch {
16393
+ }
16394
+ }
16395
+
16338
16396
  // src/telegram-pending-inbound-cleanup.ts
16339
16397
  import { readdirSync, readFileSync as readFileSync7, statSync } from "fs";
16340
16398
  import { join as join5 } from "path";
@@ -18031,9 +18089,9 @@ async function processRecoveryOutboxFile(filename) {
18031
18089
  }
18032
18090
  return;
18033
18091
  }
18034
- const text = `(I drafted this a moment ago but it didn't send \u2014 posting it now.)
18035
-
18036
- ${payload.text}`;
18092
+ const recovered = stripRepostPreambleWithMeta(payload.text);
18093
+ if (recovered.stripped) emitPreambleStripTelemetry("telegram", recovered.shape);
18094
+ const text = recovered.text;
18037
18095
  const body = {
18038
18096
  chat_id: payload.chat_id,
18039
18097
  text,
@@ -18729,6 +18787,8 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
18729
18787
  isError: true
18730
18788
  };
18731
18789
  }
18790
+ const tgSanitized = stripRepostPreambleWithMeta(text);
18791
+ if (tgSanitized.stripped) emitPreambleStripTelemetry("telegram", tgSanitized.shape);
18732
18792
  const isPrivateChat = !chat_id.startsWith("-");
18733
18793
  const tgThrottleCfg = isPrivateChat ? relaxedThrottleConfig(configFromEnv()) : configFromEnv();
18734
18794
  const tgThrottleNow = Date.now();
@@ -18763,7 +18823,9 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
18763
18823
  const timer = setTimeout(() => {
18764
18824
  void deliverQueuedReply({
18765
18825
  chatId: chat_id,
18766
- text,
18826
+ // ENG-6794: deliver the pre-sanitized text (preamble already stripped
18827
+ // and counted above, before the throttle decision).
18828
+ text: tgSanitized.text,
18767
18829
  replyToMessageId: reply_to_message_id,
18768
18830
  isReplyTool: name === "telegram.reply",
18769
18831
  throttleCfg: tgThrottleCfg
@@ -18780,7 +18842,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
18780
18842
  };
18781
18843
  }
18782
18844
  try {
18783
- const body = { chat_id, text };
18845
+ const body = { chat_id, text: tgSanitized.text };
18784
18846
  if (reply_to_message_id) body.reply_to_message_id = Number(reply_to_message_id);
18785
18847
  const drainCutoffMs = Date.now();
18786
18848
  const data = await telegramApiCall("sendMessage", body, 15e3);
@@ -34,8 +34,8 @@ import {
34
34
  writeDirectChatSessionState,
35
35
  writeEgressAllowlist,
36
36
  writePersistentClaudeWrapper
37
- } from "./chunk-6GNDRA3F.js";
38
- import "./chunk-WI6HYZ7K.js";
37
+ } from "./chunk-UVCPJVEF.js";
38
+ import "./chunk-HKKV7NJD.js";
39
39
  import "./chunk-XWVM4KPK.js";
40
40
  export {
41
41
  EGRESS_BASELINE_DOMAINS,
@@ -74,4 +74,4 @@ export {
74
74
  writeEgressAllowlist,
75
75
  writePersistentClaudeWrapper
76
76
  };
77
- //# sourceMappingURL=persistent-session-BRGQGGZY.js.map
77
+ //# sourceMappingURL=persistent-session-N4KR5IFC.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-6GNDRA3F.js";
4
- import "./chunk-WI6HYZ7K.js";
3
+ } from "./chunk-UVCPJVEF.js";
4
+ import "./chunk-HKKV7NJD.js";
5
5
  import "./chunk-XWVM4KPK.js";
6
6
 
7
7
  // src/lib/responsiveness-probe.ts
@@ -304,4 +304,4 @@ export {
304
304
  readAndResetChannelDeflections,
305
305
  readAndResetChannelLaneClassifications
306
306
  };
307
- //# sourceMappingURL=responsiveness-probe-RZYQMCM3.js.map
307
+ //# sourceMappingURL=responsiveness-probe-MYFNFOB7.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.140",
3
+ "version": "0.28.142",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {