@integrity-labs/agt-cli 0.27.162 → 0.27.164
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 +4 -4
- package/dist/{chunk-LK7R6HLJ.js → chunk-3A2H4ZLD.js} +9 -2
- package/dist/{chunk-LK7R6HLJ.js.map → chunk-3A2H4ZLD.js.map} +1 -1
- package/dist/{chunk-AEECYKHW.js → chunk-5TBIEU36.js} +2 -2
- package/dist/{chunk-H5B4ESA5.js → chunk-OIX32YSR.js} +2 -2
- package/dist/{claude-pair-runtime-TZOAZFBQ.js → claude-pair-runtime-ZEFIYDUH.js} +2 -2
- package/dist/lib/manager-worker.js +10 -13
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/slack-channel.js +302 -82
- package/dist/mcp/telegram-channel.js +255 -44
- package/dist/{persistent-session-WL22MKBS.js → persistent-session-7BLPRGWR.js} +3 -3
- package/dist/{responsiveness-probe-N3Q3O6X7.js → responsiveness-probe-AL3O7SYZ.js} +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-AEECYKHW.js.map → chunk-5TBIEU36.js.map} +0 -0
- /package/dist/{chunk-H5B4ESA5.js.map → chunk-OIX32YSR.js.map} +0 -0
- /package/dist/{claude-pair-runtime-TZOAZFBQ.js.map → claude-pair-runtime-ZEFIYDUH.js.map} +0 -0
- /package/dist/{persistent-session-WL22MKBS.js.map → persistent-session-7BLPRGWR.js.map} +0 -0
- /package/dist/{responsiveness-probe-N3Q3O6X7.js.map → responsiveness-probe-AL3O7SYZ.js.map} +0 -0
|
@@ -14318,9 +14318,9 @@ import https from "https";
|
|
|
14318
14318
|
import { createHash, randomUUID as randomUUID2 } from "crypto";
|
|
14319
14319
|
import {
|
|
14320
14320
|
createWriteStream,
|
|
14321
|
-
existsSync as
|
|
14321
|
+
existsSync as existsSync5,
|
|
14322
14322
|
mkdirSync as mkdirSync4,
|
|
14323
|
-
readFileSync as
|
|
14323
|
+
readFileSync as readFileSync6,
|
|
14324
14324
|
readdirSync as readdirSync2,
|
|
14325
14325
|
renameSync as renameSync4,
|
|
14326
14326
|
statSync,
|
|
@@ -14328,8 +14328,8 @@ import {
|
|
|
14328
14328
|
watch,
|
|
14329
14329
|
writeFileSync as writeFileSync4
|
|
14330
14330
|
} from "fs";
|
|
14331
|
-
import { homedir as
|
|
14332
|
-
import { join as
|
|
14331
|
+
import { homedir as homedir3 } from "os";
|
|
14332
|
+
import { join as join6 } from "path";
|
|
14333
14333
|
|
|
14334
14334
|
// src/channel-attachments.ts
|
|
14335
14335
|
import { homedir } from "os";
|
|
@@ -14868,6 +14868,100 @@ function decideInboundAccess(input) {
|
|
|
14868
14868
|
return { kind: "admit" };
|
|
14869
14869
|
}
|
|
14870
14870
|
|
|
14871
|
+
// src/watch-command.ts
|
|
14872
|
+
var WATCH_DEFAULT_DURATION_MS = 2 * 60 * 60 * 1e3;
|
|
14873
|
+
var WATCH_MAX_DURATION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
14874
|
+
var WATCH_MIN_DURATION_MS = 5 * 60 * 1e3;
|
|
14875
|
+
function extractDriveFileId(s) {
|
|
14876
|
+
const trimmed = s.trim().replace(/^<|>$/g, "");
|
|
14877
|
+
const pathId = trimmed.match(/\/d\/([A-Za-z0-9_-]{10,})/);
|
|
14878
|
+
if (pathId?.[1]) return pathId[1];
|
|
14879
|
+
const idParam = trimmed.match(/[?&]id=([A-Za-z0-9_-]{10,})/);
|
|
14880
|
+
if (idParam?.[1]) return idParam[1];
|
|
14881
|
+
if (!/[/:?]/.test(trimmed) && /^[A-Za-z0-9_-]{20,}$/.test(trimmed)) return trimmed;
|
|
14882
|
+
return null;
|
|
14883
|
+
}
|
|
14884
|
+
function parseDurationToken(token) {
|
|
14885
|
+
const m = token.trim().match(/^(\d+)\s*([smhd])?$/i);
|
|
14886
|
+
if (!m?.[1]) return null;
|
|
14887
|
+
const n = Number.parseInt(m[1], 10);
|
|
14888
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
14889
|
+
const unit = (m[2] ?? "m").toLowerCase();
|
|
14890
|
+
const mult = unit === "s" ? 1e3 : unit === "m" ? 6e4 : unit === "h" ? 36e5 : 864e5;
|
|
14891
|
+
return n * mult;
|
|
14892
|
+
}
|
|
14893
|
+
function parseWatchArgs(args) {
|
|
14894
|
+
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
14895
|
+
const first = parts[0];
|
|
14896
|
+
if (!first) return { ok: false, error: "usage" };
|
|
14897
|
+
if (parts.length > 2) return { ok: false, error: "usage" };
|
|
14898
|
+
const fileId = extractDriveFileId(first);
|
|
14899
|
+
if (!fileId) return { ok: false, error: "bad-url" };
|
|
14900
|
+
let durationMs = WATCH_DEFAULT_DURATION_MS;
|
|
14901
|
+
const durationToken = parts[1];
|
|
14902
|
+
if (durationToken !== void 0) {
|
|
14903
|
+
const parsed = parseDurationToken(durationToken);
|
|
14904
|
+
if (parsed === null) return { ok: false, error: "bad-duration" };
|
|
14905
|
+
durationMs = Math.min(Math.max(parsed, WATCH_MIN_DURATION_MS), WATCH_MAX_DURATION_MS);
|
|
14906
|
+
}
|
|
14907
|
+
return { ok: true, value: { fileId, durationMs } };
|
|
14908
|
+
}
|
|
14909
|
+
async function postWatchTrigger(opts) {
|
|
14910
|
+
const doFetch = opts.fetchImpl ?? fetch;
|
|
14911
|
+
try {
|
|
14912
|
+
const res = await doFetch(`${opts.host}/host/triggers`, {
|
|
14913
|
+
method: "POST",
|
|
14914
|
+
headers: {
|
|
14915
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
14916
|
+
Authorization: `Bearer ${opts.apiKey}`
|
|
14917
|
+
},
|
|
14918
|
+
body: JSON.stringify({
|
|
14919
|
+
agent_id: opts.agentId,
|
|
14920
|
+
provider: "gdrive_comments",
|
|
14921
|
+
config: { fileId: opts.fileId },
|
|
14922
|
+
expires_at: opts.expiresAtIso
|
|
14923
|
+
}),
|
|
14924
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? 15e3)
|
|
14925
|
+
});
|
|
14926
|
+
if (!res.ok) {
|
|
14927
|
+
let msg = `HTTP ${res.status}`;
|
|
14928
|
+
try {
|
|
14929
|
+
const j2 = await res.json();
|
|
14930
|
+
if (j2?.error) msg = j2.error;
|
|
14931
|
+
} catch {
|
|
14932
|
+
}
|
|
14933
|
+
return { ok: false, status: res.status, error: msg };
|
|
14934
|
+
}
|
|
14935
|
+
const j = await res.json().catch(() => ({}));
|
|
14936
|
+
return { ok: true, status: res.status, reused: !!j.reused, expiresAt: j.expires_at ?? null };
|
|
14937
|
+
} catch (err) {
|
|
14938
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
14939
|
+
}
|
|
14940
|
+
}
|
|
14941
|
+
function humanDuration(ms) {
|
|
14942
|
+
const mins = Math.round(ms / 6e4);
|
|
14943
|
+
if (mins % 1440 === 0) return `${mins / 1440}d`;
|
|
14944
|
+
if (mins % 60 === 0) return `${mins / 60}h`;
|
|
14945
|
+
return `${mins}m`;
|
|
14946
|
+
}
|
|
14947
|
+
function watchUsageText() {
|
|
14948
|
+
return "Usage: `/watch <google-doc-url> [duration]` \u2014 e.g. `/watch https://docs.google.com/document/d/\u2026/edit 2h`. Duration defaults to 2h (max 7d).";
|
|
14949
|
+
}
|
|
14950
|
+
function watchBadUrlText() {
|
|
14951
|
+
return "That doesn't look like a Google Doc link. Paste the doc's share URL (the part with `/d/<id>`).";
|
|
14952
|
+
}
|
|
14953
|
+
function watchBadDurationText() {
|
|
14954
|
+
return "I couldn't read that duration. Try `30m`, `2h`, or `1d` (max 7d).";
|
|
14955
|
+
}
|
|
14956
|
+
function watchErrorText() {
|
|
14957
|
+
return "\u274C I couldn't set up that watch just now. Please try again in a moment.";
|
|
14958
|
+
}
|
|
14959
|
+
function watchSuccessTextPlain(fileId, durationMs, reused) {
|
|
14960
|
+
const url = `https://docs.google.com/document/d/${fileId}/edit`;
|
|
14961
|
+
const verb = reused ? "Extended my watch on" : "Watching";
|
|
14962
|
+
return `\u{1F440} ${verb} ${url} for new comments that mention me, for the next ${humanDuration(durationMs)}. I'll pause automatically when the window's up. (Make sure Google Drive is connected with comment access, or I won't see them.)`;
|
|
14963
|
+
}
|
|
14964
|
+
|
|
14871
14965
|
// src/telegram-peer-rate-limiter.ts
|
|
14872
14966
|
var SECOND_MS = 1e3;
|
|
14873
14967
|
var MINUTE_MS = 60 * SECOND_MS;
|
|
@@ -15976,8 +16070,47 @@ function readLockHolder(path) {
|
|
|
15976
16070
|
}
|
|
15977
16071
|
|
|
15978
16072
|
// src/ack-reaction.ts
|
|
15979
|
-
import { readdirSync, readFileSync as
|
|
16073
|
+
import { readdirSync, readFileSync as readFileSync5 } from "fs";
|
|
16074
|
+
import { join as join5 } from "path";
|
|
16075
|
+
|
|
16076
|
+
// src/flags-cache-read.ts
|
|
16077
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
16078
|
+
import { homedir as homedir2 } from "os";
|
|
15980
16079
|
import { join as join4 } from "path";
|
|
16080
|
+
function defaultFlagsCachePath() {
|
|
16081
|
+
return join4(homedir2(), ".augmented", "flags-cache.json");
|
|
16082
|
+
}
|
|
16083
|
+
function envBoolean(raw) {
|
|
16084
|
+
if (raw === void 0) return void 0;
|
|
16085
|
+
const v = raw.trim().toLowerCase();
|
|
16086
|
+
if (v === "") return void 0;
|
|
16087
|
+
if (v === "1" || v === "true" || v === "yes" || v === "on") return true;
|
|
16088
|
+
if (v === "0" || v === "false" || v === "no" || v === "off") return false;
|
|
16089
|
+
return void 0;
|
|
16090
|
+
}
|
|
16091
|
+
function cachedBoolean(key2, path) {
|
|
16092
|
+
try {
|
|
16093
|
+
if (!existsSync4(path)) return void 0;
|
|
16094
|
+
const parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
16095
|
+
if (!parsed || typeof parsed !== "object") return void 0;
|
|
16096
|
+
const flags = parsed.flags;
|
|
16097
|
+
if (!flags || typeof flags !== "object") return void 0;
|
|
16098
|
+
const value = flags[key2];
|
|
16099
|
+
return typeof value === "boolean" ? value : void 0;
|
|
16100
|
+
} catch {
|
|
16101
|
+
return void 0;
|
|
16102
|
+
}
|
|
16103
|
+
}
|
|
16104
|
+
function resolveHostBooleanFlag(opts) {
|
|
16105
|
+
const env = opts.env ?? process.env;
|
|
16106
|
+
const envValue = envBoolean(env[opts.envVar]);
|
|
16107
|
+
if (envValue !== void 0) return envValue;
|
|
16108
|
+
const cached2 = cachedBoolean(opts.key, opts.cachePath ?? defaultFlagsCachePath());
|
|
16109
|
+
if (cached2 !== void 0) return cached2;
|
|
16110
|
+
return opts.defaultValue;
|
|
16111
|
+
}
|
|
16112
|
+
|
|
16113
|
+
// src/ack-reaction.ts
|
|
15981
16114
|
var REPLY_WEDGED_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
15982
16115
|
var ACK_STARTUP_GRACE_MS = 6e4;
|
|
15983
16116
|
var ACK_PANE_FRESH_THRESHOLD_MS = 6e4;
|
|
@@ -16010,8 +16143,11 @@ function undeliverableNoticeText() {
|
|
|
16010
16143
|
var BUSY_ACK_THRESHOLD_MS = 9e4;
|
|
16011
16144
|
var BUSY_ACK_NOTICE_THROTTLE_MS = 10 * 60 * 1e3;
|
|
16012
16145
|
function channelBusyAckEnabled() {
|
|
16013
|
-
|
|
16014
|
-
|
|
16146
|
+
return resolveHostBooleanFlag({
|
|
16147
|
+
key: "channel-busy-ack",
|
|
16148
|
+
envVar: "AGT_CHANNEL_BUSY_ACK_ENABLED",
|
|
16149
|
+
defaultValue: false
|
|
16150
|
+
});
|
|
16015
16151
|
}
|
|
16016
16152
|
function channelBusyAckThresholdMs() {
|
|
16017
16153
|
const raw = parseInt(process.env.AGT_CHANNEL_BUSY_ACK_THRESHOLD_MS ?? "", 10);
|
|
@@ -16035,7 +16171,7 @@ var GIVE_UP_SIGNAL_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
|
16035
16171
|
function readGiveUpSignalAtMs(path, now = Date.now()) {
|
|
16036
16172
|
if (!path) return null;
|
|
16037
16173
|
try {
|
|
16038
|
-
const raw = JSON.parse(
|
|
16174
|
+
const raw = JSON.parse(readFileSync5(path, "utf8"));
|
|
16039
16175
|
if (typeof raw.gave_up_at !== "string") return null;
|
|
16040
16176
|
const t = Date.parse(raw.gave_up_at);
|
|
16041
16177
|
if (!Number.isFinite(t) || t > now) return null;
|
|
@@ -16067,7 +16203,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now()) {
|
|
|
16067
16203
|
if (!name.endsWith(".json")) continue;
|
|
16068
16204
|
let receivedAt;
|
|
16069
16205
|
try {
|
|
16070
|
-
const raw = JSON.parse(
|
|
16206
|
+
const raw = JSON.parse(readFileSync5(join5(dir, name), "utf-8"));
|
|
16071
16207
|
receivedAt = raw.received_at;
|
|
16072
16208
|
} catch {
|
|
16073
16209
|
continue;
|
|
@@ -16115,7 +16251,7 @@ function redactId(id) {
|
|
|
16115
16251
|
}
|
|
16116
16252
|
var BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
16117
16253
|
var AGENT_CODE_NAME = process.env.AGT_AGENT_CODE_NAME ?? "unknown";
|
|
16118
|
-
var TELEGRAM_AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ?
|
|
16254
|
+
var TELEGRAM_AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? join6(homedir3(), ".augmented", AGENT_CODE_NAME) : null;
|
|
16119
16255
|
var AGT_HOST = process.env.AGT_HOST ?? null;
|
|
16120
16256
|
var AGT_API_KEY = process.env.AGT_API_KEY ?? null;
|
|
16121
16257
|
var AGT_AGENT_ID = process.env.AGT_AGENT_ID ?? null;
|
|
@@ -16209,9 +16345,9 @@ if (!BOT_TOKEN) {
|
|
|
16209
16345
|
var stderrLogStream = null;
|
|
16210
16346
|
if (AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown") {
|
|
16211
16347
|
try {
|
|
16212
|
-
const logDir =
|
|
16348
|
+
const logDir = join6(homedir3(), ".augmented", AGENT_CODE_NAME);
|
|
16213
16349
|
mkdirSync4(logDir, { recursive: true });
|
|
16214
|
-
stderrLogStream = createWriteStream(
|
|
16350
|
+
stderrLogStream = createWriteStream(join6(logDir, "telegram-channel-stderr.log"), {
|
|
16215
16351
|
flags: "a",
|
|
16216
16352
|
mode: 384
|
|
16217
16353
|
});
|
|
@@ -16401,7 +16537,7 @@ function scheduleBusyAck(chatId, messageId) {
|
|
|
16401
16537
|
let paneLogFreshAgeMs = null;
|
|
16402
16538
|
if (AGENT_DIR) {
|
|
16403
16539
|
try {
|
|
16404
|
-
const paneMtimeMs = statSync(
|
|
16540
|
+
const paneMtimeMs = statSync(join6(AGENT_DIR, "pane.log")).mtimeMs;
|
|
16405
16541
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
16406
16542
|
} catch {
|
|
16407
16543
|
}
|
|
@@ -16423,7 +16559,7 @@ function scheduleBusyAck(chatId, messageId) {
|
|
|
16423
16559
|
function __resetBusyAckNoticeThrottle() {
|
|
16424
16560
|
lastBusyAckNoticeAt.clear();
|
|
16425
16561
|
}
|
|
16426
|
-
var RESTART_FLAGS_DIR =
|
|
16562
|
+
var RESTART_FLAGS_DIR = join6(homedir3(), ".augmented", "restart-flags");
|
|
16427
16563
|
function writeTelegramRestartConfirm(reply, requesterName) {
|
|
16428
16564
|
if (!RESTART_CONFIRM_FILE) return;
|
|
16429
16565
|
const marker = {
|
|
@@ -16491,6 +16627,7 @@ function buildTelegramHelpMessage(codeName) {
|
|
|
16491
16627
|
`_Type these in any chat where the bot is present (intercepted by the agent):_`,
|
|
16492
16628
|
`\u2022 /help \u2014 show this help`,
|
|
16493
16629
|
`\u2022 /status \u2014 this agent's model, session origin, uptime + connectivity`,
|
|
16630
|
+
`\u2022 /watch <google-doc-url> [duration] \u2014 watch a Google Doc for comments that mention me (default 2h, max 7d; auto-pauses when the window ends)`,
|
|
16494
16631
|
`\u2022 /restart \u2014 restart this agent`,
|
|
16495
16632
|
`\u2022 /investigate-${codeName} \u2014 live tail of this agent's terminal pane (DM only; team owners/admins and the agent's reports-to person)`
|
|
16496
16633
|
].join("\n");
|
|
@@ -16520,6 +16657,63 @@ async function handleHelpCommand(opts) {
|
|
|
16520
16657
|
);
|
|
16521
16658
|
}
|
|
16522
16659
|
}
|
|
16660
|
+
async function handleWatchCommand(opts) {
|
|
16661
|
+
const reply = async (text) => {
|
|
16662
|
+
try {
|
|
16663
|
+
const resp = await telegramApiCall(
|
|
16664
|
+
"sendMessage",
|
|
16665
|
+
{ chat_id: opts.chatId, text, reply_to_message_id: Number(opts.messageId) },
|
|
16666
|
+
1e4
|
|
16667
|
+
);
|
|
16668
|
+
if (!resp.ok) {
|
|
16669
|
+
process.stderr.write(
|
|
16670
|
+
`telegram-channel(${AGENT_CODE_NAME}): /watch reply rejected (chat ${redactId(opts.chatId)}): ${resp.description ?? "unknown"}
|
|
16671
|
+
`
|
|
16672
|
+
);
|
|
16673
|
+
}
|
|
16674
|
+
} catch (err) {
|
|
16675
|
+
process.stderr.write(
|
|
16676
|
+
`telegram-channel(${AGENT_CODE_NAME}): /watch reply send failed: ${redactAugmentedPaths(err.message)}
|
|
16677
|
+
`
|
|
16678
|
+
);
|
|
16679
|
+
}
|
|
16680
|
+
};
|
|
16681
|
+
const args = opts.text.replace(/^\/watch(?:@[A-Za-z0-9_]{1,64})?\s*/i, "");
|
|
16682
|
+
const parsed = parseWatchArgs(args);
|
|
16683
|
+
if (!parsed.ok) {
|
|
16684
|
+
await reply(
|
|
16685
|
+
parsed.error === "bad-url" ? watchBadUrlText() : parsed.error === "bad-duration" ? watchBadDurationText() : watchUsageText()
|
|
16686
|
+
);
|
|
16687
|
+
return;
|
|
16688
|
+
}
|
|
16689
|
+
if (!AGT_HOST || !AGT_API_KEY || !AGT_AGENT_ID) {
|
|
16690
|
+
process.stderr.write(`telegram-channel(${AGENT_CODE_NAME}): /watch missing AGT_* env \u2014 cannot create watch
|
|
16691
|
+
`);
|
|
16692
|
+
await reply(watchErrorText());
|
|
16693
|
+
return;
|
|
16694
|
+
}
|
|
16695
|
+
const expiresAtIso = new Date(Date.now() + parsed.value.durationMs).toISOString();
|
|
16696
|
+
const res = await postWatchTrigger({
|
|
16697
|
+
host: AGT_HOST,
|
|
16698
|
+
apiKey: AGT_API_KEY,
|
|
16699
|
+
agentId: AGT_AGENT_ID,
|
|
16700
|
+
fileId: parsed.value.fileId,
|
|
16701
|
+
expiresAtIso
|
|
16702
|
+
});
|
|
16703
|
+
if (!res.ok) {
|
|
16704
|
+
process.stderr.write(
|
|
16705
|
+
`telegram-channel(${AGENT_CODE_NAME}): /watch create failed (status=${res.status ?? "?"}): ${res.error ?? "unknown"}
|
|
16706
|
+
`
|
|
16707
|
+
);
|
|
16708
|
+
await reply(watchErrorText());
|
|
16709
|
+
return;
|
|
16710
|
+
}
|
|
16711
|
+
process.stderr.write(
|
|
16712
|
+
`telegram-channel(${AGENT_CODE_NAME}): /watch ${res.reused ? "extended" : "created"} for doc ${parsed.value.fileId.slice(0, 8)}\u2026 chat ${redactId(opts.chatId)}
|
|
16713
|
+
`
|
|
16714
|
+
);
|
|
16715
|
+
await reply(watchSuccessTextPlain(parsed.value.fileId, parsed.value.durationMs, !!res.reused));
|
|
16716
|
+
}
|
|
16523
16717
|
function buildTelegramStatusReply() {
|
|
16524
16718
|
const state = readAgentSessionState(TELEGRAM_AGENT_DIR);
|
|
16525
16719
|
return buildAgentConfigReport({
|
|
@@ -16555,10 +16749,10 @@ async function handleStatusCommand(opts) {
|
|
|
16555
16749
|
}
|
|
16556
16750
|
async function handleRestartCommand(opts) {
|
|
16557
16751
|
try {
|
|
16558
|
-
if (!
|
|
16752
|
+
if (!existsSync5(RESTART_FLAGS_DIR)) {
|
|
16559
16753
|
mkdirSync4(RESTART_FLAGS_DIR, { recursive: true });
|
|
16560
16754
|
}
|
|
16561
|
-
const flagPath =
|
|
16755
|
+
const flagPath = join6(RESTART_FLAGS_DIR, `${AGENT_CODE_NAME}.flag`);
|
|
16562
16756
|
writeTelegramRestartConfirm(
|
|
16563
16757
|
{ chat_id: opts.chatId, message_id: opts.messageId },
|
|
16564
16758
|
opts.requesterName
|
|
@@ -16925,6 +17119,10 @@ var STATUS_SYNTAX_RE = /^\/status(?:@([A-Za-z0-9_]{1,64}))?(?:\s|$)/;
|
|
|
16925
17119
|
function isStatusSyntax(text) {
|
|
16926
17120
|
return STATUS_SYNTAX_RE.test(text);
|
|
16927
17121
|
}
|
|
17122
|
+
var WATCH_SYNTAX_RE = /^\/watch(?:@([A-Za-z0-9_]{1,64}))?(?:\s|$)/;
|
|
17123
|
+
function isWatchSyntax(text) {
|
|
17124
|
+
return WATCH_SYNTAX_RE.test(text);
|
|
17125
|
+
}
|
|
16928
17126
|
function isRestartSyntax(text) {
|
|
16929
17127
|
return RESTART_SYNTAX_RE.test(text);
|
|
16930
17128
|
}
|
|
@@ -16937,10 +17135,10 @@ async function classifyRestartCommand(text) {
|
|
|
16937
17135
|
if (!ours) return "verification_failed";
|
|
16938
17136
|
return target === ours ? "act" : "ignore";
|
|
16939
17137
|
}
|
|
16940
|
-
var AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ?
|
|
16941
|
-
var PENDING_INBOUND_DIR = AGENT_DIR ?
|
|
16942
|
-
var RECOVERY_OUTBOX_DIR = AGENT_DIR ?
|
|
16943
|
-
var RESTART_CONFIRM_FILE = AGENT_DIR ?
|
|
17138
|
+
var AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? join6(homedir3(), ".augmented", AGENT_CODE_NAME) : null;
|
|
17139
|
+
var PENDING_INBOUND_DIR = AGENT_DIR ? join6(AGENT_DIR, "telegram-pending-inbound") : null;
|
|
17140
|
+
var RECOVERY_OUTBOX_DIR = AGENT_DIR ? join6(AGENT_DIR, "telegram-recovery-outbox") : null;
|
|
17141
|
+
var RESTART_CONFIRM_FILE = AGENT_DIR ? join6(AGENT_DIR, "telegram-restart-confirm.json") : null;
|
|
16944
17142
|
var TELEGRAM_PROCESS_BOOT_MS = Date.now();
|
|
16945
17143
|
function safeMarkerName(chatId, messageId) {
|
|
16946
17144
|
const safe = (s) => s.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
@@ -16948,7 +17146,7 @@ function safeMarkerName(chatId, messageId) {
|
|
|
16948
17146
|
}
|
|
16949
17147
|
function pendingInboundPath(chatId, messageId) {
|
|
16950
17148
|
if (!PENDING_INBOUND_DIR) return null;
|
|
16951
|
-
return
|
|
17149
|
+
return join6(PENDING_INBOUND_DIR, safeMarkerName(chatId, messageId));
|
|
16952
17150
|
}
|
|
16953
17151
|
function writePendingInboundMarker(chatId, messageId, chatType, undeliverable = false, payload) {
|
|
16954
17152
|
const path = pendingInboundPath(chatId, messageId);
|
|
@@ -16977,7 +17175,7 @@ function writePendingInboundMarker(chatId, messageId, chatType, undeliverable =
|
|
|
16977
17175
|
function clearTelegramMarkerFileWithHeal(fullPath) {
|
|
16978
17176
|
let marker = null;
|
|
16979
17177
|
try {
|
|
16980
|
-
marker = JSON.parse(
|
|
17178
|
+
marker = JSON.parse(readFileSync6(fullPath, "utf-8"));
|
|
16981
17179
|
} catch {
|
|
16982
17180
|
}
|
|
16983
17181
|
if (marker && decideRecoveryHeal({
|
|
@@ -16987,7 +17185,7 @@ function clearTelegramMarkerFileWithHeal(fullPath) {
|
|
|
16987
17185
|
notifyBackOnline(marker.chat_id);
|
|
16988
17186
|
}
|
|
16989
17187
|
try {
|
|
16990
|
-
if (
|
|
17188
|
+
if (existsSync5(fullPath)) unlinkSync4(fullPath);
|
|
16991
17189
|
} catch {
|
|
16992
17190
|
}
|
|
16993
17191
|
}
|
|
@@ -16998,9 +17196,9 @@ function clearPendingInboundMarker(chatId, messageId) {
|
|
|
16998
17196
|
}
|
|
16999
17197
|
function readPendingInboundMarker(chatId, messageId) {
|
|
17000
17198
|
const path = pendingInboundPath(chatId, messageId);
|
|
17001
|
-
if (!path || !
|
|
17199
|
+
if (!path || !existsSync5(path)) return null;
|
|
17002
17200
|
try {
|
|
17003
|
-
return JSON.parse(
|
|
17201
|
+
return JSON.parse(readFileSync6(path, "utf-8"));
|
|
17004
17202
|
} catch {
|
|
17005
17203
|
return null;
|
|
17006
17204
|
}
|
|
@@ -17020,10 +17218,10 @@ function nextRetryName(filename) {
|
|
|
17020
17218
|
async function processRecoveryOutboxFile(filename) {
|
|
17021
17219
|
if (!RECOVERY_OUTBOX_DIR) return;
|
|
17022
17220
|
if (filename.endsWith(".poison.json") || filename.endsWith(".tmp")) return;
|
|
17023
|
-
const fullPath =
|
|
17221
|
+
const fullPath = join6(RECOVERY_OUTBOX_DIR, filename);
|
|
17024
17222
|
let payload;
|
|
17025
17223
|
try {
|
|
17026
|
-
const raw =
|
|
17224
|
+
const raw = readFileSync6(fullPath, "utf-8");
|
|
17027
17225
|
payload = JSON.parse(raw);
|
|
17028
17226
|
} catch (err) {
|
|
17029
17227
|
process.stderr.write(
|
|
@@ -17086,7 +17284,7 @@ async function processRecoveryOutboxFile(filename) {
|
|
|
17086
17284
|
const next = nextRetryName(filename);
|
|
17087
17285
|
if (next) {
|
|
17088
17286
|
try {
|
|
17089
|
-
renameSync4(fullPath,
|
|
17287
|
+
renameSync4(fullPath, join6(RECOVERY_OUTBOX_DIR, next.next));
|
|
17090
17288
|
if (next.attempt >= MAX_RECOVERY_ATTEMPTS) {
|
|
17091
17289
|
process.stderr.write(
|
|
17092
17290
|
`telegram-channel(${AGENT_CODE_NAME}): ghost-reply recovery exhausted retries \u2014 moved to ${next.next}
|
|
@@ -17126,7 +17324,7 @@ function scanRecoveryRetries() {
|
|
|
17126
17324
|
if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
|
|
17127
17325
|
let mtimeMs;
|
|
17128
17326
|
try {
|
|
17129
|
-
mtimeMs = statSync(
|
|
17327
|
+
mtimeMs = statSync(join6(RECOVERY_OUTBOX_DIR, f)).mtimeMs;
|
|
17130
17328
|
} catch {
|
|
17131
17329
|
continue;
|
|
17132
17330
|
}
|
|
@@ -17156,7 +17354,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
17156
17354
|
const watcher = watch(RECOVERY_OUTBOX_DIR, (event, filename) => {
|
|
17157
17355
|
if (event !== "rename" || !filename) return;
|
|
17158
17356
|
if (!isFirstAttemptOutboxFile(filename)) return;
|
|
17159
|
-
if (
|
|
17357
|
+
if (existsSync5(join6(RECOVERY_OUTBOX_DIR, filename))) {
|
|
17160
17358
|
void processRecoveryOutboxFile(filename);
|
|
17161
17359
|
}
|
|
17162
17360
|
});
|
|
@@ -17177,7 +17375,7 @@ function trackPendingMessage(chatId, messageId, chatType, undeliverable = false,
|
|
|
17177
17375
|
}
|
|
17178
17376
|
function sweepTelegramStaleMarkers(thresholdMs) {
|
|
17179
17377
|
if (!PENDING_INBOUND_DIR) return;
|
|
17180
|
-
if (!
|
|
17378
|
+
if (!existsSync5(PENDING_INBOUND_DIR)) return;
|
|
17181
17379
|
let filenames;
|
|
17182
17380
|
try {
|
|
17183
17381
|
filenames = readdirSync2(PENDING_INBOUND_DIR);
|
|
@@ -17193,10 +17391,10 @@ function sweepTelegramStaleMarkers(thresholdMs) {
|
|
|
17193
17391
|
for (const filename of filenames) {
|
|
17194
17392
|
if (!filename.endsWith(".json")) continue;
|
|
17195
17393
|
if (filename.endsWith(".tmp")) continue;
|
|
17196
|
-
const fullPath =
|
|
17394
|
+
const fullPath = join6(PENDING_INBOUND_DIR, filename);
|
|
17197
17395
|
let marker;
|
|
17198
17396
|
try {
|
|
17199
|
-
marker = JSON.parse(
|
|
17397
|
+
marker = JSON.parse(readFileSync6(fullPath, "utf-8"));
|
|
17200
17398
|
} catch (err) {
|
|
17201
17399
|
process.stderr.write(
|
|
17202
17400
|
`telegram-channel(${AGENT_CODE_NAME}): stale-marker parse failed for ${redactId(filename)}: ${err.message}
|
|
@@ -17235,14 +17433,14 @@ var orphanSweepTimer = setInterval(() => {
|
|
|
17235
17433
|
orphanSweepTimer.unref?.();
|
|
17236
17434
|
var lastGiveUpHandledAtMs = null;
|
|
17237
17435
|
function listPendingInboundChatIds() {
|
|
17238
|
-
if (!PENDING_INBOUND_DIR || !
|
|
17436
|
+
if (!PENDING_INBOUND_DIR || !existsSync5(PENDING_INBOUND_DIR)) return [];
|
|
17239
17437
|
const chats = /* @__PURE__ */ new Set();
|
|
17240
17438
|
try {
|
|
17241
17439
|
for (const name of readdirSync2(PENDING_INBOUND_DIR)) {
|
|
17242
17440
|
if (!name.endsWith(".json")) continue;
|
|
17243
17441
|
try {
|
|
17244
17442
|
const marker = JSON.parse(
|
|
17245
|
-
|
|
17443
|
+
readFileSync6(join6(PENDING_INBOUND_DIR, name), "utf8")
|
|
17246
17444
|
);
|
|
17247
17445
|
if (typeof marker.chat_id === "string" && marker.chat_id) chats.add(marker.chat_id);
|
|
17248
17446
|
} catch {
|
|
@@ -17283,7 +17481,7 @@ async function notifyWatchdogGiveUp(chatId) {
|
|
|
17283
17481
|
}
|
|
17284
17482
|
function checkWatchdogGiveUpNotice() {
|
|
17285
17483
|
if (!AGENT_DIR) return;
|
|
17286
|
-
const signalAtMs = readGiveUpSignalAtMs(
|
|
17484
|
+
const signalAtMs = readGiveUpSignalAtMs(join6(AGENT_DIR, GIVE_UP_SIGNAL_FILENAME));
|
|
17287
17485
|
const act = decideGiveUpNotice({
|
|
17288
17486
|
signalAtMs,
|
|
17289
17487
|
lastHandledAtMs: lastGiveUpHandledAtMs,
|
|
@@ -17361,7 +17559,7 @@ function clearPendingMessage(chatId, messageId) {
|
|
|
17361
17559
|
clearPendingInboundMarker(chatId, messageId);
|
|
17362
17560
|
return;
|
|
17363
17561
|
}
|
|
17364
|
-
if (!PENDING_INBOUND_DIR || !
|
|
17562
|
+
if (!PENDING_INBOUND_DIR || !existsSync5(PENDING_INBOUND_DIR)) return;
|
|
17365
17563
|
const safeChatId = chatId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
17366
17564
|
const prefix = `${safeChatId}__`;
|
|
17367
17565
|
let filenames;
|
|
@@ -17373,7 +17571,7 @@ function clearPendingMessage(chatId, messageId) {
|
|
|
17373
17571
|
for (const filename of filenames) {
|
|
17374
17572
|
if (!filename.startsWith(prefix)) continue;
|
|
17375
17573
|
if (!filename.endsWith(".json")) continue;
|
|
17376
|
-
clearTelegramMarkerFileWithHeal(
|
|
17574
|
+
clearTelegramMarkerFileWithHeal(join6(PENDING_INBOUND_DIR, filename));
|
|
17377
17575
|
}
|
|
17378
17576
|
}
|
|
17379
17577
|
function noteThreadActivity(chatId, messageId) {
|
|
@@ -17972,7 +18170,7 @@ await mcp.connect(new StdioServerTransport());
|
|
|
17972
18170
|
var REPLAY_SCAN_INTERVAL_MS = 6e4;
|
|
17973
18171
|
async function replayPendingTelegramMarkers() {
|
|
17974
18172
|
if (!channelReplayEnabled()) return;
|
|
17975
|
-
if (!PENDING_INBOUND_DIR || !
|
|
18173
|
+
if (!PENDING_INBOUND_DIR || !existsSync5(PENDING_INBOUND_DIR)) return;
|
|
17976
18174
|
const probe = process.env.TMUX && AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? probeAgentSessionCached(AGENT_CODE_NAME) : { tmux: "unknown", claude: "unknown" };
|
|
17977
18175
|
const sessionAlive = probe.tmux === "alive" && probe.claude === "alive";
|
|
17978
18176
|
if (!sessionAlive) return;
|
|
@@ -17986,10 +18184,10 @@ async function replayPendingTelegramMarkers() {
|
|
|
17986
18184
|
const entries = [];
|
|
17987
18185
|
for (const name of filenames) {
|
|
17988
18186
|
if (!name.endsWith(".json") || name.endsWith(".tmp")) continue;
|
|
17989
|
-
const fullPath =
|
|
18187
|
+
const fullPath = join6(PENDING_INBOUND_DIR, name);
|
|
17990
18188
|
let marker;
|
|
17991
18189
|
try {
|
|
17992
|
-
marker = JSON.parse(
|
|
18190
|
+
marker = JSON.parse(readFileSync6(fullPath, "utf-8"));
|
|
17993
18191
|
} catch {
|
|
17994
18192
|
continue;
|
|
17995
18193
|
}
|
|
@@ -18021,7 +18219,7 @@ async function replayPendingTelegramMarkers() {
|
|
|
18021
18219
|
continue;
|
|
18022
18220
|
}
|
|
18023
18221
|
try {
|
|
18024
|
-
if (
|
|
18222
|
+
if (existsSync5(path)) {
|
|
18025
18223
|
const updated = {
|
|
18026
18224
|
...marker,
|
|
18027
18225
|
replay_count: (marker.replay_count ?? 0) + 1
|
|
@@ -18166,7 +18364,7 @@ async function pollLoop() {
|
|
|
18166
18364
|
const trimmedContent = content.trim();
|
|
18167
18365
|
const isFromBot = !!msg.from?.is_bot;
|
|
18168
18366
|
const nowMs = Date.now();
|
|
18169
|
-
const telegramCommand = isHelpSyntax(trimmedContent) ? "help" : isStatusSyntax(trimmedContent) ? "status" : isRestartSyntax(trimmedContent) ? "restart" : isInvestigateSyntax(trimmedContent) ? "investigate" : void 0;
|
|
18367
|
+
const telegramCommand = isHelpSyntax(trimmedContent) ? "help" : isStatusSyntax(trimmedContent) ? "status" : isWatchSyntax(trimmedContent) ? "watch" : isRestartSyntax(trimmedContent) ? "restart" : isInvestigateSyntax(trimmedContent) ? "investigate" : void 0;
|
|
18170
18368
|
let classification;
|
|
18171
18369
|
let peerLeaf;
|
|
18172
18370
|
if (isFromBot) {
|
|
@@ -18246,6 +18444,19 @@ async function pollLoop() {
|
|
|
18246
18444
|
}
|
|
18247
18445
|
continue;
|
|
18248
18446
|
}
|
|
18447
|
+
if (access.kind === "command" && access.command === "watch") {
|
|
18448
|
+
const disposition = await classifyRestartCommand(
|
|
18449
|
+
trimmedContent.replace(/^\/watch(@[A-Za-z0-9_]{1,64})?/, "/restart$1")
|
|
18450
|
+
);
|
|
18451
|
+
if (disposition === "act") {
|
|
18452
|
+
await handleWatchCommand({
|
|
18453
|
+
chatId,
|
|
18454
|
+
messageId: String(msg.message_id),
|
|
18455
|
+
text: trimmedContent
|
|
18456
|
+
});
|
|
18457
|
+
}
|
|
18458
|
+
continue;
|
|
18459
|
+
}
|
|
18249
18460
|
if (access.kind === "command" && access.command === "restart") {
|
|
18250
18461
|
const disposition = await classifyRestartCommand(trimmedContent);
|
|
18251
18462
|
if (disposition === "act") {
|
|
@@ -18384,7 +18595,7 @@ async function pollLoop() {
|
|
|
18384
18595
|
let paneLogFreshAgeMs = null;
|
|
18385
18596
|
if (AGENT_DIR) {
|
|
18386
18597
|
try {
|
|
18387
|
-
const paneMtimeMs = statSync(
|
|
18598
|
+
const paneMtimeMs = statSync(join6(AGENT_DIR, "pane.log")).mtimeMs;
|
|
18388
18599
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
18389
18600
|
} catch {
|
|
18390
18601
|
}
|
|
@@ -25,8 +25,8 @@ import {
|
|
|
25
25
|
takeAcpxExecFailureCount,
|
|
26
26
|
takeZombieDetection,
|
|
27
27
|
writePersistentClaudeWrapper
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
28
|
+
} from "./chunk-5TBIEU36.js";
|
|
29
|
+
import "./chunk-3A2H4ZLD.js";
|
|
30
30
|
import "./chunk-XWVM4KPK.js";
|
|
31
31
|
export {
|
|
32
32
|
SEND_KEYS_ENTER_DELAY_MS,
|
|
@@ -56,4 +56,4 @@ export {
|
|
|
56
56
|
takeZombieDetection,
|
|
57
57
|
writePersistentClaudeWrapper
|
|
58
58
|
};
|
|
59
|
-
//# sourceMappingURL=persistent-session-
|
|
59
|
+
//# sourceMappingURL=persistent-session-7BLPRGWR.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paneLogPath
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-5TBIEU36.js";
|
|
4
|
+
import "./chunk-3A2H4ZLD.js";
|
|
5
5
|
import "./chunk-XWVM4KPK.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/responsiveness-probe.ts
|
|
@@ -192,4 +192,4 @@ export {
|
|
|
192
192
|
oldestLivePendingInboundMtimeMs,
|
|
193
193
|
parkPendingInbound
|
|
194
194
|
};
|
|
195
|
-
//# sourceMappingURL=responsiveness-probe-
|
|
195
|
+
//# sourceMappingURL=responsiveness-probe-AL3O7SYZ.js.map
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|