@integrity-labs/agt-cli 0.15.8 → 0.15.9
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 +3 -3
- package/dist/{chunk-32D5TUSD.js → chunk-C6UBNLUC.js} +117 -5
- package/dist/{chunk-32D5TUSD.js.map → chunk-C6UBNLUC.js.map} +1 -1
- package/dist/lib/manager-worker.js +348 -177
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/slack-channel.js +388 -11
- package/mcp/telegram-channel.js +386 -8
- package/package.json +1 -1
package/dist/bin/agt.js
CHANGED
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
success,
|
|
47
47
|
table,
|
|
48
48
|
warn
|
|
49
|
-
} from "../chunk-
|
|
49
|
+
} from "../chunk-C6UBNLUC.js";
|
|
50
50
|
|
|
51
51
|
// src/bin/agt.ts
|
|
52
52
|
import { join as join10 } from "path";
|
|
@@ -3730,7 +3730,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
3730
3730
|
import { existsSync as existsSync5, realpathSync } from "fs";
|
|
3731
3731
|
import chalk17 from "chalk";
|
|
3732
3732
|
import ora15 from "ora";
|
|
3733
|
-
var cliVersion = true ? "0.15.
|
|
3733
|
+
var cliVersion = true ? "0.15.9" : "dev";
|
|
3734
3734
|
async function fetchLatestVersion() {
|
|
3735
3735
|
const host2 = getHost();
|
|
3736
3736
|
if (!host2) return null;
|
|
@@ -4179,7 +4179,7 @@ function handleError(err) {
|
|
|
4179
4179
|
}
|
|
4180
4180
|
|
|
4181
4181
|
// src/bin/agt.ts
|
|
4182
|
-
var cliVersion2 = true ? "0.15.
|
|
4182
|
+
var cliVersion2 = true ? "0.15.9" : "dev";
|
|
4183
4183
|
var program = new Command();
|
|
4184
4184
|
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");
|
|
4185
4185
|
program.hook("preAction", (thisCommand) => {
|
|
@@ -3117,6 +3117,120 @@ function provisionStopHook(codeName) {
|
|
|
3117
3117
|
"exit 0"
|
|
3118
3118
|
].join("\n") + "\n";
|
|
3119
3119
|
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3120
|
+
const ghostHookPath = join4(claudeDir, "agt-ghost-reply-hook.sh");
|
|
3121
|
+
const ghostHookScript = [
|
|
3122
|
+
"#!/bin/bash",
|
|
3123
|
+
"# Auto-generated by Augmented (ENG-4569) \u2014 detects ghost replies and",
|
|
3124
|
+
"# drops recovery files in the channel outbox dirs. Runs on every Stop.",
|
|
3125
|
+
"set -euo pipefail",
|
|
3126
|
+
"INPUT=$(cat)",
|
|
3127
|
+
`TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty')`,
|
|
3128
|
+
'[ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ] && exit 0',
|
|
3129
|
+
`CWD=$(echo "$INPUT" | jq -r '.cwd // empty')`,
|
|
3130
|
+
`CODE_NAME=$(echo "$CWD" | sed -nE 's|.*/\\.augmented/([^/]+)/project/?$|\\1|p')`,
|
|
3131
|
+
'[ -z "$CODE_NAME" ] && exit 0',
|
|
3132
|
+
'AGENT_DIR="$(dirname "$CWD")"',
|
|
3133
|
+
'TG_MARKER_DIR="${AGENT_DIR}/telegram-pending-inbound"',
|
|
3134
|
+
'SL_MARKER_DIR="${AGENT_DIR}/slack-pending-inbound"',
|
|
3135
|
+
"# CodeRabbit ENG-4569 round-3: latest-marker correlation could leak chat",
|
|
3136
|
+
"# A's composed reply into chat B if B arrived later. Now correlate by",
|
|
3137
|
+
"# scanning the transcript for the LAST channel-source <channel ...> tag",
|
|
3138
|
+
"# in user/notification turns and routing recovery to the EXACT marker",
|
|
3139
|
+
"# whose chat_id+message_id (Telegram) / channel+thread_ts (Slack) match.",
|
|
3140
|
+
"# If the tag isn't found, skip recovery \u2014 the timeout will catch it.",
|
|
3141
|
+
"pending_markers_count() {",
|
|
3142
|
+
' local dir="$1"',
|
|
3143
|
+
' [ ! -d "$dir" ] && echo 0 && return',
|
|
3144
|
+
" shopt -s nullglob",
|
|
3145
|
+
' local files=("$dir"/*.json)',
|
|
3146
|
+
' echo "${#files[@]}"',
|
|
3147
|
+
"}",
|
|
3148
|
+
'TG_PENDING=$(pending_markers_count "$TG_MARKER_DIR")',
|
|
3149
|
+
'SL_PENDING=$(pending_markers_count "$SL_MARKER_DIR")',
|
|
3150
|
+
'[ "$TG_PENDING" = "0" ] && [ "$SL_PENDING" = "0" ] && exit 0',
|
|
3151
|
+
`LAST_ASSISTANT=$(tail -200 "$TRANSCRIPT_PATH" | jq -cs '[.[] | select(.type == "assistant" or .role == "assistant")] | last // empty' 2>/dev/null)`,
|
|
3152
|
+
'[ -z "$LAST_ASSISTANT" ] || [ "$LAST_ASSISTANT" = "null" ] && exit 0',
|
|
3153
|
+
`TEXT=$(echo "$LAST_ASSISTANT" | jq -r '(.message.content // .content // []) | map(select(.type == "text") | .text) | join("\\n\\n")' 2>/dev/null)`,
|
|
3154
|
+
"# Strip whitespace and bail only on truly-empty (vs the previous <4-char",
|
|
3155
|
+
'# threshold that dropped legit short replies like "ok", "yes", emoji).',
|
|
3156
|
+
'[ -z "${TEXT//[[:space:]]/}" ] && exit 0',
|
|
3157
|
+
`TOOL_NAMES=$(echo "$LAST_ASSISTANT" | jq -r '(.message.content // .content // []) | map(select(.type == "tool_use") | .name) | .[]' 2>/dev/null || true)`,
|
|
3158
|
+
"# Find the LAST <channel ...> tag in user/notification turns. Channel",
|
|
3159
|
+
"# notifications are forwarded into the session as text containing this",
|
|
3160
|
+
"# tag (slack-channel.ts:1247 / telegram-channel.ts:776 emit content +",
|
|
3161
|
+
"# meta which Claude Code wraps in a <channel ...> preamble). Searching",
|
|
3162
|
+
"# the raw text gives us the exact pending conversation key.",
|
|
3163
|
+
`CHANNEL_TAG=$(tail -400 "$TRANSCRIPT_PATH" | jq -r '(.message.content // .content // []) | map(select(.type == "text") | .text) | join(" ")' 2>/dev/null | grep -oE '<channel [^>]+>' | tail -1)`,
|
|
3164
|
+
'TAG_SOURCE=""',
|
|
3165
|
+
`[ -n "$CHANNEL_TAG" ] && TAG_SOURCE=$(echo "$CHANNEL_TAG" | grep -oE 'source="[^"]+"' | head -1 | sed 's/source="\\(.*\\)"/\\1/')`,
|
|
3166
|
+
'extract_attr() { echo "$1" | grep -oE "$2=\\"[^\\"]+\\"" | head -1 | sed -E "s/$2=\\"(.*)\\"/\\\\1/"; }',
|
|
3167
|
+
"# Atomic write helper: jq \u2192 tmp file in same dir, then rename. The",
|
|
3168
|
+
"# channel-side fs.watch only fires on rename, so the file is never",
|
|
3169
|
+
"# observed mid-write.",
|
|
3170
|
+
"atomic_write_payload() {",
|
|
3171
|
+
' local out_dir="$1" final="$2" jq_expr="$3"; shift 3',
|
|
3172
|
+
' mkdir -p "$out_dir"',
|
|
3173
|
+
' local tmp="$out_dir/.${final##*/}.tmp"',
|
|
3174
|
+
' jq -n "$jq_expr" "$@" > "$tmp"',
|
|
3175
|
+
' chmod 600 "$tmp" 2>/dev/null || true',
|
|
3176
|
+
' mv -f "$tmp" "$out_dir/$final"',
|
|
3177
|
+
"}",
|
|
3178
|
+
"# Sanitize an ID the same way the channel servers do (safeMarkerName /",
|
|
3179
|
+
"# safeSlackMarkerName): replace anything outside [A-Za-z0-9_-] with `_`.",
|
|
3180
|
+
`safe_id() { echo -n "$1" | sed -E 's|[^A-Za-z0-9_-]|_|g'; }`,
|
|
3181
|
+
"recover_telegram_for() {",
|
|
3182
|
+
' local chat_id="$1" msg_id="$2"',
|
|
3183
|
+
' [ -z "$chat_id" ] || [ -z "$msg_id" ] && return',
|
|
3184
|
+
" # If the agent DID call telegram.reply this turn, no recovery needed.",
|
|
3185
|
+
` echo "$TOOL_NAMES" | grep -qE '^(telegram\\.reply|telegram\\.send_message)$' && return`,
|
|
3186
|
+
" local marker_name",
|
|
3187
|
+
' marker_name="$(safe_id "$chat_id")__$(safe_id "$msg_id").json"',
|
|
3188
|
+
' local marker_path="${TG_MARKER_DIR}/${marker_name}"',
|
|
3189
|
+
' [ ! -f "$marker_path" ] && return',
|
|
3190
|
+
" local TS",
|
|
3191
|
+
" TS=$(date -u +%Y%m%dT%H%M%S%N)",
|
|
3192
|
+
' atomic_write_payload "${AGENT_DIR}/telegram-recovery-outbox" "${TS}.json" \\',
|
|
3193
|
+
` '{chat_id:$c, message_id:$m, text:$t, source:"ghost-reply-recovery"}' \\`,
|
|
3194
|
+
' --arg c "$chat_id" --arg m "$msg_id" --arg t "$TEXT"',
|
|
3195
|
+
' rm -f "$marker_path" 2>/dev/null || true',
|
|
3196
|
+
"}",
|
|
3197
|
+
"recover_slack_for() {",
|
|
3198
|
+
' local channel="$1" thread_ts="$2"',
|
|
3199
|
+
' [ -z "$channel" ] && return',
|
|
3200
|
+
" # If the agent DID call slack.reply this turn, no recovery needed.",
|
|
3201
|
+
` echo "$TOOL_NAMES" | grep -qE '^slack\\.reply$' && return`,
|
|
3202
|
+
" # Find any marker for this channel+thread (in busy threads multiple",
|
|
3203
|
+
" # message_ts entries can be pending \u2014 recover the oldest, that's the",
|
|
3204
|
+
" # one closest to firing the timeout).",
|
|
3205
|
+
' local prefix="$(safe_id "$channel")__$(safe_id "$thread_ts")__"',
|
|
3206
|
+
' local marker_path=""',
|
|
3207
|
+
" shopt -s nullglob",
|
|
3208
|
+
' for f in "$SL_MARKER_DIR"/${prefix}*.json; do',
|
|
3209
|
+
' [ -z "$marker_path" ] && marker_path="$f"',
|
|
3210
|
+
" done",
|
|
3211
|
+
' [ -z "$marker_path" ] && return',
|
|
3212
|
+
" local TS",
|
|
3213
|
+
" TS=$(date -u +%Y%m%dT%H%M%S%N)",
|
|
3214
|
+
' atomic_write_payload "${AGENT_DIR}/slack-recovery-outbox" "${TS}.json" \\',
|
|
3215
|
+
` '{channel:$c, thread_ts:$th, text:$t, source:"ghost-reply-recovery"}' \\`,
|
|
3216
|
+
' --arg c "$channel" --arg th "$thread_ts" --arg t "$TEXT"',
|
|
3217
|
+
' rm -f "$marker_path" 2>/dev/null || true',
|
|
3218
|
+
"}",
|
|
3219
|
+
"# Strict correlation: only recover if the last channel tag in the",
|
|
3220
|
+
"# transcript points at a channel/key that has an exact-match pending",
|
|
3221
|
+
"# marker. No tag found \u2192 skip; let timeout handle it.",
|
|
3222
|
+
'if [ "$TAG_SOURCE" = "telegram" ]; then',
|
|
3223
|
+
' CHAT_ID=$(extract_attr "$CHANNEL_TAG" "chat_id")',
|
|
3224
|
+
' MSG_ID=$(extract_attr "$CHANNEL_TAG" "message_id")',
|
|
3225
|
+
' recover_telegram_for "$CHAT_ID" "$MSG_ID"',
|
|
3226
|
+
'elif [ "$TAG_SOURCE" = "slack" ]; then',
|
|
3227
|
+
' CHANNEL=$(extract_attr "$CHANNEL_TAG" "channel")',
|
|
3228
|
+
' THREAD_TS=$(extract_attr "$CHANNEL_TAG" "thread_ts")',
|
|
3229
|
+
' recover_slack_for "$CHANNEL" "$THREAD_TS"',
|
|
3230
|
+
"fi",
|
|
3231
|
+
"exit 0"
|
|
3232
|
+
].join("\n") + "\n";
|
|
3233
|
+
writeFileSync4(ghostHookPath, ghostHookScript, { mode: 493 });
|
|
3120
3234
|
const settingsPath = join4(claudeDir, "settings.local.json");
|
|
3121
3235
|
let settings = {};
|
|
3122
3236
|
try {
|
|
@@ -3127,10 +3241,8 @@ function provisionStopHook(codeName) {
|
|
|
3127
3241
|
hooks["Stop"] = [
|
|
3128
3242
|
{
|
|
3129
3243
|
hooks: [
|
|
3130
|
-
{
|
|
3131
|
-
|
|
3132
|
-
command: hookScriptPath
|
|
3133
|
-
}
|
|
3244
|
+
{ type: "command", command: hookScriptPath },
|
|
3245
|
+
{ type: "command", command: ghostHookPath }
|
|
3134
3246
|
]
|
|
3135
3247
|
}
|
|
3136
3248
|
];
|
|
@@ -7122,4 +7234,4 @@ export {
|
|
|
7122
7234
|
managerStopCommand,
|
|
7123
7235
|
managerStatusCommand
|
|
7124
7236
|
};
|
|
7125
|
-
//# sourceMappingURL=chunk-
|
|
7237
|
+
//# sourceMappingURL=chunk-C6UBNLUC.js.map
|