@integrity-labs/agt-cli 0.28.449 → 0.28.450
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-MDD7H7EP.js → chunk-NJZI6BPI.js} +2 -2
- package/dist/lib/manager-worker.js +2 -2
- package/dist/mcp/slack-channel.js +538 -152
- package/dist/mcp/telegram-channel.js +488 -103
- package/package.json +1 -1
- /package/dist/{chunk-MDD7H7EP.js.map → chunk-NJZI6BPI.js.map} +0 -0
|
@@ -18870,7 +18870,7 @@ var require_filters = __commonJS({
|
|
|
18870
18870
|
return r.copySafeness(str, res);
|
|
18871
18871
|
}
|
|
18872
18872
|
_exports.indent = indent;
|
|
18873
|
-
function
|
|
18873
|
+
function join21(arr, del, attr) {
|
|
18874
18874
|
del = del || "";
|
|
18875
18875
|
if (attr) {
|
|
18876
18876
|
arr = lib.map(arr, function(v) {
|
|
@@ -18879,7 +18879,7 @@ var require_filters = __commonJS({
|
|
|
18879
18879
|
}
|
|
18880
18880
|
return arr.join(del);
|
|
18881
18881
|
}
|
|
18882
|
-
_exports.join =
|
|
18882
|
+
_exports.join = join21;
|
|
18883
18883
|
function last(arr) {
|
|
18884
18884
|
return arr[arr.length - 1];
|
|
18885
18885
|
}
|
|
@@ -22480,11 +22480,11 @@ async function waitForResolution(cfg, callbackId, opts) {
|
|
|
22480
22480
|
}
|
|
22481
22481
|
} catch {
|
|
22482
22482
|
}
|
|
22483
|
-
await
|
|
22483
|
+
await sleep2(interval);
|
|
22484
22484
|
}
|
|
22485
22485
|
return { kind: "timeout" };
|
|
22486
22486
|
}
|
|
22487
|
-
function
|
|
22487
|
+
function sleep2(ms) {
|
|
22488
22488
|
return new Promise((r) => setTimeout(r, ms));
|
|
22489
22489
|
}
|
|
22490
22490
|
function generateOptionToken() {
|
|
@@ -30393,6 +30393,40 @@ function resolveSlackScheduledChannelGuardMode(opts) {
|
|
|
30393
30393
|
if (cached2 !== void 0) return clampScheduledChannelGuardMode(cached2);
|
|
30394
30394
|
return "shadow";
|
|
30395
30395
|
}
|
|
30396
|
+
var USAGE_LIMIT_REACTIVE_FLAG_KEY = "usage-limit-reactive-notice";
|
|
30397
|
+
function parseUsageLimitReactiveMode(raw) {
|
|
30398
|
+
if (raw === void 0) return void 0;
|
|
30399
|
+
const v = raw.trim().toLowerCase();
|
|
30400
|
+
if (v === "") return void 0;
|
|
30401
|
+
if (v === "off" || v === "shadow" || v === "enforce") return v;
|
|
30402
|
+
const b = envBoolean(raw);
|
|
30403
|
+
if (b === true) return "enforce";
|
|
30404
|
+
if (b === false) return "off";
|
|
30405
|
+
return void 0;
|
|
30406
|
+
}
|
|
30407
|
+
function cachedUsageLimitReactiveMode(path) {
|
|
30408
|
+
try {
|
|
30409
|
+
if (!existsSync(path)) return void 0;
|
|
30410
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
30411
|
+
if (!parsed || typeof parsed !== "object") return void 0;
|
|
30412
|
+
const flags = parsed.flags;
|
|
30413
|
+
if (!flags || typeof flags !== "object") return void 0;
|
|
30414
|
+
const value = flags[USAGE_LIMIT_REACTIVE_FLAG_KEY];
|
|
30415
|
+
if (typeof value === "string") return parseUsageLimitReactiveMode(value);
|
|
30416
|
+
if (typeof value === "boolean") return value ? "enforce" : "off";
|
|
30417
|
+
return void 0;
|
|
30418
|
+
} catch {
|
|
30419
|
+
return void 0;
|
|
30420
|
+
}
|
|
30421
|
+
}
|
|
30422
|
+
function resolveUsageLimitReactiveMode(opts) {
|
|
30423
|
+
const env2 = opts?.env ?? process.env;
|
|
30424
|
+
const modeOverride = parseUsageLimitReactiveMode(env2["AGT_USAGE_LIMIT_REACTIVE_MODE"]);
|
|
30425
|
+
if (modeOverride !== void 0) return modeOverride;
|
|
30426
|
+
const cached2 = cachedUsageLimitReactiveMode(opts?.cachePath ?? defaultFlagsCachePath());
|
|
30427
|
+
if (cached2 !== void 0) return cached2;
|
|
30428
|
+
return "off";
|
|
30429
|
+
}
|
|
30396
30430
|
|
|
30397
30431
|
// src/maintenance-mode.ts
|
|
30398
30432
|
var FLAG_KEY = "platform-maintenance-mode";
|
|
@@ -33734,7 +33768,113 @@ var BANNER_PATTERNS = [
|
|
|
33734
33768
|
// pct=100.
|
|
33735
33769
|
new RegExp(`${SUBJECT}hit\\s+your\\s+(?:[a-z0-9-]+\\s+)?limit${SEP}resets\\s+(${RESET_DATE})`, "i")
|
|
33736
33770
|
];
|
|
33771
|
+
function parseUsageBanner(text, now = /* @__PURE__ */ new Date()) {
|
|
33772
|
+
let bestIndex = -1;
|
|
33773
|
+
let best = null;
|
|
33774
|
+
for (let i = 0; i < BANNER_PATTERNS.length; i++) {
|
|
33775
|
+
const pattern = new RegExp(BANNER_PATTERNS[i].source, "gi");
|
|
33776
|
+
let match;
|
|
33777
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
33778
|
+
if (match.index === pattern.lastIndex)
|
|
33779
|
+
pattern.lastIndex++;
|
|
33780
|
+
let pct;
|
|
33781
|
+
let resetStr;
|
|
33782
|
+
if (i === 0) {
|
|
33783
|
+
pct = Number.parseInt(match[1], 10);
|
|
33784
|
+
resetStr = match[2];
|
|
33785
|
+
} else {
|
|
33786
|
+
pct = 100;
|
|
33787
|
+
resetStr = match[1];
|
|
33788
|
+
}
|
|
33789
|
+
if (!Number.isFinite(pct) || pct < 0 || pct > 100)
|
|
33790
|
+
continue;
|
|
33791
|
+
const nextChar = text[match.index + match[0].length];
|
|
33792
|
+
if (nextChar !== void 0 && /[A-Za-z0-9]/.test(nextChar))
|
|
33793
|
+
continue;
|
|
33794
|
+
const weekResetsAt = parseResetDateTime(resetStr, now);
|
|
33795
|
+
if (!weekResetsAt)
|
|
33796
|
+
continue;
|
|
33797
|
+
if (match.index >= bestIndex) {
|
|
33798
|
+
bestIndex = match.index;
|
|
33799
|
+
best = { pct, weekResetsAt };
|
|
33800
|
+
}
|
|
33801
|
+
}
|
|
33802
|
+
}
|
|
33803
|
+
return best;
|
|
33804
|
+
}
|
|
33805
|
+
var MONTHS = [
|
|
33806
|
+
"jan",
|
|
33807
|
+
"feb",
|
|
33808
|
+
"mar",
|
|
33809
|
+
"apr",
|
|
33810
|
+
"may",
|
|
33811
|
+
"jun",
|
|
33812
|
+
"jul",
|
|
33813
|
+
"aug",
|
|
33814
|
+
"sep",
|
|
33815
|
+
"oct",
|
|
33816
|
+
"nov",
|
|
33817
|
+
"dec"
|
|
33818
|
+
];
|
|
33819
|
+
var TIME_TAIL = /,\s*(\d{1,2})(?::(\d{2}))?\s*(am|pm)(?:\s*\(?UTC\)?)?\s*$/i;
|
|
33820
|
+
var TIME_ONLY = /^(\d{1,2})(?::(\d{2}))?\s*(am|pm)(?:\s*\(?UTC\)?)?$/i;
|
|
33737
33821
|
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
33822
|
+
function parseAmPm(hourStr, minStr, ampm) {
|
|
33823
|
+
const rawHour = Number.parseInt(hourStr, 10);
|
|
33824
|
+
if (!Number.isFinite(rawHour) || rawHour < 1 || rawHour > 12)
|
|
33825
|
+
return null;
|
|
33826
|
+
let minute = 0;
|
|
33827
|
+
if (minStr) {
|
|
33828
|
+
minute = Number.parseInt(minStr, 10);
|
|
33829
|
+
if (!Number.isFinite(minute) || minute < 0 || minute > 59)
|
|
33830
|
+
return null;
|
|
33831
|
+
}
|
|
33832
|
+
const isPm = ampm.toLowerCase() === "pm";
|
|
33833
|
+
return { hour: rawHour % 12 + (isPm ? 12 : 0), minute };
|
|
33834
|
+
}
|
|
33835
|
+
function parseResetDateTime(humanDate, now) {
|
|
33836
|
+
const trimmed = humanDate.trim();
|
|
33837
|
+
const timeOnly = trimmed.match(TIME_ONLY);
|
|
33838
|
+
if (timeOnly) {
|
|
33839
|
+
const hm = parseAmPm(timeOnly[1], timeOnly[2], timeOnly[3]);
|
|
33840
|
+
if (!hm)
|
|
33841
|
+
return null;
|
|
33842
|
+
const todayAt = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), hm.hour, hm.minute);
|
|
33843
|
+
return new Date(todayAt <= now.getTime() ? todayAt + MS_PER_DAY : todayAt);
|
|
33844
|
+
}
|
|
33845
|
+
const timeMatch = trimmed.match(TIME_TAIL);
|
|
33846
|
+
const dateOnly = timeMatch ? trimmed.slice(0, timeMatch.index).trim() : trimmed;
|
|
33847
|
+
const parts = dateOnly.split(/\s+/);
|
|
33848
|
+
if (parts.length !== 2)
|
|
33849
|
+
return null;
|
|
33850
|
+
const month = MONTHS.indexOf(parts[0].slice(0, 3).toLowerCase());
|
|
33851
|
+
if (month < 0)
|
|
33852
|
+
return null;
|
|
33853
|
+
const day = Number.parseInt(parts[1], 10);
|
|
33854
|
+
if (!Number.isFinite(day) || day < 1 || day > 31)
|
|
33855
|
+
return null;
|
|
33856
|
+
let hour = 0;
|
|
33857
|
+
let minute = 0;
|
|
33858
|
+
if (timeMatch) {
|
|
33859
|
+
const hm = parseAmPm(timeMatch[1], timeMatch[2], timeMatch[3]);
|
|
33860
|
+
if (!hm)
|
|
33861
|
+
return null;
|
|
33862
|
+
hour = hm.hour;
|
|
33863
|
+
minute = hm.minute;
|
|
33864
|
+
}
|
|
33865
|
+
const baseYear = now.getUTCFullYear();
|
|
33866
|
+
let resolved = null;
|
|
33867
|
+
let bestDelta = Number.POSITIVE_INFINITY;
|
|
33868
|
+
for (const y of [baseYear - 1, baseYear, baseYear + 1]) {
|
|
33869
|
+
const candidate = new Date(Date.UTC(y, month, day, hour, minute));
|
|
33870
|
+
const delta = Math.abs(candidate.getTime() - now.getTime());
|
|
33871
|
+
if (delta < bestDelta) {
|
|
33872
|
+
bestDelta = delta;
|
|
33873
|
+
resolved = candidate;
|
|
33874
|
+
}
|
|
33875
|
+
}
|
|
33876
|
+
return resolved;
|
|
33877
|
+
}
|
|
33738
33878
|
|
|
33739
33879
|
// ../core/dist/claude-code-usage/usage-limit-marker.js
|
|
33740
33880
|
var USAGE_LIMIT_MARKER_FILENAME = "claude-usage-limit.json";
|
|
@@ -33779,6 +33919,101 @@ var UNKNOWN_RATE_LIMIT = Object.freeze({
|
|
|
33779
33919
|
resetsAt: null,
|
|
33780
33920
|
text: null
|
|
33781
33921
|
});
|
|
33922
|
+
function contentText(record2) {
|
|
33923
|
+
const candidates = [record2.content];
|
|
33924
|
+
const message = record2.message;
|
|
33925
|
+
if (typeof message === "object" && message !== null) {
|
|
33926
|
+
candidates.push(message.content);
|
|
33927
|
+
}
|
|
33928
|
+
const parts = [];
|
|
33929
|
+
for (const candidate of candidates) {
|
|
33930
|
+
if (typeof candidate === "string") {
|
|
33931
|
+
if (candidate)
|
|
33932
|
+
parts.push(candidate);
|
|
33933
|
+
continue;
|
|
33934
|
+
}
|
|
33935
|
+
if (!Array.isArray(candidate))
|
|
33936
|
+
continue;
|
|
33937
|
+
for (const block of candidate) {
|
|
33938
|
+
if (typeof block === "string") {
|
|
33939
|
+
if (block)
|
|
33940
|
+
parts.push(block);
|
|
33941
|
+
continue;
|
|
33942
|
+
}
|
|
33943
|
+
if (typeof block !== "object" || block === null)
|
|
33944
|
+
continue;
|
|
33945
|
+
const text = block.text;
|
|
33946
|
+
if (typeof text === "string" && text)
|
|
33947
|
+
parts.push(text);
|
|
33948
|
+
}
|
|
33949
|
+
}
|
|
33950
|
+
const joined = parts.join("\n").trim();
|
|
33951
|
+
return joined ? joined : null;
|
|
33952
|
+
}
|
|
33953
|
+
function classifyTranscriptLine(line, startMs, endMs, now) {
|
|
33954
|
+
const trimmed = line.trim();
|
|
33955
|
+
if (!trimmed)
|
|
33956
|
+
return null;
|
|
33957
|
+
let obj;
|
|
33958
|
+
try {
|
|
33959
|
+
obj = JSON.parse(trimmed);
|
|
33960
|
+
} catch {
|
|
33961
|
+
return null;
|
|
33962
|
+
}
|
|
33963
|
+
if (typeof obj !== "object" || obj === null)
|
|
33964
|
+
return null;
|
|
33965
|
+
const record2 = obj;
|
|
33966
|
+
if (record2.type !== "assistant")
|
|
33967
|
+
return null;
|
|
33968
|
+
const ts = record2.timestamp;
|
|
33969
|
+
if (typeof ts !== "string" || !ts)
|
|
33970
|
+
return null;
|
|
33971
|
+
const tsMs = new Date(ts).getTime();
|
|
33972
|
+
if (!Number.isFinite(tsMs) || tsMs < startMs || tsMs > endMs)
|
|
33973
|
+
return null;
|
|
33974
|
+
if (record2.error === "rate_limit" || record2.apiErrorStatus === 429) {
|
|
33975
|
+
const text = contentText(record2);
|
|
33976
|
+
const observation = text ? parseUsageBanner(text, now ?? new Date(endMs)) : null;
|
|
33977
|
+
return { verdict: "capped", atMs: tsMs, resetsAt: observation?.weekResetsAt ?? null, text };
|
|
33978
|
+
}
|
|
33979
|
+
if (record2.isApiErrorMessage === true)
|
|
33980
|
+
return null;
|
|
33981
|
+
const message = record2.message;
|
|
33982
|
+
if (typeof message !== "object" || message === null)
|
|
33983
|
+
return null;
|
|
33984
|
+
const msg = message;
|
|
33985
|
+
if (msg.model === "<synthetic>")
|
|
33986
|
+
return null;
|
|
33987
|
+
const usage = msg.usage;
|
|
33988
|
+
if (typeof usage !== "object" || usage === null)
|
|
33989
|
+
return null;
|
|
33990
|
+
const u = usage;
|
|
33991
|
+
const spent = Number(u.input_tokens ?? 0) + Number(u.output_tokens ?? 0) + Number(u.cache_creation_input_tokens ?? 0) + Number(u.cache_read_input_tokens ?? 0);
|
|
33992
|
+
if (!Number.isFinite(spent) || spent <= 0)
|
|
33993
|
+
return null;
|
|
33994
|
+
return { verdict: "serving", atMs: tsMs, resetsAt: null, text: null };
|
|
33995
|
+
}
|
|
33996
|
+
function pickNewerClassification(current, next) {
|
|
33997
|
+
if (next.verdict === "unknown")
|
|
33998
|
+
return current;
|
|
33999
|
+
if (current.verdict === "unknown")
|
|
34000
|
+
return next;
|
|
34001
|
+
return next.atMs >= current.atMs ? next : current;
|
|
34002
|
+
}
|
|
34003
|
+
function classifyTranscriptRateLimit(jsonl, startMs, endMs, now) {
|
|
34004
|
+
let newest = UNKNOWN_RATE_LIMIT;
|
|
34005
|
+
for (const line of jsonl.split("\n")) {
|
|
34006
|
+
const classified = classifyTranscriptLine(line, startMs, endMs, now);
|
|
34007
|
+
if (classified)
|
|
34008
|
+
newest = pickNewerClassification(newest, classified);
|
|
34009
|
+
}
|
|
34010
|
+
return newest;
|
|
34011
|
+
}
|
|
34012
|
+
|
|
34013
|
+
// ../core/dist/claude-code-usage/transcript-location.js
|
|
34014
|
+
function encodeClaudeProjectPath(projectDir) {
|
|
34015
|
+
return "-" + projectDir.replace(/^\//, "").replace(/[/.]/g, "-");
|
|
34016
|
+
}
|
|
33782
34017
|
|
|
33783
34018
|
// ../core/dist/account-enforcement/marker.js
|
|
33784
34019
|
var ACCOUNT_ENFORCEMENT_MARKER_FILENAME = "account-enforcement.json";
|
|
@@ -36309,11 +36544,102 @@ function emitToolCallMarkupRedactionTelemetry(channel) {
|
|
|
36309
36544
|
}
|
|
36310
36545
|
}
|
|
36311
36546
|
|
|
36547
|
+
// src/rate-limit-watch.ts
|
|
36548
|
+
import { readFileSync as readFileSync6, readdirSync as readdirSync2, statSync } from "fs";
|
|
36549
|
+
import { homedir as homedir5 } from "os";
|
|
36550
|
+
import { join as join7 } from "path";
|
|
36551
|
+
var DEFAULT_WATCH_MS = 5e3;
|
|
36552
|
+
var DEFAULT_POLL_MS = 400;
|
|
36553
|
+
function agentTranscriptDir(opts) {
|
|
36554
|
+
const cwd = opts?.cwd ?? process.cwd();
|
|
36555
|
+
const home = opts?.home ?? homedir5();
|
|
36556
|
+
return join7(home, ".claude", "projects", encodeClaudeProjectPath(cwd));
|
|
36557
|
+
}
|
|
36558
|
+
function classifyTranscriptSince(opts) {
|
|
36559
|
+
const dir = opts.transcriptDir ?? agentTranscriptDir({ cwd: opts.cwd, home: opts.home });
|
|
36560
|
+
let entries;
|
|
36561
|
+
try {
|
|
36562
|
+
entries = readdirSync2(dir);
|
|
36563
|
+
} catch {
|
|
36564
|
+
return UNKNOWN_RATE_LIMIT;
|
|
36565
|
+
}
|
|
36566
|
+
let newest = UNKNOWN_RATE_LIMIT;
|
|
36567
|
+
for (const name of entries) {
|
|
36568
|
+
if (!name.endsWith(".jsonl")) continue;
|
|
36569
|
+
const path = join7(dir, name);
|
|
36570
|
+
try {
|
|
36571
|
+
const st = statSync(path);
|
|
36572
|
+
if (!st.isFile() || st.mtimeMs < opts.sinceMs) continue;
|
|
36573
|
+
} catch {
|
|
36574
|
+
continue;
|
|
36575
|
+
}
|
|
36576
|
+
let content;
|
|
36577
|
+
try {
|
|
36578
|
+
content = readFileSync6(path, "utf-8");
|
|
36579
|
+
} catch {
|
|
36580
|
+
continue;
|
|
36581
|
+
}
|
|
36582
|
+
newest = pickNewerClassification(
|
|
36583
|
+
newest,
|
|
36584
|
+
classifyTranscriptRateLimit(content, opts.sinceMs, opts.nowMs, new Date(opts.nowMs))
|
|
36585
|
+
);
|
|
36586
|
+
}
|
|
36587
|
+
return newest;
|
|
36588
|
+
}
|
|
36589
|
+
var sleep = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
36590
|
+
async function watchForRateLimitRefusal(opts) {
|
|
36591
|
+
const now = opts.now ?? (() => Date.now());
|
|
36592
|
+
const wait = opts.wait ?? sleep;
|
|
36593
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_WATCH_MS;
|
|
36594
|
+
const pollMs = opts.pollMs ?? DEFAULT_POLL_MS;
|
|
36595
|
+
const deadline = now() + timeoutMs;
|
|
36596
|
+
for (; ; ) {
|
|
36597
|
+
let result;
|
|
36598
|
+
try {
|
|
36599
|
+
result = classifyTranscriptSince({
|
|
36600
|
+
sinceMs: opts.sinceMs,
|
|
36601
|
+
nowMs: now(),
|
|
36602
|
+
transcriptDir: opts.transcriptDir,
|
|
36603
|
+
cwd: opts.cwd,
|
|
36604
|
+
home: opts.home
|
|
36605
|
+
});
|
|
36606
|
+
} catch {
|
|
36607
|
+
return null;
|
|
36608
|
+
}
|
|
36609
|
+
if (result.verdict === "capped") return result;
|
|
36610
|
+
if (result.verdict === "serving") return null;
|
|
36611
|
+
if (now() >= deadline) return null;
|
|
36612
|
+
await wait(pollMs);
|
|
36613
|
+
}
|
|
36614
|
+
}
|
|
36615
|
+
|
|
36616
|
+
// src/usage-limit-reactive-decision.ts
|
|
36617
|
+
import { createHash } from "crypto";
|
|
36618
|
+
function shouldReadPredictiveMarker(mode) {
|
|
36619
|
+
return mode !== "enforce";
|
|
36620
|
+
}
|
|
36621
|
+
function armedWatchMode(opts) {
|
|
36622
|
+
if (opts.mode === "off") return null;
|
|
36623
|
+
if (opts.isBot || !opts.replyOwed) return null;
|
|
36624
|
+
return opts.mode;
|
|
36625
|
+
}
|
|
36626
|
+
function decideRefusalAction(opts) {
|
|
36627
|
+
const { refusal } = opts;
|
|
36628
|
+
if (!refusal || refusal.verdict !== "capped") return "none";
|
|
36629
|
+
if (!refusal.resetsAt) return "missing-reset";
|
|
36630
|
+
return opts.mode === "shadow" ? "shadow-log" : "notify";
|
|
36631
|
+
}
|
|
36632
|
+
function describeUnparsedRefusal(text) {
|
|
36633
|
+
if (!text) return "refusal=absent";
|
|
36634
|
+
const hash = createHash("sha256").update(text).digest("hex").slice(0, 12);
|
|
36635
|
+
return `refusal_hash=${hash} refusal_len=${text.length}`;
|
|
36636
|
+
}
|
|
36637
|
+
|
|
36312
36638
|
// src/reply-intent-runtime.ts
|
|
36313
36639
|
import { execFile as execFile2 } from "child_process";
|
|
36314
36640
|
import { existsSync as existsSync3, mkdirSync, writeFileSync as writeFileSync2 } from "fs";
|
|
36315
|
-
import { homedir as
|
|
36316
|
-
import { join as
|
|
36641
|
+
import { homedir as homedir6 } from "os";
|
|
36642
|
+
import { join as join8 } from "path";
|
|
36317
36643
|
var DEFAULT_CLAUDE_EVAL_MODEL = "claude-haiku-4-5-20251001";
|
|
36318
36644
|
var DEFAULT_ANTHROPIC_MESSAGES_URL = "https://api.anthropic.com/v1/messages";
|
|
36319
36645
|
var ANTHROPIC_API_VERSION = "2023-06-01";
|
|
@@ -36412,12 +36738,12 @@ async function runAnthropicMessages(prompt, opts) {
|
|
|
36412
36738
|
var emptyMcpConfigPath = null;
|
|
36413
36739
|
function ensureEmptyMcpConfig() {
|
|
36414
36740
|
if (emptyMcpConfigPath && existsSync3(emptyMcpConfigPath)) return emptyMcpConfigPath;
|
|
36415
|
-
const dir =
|
|
36741
|
+
const dir = join8(homedir6(), ".augmented");
|
|
36416
36742
|
try {
|
|
36417
36743
|
mkdirSync(dir, { recursive: true });
|
|
36418
36744
|
} catch {
|
|
36419
36745
|
}
|
|
36420
|
-
const p2 =
|
|
36746
|
+
const p2 = join8(dir, ".reply-intent-empty-mcp.json");
|
|
36421
36747
|
writeFileSync2(p2, JSON.stringify({ mcpServers: {} }));
|
|
36422
36748
|
emptyMcpConfigPath = p2;
|
|
36423
36749
|
return p2;
|
|
@@ -36442,7 +36768,7 @@ function runClaudeP(prompt, model) {
|
|
|
36442
36768
|
execFile2(
|
|
36443
36769
|
"claude",
|
|
36444
36770
|
args,
|
|
36445
|
-
{ cwd:
|
|
36771
|
+
{ cwd: homedir6(), timeout: CLASSIFY_TIMEOUT_MS, maxBuffer: 1 << 20 },
|
|
36446
36772
|
(err, stdout) => {
|
|
36447
36773
|
if (err) {
|
|
36448
36774
|
reject(err);
|
|
@@ -36564,8 +36890,8 @@ function emitTransientApiErrorTelemetry(channel, match, original) {
|
|
|
36564
36890
|
}
|
|
36565
36891
|
|
|
36566
36892
|
// src/slack-pending-inbound-cleanup.ts
|
|
36567
|
-
import { existsSync as existsSync4, readdirSync as
|
|
36568
|
-
import { join as
|
|
36893
|
+
import { existsSync as existsSync4, readdirSync as readdirSync3, statSync as statSync2, unlinkSync } from "fs";
|
|
36894
|
+
import { join as join9 } from "path";
|
|
36569
36895
|
function sanitizeMarkerSegment(value) {
|
|
36570
36896
|
return value.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
36571
36897
|
}
|
|
@@ -36579,9 +36905,9 @@ function applyToMatchingMarkers(dir, prefix, suffix, op) {
|
|
|
36579
36905
|
if (!dir) return 0;
|
|
36580
36906
|
let applied = 0;
|
|
36581
36907
|
try {
|
|
36582
|
-
for (const f of
|
|
36908
|
+
for (const f of readdirSync3(dir)) {
|
|
36583
36909
|
if (!f.startsWith(prefix) || !f.endsWith(suffix)) continue;
|
|
36584
|
-
op(
|
|
36910
|
+
op(join9(dir, f));
|
|
36585
36911
|
applied += 1;
|
|
36586
36912
|
}
|
|
36587
36913
|
} catch {
|
|
@@ -36610,11 +36936,11 @@ function clearOldestSlackPendingMarkerInChannel(dir, channel, clear = defaultCle
|
|
|
36610
36936
|
if (!dir) return null;
|
|
36611
36937
|
const channelPrefix = `${sanitizeMarkerSegment(channel)}__`;
|
|
36612
36938
|
try {
|
|
36613
|
-
const entries =
|
|
36614
|
-
const full =
|
|
36939
|
+
const entries = readdirSync3(dir).filter((f) => f.startsWith(channelPrefix) && f.endsWith(".json")).map((f) => {
|
|
36940
|
+
const full = join9(dir, f);
|
|
36615
36941
|
let mtime = 0;
|
|
36616
36942
|
try {
|
|
36617
|
-
mtime =
|
|
36943
|
+
mtime = statSync2(full).mtimeMs;
|
|
36618
36944
|
} catch {
|
|
36619
36945
|
}
|
|
36620
36946
|
return { name: f, full, mtime };
|
|
@@ -36630,12 +36956,12 @@ function clearOldestSlackPendingMarkerInChannel(dir, channel, clear = defaultCle
|
|
|
36630
36956
|
|
|
36631
36957
|
// src/recovery-ledger.ts
|
|
36632
36958
|
import { existsSync as existsSync5, unlinkSync as unlinkSync2 } from "fs";
|
|
36633
|
-
import { join as
|
|
36959
|
+
import { join as join10 } from "path";
|
|
36634
36960
|
function recoveryLedgerEntryExists(ledgerDir, markerName, exists = (p2) => existsSync5(p2)) {
|
|
36635
36961
|
if (!ledgerDir || !markerName) return false;
|
|
36636
36962
|
if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return false;
|
|
36637
36963
|
try {
|
|
36638
|
-
return exists(
|
|
36964
|
+
return exists(join10(ledgerDir, markerName));
|
|
36639
36965
|
} catch {
|
|
36640
36966
|
return false;
|
|
36641
36967
|
}
|
|
@@ -36646,7 +36972,7 @@ function removeRecoveryLedgerEntry(ledgerDir, markerName, unlink = (p2) => {
|
|
|
36646
36972
|
if (!ledgerDir || !markerName) return;
|
|
36647
36973
|
if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return;
|
|
36648
36974
|
try {
|
|
36649
|
-
unlink(
|
|
36975
|
+
unlink(join10(ledgerDir, markerName));
|
|
36650
36976
|
} catch {
|
|
36651
36977
|
}
|
|
36652
36978
|
}
|
|
@@ -36883,18 +37209,18 @@ function applyHotThreadGuard(input) {
|
|
|
36883
37209
|
}
|
|
36884
37210
|
|
|
36885
37211
|
// src/slack-hot-thread-telemetry.ts
|
|
36886
|
-
import { readFileSync as
|
|
36887
|
-
import { join as
|
|
37212
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
|
|
37213
|
+
import { join as join11 } from "path";
|
|
36888
37214
|
var HOT_THREAD_CLASSIFICATION_COUNTER_SUFFIX = "-hot-thread-classifications.json";
|
|
36889
37215
|
function hotThreadKey(mode, outcome, proactive) {
|
|
36890
37216
|
return `${mode}|${outcome}|${proactive ? "true" : "false"}`;
|
|
36891
37217
|
}
|
|
36892
37218
|
function recordHotThreadClassification(agentDir, channel, classification) {
|
|
36893
37219
|
if (!agentDir || !channel) return;
|
|
36894
|
-
const path =
|
|
37220
|
+
const path = join11(agentDir, `${channel}${HOT_THREAD_CLASSIFICATION_COUNTER_SUFFIX}`);
|
|
36895
37221
|
let counts = {};
|
|
36896
37222
|
try {
|
|
36897
|
-
const parsed = JSON.parse(
|
|
37223
|
+
const parsed = JSON.parse(readFileSync7(path, "utf-8"));
|
|
36898
37224
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
36899
37225
|
for (const [k, v] of Object.entries(parsed)) {
|
|
36900
37226
|
if (typeof v === "number" && Number.isInteger(v) && v >= 0) counts[k] = v;
|
|
@@ -36911,7 +37237,7 @@ function recordHotThreadClassification(agentDir, channel, classification) {
|
|
|
36911
37237
|
}
|
|
36912
37238
|
|
|
36913
37239
|
// src/restart-confirm.ts
|
|
36914
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as
|
|
37240
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync8, renameSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
36915
37241
|
import { dirname } from "path";
|
|
36916
37242
|
import { randomUUID } from "crypto";
|
|
36917
37243
|
var RESTART_CONFIRM_MAX_AGE_MS = 10 * 60 * 1e3;
|
|
@@ -36937,7 +37263,7 @@ function writeRestartConfirmMarker(filePath, marker) {
|
|
|
36937
37263
|
function readRestartConfirmMarker(filePath) {
|
|
36938
37264
|
try {
|
|
36939
37265
|
if (!existsSync6(filePath)) return null;
|
|
36940
|
-
const parsed = JSON.parse(
|
|
37266
|
+
const parsed = JSON.parse(readFileSync8(filePath, "utf8"));
|
|
36941
37267
|
if (!parsed || typeof parsed !== "object") return null;
|
|
36942
37268
|
return parsed;
|
|
36943
37269
|
} catch {
|
|
@@ -37082,21 +37408,21 @@ import {
|
|
|
37082
37408
|
ftruncateSync,
|
|
37083
37409
|
mkdirSync as mkdirSync9,
|
|
37084
37410
|
openSync,
|
|
37085
|
-
readFileSync as
|
|
37086
|
-
readdirSync as
|
|
37411
|
+
readFileSync as readFileSync20,
|
|
37412
|
+
readdirSync as readdirSync6,
|
|
37087
37413
|
renameSync as renameSync5,
|
|
37088
|
-
statSync as
|
|
37414
|
+
statSync as statSync4,
|
|
37089
37415
|
unlinkSync as unlinkSync7,
|
|
37090
37416
|
watch,
|
|
37091
37417
|
writeFileSync as writeFileSync14,
|
|
37092
37418
|
writeSync
|
|
37093
37419
|
} from "fs";
|
|
37094
|
-
import { basename, join as
|
|
37095
|
-
import { homedir as
|
|
37096
|
-
import { createHash as
|
|
37420
|
+
import { basename, join as join20, resolve as resolve2 } from "path";
|
|
37421
|
+
import { homedir as homedir7 } from "os";
|
|
37422
|
+
import { createHash as createHash3, randomUUID as randomUUID2 } from "crypto";
|
|
37097
37423
|
|
|
37098
37424
|
// src/slack-thread-store.ts
|
|
37099
|
-
import { mkdirSync as mkdirSync3, readFileSync as
|
|
37425
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
|
|
37100
37426
|
import { dirname as dirname2 } from "path";
|
|
37101
37427
|
function isParticipatingThread(entry) {
|
|
37102
37428
|
if (!entry) return false;
|
|
@@ -37111,7 +37437,7 @@ function loadThreadStore(filePath, opts = {}) {
|
|
|
37111
37437
|
const ttlMs = ttlDays * 24 * 60 * 60 * 1e3;
|
|
37112
37438
|
let raw;
|
|
37113
37439
|
try {
|
|
37114
|
-
raw =
|
|
37440
|
+
raw = readFileSync9(filePath, "utf-8");
|
|
37115
37441
|
} catch {
|
|
37116
37442
|
return { threads: /* @__PURE__ */ new Map(), pruned: 0 };
|
|
37117
37443
|
}
|
|
@@ -37212,7 +37538,7 @@ function isThreadEntry(value) {
|
|
|
37212
37538
|
}
|
|
37213
37539
|
|
|
37214
37540
|
// src/dm-restart-notice.ts
|
|
37215
|
-
import { mkdirSync as mkdirSync4, readFileSync as
|
|
37541
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync10, unlinkSync as unlinkSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
37216
37542
|
import { dirname as dirname3 } from "path";
|
|
37217
37543
|
var RECENT_DM_VERSION = 1;
|
|
37218
37544
|
var DEFAULT_RECENT_DM_TTL_MS = 30 * 60 * 1e3;
|
|
@@ -37236,7 +37562,7 @@ function loadRecentDms(filePath, opts = {}) {
|
|
|
37236
37562
|
const ttlMs = opts.ttlMs ?? DEFAULT_RECENT_DM_TTL_MS;
|
|
37237
37563
|
let raw;
|
|
37238
37564
|
try {
|
|
37239
|
-
raw =
|
|
37565
|
+
raw = readFileSync10(filePath, "utf-8");
|
|
37240
37566
|
} catch (err) {
|
|
37241
37567
|
const code = err.code;
|
|
37242
37568
|
if (code !== "ENOENT") {
|
|
@@ -37321,7 +37647,7 @@ var CHANNEL_ADD_RESTART_MAX_AGE_MS = 15 * 60 * 1e3;
|
|
|
37321
37647
|
function readChannelAddRestartMarker(filePath) {
|
|
37322
37648
|
let raw;
|
|
37323
37649
|
try {
|
|
37324
|
-
raw =
|
|
37650
|
+
raw = readFileSync10(filePath, "utf-8");
|
|
37325
37651
|
} catch {
|
|
37326
37652
|
return null;
|
|
37327
37653
|
}
|
|
@@ -37379,13 +37705,13 @@ async function runOrRetry(fn, opts) {
|
|
|
37379
37705
|
}
|
|
37380
37706
|
|
|
37381
37707
|
// src/turn-initiator-marker.ts
|
|
37382
|
-
import { writeFileSync as writeFileSync7, readFileSync as
|
|
37383
|
-
import { dirname as dirname4, join as
|
|
37708
|
+
import { writeFileSync as writeFileSync7, readFileSync as readFileSync11, mkdirSync as mkdirSync5, renameSync as renameSync2 } from "fs";
|
|
37709
|
+
import { dirname as dirname4, join as join12 } from "path";
|
|
37384
37710
|
var TURN_INITIATOR_MAX_AGE_MS = 5 * 60 * 1e3;
|
|
37385
37711
|
var TURN_INITIATOR_LEDGER_MAX_ENTRIES = 20;
|
|
37386
37712
|
var TURN_INITIATOR_LEDGER_FILENAME = ".turn-initiator-ledger.json";
|
|
37387
37713
|
function turnInitiatorLedgerPath(singleSlotFile) {
|
|
37388
|
-
return
|
|
37714
|
+
return join12(dirname4(singleSlotFile), TURN_INITIATOR_LEDGER_FILENAME);
|
|
37389
37715
|
}
|
|
37390
37716
|
function foldTurnInitiatorLedger(existing, marker, maxAgeMs = TURN_INITIATOR_MAX_AGE_MS, maxEntries = TURN_INITIATOR_LEDGER_MAX_ENTRIES) {
|
|
37391
37717
|
const now = marker.ts;
|
|
@@ -37410,7 +37736,7 @@ function updateTurnInitiatorLedger(singleSlotFile, marker) {
|
|
|
37410
37736
|
const ledgerFile = turnInitiatorLedgerPath(singleSlotFile);
|
|
37411
37737
|
let existing = null;
|
|
37412
37738
|
try {
|
|
37413
|
-
const parsed = JSON.parse(
|
|
37739
|
+
const parsed = JSON.parse(readFileSync11(ledgerFile, "utf8"));
|
|
37414
37740
|
if (parsed && parsed.v === 1 && Array.isArray(parsed.entries)) existing = parsed;
|
|
37415
37741
|
} catch {
|
|
37416
37742
|
}
|
|
@@ -37437,7 +37763,7 @@ function writeTurnInitiatorMarker(input) {
|
|
|
37437
37763
|
}
|
|
37438
37764
|
|
|
37439
37765
|
// src/slack-bot-photo.ts
|
|
37440
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as
|
|
37766
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "fs";
|
|
37441
37767
|
import { dirname as dirname5 } from "path";
|
|
37442
37768
|
async function applyBotPhoto(opts) {
|
|
37443
37769
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
@@ -37447,7 +37773,7 @@ async function applyBotPhoto(opts) {
|
|
|
37447
37773
|
const { token, avatarUrl, markerPath } = opts;
|
|
37448
37774
|
if (markerPath && existsSync7(markerPath)) {
|
|
37449
37775
|
try {
|
|
37450
|
-
if (
|
|
37776
|
+
if (readFileSync12(markerPath, "utf-8").trim() === avatarUrl) {
|
|
37451
37777
|
return { status: "skipped-unchanged" };
|
|
37452
37778
|
}
|
|
37453
37779
|
} catch {
|
|
@@ -37572,8 +37898,8 @@ function conversationalLaneMeta(expectsReply = true) {
|
|
|
37572
37898
|
}
|
|
37573
37899
|
|
|
37574
37900
|
// src/inbound-lane-telemetry.ts
|
|
37575
|
-
import { readFileSync as
|
|
37576
|
-
import { join as
|
|
37901
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "fs";
|
|
37902
|
+
import { join as join13 } from "path";
|
|
37577
37903
|
var LANE_CLASSIFICATION_COUNTER_SUFFIX = "-lane-classifications.json";
|
|
37578
37904
|
var SUSPECTED_MISCLASSIFICATION_KEY = "suspected_misclassification";
|
|
37579
37905
|
var HUMAN_CHANNEL_SOURCES = /* @__PURE__ */ new Set([
|
|
@@ -37590,10 +37916,10 @@ function isSuspectedMisclassification(lane, source) {
|
|
|
37590
37916
|
}
|
|
37591
37917
|
function recordLaneClassification(agentDir, channel, classification) {
|
|
37592
37918
|
if (!agentDir) return;
|
|
37593
|
-
const path =
|
|
37919
|
+
const path = join13(agentDir, `${channel}${LANE_CLASSIFICATION_COUNTER_SUFFIX}`);
|
|
37594
37920
|
let counts = {};
|
|
37595
37921
|
try {
|
|
37596
|
-
const parsed = JSON.parse(
|
|
37922
|
+
const parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
37597
37923
|
if (parsed && typeof parsed === "object") counts = parsed;
|
|
37598
37924
|
} catch {
|
|
37599
37925
|
}
|
|
@@ -37609,8 +37935,8 @@ function recordLaneClassification(agentDir, channel, classification) {
|
|
|
37609
37935
|
}
|
|
37610
37936
|
|
|
37611
37937
|
// src/slack-inbound-registry.ts
|
|
37612
|
-
import { readdirSync as
|
|
37613
|
-
import { join as
|
|
37938
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync14 } from "fs";
|
|
37939
|
+
import { join as join14 } from "path";
|
|
37614
37940
|
var DEFAULT_MAX_ENTRIES = 500;
|
|
37615
37941
|
var DEFAULT_CLEARED_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
37616
37942
|
function entryKey(channel, messageTs) {
|
|
@@ -37722,7 +38048,7 @@ function createInboundRegistry(opts = {}) {
|
|
|
37722
38048
|
function seedFromMarkerDir(dir) {
|
|
37723
38049
|
let names;
|
|
37724
38050
|
try {
|
|
37725
|
-
names =
|
|
38051
|
+
names = readdirSync4(dir);
|
|
37726
38052
|
} catch {
|
|
37727
38053
|
return;
|
|
37728
38054
|
}
|
|
@@ -37731,7 +38057,7 @@ function createInboundRegistry(opts = {}) {
|
|
|
37731
38057
|
if (name.includes(".retry-") || name.includes(".poison")) continue;
|
|
37732
38058
|
let marker;
|
|
37733
38059
|
try {
|
|
37734
|
-
marker = JSON.parse(
|
|
38060
|
+
marker = JSON.parse(readFileSync14(join14(dir, name), "utf-8"));
|
|
37735
38061
|
} catch {
|
|
37736
38062
|
continue;
|
|
37737
38063
|
}
|
|
@@ -37768,16 +38094,16 @@ function createInboundRegistry(opts = {}) {
|
|
|
37768
38094
|
}
|
|
37769
38095
|
|
|
37770
38096
|
// src/slack-inbound-id.ts
|
|
37771
|
-
import { createHash } from "crypto";
|
|
38097
|
+
import { createHash as createHash2 } from "crypto";
|
|
37772
38098
|
var INBOUND_ID_HEX_LEN = 12;
|
|
37773
38099
|
function slackInboundId(channel, threadTs, messageTs) {
|
|
37774
|
-
const digest =
|
|
38100
|
+
const digest = createHash2("sha256").update(`${channel}|${threadTs}|${messageTs}`).digest("hex").slice(0, INBOUND_ID_HEX_LEN);
|
|
37775
38101
|
return `ib_${digest}`;
|
|
37776
38102
|
}
|
|
37777
38103
|
|
|
37778
38104
|
// src/inbound-delivery-ledger.ts
|
|
37779
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readdirSync as
|
|
37780
|
-
import { join as
|
|
38105
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readdirSync as readdirSync5, readFileSync as readFileSync15, renameSync as renameSync3, writeFileSync as writeFileSync10 } from "fs";
|
|
38106
|
+
import { join as join15 } from "path";
|
|
37781
38107
|
function safeInboundId(inboundId) {
|
|
37782
38108
|
return inboundId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
37783
38109
|
}
|
|
@@ -37785,8 +38111,8 @@ var defaultDeps = {
|
|
|
37785
38111
|
mkdir: (dir) => mkdirSync7(dir, { recursive: true }),
|
|
37786
38112
|
writeFile: (path, data) => writeFileSync10(path, data, "utf8"),
|
|
37787
38113
|
rename: (from, to) => renameSync3(from, to),
|
|
37788
|
-
readdir: (dir) =>
|
|
37789
|
-
readFile: (path) =>
|
|
38114
|
+
readdir: (dir) => readdirSync5(dir),
|
|
38115
|
+
readFile: (path) => readFileSync15(path, "utf8"),
|
|
37790
38116
|
exists: (path) => existsSync8(path)
|
|
37791
38117
|
};
|
|
37792
38118
|
function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
|
|
@@ -37795,7 +38121,7 @@ function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
|
|
|
37795
38121
|
if (!safe || safe.includes("/") || safe.includes("\\") || safe.includes("..")) return;
|
|
37796
38122
|
try {
|
|
37797
38123
|
deps.mkdir(dir);
|
|
37798
|
-
const final =
|
|
38124
|
+
const final = join15(dir, `${safe}.json`);
|
|
37799
38125
|
const tmp = `${final}.tmp`;
|
|
37800
38126
|
deps.writeFile(tmp, JSON.stringify(record2));
|
|
37801
38127
|
deps.rename(tmp, final);
|
|
@@ -37951,8 +38277,8 @@ function describeChannelRedirect(input) {
|
|
|
37951
38277
|
}
|
|
37952
38278
|
|
|
37953
38279
|
// src/slack-reply-binding-telemetry.ts
|
|
37954
|
-
import { readFileSync as
|
|
37955
|
-
import { join as
|
|
38280
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync11 } from "fs";
|
|
38281
|
+
import { join as join16 } from "path";
|
|
37956
38282
|
var REPLY_BINDING_CLASSIFICATION_COUNTER_SUFFIX = "-reply-binding-classifications.json";
|
|
37957
38283
|
var UNKNOWN_INBOUND_ID_KEY = "unknown_inbound_id";
|
|
37958
38284
|
var CHANNEL_MISTARGET_CORRECTED_KEY = "channel_mistarget_corrected";
|
|
@@ -37967,10 +38293,10 @@ function slackReplyBindingMode() {
|
|
|
37967
38293
|
}
|
|
37968
38294
|
function recordReplyBindingClassification(agentDir, channel, input) {
|
|
37969
38295
|
if (!agentDir) return;
|
|
37970
|
-
const path =
|
|
38296
|
+
const path = join16(agentDir, `${channel}${REPLY_BINDING_CLASSIFICATION_COUNTER_SUFFIX}`);
|
|
37971
38297
|
let counts = {};
|
|
37972
38298
|
try {
|
|
37973
|
-
const parsed = JSON.parse(
|
|
38299
|
+
const parsed = JSON.parse(readFileSync16(path, "utf-8"));
|
|
37974
38300
|
if (parsed && typeof parsed === "object") counts = parsed;
|
|
37975
38301
|
} catch {
|
|
37976
38302
|
}
|
|
@@ -37985,10 +38311,10 @@ function recordReplyBindingClassification(agentDir, channel, input) {
|
|
|
37985
38311
|
}
|
|
37986
38312
|
function recordScheduledChannelOverride(agentDir, channel, input) {
|
|
37987
38313
|
if (!agentDir) return;
|
|
37988
|
-
const path =
|
|
38314
|
+
const path = join16(agentDir, `${channel}${REPLY_BINDING_CLASSIFICATION_COUNTER_SUFFIX}`);
|
|
37989
38315
|
let counts = {};
|
|
37990
38316
|
try {
|
|
37991
|
-
const parsed = JSON.parse(
|
|
38317
|
+
const parsed = JSON.parse(readFileSync16(path, "utf-8"));
|
|
37992
38318
|
if (parsed && typeof parsed === "object") counts = parsed;
|
|
37993
38319
|
} catch {
|
|
37994
38320
|
}
|
|
@@ -38001,10 +38327,10 @@ function recordScheduledChannelOverride(agentDir, channel, input) {
|
|
|
38001
38327
|
}
|
|
38002
38328
|
function recordChannelMistarget(agentDir, channel, input) {
|
|
38003
38329
|
if (!agentDir) return;
|
|
38004
|
-
const path =
|
|
38330
|
+
const path = join16(agentDir, `${channel}${REPLY_BINDING_CLASSIFICATION_COUNTER_SUFFIX}`);
|
|
38005
38331
|
let counts = {};
|
|
38006
38332
|
try {
|
|
38007
|
-
const parsed = JSON.parse(
|
|
38333
|
+
const parsed = JSON.parse(readFileSync16(path, "utf-8"));
|
|
38008
38334
|
if (parsed && typeof parsed === "object") counts = parsed;
|
|
38009
38335
|
} catch {
|
|
38010
38336
|
}
|
|
@@ -38019,8 +38345,8 @@ function recordChannelMistarget(agentDir, channel, input) {
|
|
|
38019
38345
|
}
|
|
38020
38346
|
|
|
38021
38347
|
// src/slack-reply-target-telemetry.ts
|
|
38022
|
-
import { readFileSync as
|
|
38023
|
-
import { join as
|
|
38348
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync12 } from "fs";
|
|
38349
|
+
import { join as join17 } from "path";
|
|
38024
38350
|
var REPLY_TARGET_CLASSIFICATION_COUNTER_SUFFIX = "-reply-target-classifications.json";
|
|
38025
38351
|
function pendingThreadsBucket(n) {
|
|
38026
38352
|
if (n <= 0) return "0";
|
|
@@ -38053,10 +38379,10 @@ function classifyReplyTarget(input) {
|
|
|
38053
38379
|
}
|
|
38054
38380
|
function recordReplyTargetClassification(agentDir, channel, classification) {
|
|
38055
38381
|
if (!agentDir) return;
|
|
38056
|
-
const path =
|
|
38382
|
+
const path = join17(agentDir, `${channel}${REPLY_TARGET_CLASSIFICATION_COUNTER_SUFFIX}`);
|
|
38057
38383
|
let counts = {};
|
|
38058
38384
|
try {
|
|
38059
|
-
const parsed = JSON.parse(
|
|
38385
|
+
const parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
38060
38386
|
if (parsed && typeof parsed === "object") counts = parsed;
|
|
38061
38387
|
} catch {
|
|
38062
38388
|
}
|
|
@@ -38072,8 +38398,8 @@ function recordReplyTargetClassification(agentDir, channel, classification) {
|
|
|
38072
38398
|
}
|
|
38073
38399
|
|
|
38074
38400
|
// src/scheduled-turn-marker.ts
|
|
38075
|
-
import { readFileSync as
|
|
38076
|
-
import { join as
|
|
38401
|
+
import { readFileSync as readFileSync18, unlinkSync as unlinkSync5 } from "fs";
|
|
38402
|
+
import { join as join18 } from "path";
|
|
38077
38403
|
var SCHEDULED_TURN_MARKER_FILENAME2 = ".current-scheduled-turn.json";
|
|
38078
38404
|
var SCHEDULED_TURN_MAX_AGE_MS = 15 * 60 * 1e3;
|
|
38079
38405
|
function validateScheduledTurnMarker(raw, now, maxAgeMs = SCHEDULED_TURN_MAX_AGE_MS) {
|
|
@@ -38111,7 +38437,7 @@ function readScheduledTurnMarker(agentDir, now = Date.now()) {
|
|
|
38111
38437
|
if (!agentDir) return null;
|
|
38112
38438
|
try {
|
|
38113
38439
|
const raw = JSON.parse(
|
|
38114
|
-
|
|
38440
|
+
readFileSync18(join18(agentDir, SCHEDULED_TURN_MARKER_FILENAME2), "utf8")
|
|
38115
38441
|
);
|
|
38116
38442
|
return validateScheduledTurnMarker(raw, now);
|
|
38117
38443
|
} catch {
|
|
@@ -38121,7 +38447,7 @@ function readScheduledTurnMarker(agentDir, now = Date.now()) {
|
|
|
38121
38447
|
function clearScheduledTurnMarker(agentDir) {
|
|
38122
38448
|
if (!agentDir) return;
|
|
38123
38449
|
try {
|
|
38124
|
-
unlinkSync5(
|
|
38450
|
+
unlinkSync5(join18(agentDir, SCHEDULED_TURN_MARKER_FILENAME2));
|
|
38125
38451
|
} catch {
|
|
38126
38452
|
}
|
|
38127
38453
|
}
|
|
@@ -38919,14 +39245,14 @@ async function actuateHostRestart(opts) {
|
|
|
38919
39245
|
import {
|
|
38920
39246
|
existsSync as existsSync9,
|
|
38921
39247
|
mkdirSync as mkdirSync8,
|
|
38922
|
-
readFileSync as
|
|
39248
|
+
readFileSync as readFileSync19,
|
|
38923
39249
|
renameSync as renameSync4,
|
|
38924
|
-
statSync as
|
|
39250
|
+
statSync as statSync3,
|
|
38925
39251
|
unlinkSync as unlinkSync6,
|
|
38926
39252
|
utimesSync,
|
|
38927
39253
|
writeFileSync as writeFileSync13
|
|
38928
39254
|
} from "fs";
|
|
38929
|
-
import { join as
|
|
39255
|
+
import { join as join19 } from "path";
|
|
38930
39256
|
var STALE_LOCK_MS = 9e4;
|
|
38931
39257
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
38932
39258
|
function defaultIsPidAlive(pid) {
|
|
@@ -38949,7 +39275,7 @@ function acquireMcpSpawnLock(args) {
|
|
|
38949
39275
|
const nowMs = options.nowMs ?? (() => Date.now());
|
|
38950
39276
|
const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
|
|
38951
39277
|
const staleMs = options.staleMs ?? STALE_LOCK_MS;
|
|
38952
|
-
const path =
|
|
39278
|
+
const path = join19(agentDir, basename2);
|
|
38953
39279
|
const existing = readLockHolder(path);
|
|
38954
39280
|
if (existing) {
|
|
38955
39281
|
if (existing.pid === selfPid) {
|
|
@@ -39008,7 +39334,7 @@ function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
|
|
|
39008
39334
|
}
|
|
39009
39335
|
function defaultLockMtimeMs(path) {
|
|
39010
39336
|
try {
|
|
39011
|
-
return
|
|
39337
|
+
return statSync3(path).mtimeMs;
|
|
39012
39338
|
} catch {
|
|
39013
39339
|
return null;
|
|
39014
39340
|
}
|
|
@@ -39016,7 +39342,7 @@ function defaultLockMtimeMs(path) {
|
|
|
39016
39342
|
function readLockHolder(path) {
|
|
39017
39343
|
if (!existsSync9(path)) return null;
|
|
39018
39344
|
try {
|
|
39019
|
-
const raw =
|
|
39345
|
+
const raw = readFileSync19(path, "utf8");
|
|
39020
39346
|
const parsed = JSON.parse(raw);
|
|
39021
39347
|
const pid = typeof parsed.pid === "number" ? parsed.pid : Number(parsed.pid);
|
|
39022
39348
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
@@ -39247,6 +39573,49 @@ async function maybeSendUsageLimitNotice(args) {
|
|
|
39247
39573
|
clearTimeout(timeoutId);
|
|
39248
39574
|
}
|
|
39249
39575
|
}
|
|
39576
|
+
function armSlackUsageLimitWatch(args) {
|
|
39577
|
+
void (async () => {
|
|
39578
|
+
try {
|
|
39579
|
+
const refusal = await watchForRateLimitRefusal({ sinceMs: args.sinceMs });
|
|
39580
|
+
const action = decideRefusalAction({ mode: args.mode, refusal });
|
|
39581
|
+
if (action === "none") return;
|
|
39582
|
+
if (action === "missing-reset") {
|
|
39583
|
+
process.stderr.write(
|
|
39584
|
+
`slack-channel(${AGENT_CODE_NAME}): [usage-limit-reactive] mode=${args.mode} refusal detected for channel=${redactSlackId(args.channel)} but no reset time in it (${describeUnparsedRefusal(refusal?.text)}) - no notice
|
|
39585
|
+
`
|
|
39586
|
+
);
|
|
39587
|
+
return;
|
|
39588
|
+
}
|
|
39589
|
+
const resetsAt = refusal?.resetsAt;
|
|
39590
|
+
if (!resetsAt) return;
|
|
39591
|
+
if (action === "shadow-log") {
|
|
39592
|
+
process.stderr.write(
|
|
39593
|
+
`slack-channel(${AGENT_CODE_NAME}): [usage-limit-reactive] mode=shadow WOULD notify channel=${redactSlackId(args.channel)} ts=${redactSlackId(args.messageTs)} resets=${resetsAt.toISOString()}
|
|
39594
|
+
`
|
|
39595
|
+
);
|
|
39596
|
+
return;
|
|
39597
|
+
}
|
|
39598
|
+
await maybeSendUsageLimitNotice({
|
|
39599
|
+
channel: args.channel,
|
|
39600
|
+
senderId: args.senderId,
|
|
39601
|
+
threadTs: args.threadTs,
|
|
39602
|
+
limitedUntil: resetsAt
|
|
39603
|
+
});
|
|
39604
|
+
if (args.channel && args.messageTs) {
|
|
39605
|
+
clearSlackPendingMarkerByMessageTs2(args.channel, args.messageTs);
|
|
39606
|
+
}
|
|
39607
|
+
process.stderr.write(
|
|
39608
|
+
`slack-channel(${AGENT_CODE_NAME}): [usage-limit-reactive] reported refusal for channel=${redactSlackId(args.channel)} ts=${redactSlackId(args.messageTs)} resets=${resetsAt.toISOString()}
|
|
39609
|
+
`
|
|
39610
|
+
);
|
|
39611
|
+
} catch (err) {
|
|
39612
|
+
process.stderr.write(
|
|
39613
|
+
`slack-channel(${AGENT_CODE_NAME}): [usage-limit-reactive] watch failed for channel=${redactSlackId(args.channel)}: ${err.message}
|
|
39614
|
+
`
|
|
39615
|
+
);
|
|
39616
|
+
}
|
|
39617
|
+
})();
|
|
39618
|
+
}
|
|
39250
39619
|
var SLACK_ACCOUNT_MUTE_NOTICE_CACHE = /* @__PURE__ */ new Map();
|
|
39251
39620
|
async function maybeSendAccountMuteNotice(args) {
|
|
39252
39621
|
if (!BOT_TOKEN) return;
|
|
@@ -39422,18 +39791,18 @@ var SLACK_TEAM_PEER_USER_IDS = parseTeamPeerUserIdsEnv(
|
|
|
39422
39791
|
process.env.SLACK_TEAM_PEER_USER_IDS
|
|
39423
39792
|
);
|
|
39424
39793
|
var PEER_HINT_SEEN = /* @__PURE__ */ new Set();
|
|
39425
|
-
var SLACK_AGENT_DIR = AGENT_CODE_NAME ?
|
|
39426
|
-
var SLACK_MCP_CONFIG_PATH = SLACK_AGENT_DIR ?
|
|
39794
|
+
var SLACK_AGENT_DIR = AGENT_CODE_NAME ? join20(homedir7(), ".augmented", AGENT_CODE_NAME) : null;
|
|
39795
|
+
var SLACK_MCP_CONFIG_PATH = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "project", ".mcp.json") : null;
|
|
39427
39796
|
var liveAllowedUsersCache = null;
|
|
39428
39797
|
function readLiveAllowedUsers() {
|
|
39429
39798
|
if (!SLACK_MCP_CONFIG_PATH) return null;
|
|
39430
39799
|
try {
|
|
39431
|
-
const mtimeMs =
|
|
39800
|
+
const mtimeMs = statSync4(SLACK_MCP_CONFIG_PATH).mtimeMs;
|
|
39432
39801
|
if (liveAllowedUsersCache && liveAllowedUsersCache.mtimeMs === mtimeMs) {
|
|
39433
39802
|
return liveAllowedUsersCache.value;
|
|
39434
39803
|
}
|
|
39435
39804
|
const value = extractAllowedUsersFromMcpJson(
|
|
39436
|
-
|
|
39805
|
+
readFileSync20(SLACK_MCP_CONFIG_PATH, "utf-8")
|
|
39437
39806
|
);
|
|
39438
39807
|
if (value === null) return null;
|
|
39439
39808
|
liveAllowedUsersCache = { mtimeMs, value };
|
|
@@ -39449,12 +39818,12 @@ var livePingAllowedUsersCache = null;
|
|
|
39449
39818
|
function readLivePingAllowedUsers() {
|
|
39450
39819
|
if (!SLACK_MCP_CONFIG_PATH) return null;
|
|
39451
39820
|
try {
|
|
39452
|
-
const mtimeMs =
|
|
39821
|
+
const mtimeMs = statSync4(SLACK_MCP_CONFIG_PATH).mtimeMs;
|
|
39453
39822
|
if (livePingAllowedUsersCache && livePingAllowedUsersCache.mtimeMs === mtimeMs) {
|
|
39454
39823
|
return livePingAllowedUsersCache.value;
|
|
39455
39824
|
}
|
|
39456
39825
|
const value = extractPingAllowedUsersFromMcpJson(
|
|
39457
|
-
|
|
39826
|
+
readFileSync20(SLACK_MCP_CONFIG_PATH, "utf-8")
|
|
39458
39827
|
);
|
|
39459
39828
|
if (value === null) return null;
|
|
39460
39829
|
livePingAllowedUsersCache = { mtimeMs, value };
|
|
@@ -39466,20 +39835,20 @@ function readLivePingAllowedUsers() {
|
|
|
39466
39835
|
function getEffectivePingAllowedUsers() {
|
|
39467
39836
|
return readLivePingAllowedUsers() ?? PING_ALLOWED_USERS;
|
|
39468
39837
|
}
|
|
39469
|
-
var SLACK_PENDING_INBOUND_DIR = SLACK_AGENT_DIR ?
|
|
39470
|
-
var SLACK_RESTART_CONTEXT_DIR = SLACK_AGENT_DIR ?
|
|
39471
|
-
var SLACK_RECOVERY_OUTBOX_DIR = SLACK_AGENT_DIR ?
|
|
39472
|
-
var SLACK_RECOVERY_LEDGER_DIR = SLACK_AGENT_DIR ?
|
|
39473
|
-
var SLACK_DELIVERY_LEDGER_DIR = SLACK_AGENT_DIR ?
|
|
39838
|
+
var SLACK_PENDING_INBOUND_DIR = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "slack-pending-inbound") : null;
|
|
39839
|
+
var SLACK_RESTART_CONTEXT_DIR = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "slack-restart-context") : null;
|
|
39840
|
+
var SLACK_RECOVERY_OUTBOX_DIR = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "slack-recovery-outbox") : null;
|
|
39841
|
+
var SLACK_RECOVERY_LEDGER_DIR = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, ".agt-slack-recovery-ledger") : null;
|
|
39842
|
+
var SLACK_DELIVERY_LEDGER_DIR = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, ".agt-inbound-delivery-ledger") : null;
|
|
39474
39843
|
var slackInboundRegistry = createInboundRegistry();
|
|
39475
|
-
var SLACK_RESTART_CONFIRM_FILE = SLACK_AGENT_DIR ?
|
|
39476
|
-
var SLACK_RECENT_DMS_FILE = SLACK_AGENT_DIR ?
|
|
39477
|
-
var SLACK_CHANNEL_ADD_RESTART_FILE = SLACK_AGENT_DIR ?
|
|
39844
|
+
var SLACK_RESTART_CONFIRM_FILE = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "slack-restart-confirm.json") : null;
|
|
39845
|
+
var SLACK_RECENT_DMS_FILE = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "slack-recent-dms.json") : null;
|
|
39846
|
+
var SLACK_CHANNEL_ADD_RESTART_FILE = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "slack-channel-add-restart.json") : null;
|
|
39478
39847
|
var SLACK_MAX_RECOVERY_ATTEMPTS = 3;
|
|
39479
|
-
var SLACK_AVATAR_MARKER_PATH = SLACK_AGENT_DIR ?
|
|
39848
|
+
var SLACK_AVATAR_MARKER_PATH = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "slack-avatar-applied") : null;
|
|
39480
39849
|
function redactSlackId(id) {
|
|
39481
39850
|
if (!id) return "<none>";
|
|
39482
|
-
return
|
|
39851
|
+
return createHash3("sha256").update(id).digest("hex").slice(0, 8);
|
|
39483
39852
|
}
|
|
39484
39853
|
function safeSlackMarkerName(channel, threadTs, messageTs) {
|
|
39485
39854
|
const safe = (s) => s.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
@@ -39487,7 +39856,7 @@ function safeSlackMarkerName(channel, threadTs, messageTs) {
|
|
|
39487
39856
|
}
|
|
39488
39857
|
function slackPendingInboundPath(channel, threadTs, messageTs) {
|
|
39489
39858
|
if (!SLACK_PENDING_INBOUND_DIR) return null;
|
|
39490
|
-
return
|
|
39859
|
+
return join20(SLACK_PENDING_INBOUND_DIR, safeSlackMarkerName(channel, threadTs, messageTs));
|
|
39491
39860
|
}
|
|
39492
39861
|
function writeSlackPendingInboundMarker(channel, threadTs, messageTs, undeliverable = false, discretionary = false, payload) {
|
|
39493
39862
|
const path = slackPendingInboundPath(channel, threadTs, messageTs);
|
|
@@ -39538,7 +39907,7 @@ function rewriteSlackMarkerInPlace(path, marker) {
|
|
|
39538
39907
|
function markSlackMarkerSeenInPlace(fullPath) {
|
|
39539
39908
|
let marker;
|
|
39540
39909
|
try {
|
|
39541
|
-
marker = JSON.parse(
|
|
39910
|
+
marker = JSON.parse(readFileSync20(fullPath, "utf-8"));
|
|
39542
39911
|
} catch {
|
|
39543
39912
|
return;
|
|
39544
39913
|
}
|
|
@@ -39552,7 +39921,7 @@ function attachSlackReplayPayload(channel, threadTs, messageTs, payload) {
|
|
|
39552
39921
|
if (!path) return;
|
|
39553
39922
|
let marker;
|
|
39554
39923
|
try {
|
|
39555
|
-
marker = JSON.parse(
|
|
39924
|
+
marker = JSON.parse(readFileSync20(path, "utf-8"));
|
|
39556
39925
|
} catch {
|
|
39557
39926
|
return;
|
|
39558
39927
|
}
|
|
@@ -39563,7 +39932,7 @@ function readSlackPendingInboundMarker(channel, threadTs, messageTs) {
|
|
|
39563
39932
|
const path = slackPendingInboundPath(channel, threadTs, messageTs);
|
|
39564
39933
|
if (!path || !existsSync10(path)) return null;
|
|
39565
39934
|
try {
|
|
39566
|
-
return JSON.parse(
|
|
39935
|
+
return JSON.parse(readFileSync20(path, "utf-8"));
|
|
39567
39936
|
} catch {
|
|
39568
39937
|
return null;
|
|
39569
39938
|
}
|
|
@@ -39679,7 +40048,7 @@ function scheduleBusyAck(channel, threadTs, messageTs, isThreadReply, arrivedWhi
|
|
|
39679
40048
|
let paneLogFreshAgeMs = null;
|
|
39680
40049
|
if (SLACK_AGENT_DIR) {
|
|
39681
40050
|
try {
|
|
39682
|
-
const paneMtimeMs =
|
|
40051
|
+
const paneMtimeMs = statSync4(join20(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
|
|
39683
40052
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
39684
40053
|
} catch {
|
|
39685
40054
|
}
|
|
@@ -39712,7 +40081,7 @@ function __resetSlackBusyAckNoticeThrottle() {
|
|
|
39712
40081
|
function clearSlackMarkerFileWithHeal(fullPath) {
|
|
39713
40082
|
let marker = null;
|
|
39714
40083
|
try {
|
|
39715
|
-
marker = JSON.parse(
|
|
40084
|
+
marker = JSON.parse(readFileSync20(fullPath, "utf-8"));
|
|
39716
40085
|
} catch {
|
|
39717
40086
|
}
|
|
39718
40087
|
if (marker && decideRecoveryHeal({
|
|
@@ -39730,7 +40099,7 @@ function clearSlackMarkerFileWithHeal(fullPath) {
|
|
|
39730
40099
|
function markSlackMarkerSeenWithHeal(fullPath) {
|
|
39731
40100
|
let marker = null;
|
|
39732
40101
|
try {
|
|
39733
|
-
marker = JSON.parse(
|
|
40102
|
+
marker = JSON.parse(readFileSync20(fullPath, "utf-8"));
|
|
39734
40103
|
} catch {
|
|
39735
40104
|
return;
|
|
39736
40105
|
}
|
|
@@ -39799,10 +40168,10 @@ function slackNextRetryName(filename) {
|
|
|
39799
40168
|
async function processSlackRecoveryOutboxFile(filename) {
|
|
39800
40169
|
if (!SLACK_RECOVERY_OUTBOX_DIR) return;
|
|
39801
40170
|
if (filename.endsWith(".poison.json") || filename.endsWith(".tmp")) return;
|
|
39802
|
-
const fullPath =
|
|
40171
|
+
const fullPath = join20(SLACK_RECOVERY_OUTBOX_DIR, filename);
|
|
39803
40172
|
let payload;
|
|
39804
40173
|
try {
|
|
39805
|
-
payload = JSON.parse(
|
|
40174
|
+
payload = JSON.parse(readFileSync20(fullPath, "utf-8"));
|
|
39806
40175
|
} catch (err) {
|
|
39807
40176
|
process.stderr.write(
|
|
39808
40177
|
`slack-channel(${AGENT_CODE_NAME}): recovery outbox parse failed (${filename}): ${err.message}
|
|
@@ -39906,7 +40275,7 @@ async function processSlackRecoveryOutboxFile(filename) {
|
|
|
39906
40275
|
const next = slackNextRetryName(filename);
|
|
39907
40276
|
if (next) {
|
|
39908
40277
|
try {
|
|
39909
|
-
renameSync5(fullPath,
|
|
40278
|
+
renameSync5(fullPath, join20(SLACK_RECOVERY_OUTBOX_DIR, next.next));
|
|
39910
40279
|
if (next.attempt >= SLACK_MAX_RECOVERY_ATTEMPTS) {
|
|
39911
40280
|
process.stderr.write(
|
|
39912
40281
|
`slack-channel(${AGENT_CODE_NAME}): ghost-reply recovery exhausted retries \u2014 moved to ${next.next}
|
|
@@ -39937,7 +40306,7 @@ function scanSlackRecoveryRetries() {
|
|
|
39937
40306
|
if (!SLACK_RECOVERY_OUTBOX_DIR) return;
|
|
39938
40307
|
let entries;
|
|
39939
40308
|
try {
|
|
39940
|
-
entries =
|
|
40309
|
+
entries = readdirSync6(SLACK_RECOVERY_OUTBOX_DIR);
|
|
39941
40310
|
} catch {
|
|
39942
40311
|
return;
|
|
39943
40312
|
}
|
|
@@ -39946,7 +40315,7 @@ function scanSlackRecoveryRetries() {
|
|
|
39946
40315
|
if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
|
|
39947
40316
|
let mtimeMs;
|
|
39948
40317
|
try {
|
|
39949
|
-
mtimeMs =
|
|
40318
|
+
mtimeMs = statSync4(join20(SLACK_RECOVERY_OUTBOX_DIR, f)).mtimeMs;
|
|
39950
40319
|
} catch {
|
|
39951
40320
|
continue;
|
|
39952
40321
|
}
|
|
@@ -39967,7 +40336,7 @@ function startSlackRecoveryOutboxWatcher() {
|
|
|
39967
40336
|
return;
|
|
39968
40337
|
}
|
|
39969
40338
|
try {
|
|
39970
|
-
for (const f of
|
|
40339
|
+
for (const f of readdirSync6(SLACK_RECOVERY_OUTBOX_DIR)) {
|
|
39971
40340
|
if (isFirstAttemptSlackOutboxFile(f)) void processSlackRecoveryOutboxFile(f);
|
|
39972
40341
|
}
|
|
39973
40342
|
} catch {
|
|
@@ -39976,7 +40345,7 @@ function startSlackRecoveryOutboxWatcher() {
|
|
|
39976
40345
|
const watcher = watch(SLACK_RECOVERY_OUTBOX_DIR, (event, filename) => {
|
|
39977
40346
|
if (event !== "rename" || !filename) return;
|
|
39978
40347
|
if (!isFirstAttemptSlackOutboxFile(filename)) return;
|
|
39979
|
-
if (existsSync10(
|
|
40348
|
+
if (existsSync10(join20(SLACK_RECOVERY_OUTBOX_DIR, filename))) {
|
|
39980
40349
|
void processSlackRecoveryOutboxFile(filename);
|
|
39981
40350
|
}
|
|
39982
40351
|
});
|
|
@@ -39991,7 +40360,7 @@ function startSlackRecoveryOutboxWatcher() {
|
|
|
39991
40360
|
retryTimer.unref?.();
|
|
39992
40361
|
}
|
|
39993
40362
|
startSlackRecoveryOutboxWatcher();
|
|
39994
|
-
var SLACK_NOTICE_OUTBOX_DIR = SLACK_AGENT_DIR ?
|
|
40363
|
+
var SLACK_NOTICE_OUTBOX_DIR = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "slack-notice-outbox") : null;
|
|
39995
40364
|
var SLACK_NOTICE_MAX_AGE_MS = 9e4;
|
|
39996
40365
|
var SLACK_NOTICE_INFLIGHT = /* @__PURE__ */ new Set();
|
|
39997
40366
|
async function processSlackNoticeOutboxFile(filename) {
|
|
@@ -39999,11 +40368,11 @@ async function processSlackNoticeOutboxFile(filename) {
|
|
|
39999
40368
|
if (filename.startsWith(".") || filename.endsWith(".tmp") || !filename.endsWith(".json")) return;
|
|
40000
40369
|
if (SLACK_NOTICE_INFLIGHT.has(filename)) return;
|
|
40001
40370
|
SLACK_NOTICE_INFLIGHT.add(filename);
|
|
40002
|
-
const fullPath =
|
|
40371
|
+
const fullPath = join20(SLACK_NOTICE_OUTBOX_DIR, filename);
|
|
40003
40372
|
try {
|
|
40004
40373
|
let mtimeMs;
|
|
40005
40374
|
try {
|
|
40006
|
-
mtimeMs =
|
|
40375
|
+
mtimeMs = statSync4(fullPath).mtimeMs;
|
|
40007
40376
|
} catch {
|
|
40008
40377
|
return;
|
|
40009
40378
|
}
|
|
@@ -40016,7 +40385,7 @@ async function processSlackNoticeOutboxFile(filename) {
|
|
|
40016
40385
|
}
|
|
40017
40386
|
let payload;
|
|
40018
40387
|
try {
|
|
40019
|
-
const parsed = JSON.parse(
|
|
40388
|
+
const parsed = JSON.parse(readFileSync20(fullPath, "utf-8"));
|
|
40020
40389
|
if (!parsed || typeof parsed !== "object") throw new Error("not an object");
|
|
40021
40390
|
payload = parsed;
|
|
40022
40391
|
} catch {
|
|
@@ -40099,13 +40468,13 @@ function startSlackNoticeOutboxWatcher() {
|
|
|
40099
40468
|
return;
|
|
40100
40469
|
}
|
|
40101
40470
|
try {
|
|
40102
|
-
for (const f of
|
|
40471
|
+
for (const f of readdirSync6(SLACK_NOTICE_OUTBOX_DIR)) void processSlackNoticeOutboxFile(f);
|
|
40103
40472
|
} catch {
|
|
40104
40473
|
}
|
|
40105
40474
|
try {
|
|
40106
40475
|
const watcher = watch(SLACK_NOTICE_OUTBOX_DIR, (event, filename) => {
|
|
40107
40476
|
if (event !== "rename" || !filename) return;
|
|
40108
|
-
if (existsSync10(
|
|
40477
|
+
if (existsSync10(join20(SLACK_NOTICE_OUTBOX_DIR, filename))) {
|
|
40109
40478
|
void processSlackNoticeOutboxFile(filename);
|
|
40110
40479
|
}
|
|
40111
40480
|
});
|
|
@@ -40128,7 +40497,7 @@ function sweepSlackStaleMarkers(thresholdMs) {
|
|
|
40128
40497
|
if (!existsSync10(SLACK_PENDING_INBOUND_DIR)) return;
|
|
40129
40498
|
let filenames;
|
|
40130
40499
|
try {
|
|
40131
|
-
filenames =
|
|
40500
|
+
filenames = readdirSync6(SLACK_PENDING_INBOUND_DIR);
|
|
40132
40501
|
} catch (err) {
|
|
40133
40502
|
process.stderr.write(
|
|
40134
40503
|
`slack-channel(${AGENT_CODE_NAME}): stale-marker readdir failed: ${err.message}
|
|
@@ -40142,10 +40511,10 @@ function sweepSlackStaleMarkers(thresholdMs) {
|
|
|
40142
40511
|
for (const filename of filenames) {
|
|
40143
40512
|
if (!filename.endsWith(".json")) continue;
|
|
40144
40513
|
if (filename.endsWith(".tmp")) continue;
|
|
40145
|
-
const fullPath =
|
|
40514
|
+
const fullPath = join20(SLACK_PENDING_INBOUND_DIR, filename);
|
|
40146
40515
|
let marker;
|
|
40147
40516
|
try {
|
|
40148
|
-
marker = JSON.parse(
|
|
40517
|
+
marker = JSON.parse(readFileSync20(fullPath, "utf-8"));
|
|
40149
40518
|
} catch (err) {
|
|
40150
40519
|
process.stderr.write(
|
|
40151
40520
|
`slack-channel(${AGENT_CODE_NAME}): stale-marker parse failed for ${redactSlackId(filename)}: ${err.message}
|
|
@@ -40203,13 +40572,13 @@ var slackOrphanSweepTimer = setInterval(() => {
|
|
|
40203
40572
|
checkSlackWatchdogGiveUpNotice();
|
|
40204
40573
|
}, orphanSweepIntervalMs());
|
|
40205
40574
|
slackOrphanSweepTimer.unref?.();
|
|
40206
|
-
var SLACK_PROGRESS_HEARTBEAT_PATH = SLACK_AGENT_DIR ?
|
|
40575
|
+
var SLACK_PROGRESS_HEARTBEAT_PATH = SLACK_AGENT_DIR ? join20(SLACK_AGENT_DIR, "channel-progress-heartbeat.json") : null;
|
|
40207
40576
|
var slackTrackedProgress = null;
|
|
40208
40577
|
var slackProgressTickRunning = false;
|
|
40209
40578
|
function readSlackProgressHeartbeat() {
|
|
40210
40579
|
if (!SLACK_PROGRESS_HEARTBEAT_PATH || !existsSync10(SLACK_PROGRESS_HEARTBEAT_PATH)) return null;
|
|
40211
40580
|
try {
|
|
40212
|
-
return parseProgressHeartbeat(
|
|
40581
|
+
return parseProgressHeartbeat(readFileSync20(SLACK_PROGRESS_HEARTBEAT_PATH, "utf-8"));
|
|
40213
40582
|
} catch {
|
|
40214
40583
|
return null;
|
|
40215
40584
|
}
|
|
@@ -40232,11 +40601,11 @@ function findSlackProgressTarget() {
|
|
|
40232
40601
|
let best = null;
|
|
40233
40602
|
let bestMs = Infinity;
|
|
40234
40603
|
try {
|
|
40235
|
-
for (const name of
|
|
40604
|
+
for (const name of readdirSync6(SLACK_PENDING_INBOUND_DIR)) {
|
|
40236
40605
|
if (!name.endsWith(".json")) continue;
|
|
40237
40606
|
let m;
|
|
40238
40607
|
try {
|
|
40239
|
-
m = JSON.parse(
|
|
40608
|
+
m = JSON.parse(readFileSync20(join20(SLACK_PENDING_INBOUND_DIR, name), "utf-8"));
|
|
40240
40609
|
} catch {
|
|
40241
40610
|
continue;
|
|
40242
40611
|
}
|
|
@@ -40383,11 +40752,11 @@ function listPendingSlackConversations() {
|
|
|
40383
40752
|
if (!SLACK_PENDING_INBOUND_DIR || !existsSync10(SLACK_PENDING_INBOUND_DIR)) return [];
|
|
40384
40753
|
const byKey = /* @__PURE__ */ new Map();
|
|
40385
40754
|
try {
|
|
40386
|
-
for (const name of
|
|
40755
|
+
for (const name of readdirSync6(SLACK_PENDING_INBOUND_DIR)) {
|
|
40387
40756
|
if (!name.endsWith(".json")) continue;
|
|
40388
40757
|
try {
|
|
40389
40758
|
const marker = JSON.parse(
|
|
40390
|
-
|
|
40759
|
+
readFileSync20(join20(SLACK_PENDING_INBOUND_DIR, name), "utf8")
|
|
40391
40760
|
);
|
|
40392
40761
|
if (typeof marker.channel !== "string" || !marker.channel) continue;
|
|
40393
40762
|
if (typeof marker.thread_ts !== "string" || !marker.thread_ts) continue;
|
|
@@ -40439,7 +40808,7 @@ function postSlackWatchdogGiveUpNotice(channel, threadTs, isThreadReply, reason)
|
|
|
40439
40808
|
}
|
|
40440
40809
|
function checkSlackWatchdogGiveUpNotice() {
|
|
40441
40810
|
if (!SLACK_AGENT_DIR) return;
|
|
40442
|
-
const signal = readGiveUpSignal(
|
|
40811
|
+
const signal = readGiveUpSignal(join20(SLACK_AGENT_DIR, GIVE_UP_SIGNAL_FILENAME));
|
|
40443
40812
|
const signalAtMs = signal?.atMs ?? null;
|
|
40444
40813
|
const act = decideGiveUpNotice({
|
|
40445
40814
|
signalAtMs,
|
|
@@ -40471,7 +40840,7 @@ function readRestartTopicForMarker(filename, channel, threadTs) {
|
|
|
40471
40840
|
if (!SLACK_RESTART_CONTEXT_DIR) return null;
|
|
40472
40841
|
let raw;
|
|
40473
40842
|
try {
|
|
40474
|
-
raw =
|
|
40843
|
+
raw = readFileSync20(join20(SLACK_RESTART_CONTEXT_DIR, filename), "utf-8");
|
|
40475
40844
|
} catch {
|
|
40476
40845
|
return null;
|
|
40477
40846
|
}
|
|
@@ -40480,7 +40849,7 @@ function readRestartTopicForMarker(filename, channel, threadTs) {
|
|
|
40480
40849
|
function removeRestartContextHint(filename) {
|
|
40481
40850
|
if (!SLACK_RESTART_CONTEXT_DIR) return;
|
|
40482
40851
|
try {
|
|
40483
|
-
unlinkSync7(
|
|
40852
|
+
unlinkSync7(join20(SLACK_RESTART_CONTEXT_DIR, filename));
|
|
40484
40853
|
} catch {
|
|
40485
40854
|
}
|
|
40486
40855
|
}
|
|
@@ -40488,14 +40857,14 @@ function clearAllRestartContextHints() {
|
|
|
40488
40857
|
if (!SLACK_RESTART_CONTEXT_DIR) return;
|
|
40489
40858
|
let names;
|
|
40490
40859
|
try {
|
|
40491
|
-
names =
|
|
40860
|
+
names = readdirSync6(SLACK_RESTART_CONTEXT_DIR);
|
|
40492
40861
|
} catch {
|
|
40493
40862
|
return;
|
|
40494
40863
|
}
|
|
40495
40864
|
for (const name of names) {
|
|
40496
40865
|
if (!name.endsWith(".json")) continue;
|
|
40497
40866
|
try {
|
|
40498
|
-
unlinkSync7(
|
|
40867
|
+
unlinkSync7(join20(SLACK_RESTART_CONTEXT_DIR, name));
|
|
40499
40868
|
} catch {
|
|
40500
40869
|
}
|
|
40501
40870
|
}
|
|
@@ -40512,7 +40881,7 @@ async function notifyStrandedInboundsOnFirstConnect() {
|
|
|
40512
40881
|
if (!SLACK_PENDING_INBOUND_DIR || !existsSync10(SLACK_PENDING_INBOUND_DIR)) return;
|
|
40513
40882
|
let filenames;
|
|
40514
40883
|
try {
|
|
40515
|
-
filenames =
|
|
40884
|
+
filenames = readdirSync6(SLACK_PENDING_INBOUND_DIR);
|
|
40516
40885
|
} catch {
|
|
40517
40886
|
hadFailure = true;
|
|
40518
40887
|
return;
|
|
@@ -40522,10 +40891,10 @@ async function notifyStrandedInboundsOnFirstConnect() {
|
|
|
40522
40891
|
let notified = 0;
|
|
40523
40892
|
for (const filename of filenames) {
|
|
40524
40893
|
if (!filename.endsWith(".json")) continue;
|
|
40525
|
-
const fullPath =
|
|
40894
|
+
const fullPath = join20(SLACK_PENDING_INBOUND_DIR, filename);
|
|
40526
40895
|
let marker;
|
|
40527
40896
|
try {
|
|
40528
|
-
marker = JSON.parse(
|
|
40897
|
+
marker = JSON.parse(readFileSync20(fullPath, "utf-8"));
|
|
40529
40898
|
} catch {
|
|
40530
40899
|
continue;
|
|
40531
40900
|
}
|
|
@@ -40699,7 +41068,7 @@ function noteThreadActivityByMessageTs(channel, messageTs) {
|
|
|
40699
41068
|
markSeenAllSlackPendingMarkersForThread2(channel, messageTs);
|
|
40700
41069
|
markSeenSlackPendingMarkerByMessageTs2(channel, messageTs);
|
|
40701
41070
|
}
|
|
40702
|
-
var RESTART_FLAGS_DIR =
|
|
41071
|
+
var RESTART_FLAGS_DIR = join20(homedir7(), ".augmented", "restart-flags");
|
|
40703
41072
|
function actuateHostRestartSlack() {
|
|
40704
41073
|
return actuateHostRestart({
|
|
40705
41074
|
agtHost: AGT_HOST,
|
|
@@ -40720,10 +41089,10 @@ function buildAugmentedSlackMetadata() {
|
|
|
40720
41089
|
};
|
|
40721
41090
|
}
|
|
40722
41091
|
function hashChannelId(id) {
|
|
40723
|
-
return
|
|
41092
|
+
return createHash3("sha256").update(id).digest("hex").slice(0, 8);
|
|
40724
41093
|
}
|
|
40725
41094
|
function hashId(id) {
|
|
40726
|
-
return
|
|
41095
|
+
return createHash3("sha256").update(id).digest("hex").slice(0, 8);
|
|
40727
41096
|
}
|
|
40728
41097
|
async function postSlackMessage(body) {
|
|
40729
41098
|
const augmentedMeta = buildAugmentedSlackMetadata();
|
|
@@ -41304,7 +41673,7 @@ async function handleSlashCommandEnvelope(payload) {
|
|
|
41304
41673
|
if (!existsSync10(RESTART_FLAGS_DIR)) {
|
|
41305
41674
|
mkdirSync9(RESTART_FLAGS_DIR, { recursive: true });
|
|
41306
41675
|
}
|
|
41307
|
-
const flagPath =
|
|
41676
|
+
const flagPath = join20(RESTART_FLAGS_DIR, `${codeName}.flag`);
|
|
41308
41677
|
const flag = {
|
|
41309
41678
|
codeName,
|
|
41310
41679
|
source: "slack",
|
|
@@ -41447,7 +41816,7 @@ async function handleRestartCommand(opts) {
|
|
|
41447
41816
|
if (!existsSync10(RESTART_FLAGS_DIR)) {
|
|
41448
41817
|
mkdirSync9(RESTART_FLAGS_DIR, { recursive: true });
|
|
41449
41818
|
}
|
|
41450
|
-
const flagPath =
|
|
41819
|
+
const flagPath = join20(RESTART_FLAGS_DIR, `${codeName}.flag`);
|
|
41451
41820
|
const flag = {
|
|
41452
41821
|
codeName,
|
|
41453
41822
|
source: "slack",
|
|
@@ -41569,7 +41938,7 @@ var SLACK_HOT_THREAD_WINDOW_MS = parseHotThreadWindowMs(
|
|
|
41569
41938
|
);
|
|
41570
41939
|
function resolveThreadStorePath() {
|
|
41571
41940
|
if (!AGENT_CODE_NAME) return null;
|
|
41572
|
-
return
|
|
41941
|
+
return join20(homedir7(), ".augmented", AGENT_CODE_NAME, "slack-tracked-threads.json");
|
|
41573
41942
|
}
|
|
41574
41943
|
function parseTtlDays(raw) {
|
|
41575
41944
|
if (!raw) return void 0;
|
|
@@ -41608,9 +41977,9 @@ if (!BOT_TOKEN || !APP_TOKEN) {
|
|
|
41608
41977
|
var slackStderrLogStream = null;
|
|
41609
41978
|
if (AGENT_CODE_NAME) {
|
|
41610
41979
|
try {
|
|
41611
|
-
const logDir =
|
|
41980
|
+
const logDir = join20(homedir7(), ".augmented", AGENT_CODE_NAME);
|
|
41612
41981
|
mkdirSync9(logDir, { recursive: true });
|
|
41613
|
-
slackStderrLogStream = createWriteStream(
|
|
41982
|
+
slackStderrLogStream = createWriteStream(join20(logDir, "slack-channel-stderr.log"), {
|
|
41614
41983
|
flags: "a",
|
|
41615
41984
|
mode: 384
|
|
41616
41985
|
});
|
|
@@ -42486,7 +42855,7 @@ ${result.formatted}` : "No messages in range, or the bot is not a member of this
|
|
|
42486
42855
|
isError: true
|
|
42487
42856
|
};
|
|
42488
42857
|
}
|
|
42489
|
-
const allowedRoot = resolve2(
|
|
42858
|
+
const allowedRoot = resolve2(homedir7(), ".augmented", AGENT_CODE_NAME, "project") + "/";
|
|
42490
42859
|
const resolvedPath = resolve2(path);
|
|
42491
42860
|
if (!resolvedPath.startsWith(allowedRoot)) {
|
|
42492
42861
|
return {
|
|
@@ -42500,7 +42869,7 @@ ${result.formatted}` : "No messages in range, or the bot is not a member of this
|
|
|
42500
42869
|
let bytes;
|
|
42501
42870
|
let size;
|
|
42502
42871
|
try {
|
|
42503
|
-
const stat2 =
|
|
42872
|
+
const stat2 = statSync4(resolvedPath);
|
|
42504
42873
|
if (!stat2.isFile()) {
|
|
42505
42874
|
return {
|
|
42506
42875
|
content: [{ type: "text", text: `Upload refused: ${resolvedPath} is not a regular file.` }],
|
|
@@ -42508,7 +42877,7 @@ ${result.formatted}` : "No messages in range, or the bot is not a member of this
|
|
|
42508
42877
|
};
|
|
42509
42878
|
}
|
|
42510
42879
|
size = stat2.size;
|
|
42511
|
-
bytes =
|
|
42880
|
+
bytes = readFileSync20(resolvedPath);
|
|
42512
42881
|
} catch (err) {
|
|
42513
42882
|
return {
|
|
42514
42883
|
content: [{ type: "text", text: `Failed to read file: ${err.message}` }],
|
|
@@ -43163,7 +43532,7 @@ function isDownloadableFileId(fileId, channel) {
|
|
|
43163
43532
|
}
|
|
43164
43533
|
function redactAugmentedPaths2(msg) {
|
|
43165
43534
|
return msg.replaceAll(
|
|
43166
|
-
new RegExp(`${
|
|
43535
|
+
new RegExp(`${homedir7().replace(/[.*+?^${}()|[\\]\\\\]/g, "\\\\$&")}/\\.augmented/[^\\s'"\`]*`, "g"),
|
|
43167
43536
|
"<augmented-path>"
|
|
43168
43537
|
);
|
|
43169
43538
|
}
|
|
@@ -43283,7 +43652,7 @@ async function replayPendingSlackMarkers() {
|
|
|
43283
43652
|
if (!sessionAlive) return;
|
|
43284
43653
|
let filenames;
|
|
43285
43654
|
try {
|
|
43286
|
-
filenames =
|
|
43655
|
+
filenames = readdirSync6(SLACK_PENDING_INBOUND_DIR);
|
|
43287
43656
|
} catch {
|
|
43288
43657
|
return;
|
|
43289
43658
|
}
|
|
@@ -43291,7 +43660,7 @@ async function replayPendingSlackMarkers() {
|
|
|
43291
43660
|
let paneFreshAgeMs = null;
|
|
43292
43661
|
if (SLACK_AGENT_DIR) {
|
|
43293
43662
|
try {
|
|
43294
|
-
paneFreshAgeMs = Math.max(0, now -
|
|
43663
|
+
paneFreshAgeMs = Math.max(0, now - statSync4(join20(SLACK_AGENT_DIR, "pane.log")).mtimeMs);
|
|
43295
43664
|
} catch {
|
|
43296
43665
|
}
|
|
43297
43666
|
}
|
|
@@ -43299,10 +43668,10 @@ async function replayPendingSlackMarkers() {
|
|
|
43299
43668
|
const entries = [];
|
|
43300
43669
|
for (const name of filenames) {
|
|
43301
43670
|
if (!name.endsWith(".json") || name.endsWith(".tmp")) continue;
|
|
43302
|
-
const fullPath =
|
|
43671
|
+
const fullPath = join20(SLACK_PENDING_INBOUND_DIR, name);
|
|
43303
43672
|
let marker;
|
|
43304
43673
|
try {
|
|
43305
|
-
marker = JSON.parse(
|
|
43674
|
+
marker = JSON.parse(readFileSync20(fullPath, "utf-8"));
|
|
43306
43675
|
} catch {
|
|
43307
43676
|
continue;
|
|
43308
43677
|
}
|
|
@@ -43649,7 +44018,7 @@ async function connectSocketMode() {
|
|
|
43649
44018
|
const passedIdentity = access.kind !== "drop" || access.reason.startsWith("peer:");
|
|
43650
44019
|
if (passedIdentity) recordActivity("inbound");
|
|
43651
44020
|
if (access.kind === "drop") {
|
|
43652
|
-
const channelHash =
|
|
44021
|
+
const channelHash = createHash3("sha256").update(evt.channel ?? "").digest("hex").slice(0, 8);
|
|
43653
44022
|
const subtypeSuffix = access.reason === "content:subtype" ? ` subtype=${evt.subtype ?? "none"}` : "";
|
|
43654
44023
|
process.stderr.write(
|
|
43655
44024
|
`slack-channel: inbound drop reason=${access.reason}${subtypeSuffix} channel=${channelHash} ts=${redactSlackId(evt.ts)}
|
|
@@ -43774,7 +44143,8 @@ async function connectSocketMode() {
|
|
|
43774
44143
|
});
|
|
43775
44144
|
return;
|
|
43776
44145
|
}
|
|
43777
|
-
const
|
|
44146
|
+
const reactiveMode = resolveUsageLimitReactiveMode();
|
|
44147
|
+
const usageLimitUntil = !isBot && shouldReadPredictiveMarker(reactiveMode) ? readUsageLimitUntil({ codeName: AGENT_CODE_NAME }) : null;
|
|
43778
44148
|
if (usageLimitUntil) {
|
|
43779
44149
|
process.stderr.write(
|
|
43780
44150
|
`slack-channel(${AGENT_CODE_NAME}): usage-limit active until ${usageLimitUntil.toISOString()} \u2014 notice, no dispatch (channel=${redactSlackId(evt.channel)})
|
|
@@ -43833,7 +44203,7 @@ async function connectSocketMode() {
|
|
|
43833
44203
|
if (evt.type === "message" && evt.channel && !isDirectMessage) {
|
|
43834
44204
|
if (isThreadReply) {
|
|
43835
44205
|
const logThreadDrop = (reason) => {
|
|
43836
|
-
const channelHash =
|
|
44206
|
+
const channelHash = createHash3("sha256").update(evt.channel ?? "").digest("hex").slice(0, 8);
|
|
43837
44207
|
process.stderr.write(
|
|
43838
44208
|
`slack-channel(${AGENT_CODE_NAME}): thread-reply drop reason=${reason} auto_follow=${THREAD_AUTO_FOLLOW} channel=${channelHash} ts=${redactSlackId(evt.ts)}
|
|
43839
44209
|
`
|
|
@@ -43899,7 +44269,7 @@ async function connectSocketMode() {
|
|
|
43899
44269
|
let paneLogFreshAgeMs = null;
|
|
43900
44270
|
if (SLACK_AGENT_DIR) {
|
|
43901
44271
|
try {
|
|
43902
|
-
const paneMtimeMs =
|
|
44272
|
+
const paneMtimeMs = statSync4(join20(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
|
|
43903
44273
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
43904
44274
|
} catch {
|
|
43905
44275
|
}
|
|
@@ -44065,10 +44435,26 @@ ${forwarded.text}` : forwarded.text;
|
|
|
44065
44435
|
});
|
|
44066
44436
|
clearScheduledTurnMarker(SLACK_AGENT_DIR);
|
|
44067
44437
|
}
|
|
44438
|
+
const dispatchedAtMs = Date.now();
|
|
44068
44439
|
await mcp.notification({
|
|
44069
44440
|
method: "notifications/claude/channel",
|
|
44070
44441
|
params: replayPayload
|
|
44071
44442
|
});
|
|
44443
|
+
const watchMode = armedWatchMode({
|
|
44444
|
+
mode: reactiveMode,
|
|
44445
|
+
isBot: isFromBot,
|
|
44446
|
+
replyOwed: shouldEngage
|
|
44447
|
+
});
|
|
44448
|
+
if (watchMode) {
|
|
44449
|
+
armSlackUsageLimitWatch({
|
|
44450
|
+
mode: watchMode,
|
|
44451
|
+
channel,
|
|
44452
|
+
senderId: evt.user,
|
|
44453
|
+
threadTs,
|
|
44454
|
+
messageTs: ts,
|
|
44455
|
+
sinceMs: dispatchedAtMs
|
|
44456
|
+
});
|
|
44457
|
+
}
|
|
44072
44458
|
if (shouldEngage) seedSlackProgressHeartbeat();
|
|
44073
44459
|
if (channel) {
|
|
44074
44460
|
conversationIngestClient?.ingest({
|