@integrity-labs/agt-cli 0.28.331 → 0.28.332

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
@@ -38,7 +38,7 @@ import {
38
38
  success,
39
39
  table,
40
40
  warn
41
- } from "../chunk-4Y3UPOR2.js";
41
+ } from "../chunk-YNHMQ4CW.js";
42
42
  import {
43
43
  AnchorSessionClient,
44
44
  CHANNEL_REGISTRY,
@@ -4827,7 +4827,7 @@ import { execFileSync, execSync } from "child_process";
4827
4827
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4828
4828
  import chalk18 from "chalk";
4829
4829
  import ora16 from "ora";
4830
- var cliVersion = true ? "0.28.331" : "dev";
4830
+ var cliVersion = true ? "0.28.332" : "dev";
4831
4831
  async function fetchLatestVersion() {
4832
4832
  const host2 = getHost();
4833
4833
  if (!host2) return null;
@@ -5931,7 +5931,7 @@ function handleError(err) {
5931
5931
  }
5932
5932
 
5933
5933
  // src/bin/agt.ts
5934
- var cliVersion2 = true ? "0.28.331" : "dev";
5934
+ var cliVersion2 = true ? "0.28.332" : "dev";
5935
5935
  var program = new Command();
5936
5936
  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");
5937
5937
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -2772,9 +2772,19 @@ function provisionStopHook(codeName) {
2772
2772
  " # it moved on and TEXT is not a reliably-correlated ghost of THIS inbound \u2014",
2773
2773
  " # recovering it would post mis-correlated text. Stay silent: a silent gap the",
2774
2774
  " # operator re-pings beats wrong content that poisons trust.",
2775
- " local replied_other",
2776
- ` replied_other=$(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 ")) and (($all[.]|(.type // .role // "")) != "assistant")) ] | 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 // "")|tostring) as $c | ($c != $cid and $c != ""))) ] | length' "$RECENT_FILE" 2>/dev/null || true)`,
2777
- ' if [ "${replied_other:-0}" -gt 0 ] 2>/dev/null; then return; fi',
2775
+ " # ENG-7806 (fm1): delivery-ledger read replaces the transcript scan (conv_key",
2776
+ " # = chat_id, Telegram's conversation grain). no_ledger falls back to the scan.",
2777
+ ' local _tg_m="${TG_MARKER_DIR}/$(safe_id "$chat_id")__$(safe_id "$msg_id").json" _tg_iid="" _tg_recv=""',
2778
+ ` if [ -f "$_tg_m" ]; then _tg_iid=$(jq -r '.inbound_id // ""' "$_tg_m" 2>/dev/null || echo ""); _tg_recv=$(jq -r '.received_at // ""' "$_tg_m" 2>/dev/null || echo ""); fi`,
2779
+ ' case "$(delivery_ledger_verdict "$_tg_iid" "$chat_id" "$_tg_recv")" in',
2780
+ ' self) log_ghost "telegram skip=already_delivered chat=$(safe_id "$chat_id")"; return ;;',
2781
+ ' moved_on) log_ghost "telegram skip=moved_on_after_tag_ledger chat=$(safe_id "$chat_id")"; return ;;',
2782
+ " no_ledger)",
2783
+ " local replied_other",
2784
+ ` replied_other=$(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 ")) and (($all[.]|(.type // .role // "")) != "assistant")) ] | 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 // "")|tostring) as $c | ($c != $cid and $c != ""))) ] | length' "$RECENT_FILE" 2>/dev/null || true)`,
2785
+ ' if [ "${replied_other:-0}" -gt 0 ] 2>/dev/null; then return; fi',
2786
+ " ;;",
2787
+ " esac",
2778
2788
  " local marker_name",
2779
2789
  ' marker_name="$(safe_id "$chat_id")__$(safe_id "$msg_id").json"',
2780
2790
  ' local marker_path="${TG_MARKER_DIR}/${marker_name}"',
@@ -2827,19 +2837,33 @@ function provisionStopHook(codeName) {
2827
2837
  " # kickoff's, not the DM's). Replies BEFORE this inbound no longer suppress,",
2828
2838
  " # so answering an older thread then this one recovers correctly. Silence on",
2829
2839
  " # a genuine move-on still beats posting mis-correlated text.",
2830
- " local replied_other",
2831
- ` replied_other=$(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 ")) and (($all[.]|(.type // .role // "")) != "assistant")) ] | 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' "$RECENT_FILE" 2>/dev/null || true)`,
2832
- ' 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',
2833
- " # Find any marker for this channel+thread (in busy threads multiple",
2834
- " # message_ts entries can be pending \u2014 recover the oldest, that's the",
2835
- " # one closest to firing the timeout).",
2840
+ " # ENG-7806 (fm1): read the inbound-delivery ledger instead of scraping the",
2841
+ " # transcript. Find the target marker for its inbound_id + received_at, then ask",
2842
+ ' # the ledger "already delivered / moved on to another conversation?" - a',
2843
+ " # byte-exact record, not coordinate/recency inference. no_ledger (a pre-C",
2844
+ " # session with no ledger data) falls back to the old transcript scan below.",
2845
+ " # CodeRabbit: select the SAME marker recovery will process (oldest for this",
2846
+ " # channel+thread) ONCE, so the self-check reads the exact inbound being recovered,",
2847
+ " # never a sibling message in a busy thread. Reused by the CS-1444 guard + recovery below.",
2836
2848
  ' local prefix="$(safe_id "$channel")__$(safe_id "$thread_ts")__"',
2837
2849
  ' local marker_path=""',
2838
2850
  " shopt -s nullglob",
2839
- ' for f in "$SL_MARKER_DIR"/${prefix}*.json; do',
2840
- ' if [ -z "$marker_path" ]; then marker_path="$f"; fi',
2841
- " done",
2851
+ ' for f in "$SL_MARKER_DIR"/${prefix}*.json; do if [ -z "$marker_path" ]; then marker_path="$f"; fi; done',
2842
2852
  ' if [ -z "$marker_path" ]; then log_ghost "slack skip=no_pending_marker channel=$(safe_id "$channel") thread=$(safe_id "$thread_ts")"; return; fi',
2853
+ ' local _sl_iid="" _sl_recv=""',
2854
+ ` _sl_iid=$(jq -r '.inbound_id // ""' "$marker_path" 2>/dev/null || echo ""); _sl_recv=$(jq -r '.received_at // ""' "$marker_path" 2>/dev/null || echo "")`,
2855
+ ' case "$(delivery_ledger_verdict "$_sl_iid" "$thread_ts" "$_sl_recv")" in',
2856
+ ' self) log_ghost "slack skip=already_delivered thread=$(safe_id "$thread_ts")"; return ;;',
2857
+ ' moved_on) log_ghost "slack skip=moved_on_after_tag_ledger thread=$(safe_id "$thread_ts")"; return ;;',
2858
+ " no_ledger)",
2859
+ " local replied_other",
2860
+ ` replied_other=$(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 ")) and (($all[.]|(.type // .role // "")) != "assistant")) ] | 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' "$RECENT_FILE" 2>/dev/null || true)`,
2861
+ ' 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',
2862
+ " ;;",
2863
+ " esac",
2864
+ " # marker_path (the oldest for this channel+thread, closest to firing the timeout)",
2865
+ " # was selected above and reused here - one selection shared by the ledger read,",
2866
+ " # the CS-1444 guard, and recovery.",
2843
2867
  " # CS-1444: precedence guard against cross-thread mis-delivery. The last",
2844
2868
  " # <channel> tag can point at a DISCRETIONARY (auto-followed, un-mentioned)",
2845
2869
  " # inbound the agent never owed a reply to (ENG-6319). If the trailing text",
@@ -2919,23 +2943,31 @@ function provisionStopHook(codeName) {
2919
2943
  " # teams.replied to a DIFFERENT conversation_id AFTER this inbound tag, TEXT is",
2920
2944
  " # not a reliably-correlated ghost of THIS inbound \u2014 stay silent rather than post",
2921
2945
  " # mis-correlated text (silence the operator re-pings beats wrong content).",
2922
- " local replied_other",
2923
- ` replied_other=$(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 ")) and (($all[.]|(.type // .role // "")) != "assistant")) ] | 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' "$RECENT_FILE" 2>/dev/null || true)`,
2924
- ' if [ "${replied_other:-0}" -gt 0 ] 2>/dev/null; then return; fi',
2925
- " # teams-channel.ts encodes the marker filename as",
2926
- " # hex(conversation_id)[..64]--hex(activity_id)[..64].json",
2927
- " # We don't have the original activity_id here, only the",
2928
- " # reply_to_id from the channel tag (which IS the original",
2929
- " # activity_id the agent saw). Try a prefix match against the",
2930
- " # marker dir.",
2946
+ " # ENG-7806 (fm1): delivery-ledger read replaces the transcript scan (conv_key",
2947
+ " # = conversation_id). no_ledger falls back to the scan. The teams marker file",
2948
+ " # is hex(conversation_id)[..64]--... so locate it the same way to read its id.",
2949
+ " # CodeRabbit: select the SAME marker recovery will process ONCE (hex(conversation_id)",
2950
+ " # prefix; the activity_id is not available here), so the self-check reads the exact",
2951
+ " # inbound being recovered. Reused by the recovery block below.",
2931
2952
  " local hex_conv",
2932
2953
  ' hex_conv=$(printf %s "$conversation_id" | od -An -tx1 | tr -d " \\n" | cut -c1-64)',
2933
2954
  ' local marker_path=""',
2934
2955
  " shopt -s nullglob",
2935
- ' for f in "$MS_MARKER_DIR"/${hex_conv}*.json; do',
2936
- ' if [ -z "$marker_path" ]; then marker_path="$f"; fi',
2937
- " done",
2956
+ ' for f in "$MS_MARKER_DIR"/${hex_conv}*.json; do if [ -z "$marker_path" ]; then marker_path="$f"; fi; done',
2938
2957
  ' if [ -z "$marker_path" ]; then log_ghost "teams skip=no_pending_marker conv=$(safe_id "$conversation_id")"; return; fi',
2958
+ ' local _ms_iid="" _ms_recv=""',
2959
+ ` _ms_iid=$(jq -r '.inbound_id // ""' "$marker_path" 2>/dev/null || echo ""); _ms_recv=$(jq -r '.received_at // ""' "$marker_path" 2>/dev/null || echo "")`,
2960
+ ' case "$(delivery_ledger_verdict "$_ms_iid" "$conversation_id" "$_ms_recv")" in',
2961
+ ' self) log_ghost "teams skip=already_delivered conv=$(safe_id "$conversation_id")"; return ;;',
2962
+ ' moved_on) log_ghost "teams skip=moved_on_after_tag_ledger conv=$(safe_id "$conversation_id")"; return ;;',
2963
+ " no_ledger)",
2964
+ " local replied_other",
2965
+ ` replied_other=$(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 ")) and (($all[.]|(.type // .role // "")) != "assistant")) ] | 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' "$RECENT_FILE" 2>/dev/null || true)`,
2966
+ ' if [ "${replied_other:-0}" -gt 0 ] 2>/dev/null; then return; fi',
2967
+ " ;;",
2968
+ " esac",
2969
+ " # marker_path (hex(conversation_id) prefix match, the marker the agent saw whose",
2970
+ " # activity_id we lack) was selected above and is reused here.",
2939
2971
  ' local marker_name; marker_name="$(basename "$marker_path")"',
2940
2972
  " # ENG-7805 (fm2): confirm-before-clear. Cap re-fire with a per-marker ledger and",
2941
2973
  " # LEAVE the marker for the consumer to clear on confirmed send (ledger-first fail-safe).",
@@ -3047,6 +3079,67 @@ function provisionStopHook(codeName) {
3047
3079
  'for _rl in "$SL_RECOVERY_LEDGER_DIR" "$TG_RECOVERY_LEDGER_DIR" "$MS_RECOVERY_LEDGER_DIR"; do',
3048
3080
  ' if [ -d "$_rl" ]; then find "$_rl" -type f -mtime +1 -delete 2>/dev/null || true; fi',
3049
3081
  "done",
3082
+ "# ENG-7806 (ENG-6722 slice C): the inbound-delivery ledger - a durable, POSITIVE",
3083
+ '# record ("inbound X was confirmed-delivered at time T") the channel MCPs write on',
3084
+ "# each confirmed reply, keyed by inbound_id. The recover_*_for path reads it instead",
3085
+ "# of scraping the transcript for the replied_other/moved-on decision (fm1). Disjoint",
3086
+ "# from the recovery-ledgers above (those are marker-filename-keyed, negative/in-flight).",
3087
+ "# GC at 1 day like the others (a delivery record only needs to outlive the pending",
3088
+ "# marker + a restart within the recovery window; the MCP never needs it after the",
3089
+ "# marker is gone).",
3090
+ 'DELIVERY_LEDGER_DIR="${AGENT_DIR}/.agt-inbound-delivery-ledger"',
3091
+ 'if [ -d "$DELIVERY_LEDGER_DIR" ]; then find "$DELIVERY_LEDGER_DIR" -type f -mtime +1 -delete 2>/dev/null || true; fi',
3092
+ "# ENG-7806 telemetry: count each ledger verdict into a counter file the manager",
3093
+ "# already reads+resets (the *-reply-binding-classifications.json suffix), so it",
3094
+ "# reaches CloudWatch as Classification dims with no new pipeline. Best-effort +",
3095
+ "# fully silent (no stdout) - delivery_ledger_verdict runs in $(...), so a stray",
3096
+ "# byte would corrupt the captured verdict.",
3097
+ 'LEDGER_METRIC_FILE="${AGENT_DIR}/ghost-ledger-reply-binding-classifications.json"',
3098
+ "bump_ledger_metric() {",
3099
+ ' local key="$1" tmp="${LEDGER_METRIC_FILE}.$$.tmp"',
3100
+ ' if [ -f "$LEDGER_METRIC_FILE" ]; then',
3101
+ ` jq --arg k "$key" '.[$k] = ((.[$k] // 0) + 1)' "$LEDGER_METRIC_FILE" > "$tmp" 2>/dev/null && mv -f "$tmp" "$LEDGER_METRIC_FILE" 2>/dev/null || rm -f "$tmp" 2>/dev/null || true`,
3102
+ " else",
3103
+ ` jq -n --arg k "$key" '{($k): 1}' > "$tmp" 2>/dev/null && mv -f "$tmp" "$LEDGER_METRIC_FILE" 2>/dev/null || rm -f "$tmp" 2>/dev/null || true`,
3104
+ " fi",
3105
+ "}",
3106
+ "# Deterministic replacement for the recover_*_for replied_other transcript scan.",
3107
+ "# Echoes exactly one verdict for (inbound_id, conv_key, received_at):",
3108
+ "# self - a delivery record for THIS inbound_id exists (already answered)",
3109
+ "# moved_on - a record for a DIFFERENT conv_key was delivered AFTER this inbound",
3110
+ "# arrived (the agent answered elsewhere; trailing text is ambiguous)",
3111
+ "# clear - the ledger has data but neither of the above (safe to recover)",
3112
+ "# no_ledger - the ledger is empty/absent (pre-C session) -> caller falls back to",
3113
+ "# the transcript scan, so the rollout is safe.",
3114
+ "# ISO-8601 Z timestamps sort lexicographically == chronologically, so a string",
3115
+ "# compare is a correct time compare here (all delivered_at/received_at are UTC Z).",
3116
+ "delivery_ledger_verdict() {",
3117
+ ' local iid="$1" convk="$2" recv="$3"',
3118
+ ' if [ ! -d "$DELIVERY_LEDGER_DIR" ]; then bump_ledger_metric delivery_ledger_fallback; echo "no_ledger"; return; fi',
3119
+ " shopt -s nullglob",
3120
+ ' local _dl_files=("$DELIVERY_LEDGER_DIR"/*.json)',
3121
+ ' if [ "${#_dl_files[@]}" = "0" ]; then bump_ledger_metric delivery_ledger_fallback; echo "no_ledger"; return; fi',
3122
+ " # Self-check first (needs only inbound_id): a delivery record for THIS inbound_id",
3123
+ " # means it was already answered, so suppress even if the marker somehow lacks a",
3124
+ " # received_at.",
3125
+ ' if [ -n "$iid" ] && [ -f "${DELIVERY_LEDGER_DIR}/$(safe_id "$iid").json" ]; then bump_ledger_metric delivery_ledger_self; echo "self"; return; fi',
3126
+ " # ENG-7806 (CodeRabbit): after the self-check, without THIS marker's own inbound_id",
3127
+ " # AND received_at we cannot make a trustworthy moved-on decision for it (a pre-C",
3128
+ " # marker that predates the ledger, or a torn read). Fall back to the transcript",
3129
+ " # scan rather than defaulting to clear - otherwise, once ANY ledger file exists, an",
3130
+ " # id-less marker would bypass the rollout fallback and recover text the old scan",
3131
+ " # would suppress.",
3132
+ ' if [ -z "$iid" ] || [ -z "$recv" ]; then bump_ledger_metric delivery_ledger_fallback; echo "no_ledger"; return; fi',
3133
+ " local _dl_f _dl_ck _dl_da",
3134
+ ' for _dl_f in "${_dl_files[@]}"; do',
3135
+ ` _dl_ck=$(jq -r '.conv_key // ""' "$_dl_f" 2>/dev/null || echo "")`,
3136
+ ` _dl_da=$(jq -r '.delivered_at // ""' "$_dl_f" 2>/dev/null || echo "")`,
3137
+ ' if [ -n "$_dl_ck" ] && [ "$_dl_ck" != "$convk" ] && [ -n "$_dl_da" ] && [ -n "$recv" ] && [[ "$_dl_da" > "$recv" ]]; then',
3138
+ ' bump_ledger_metric delivery_ledger_moved_on; echo "moved_on"; return',
3139
+ " fi",
3140
+ " done",
3141
+ ' bump_ledger_metric delivery_ledger_clear; echo "clear"',
3142
+ "}",
3050
3143
  "# Returns 0 (after printing the block JSON to stdout) when it blocked; 1 otherwise.",
3051
3144
  '# $1 = "yes"/"no" \u2014 did the agent reply to THIS conversation in the final turn?',
3052
3145
  "# (ENG-6727: per-conversation, computed by the caller via replied_this_conv_*)",
@@ -6863,7 +6956,7 @@ function requireHost() {
6863
6956
  }
6864
6957
 
6865
6958
  // src/lib/api-client.ts
6866
- var agtCliVersion = true ? "0.28.331" : "dev";
6959
+ var agtCliVersion = true ? "0.28.332" : "dev";
6867
6960
  var lastConfigHash = null;
6868
6961
  function setConfigHash(hash) {
6869
6962
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -9260,4 +9353,4 @@ export {
9260
9353
  managerInstallSystemUnitCommand,
9261
9354
  managerUninstallSystemUnitCommand
9262
9355
  };
9263
- //# sourceMappingURL=chunk-4Y3UPOR2.js.map
9356
+ //# sourceMappingURL=chunk-YNHMQ4CW.js.map