@integrity-labs/agt-cli 0.28.102 → 0.28.103

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-25QKPD27.js";
40
+ } from "../chunk-UL7V7NIG.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.102" : "dev";
4780
+ var cliVersion = true ? "0.28.103" : "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.102" : "dev";
5794
+ var cliVersion2 = true ? "0.28.103" : "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) => {
@@ -4546,7 +4546,19 @@ function provisionStopHook(codeName) {
4546
4546
  "# jq error, which the 2>/dev/null swallowed, so the tag came back empty",
4547
4547
  "# and recovery silently no-oped on every Slack ghost reply (confirmed",
4548
4548
  "# live on sherlock/agt-aws-1 2026-06-10). Normalize before mapping.",
4549
- `CHANNEL_TAG=$(tail -400 "$TRANSCRIPT_PATH" | jq -r '${jqNormalizeContent} | map(select(type == "object" and .type == "text") | .text) | join(" ")' 2>/dev/null | grep -oE '<channel [^>]+>' | tail -1 || true)`,
4549
+ "# ENG-6467: grep is line-oriented, so `[^>]+` can never span a newline. A",
4550
+ "# channel preamble whose thread_context embeds a multi-paragraph prior reply",
4551
+ "# (exactly the high-value brief/research threads) splits the opening tag",
4552
+ "# across lines, so the regex matched nothing \u2192 TAG_SOURCE=none \u2192 the whole",
4553
+ "# recovery (and block-turn-end) chain was skipped (Sophie / two-tractors-host,",
4554
+ "# 2026-06-17). Flatten newlines to spaces PER TEXT BLOCK inside jq (gsub),",
4555
+ "# before join: each transcript record stays on its own output line, so a",
4556
+ "# partial/unterminated tag in one record can't be closed by a `>` in the",
4557
+ "# next (a post-join `tr` would synthesize that false tag). A `>` inside",
4558
+ "# thread_context can truncate the match early, but every scalar attr we read",
4559
+ "# (source/channel/thread_ts/message_ts/chat_id/conversation_id) precedes",
4560
+ "# thread_context, so the truncated tag still carries them.",
4561
+ `CHANNEL_TAG=$(tail -400 "$TRANSCRIPT_PATH" | jq -r '${jqNormalizeContent} | map(select(type == "object" and .type == "text") | .text | gsub("[\\n\\r]+"; " ")) | join(" ")' 2>/dev/null | grep -oE '<channel [^>]+>' | tail -1 || true)`,
4550
4562
  'TAG_SOURCE=""',
4551
4563
  `if [ -n "$CHANNEL_TAG" ]; then TAG_SOURCE=$(echo "$CHANNEL_TAG" | grep -oE 'source="[^"]+"' | head -1 | sed 's/source="\\(.*\\)"/\\1/' || true); fi`,
4552
4564
  "# ENG-6567: one context line per Stop that reached here (non-empty assistant",
@@ -4588,7 +4600,7 @@ function provisionStopHook(codeName) {
4588
4600
  " # of THIS inbound \u2014 recovering it would post mis-correlated text. Stay silent: a",
4589
4601
  " # silent gap the operator re-pings beats wrong content that poisons trust.",
4590
4602
  " local replied_other",
4591
- ` replied_other=$(tail -400 "$TRANSCRIPT_PATH" 2>/dev/null | jq -s --arg cid "$chat_id" '[ .[] | select((.type // .role)=="assistant") | (.message.content // .content // []) | (if type=="array" then . else [] end) | .[] | select((.type=="tool_use") and ((.name|tostring)|test("telegram[._](reply|send_message)$")) and (((.input.chat_id // "")) as $c | ($c != $cid and $c != ""))) ] | length' 2>/dev/null || true)`,
4603
+ ` replied_other=$(tail -400 "$TRANSCRIPT_PATH" 2>/dev/null | jq -s --arg cid "$chat_id" 'def ctext: (.message.content // .content // []) | if type=="string" then . elif type=="array" then (map(select(type=="object" and .type=="text")|.text)|join(" ")) else "" end; . as $all | ([ range(0; ($all|length)) | select(($all[.]|ctext)|test("<channel ")) ] | last) as $idx | [ $all[(($idx // -1)+1):][] | select((.type // .role)=="assistant") | (.message.content // .content // []) | (if type=="array" then . else [] end) | .[] | select((.type=="tool_use") and ((.name|tostring)|test("telegram[._](reply|send_message)$")) and (((.input.chat_id // "")) as $c | ($c != $cid and $c != ""))) ] | length' 2>/dev/null || true)`,
4592
4604
  ' if [ "${replied_other:-0}" -gt 0 ] 2>/dev/null; then return; fi',
4593
4605
  " local marker_name",
4594
4606
  ' marker_name="$(safe_id "$chat_id")__$(safe_id "$msg_id").json"',
@@ -4612,17 +4624,20 @@ function provisionStopHook(codeName) {
4612
4624
  " # real transcript, so this same-turn guard was dead in prod and only",
4613
4625
  " # masked by the MCP-side marker clear.",
4614
4626
  ` if echo "$TOOL_NAMES" | grep -qE '(^|__)slack[._]reply$'; then log_ghost "slack skip=replied_this_turn thread=$(safe_id "$thread_ts")"; return; fi`,
4615
- " # ENG-6387 \u2014 correlation + fail-silent. The single-turn check above is",
4616
- " # not enough: a reply and trailing narration can straddle turns. If the",
4617
- " # agent has slack.replied to a DIFFERENT thread than THIS marker anywhere",
4618
- " # in the recent window, it is actively conversing elsewhere and its",
4619
- " # trailing text is NOT a reliably-correlated ghost of this inbound \u2014",
4620
- " # recovering it posts mis-correlated text (koda 2026-06-12: a DM marker",
4621
- " # recovered with unrelated kickoff-thread narration). Stay silent: a",
4622
- " # silent gap the operator re-pings beats wrong content that poisons trust.",
4627
+ " # ENG-6387 plus ENG-6467: recency-aware correlation + fail-silent. A reply and",
4628
+ " # trailing narration can straddle turns, so a single-turn check is not",
4629
+ " # enough. ENG-6387 bailed on a reply to ANY other thread ANYWHERE in the",
4630
+ " # window; a multi-thread agent (sherlock) satisfies that on nearly every",
4631
+ " # turn, so it silently dropped composed replies (ENG-6467). Narrowed to",
4632
+ " # RECENCY: suppress only if the agent replied to a DIFFERENT thread AFTER",
4633
+ " # this inbound's <channel> tag (it moved on, the koda 2026-06-12 case: a DM",
4634
+ " # tag followed by a reply to the kickoff thread, so the trailing text is the",
4635
+ " # kickoff's, not the DM's). Replies BEFORE this inbound no longer suppress,",
4636
+ " # so answering an older thread then this one recovers correctly. Silence on",
4637
+ " # a genuine move-on still beats posting mis-correlated text.",
4623
4638
  " local replied_other",
4624
- ` replied_other=$(tail -400 "$TRANSCRIPT_PATH" 2>/dev/null | jq -s --arg th "$thread_ts" '[ .[] | select((.type // .role)=="assistant") | (.message.content // .content // []) | (if type=="array" then . else [] end) | .[] | select((.type=="tool_use") and ((.name|tostring)|test("slack[._]reply$")) and (((.input.thread_ts // .input.message_ts // "")) as $t | ($t != $th and $t != ""))) ] | length' 2>/dev/null || true)`,
4625
- ' if [ "${replied_other:-0}" -gt 0 ] 2>/dev/null; then log_ghost "slack skip=replied_other_thread thread=$(safe_id "$thread_ts")"; return; fi',
4639
+ ` replied_other=$(tail -400 "$TRANSCRIPT_PATH" 2>/dev/null | jq -s --arg th "$thread_ts" 'def ctext: (.message.content // .content // []) | if type=="string" then . elif type=="array" then (map(select(type=="object" and .type=="text")|.text)|join(" ")) else "" end; . as $all | ([ range(0; ($all|length)) | select(($all[.]|ctext)|test("<channel ")) ] | last) as $idx | [ $all[(($idx // -1)+1):][] | select((.type // .role)=="assistant") | (.message.content // .content // []) | (if type=="array" then . else [] end) | .[] | select((.type=="tool_use") and ((.name|tostring)|test("slack[._]reply$")) and (((.input.thread_ts // .input.message_ts // "")) as $t | ($t != $th and $t != ""))) ] | length' 2>/dev/null || true)`,
4640
+ ' if [ "${replied_other:-0}" -gt 0 ] 2>/dev/null; then log_ghost "slack skip=moved_on_after_tag thread=$(safe_id "$thread_ts")"; return; fi',
4626
4641
  " # Find any marker for this channel+thread (in busy threads multiple",
4627
4642
  " # message_ts entries can be pending \u2014 recover the oldest, that's the",
4628
4643
  " # one closest to firing the timeout).",
@@ -4654,7 +4669,7 @@ function provisionStopHook(codeName) {
4654
4669
  " # correlated ghost of THIS inbound \u2014 stay silent rather than post mis-correlated",
4655
4670
  " # text (silence the operator re-pings beats wrong content that poisons trust).",
4656
4671
  " local replied_other",
4657
- ` replied_other=$(tail -400 "$TRANSCRIPT_PATH" 2>/dev/null | jq -s --arg cid "$conversation_id" '[ .[] | select((.type // .role)=="assistant") | (.message.content // .content // []) | (if type=="array" then . else [] end) | .[] | select((.type=="tool_use") and ((.name|tostring)|test("teams[._]reply$")) and (((.input.conversation_id // "")) as $c | ($c != $cid and $c != ""))) ] | length' 2>/dev/null || true)`,
4672
+ ` replied_other=$(tail -400 "$TRANSCRIPT_PATH" 2>/dev/null | jq -s --arg cid "$conversation_id" 'def ctext: (.message.content // .content // []) | if type=="string" then . elif type=="array" then (map(select(type=="object" and .type=="text")|.text)|join(" ")) else "" end; . as $all | ([ range(0; ($all|length)) | select(($all[.]|ctext)|test("<channel ")) ] | last) as $idx | [ $all[(($idx // -1)+1):][] | select((.type // .role)=="assistant") | (.message.content // .content // []) | (if type=="array" then . else [] end) | .[] | select((.type=="tool_use") and ((.name|tostring)|test("teams[._]reply$")) and (((.input.conversation_id // "")) as $c | ($c != $cid and $c != ""))) ] | length' 2>/dev/null || true)`,
4658
4673
  ' if [ "${replied_other:-0}" -gt 0 ] 2>/dev/null; then return; fi',
4659
4674
  " # teams-channel.ts encodes the marker filename as",
4660
4675
  " # hex(conversation_id)[..64]--hex(activity_id)[..64].json",
@@ -4769,6 +4784,50 @@ function provisionStopHook(codeName) {
4769
4784
  ` if emit_block_if_obligated '(^|__)teams[._]reply$' "$MS_CAND" 'teams.reply'; then exit 0; fi`,
4770
4785
  " fi",
4771
4786
  ' recover_teams_for "$CONVERSATION_ID" "$REPLY_TO_ID" "$SERVICE_URL"',
4787
+ 'elif [ -z "$TAG_SOURCE" ]; then',
4788
+ " # ENG-6467: TAG_SOURCE=none fallback (AC1). Guarded on an EMPTY source, not",
4789
+ " # a catch-all else: a parsed-but-unsupported source (e.g. direct-chat, which",
4790
+ " # has its own durable replay) must NOT fall through here, or its trailing",
4791
+ " # text could be misdelivered to a pending slack/telegram/teams marker.",
4792
+ " # The last <channel> tag could not be parsed (a malformed/partial preamble,",
4793
+ " # or any residual extraction miss) yet a reply is owed. When EXACTLY ONE",
4794
+ " # channel marker is pending",
4795
+ " # agent-wide AND the final turn produced text with NO reply tool call,",
4796
+ " # there is a single unambiguous candidate, so recover it. Cross-thread",
4797
+ " # mis-correlation (the koda risk) is impossible with one candidate, and the",
4798
+ " # recover_*_for recency guard still suppresses if the agent moved on. The",
4799
+ " # marker key is read from the marker contents (real channel markers carry",
4800
+ " # channel/thread_ts | chat_id/message_id | conversation_id/service_url); a",
4801
+ " # contentless {} marker yields empty keys and recover_*_for returns early.",
4802
+ " TOTAL_PENDING=$(( TG_PENDING + SL_PENDING + MS_PENDING ))",
4803
+ ' if [ "$TOTAL_PENDING" = "1" ] && [ "$REPLY_IN_LAST" = "no" ]; then',
4804
+ " shopt -s nullglob",
4805
+ ' if [ "$SL_PENDING" = "1" ]; then',
4806
+ ' for f in "$SL_MARKER_DIR"/*.json; do',
4807
+ ` FB_CH=$(jq -r '.channel // empty' "$f" 2>/dev/null || true)`,
4808
+ ` FB_TH=$(jq -r '.thread_ts // empty' "$f" 2>/dev/null || true)`,
4809
+ ' log_ghost "fallback=tag_source_none channel=slack marker=$(basename "$f")"',
4810
+ ' recover_slack_for "$FB_CH" "$FB_TH"',
4811
+ " done",
4812
+ ' elif [ "$TG_PENDING" = "1" ]; then',
4813
+ ' for f in "$TG_MARKER_DIR"/*.json; do',
4814
+ ` FB_CID=$(jq -r '.chat_id // empty' "$f" 2>/dev/null || true)`,
4815
+ ` FB_MID=$(jq -r '.message_id // empty' "$f" 2>/dev/null || true)`,
4816
+ ' log_ghost "fallback=tag_source_none channel=telegram marker=$(basename "$f")"',
4817
+ ' recover_telegram_for "$FB_CID" "$FB_MID"',
4818
+ " done",
4819
+ ' elif [ "$MS_PENDING" = "1" ]; then',
4820
+ ' for f in "$MS_MARKER_DIR"/*.json; do',
4821
+ ` FB_CONV=$(jq -r '.conversation_id // empty' "$f" 2>/dev/null || true)`,
4822
+ ` FB_RID=$(jq -r '.reply_to_id // .activity_id // empty' "$f" 2>/dev/null || true)`,
4823
+ ` FB_SVC=$(jq -r '.service_url // empty' "$f" 2>/dev/null || true)`,
4824
+ ' log_ghost "fallback=tag_source_none channel=msteams marker=$(basename "$f")"',
4825
+ ' recover_teams_for "$FB_CONV" "$FB_RID" "$FB_SVC"',
4826
+ " done",
4827
+ " fi",
4828
+ " else",
4829
+ ' log_ghost "skip=tag_source_none pending_total=$TOTAL_PENDING reply_in_last=$REPLY_IN_LAST"',
4830
+ " fi",
4772
4831
  "fi",
4773
4832
  "exit 0"
4774
4833
  ].join("\n") + "\n";
@@ -7541,7 +7600,7 @@ function requireHost() {
7541
7600
  }
7542
7601
 
7543
7602
  // src/lib/api-client.ts
7544
- var agtCliVersion = true ? "0.28.102" : "dev";
7603
+ var agtCliVersion = true ? "0.28.103" : "dev";
7545
7604
  var lastConfigHash = null;
7546
7605
  function setConfigHash(hash) {
7547
7606
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -8838,4 +8897,4 @@ export {
8838
8897
  managerInstallSystemUnitCommand,
8839
8898
  managerUninstallSystemUnitCommand
8840
8899
  };
8841
- //# sourceMappingURL=chunk-25QKPD27.js.map
8900
+ //# sourceMappingURL=chunk-UL7V7NIG.js.map