@integrity-labs/agt-cli 0.28.1177 → 0.28.1179
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 +104 -417
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-DJNCIWVG.js → chunk-2FHYCFZM.js} +2 -2
- package/dist/{chunk-H37WRW2E.js → chunk-GJD536LU.js} +9 -6
- package/dist/chunk-GJD536LU.js.map +1 -0
- package/dist/{manager-supervisor-KIFBGETA.js → chunk-H3JMPEH7.js} +176 -8
- package/dist/chunk-H3JMPEH7.js.map +1 -0
- package/dist/{chunk-NHUXO5H2.js → chunk-KDYZNWZW.js} +2 -2
- package/dist/{chunk-45UH24I2.js → chunk-O5P2OS36.js} +435 -56
- package/dist/chunk-O5P2OS36.js.map +1 -0
- package/dist/{chunk-47P33SZF.js → chunk-PINFVWGX.js} +120 -3
- package/dist/chunk-PINFVWGX.js.map +1 -0
- package/dist/{claude-code-updater-H7RNX6M7.js → claude-code-updater-LL7KVAU3.js} +3 -3
- package/dist/{claude-pair-runtime-53JY6TQX.js → claude-pair-runtime-R5MNSUM7.js} +3 -3
- package/dist/lib/manager-worker.js +636 -262
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/manager-supervisor-TD7E6FPC.js +26 -0
- package/dist/mcp/direct-chat-channel.js +18 -1
- package/dist/mcp/index.js +151 -63
- package/dist/mcp/origami.js +18 -1
- package/dist/mcp/slack-channel.js +18 -1
- package/dist/mcp/telegram-channel.js +18 -1
- package/dist/{persistent-session-HVYGIS5C.js → persistent-session-34QXCPJK.js} +4 -4
- package/dist/persistent-session-34QXCPJK.js.map +1 -0
- package/dist/{responsiveness-probe-OGZ6ADVR.js → responsiveness-probe-ZT6ITMYI.js} +4 -4
- package/dist/{session-auth-dead-2JJLKURE.js → session-auth-dead-KAHV2ES2.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-45UH24I2.js.map +0 -1
- package/dist/chunk-47P33SZF.js.map +0 -1
- package/dist/chunk-H37WRW2E.js.map +0 -1
- package/dist/manager-supervisor-KIFBGETA.js.map +0 -1
- /package/dist/{chunk-DJNCIWVG.js.map → chunk-2FHYCFZM.js.map} +0 -0
- /package/dist/{chunk-NHUXO5H2.js.map → chunk-KDYZNWZW.js.map} +0 -0
- /package/dist/{claude-code-updater-H7RNX6M7.js.map → claude-code-updater-LL7KVAU3.js.map} +0 -0
- /package/dist/{claude-pair-runtime-53JY6TQX.js.map → claude-pair-runtime-R5MNSUM7.js.map} +0 -0
- /package/dist/{persistent-session-HVYGIS5C.js.map → manager-supervisor-TD7E6FPC.js.map} +0 -0
- /package/dist/{responsiveness-probe-OGZ6ADVR.js.map → responsiveness-probe-ZT6ITMYI.js.map} +0 -0
- /package/dist/{session-auth-dead-2JJLKURE.js.map → session-auth-dead-KAHV2ES2.js.map} +0 -0
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
RestartBreaker,
|
|
12
12
|
SUPERVISOR_RESTART_EXIT_CODE,
|
|
13
13
|
TunnelWatcher,
|
|
14
|
+
adoptHostKeyInProcess,
|
|
14
15
|
api,
|
|
15
16
|
atomicWriteFileSync,
|
|
16
17
|
buildClaudeAgentMatcher,
|
|
@@ -52,6 +53,7 @@ import {
|
|
|
52
53
|
markQuarantinedForProbe,
|
|
53
54
|
migrateAgentDirToIdKeyed,
|
|
54
55
|
mintAgentKey,
|
|
56
|
+
mintRotatedHostKey,
|
|
55
57
|
parseRmPolicy,
|
|
56
58
|
pinAllowsUrgent,
|
|
57
59
|
provision,
|
|
@@ -65,6 +67,7 @@ import {
|
|
|
65
67
|
provisionSessionStateHook,
|
|
66
68
|
provisionStopHook,
|
|
67
69
|
readEnvNumber,
|
|
70
|
+
readEtcEnvironmentValue,
|
|
68
71
|
readHostArchiveAddress,
|
|
69
72
|
reapLegacyTokenFile,
|
|
70
73
|
reapMissingMcpSessions,
|
|
@@ -76,8 +79,10 @@ import {
|
|
|
76
79
|
safeWriteJsonAtomic,
|
|
77
80
|
setConfigHash,
|
|
78
81
|
shellGuard,
|
|
79
|
-
tripClass
|
|
80
|
-
|
|
82
|
+
tripClass,
|
|
83
|
+
writeEtcEnvironment,
|
|
84
|
+
writeProfileDScript
|
|
85
|
+
} from "../chunk-O5P2OS36.js";
|
|
81
86
|
import {
|
|
82
87
|
CLAUDE_CODE_SECURITY_FLOOR,
|
|
83
88
|
SELF_UPDATE_TIMEOUTS,
|
|
@@ -91,7 +96,11 @@ import {
|
|
|
91
96
|
runSafeCleanup,
|
|
92
97
|
tightestDiskStat,
|
|
93
98
|
withPackageCacheLock
|
|
94
|
-
} from "../chunk-
|
|
99
|
+
} from "../chunk-KDYZNWZW.js";
|
|
100
|
+
import {
|
|
101
|
+
rewriteSupervisorApiKey,
|
|
102
|
+
supervisorChannelsRefusing
|
|
103
|
+
} from "../chunk-H3JMPEH7.js";
|
|
95
104
|
import {
|
|
96
105
|
getProjectDir as getProjectDir2,
|
|
97
106
|
getReadyTasks,
|
|
@@ -130,6 +139,7 @@ import {
|
|
|
130
139
|
injectMessage,
|
|
131
140
|
injectMessageWithStatus,
|
|
132
141
|
injectOpencodeMessage,
|
|
142
|
+
isActivelyProcessing,
|
|
133
143
|
isConfirmedRespawn,
|
|
134
144
|
isOpencodeSessionHealthy,
|
|
135
145
|
isSessionHealthy,
|
|
@@ -178,7 +188,7 @@ import {
|
|
|
178
188
|
webFetchBaselineValue,
|
|
179
189
|
webFetchRestartNeeded,
|
|
180
190
|
writeEgressAllowlist
|
|
181
|
-
} from "../chunk-
|
|
191
|
+
} from "../chunk-GJD536LU.js";
|
|
182
192
|
import {
|
|
183
193
|
isAgentIdle,
|
|
184
194
|
isStaleForToday,
|
|
@@ -187,12 +197,13 @@ import {
|
|
|
187
197
|
sessionTranscriptDir,
|
|
188
198
|
subagentActivityAgeSeconds,
|
|
189
199
|
transcriptActivityAgeSeconds
|
|
190
|
-
} from "../chunk-
|
|
200
|
+
} from "../chunk-2FHYCFZM.js";
|
|
191
201
|
import {
|
|
192
202
|
classifyUnanswerablePane,
|
|
193
203
|
focusedConfirmDialogBlock,
|
|
194
204
|
isParkedOnToolPermissionPrompt,
|
|
195
205
|
paneRemedy,
|
|
206
|
+
parkedModalKind,
|
|
196
207
|
sendDialogKeys,
|
|
197
208
|
simpleTextHash
|
|
198
209
|
} from "../chunk-OO36JBFI.js";
|
|
@@ -226,6 +237,7 @@ import {
|
|
|
226
237
|
MANAGER_LIVENESS_HEARTBEAT_INTERVAL_MS,
|
|
227
238
|
MAX_AVATAR_ENV_URL_BYTES,
|
|
228
239
|
NO_FAILING_TURN_RUN,
|
|
240
|
+
NO_TRANSCRIPT_ACTIVITY,
|
|
229
241
|
SCHEDULED_TURN_MARKER_FILENAME,
|
|
230
242
|
SKILLS_INDEX_SECTION_END,
|
|
231
243
|
SKILLS_INDEX_SECTION_START,
|
|
@@ -300,12 +312,15 @@ import {
|
|
|
300
312
|
resolveChannels,
|
|
301
313
|
resolveCrossTeamPeerIntraOrg,
|
|
302
314
|
resolveDmTarget,
|
|
315
|
+
resolveSessionActivityState,
|
|
303
316
|
scrubPreservingIdentifiers,
|
|
304
317
|
senderPolicyIsEnforcedOn,
|
|
305
318
|
serializeAccountEnforcementMarker,
|
|
319
|
+
shouldMintReplacementKey,
|
|
306
320
|
stabiliseResetInstant,
|
|
307
|
-
sumTranscriptUsageInWindow
|
|
308
|
-
|
|
321
|
+
sumTranscriptUsageInWindow,
|
|
322
|
+
summarizeTranscriptActivity
|
|
323
|
+
} from "../chunk-PINFVWGX.js";
|
|
309
324
|
import {
|
|
310
325
|
CLAUDE_CONFIG_DIR_ENV,
|
|
311
326
|
claudeConfigDirFor,
|
|
@@ -317,7 +332,7 @@ import "../chunk-DGUM43GV.js";
|
|
|
317
332
|
|
|
318
333
|
// src/lib/manager-worker.ts
|
|
319
334
|
import { createHash as createHash20 } from "crypto";
|
|
320
|
-
import { readFileSync as readFileSync34, writeFileSync as writeFileSync18, mkdirSync as mkdirSync16, existsSync as existsSync19, rmSync as rmSync8, readdirSync as
|
|
335
|
+
import { readFileSync as readFileSync34, writeFileSync as writeFileSync18, mkdirSync as mkdirSync16, existsSync as existsSync19, rmSync as rmSync8, readdirSync as readdirSync14, statSync as statSync15, unlinkSync as unlinkSync6, renameSync as renameSync11, utimesSync as utimesSync4, readlinkSync as readlinkSync2 } from "fs";
|
|
321
336
|
|
|
322
337
|
// src/lib/atomic-file-replace.ts
|
|
323
338
|
import { copyFileSync, renameSync, unlinkSync } from "fs";
|
|
@@ -734,7 +749,7 @@ function clearEpisode(codeName) {
|
|
|
734
749
|
}
|
|
735
750
|
|
|
736
751
|
// src/lib/manager-worker.ts
|
|
737
|
-
import { join as
|
|
752
|
+
import { join as join44, dirname as dirname11, delimiter as pathDelimiter } from "path";
|
|
738
753
|
import { homedir as homedir17, hostname, platform as platform3 } from "os";
|
|
739
754
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
740
755
|
|
|
@@ -3641,6 +3656,100 @@ function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
|
|
|
3641
3656
|
}
|
|
3642
3657
|
}
|
|
3643
3658
|
|
|
3659
|
+
// src/lib/host-key-rotation.ts
|
|
3660
|
+
async function adoptRotatedHostKey(deps) {
|
|
3661
|
+
const refusals = deps.preflightPersist?.() ?? [];
|
|
3662
|
+
if (refusals.length > 0) {
|
|
3663
|
+
deps.log(
|
|
3664
|
+
`[key-rotation] not minting: ${refusals.length} persist channel(s) would refuse the new key, so a mint would leak an active credential for nothing. ${refusals.join(" | ")}`
|
|
3665
|
+
);
|
|
3666
|
+
return deps.held ? { status: "persist-refused", reasons: refusals, held: deps.held } : { status: "persist-refused", reasons: refusals };
|
|
3667
|
+
}
|
|
3668
|
+
let minted;
|
|
3669
|
+
if (deps.held) {
|
|
3670
|
+
minted = deps.held;
|
|
3671
|
+
deps.log(`[key-rotation] retrying the persist of ${minted.prefix}, minted earlier for this request`);
|
|
3672
|
+
} else {
|
|
3673
|
+
let result;
|
|
3674
|
+
try {
|
|
3675
|
+
result = await deps.mint();
|
|
3676
|
+
} catch (err) {
|
|
3677
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
3678
|
+
deps.log(`[key-rotation] mint failed: ${detail}`);
|
|
3679
|
+
return { status: "error", detail };
|
|
3680
|
+
}
|
|
3681
|
+
if (result && "refused" in result) {
|
|
3682
|
+
deps.log(
|
|
3683
|
+
`[key-rotation] the control plane refused the mint for good: ${result.refused}. Not retrying this request. If it never completes, a compromised rotation clears it (docs/runbooks/host-api-key-rotation.md).`
|
|
3684
|
+
);
|
|
3685
|
+
return { status: "mint-refused", reason: result.refused };
|
|
3686
|
+
}
|
|
3687
|
+
if (!result || !result.rawKey || !result.prefix) {
|
|
3688
|
+
deps.log("[key-rotation] mint returned nothing usable - leaving the current key in force");
|
|
3689
|
+
return { status: "mint-failed" };
|
|
3690
|
+
}
|
|
3691
|
+
minted = result;
|
|
3692
|
+
}
|
|
3693
|
+
let persisted;
|
|
3694
|
+
try {
|
|
3695
|
+
persisted = deps.persist(minted.rawKey);
|
|
3696
|
+
} catch (err) {
|
|
3697
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
3698
|
+
deps.log(
|
|
3699
|
+
`[key-rotation] could not persist the new key (${minted.prefix}): ${detail} - NOT adopting, NOT acking; the current key stays in force`
|
|
3700
|
+
);
|
|
3701
|
+
return { status: "error", detail, held: minted };
|
|
3702
|
+
}
|
|
3703
|
+
if (!persisted) {
|
|
3704
|
+
deps.log(
|
|
3705
|
+
`[key-rotation] could not persist the new key (${minted.prefix}) - NOT adopting, NOT acking; the current key stays in force`
|
|
3706
|
+
);
|
|
3707
|
+
return { status: "persist-failed", prefix: minted.prefix, held: minted };
|
|
3708
|
+
}
|
|
3709
|
+
if (deps.onPersisted && !deps.onPersisted(minted.prefix)) {
|
|
3710
|
+
deps.log(
|
|
3711
|
+
`[key-rotation] persisted ${minted.prefix} but could not save the pending ack - NOT adopting; the current key stays in force and the retry reuses this key`
|
|
3712
|
+
);
|
|
3713
|
+
return { status: "error", detail: "pending ack could not be saved", held: minted };
|
|
3714
|
+
}
|
|
3715
|
+
try {
|
|
3716
|
+
deps.adoptInProcess(minted.rawKey);
|
|
3717
|
+
} catch (err) {
|
|
3718
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
3719
|
+
deps.log(
|
|
3720
|
+
`[key-rotation] persisted ${minted.prefix} but could not adopt it in-process: ${detail} - it will take effect on the next manager restart`
|
|
3721
|
+
);
|
|
3722
|
+
return { status: "error", detail, held: minted };
|
|
3723
|
+
}
|
|
3724
|
+
deps.log(
|
|
3725
|
+
`[key-rotation] adopted new host key ${minted.prefix}. The previous key stays valid until the control plane expires it on this host's ack.`
|
|
3726
|
+
);
|
|
3727
|
+
return { status: "adopted", prefix: minted.prefix };
|
|
3728
|
+
}
|
|
3729
|
+
function nextPendingAck(pending2, resp) {
|
|
3730
|
+
if (!pending2) return { pending: null, log: null };
|
|
3731
|
+
if (!resp || !("key_rotation_requested_at" in resp)) {
|
|
3732
|
+
return {
|
|
3733
|
+
pending: pending2,
|
|
3734
|
+
log: `[key-rotation] the heartbeat did not report key_rotation_requested_at, so nothing confirms ${pending2} was finalized. Re-acking next poll; the current key stays in force.`
|
|
3735
|
+
};
|
|
3736
|
+
}
|
|
3737
|
+
if (resp.key_rotation_requested_at) {
|
|
3738
|
+
return {
|
|
3739
|
+
pending: pending2,
|
|
3740
|
+
log: `[key-rotation] acked ${pending2} but the request is still armed server-side, so the outgoing key was NOT expired. Re-acking next poll; the current key stays in force either way.`
|
|
3741
|
+
};
|
|
3742
|
+
}
|
|
3743
|
+
return {
|
|
3744
|
+
pending: null,
|
|
3745
|
+
log: `[key-rotation] acked adoption of ${pending2}; the previous key is now expiring`
|
|
3746
|
+
};
|
|
3747
|
+
}
|
|
3748
|
+
function alreadyHandledRotationRequest(requestedAt, lastHandled) {
|
|
3749
|
+
if (!requestedAt) return true;
|
|
3750
|
+
return requestedAt === lastHandled;
|
|
3751
|
+
}
|
|
3752
|
+
|
|
3644
3753
|
// src/lib/heartbeat-account-email.ts
|
|
3645
3754
|
function mayReportAccountEmail(rawMode) {
|
|
3646
3755
|
return rawMode === "subscription";
|
|
@@ -4716,9 +4825,130 @@ function failingTurnLoops(now = Date.now(), threshold = failingTurnThreshold(),
|
|
|
4716
4825
|
return [...failing, ...recovered];
|
|
4717
4826
|
}
|
|
4718
4827
|
|
|
4719
|
-
// src/lib/
|
|
4720
|
-
import { readdirSync as readdirSync3,
|
|
4828
|
+
// src/lib/session-activity.ts
|
|
4829
|
+
import { readdirSync as readdirSync3, statSync as statSync3 } from "fs";
|
|
4721
4830
|
import { join as join18 } from "path";
|
|
4831
|
+
var RULE = /^[─━]{10,}/;
|
|
4832
|
+
var CARET_LINE = /^\s*❯(\s|$)/;
|
|
4833
|
+
var NON_BLOCKING_PICKER = { title: "We recommend compacting earlier", footer: "esc not now", kind: "compaction-suggestion" };
|
|
4834
|
+
var TOOL_NAME_MAX = 120;
|
|
4835
|
+
var MIN_TRANSCRIPT_CHECK_MS = 3e4;
|
|
4836
|
+
function classifyPane(screen, tmuxAlive) {
|
|
4837
|
+
if (!tmuxAlive) return { state: "no_session", promptKind: null };
|
|
4838
|
+
if (!screen || !screen.trim()) return null;
|
|
4839
|
+
const kind = parkedModalKind(screen);
|
|
4840
|
+
if (kind) return { state: "blocked_on_prompt", promptKind: kind };
|
|
4841
|
+
const lines = screen.split("\n");
|
|
4842
|
+
const rules = lines.flatMap((l, i) => RULE.test(l.trim()) ? [i] : []);
|
|
4843
|
+
const lastRule = rules[rules.length - 1] ?? -1;
|
|
4844
|
+
const carets = lines.flatMap((l, i) => CARET_LINE.test(l) ? [i] : []);
|
|
4845
|
+
const lastCaret = carets[carets.length - 1] ?? -1;
|
|
4846
|
+
if (lastCaret > lastRule) {
|
|
4847
|
+
const below = lines.slice(lastRule + 1);
|
|
4848
|
+
const footer = below.filter((l) => l.trim()).at(-1) ?? "";
|
|
4849
|
+
if (below.some((l) => l.includes(NON_BLOCKING_PICKER.title)) && footer.includes(NON_BLOCKING_PICKER.footer)) {
|
|
4850
|
+
return isActivelyProcessing(screen) ? { state: "mid_turn", promptKind: null } : { state: "idle_at_prompt", promptKind: NON_BLOCKING_PICKER.kind };
|
|
4851
|
+
}
|
|
4852
|
+
return { state: "blocked_on_prompt", promptKind: "unknown" };
|
|
4853
|
+
}
|
|
4854
|
+
if (isActivelyProcessing(screen)) return { state: "mid_turn", promptKind: null };
|
|
4855
|
+
const prevRule = rules[rules.length - 2] ?? -1;
|
|
4856
|
+
const hasInputBox = lastCaret > prevRule && lastCaret < lastRule && prevRule >= 0;
|
|
4857
|
+
if (!hasInputBox) return { state: "blocked_on_prompt", promptKind: "unknown" };
|
|
4858
|
+
return { state: "idle_at_prompt", promptKind: null };
|
|
4859
|
+
}
|
|
4860
|
+
var cache = /* @__PURE__ */ new Map();
|
|
4861
|
+
function newestTranscript(dir) {
|
|
4862
|
+
let names;
|
|
4863
|
+
try {
|
|
4864
|
+
names = readdirSync3(dir);
|
|
4865
|
+
} catch {
|
|
4866
|
+
return null;
|
|
4867
|
+
}
|
|
4868
|
+
let best = null;
|
|
4869
|
+
for (const name of names) {
|
|
4870
|
+
if (!name.endsWith(".jsonl")) continue;
|
|
4871
|
+
const path = join18(dir, name);
|
|
4872
|
+
try {
|
|
4873
|
+
const st = statSync3(path);
|
|
4874
|
+
if (st.isFile() && (best === null || st.mtimeMs > best.mtimeMs)) {
|
|
4875
|
+
best = { path, mtimeMs: st.mtimeMs, size: st.size };
|
|
4876
|
+
}
|
|
4877
|
+
} catch {
|
|
4878
|
+
continue;
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
return best;
|
|
4882
|
+
}
|
|
4883
|
+
function sessionTranscript(dir, sessionId) {
|
|
4884
|
+
if (!sessionId) return newestTranscript(dir);
|
|
4885
|
+
const path = join18(dir, `${sessionId}.jsonl`);
|
|
4886
|
+
try {
|
|
4887
|
+
const st = statSync3(path);
|
|
4888
|
+
return st.isFile() ? { path, mtimeMs: st.mtimeMs, size: st.size } : null;
|
|
4889
|
+
} catch {
|
|
4890
|
+
return null;
|
|
4891
|
+
}
|
|
4892
|
+
}
|
|
4893
|
+
function readTranscript(codeName, dir, sessionId, nowMs) {
|
|
4894
|
+
const session = sessionId ?? null;
|
|
4895
|
+
const prev = cache.get(codeName)?.sessionId === session ? cache.get(codeName) : void 0;
|
|
4896
|
+
if (prev && nowMs - prev.checkedAt < MIN_TRANSCRIPT_CHECK_MS) return prev;
|
|
4897
|
+
const file = sessionTranscript(dir, sessionId);
|
|
4898
|
+
if (!file) {
|
|
4899
|
+
const none = { checkedAt: nowMs, sessionId: session, path: null, mtimeMs: null, size: 0, activity: NO_TRANSCRIPT_ACTIVITY };
|
|
4900
|
+
cache.set(codeName, none);
|
|
4901
|
+
return none;
|
|
4902
|
+
}
|
|
4903
|
+
if (prev && prev.path === file.path && prev.mtimeMs === file.mtimeMs && prev.size === file.size) {
|
|
4904
|
+
prev.checkedAt = nowMs;
|
|
4905
|
+
return prev;
|
|
4906
|
+
}
|
|
4907
|
+
const next = {
|
|
4908
|
+
checkedAt: nowMs,
|
|
4909
|
+
sessionId: session,
|
|
4910
|
+
path: file.path,
|
|
4911
|
+
mtimeMs: file.mtimeMs,
|
|
4912
|
+
size: file.size,
|
|
4913
|
+
activity: summarizeTranscriptActivity(readTail(file.path, file.size))
|
|
4914
|
+
};
|
|
4915
|
+
cache.set(codeName, next);
|
|
4916
|
+
return next;
|
|
4917
|
+
}
|
|
4918
|
+
function iso(ms) {
|
|
4919
|
+
return ms === null ? null : new Date(ms).toISOString();
|
|
4920
|
+
}
|
|
4921
|
+
function buildSessionActivityReport(args) {
|
|
4922
|
+
const nowMs = args.now ?? Date.now();
|
|
4923
|
+
try {
|
|
4924
|
+
const pane = classifyPane(args.screenCapture, args.tmuxAlive);
|
|
4925
|
+
if (!pane) return null;
|
|
4926
|
+
const transcript = readTranscript(args.codeName, args.transcriptDir, args.sessionId, nowMs);
|
|
4927
|
+
const state10 = resolveSessionActivityState({
|
|
4928
|
+
pane,
|
|
4929
|
+
transcript: transcript.activity,
|
|
4930
|
+
transcriptMtimeMs: transcript.mtimeMs,
|
|
4931
|
+
// When the mtime was read, not now: it can be up to 30s old, and a stale read
|
|
4932
|
+
// must not age a transcript that has since moved into `turn_killed`.
|
|
4933
|
+
nowMs: transcript.checkedAt
|
|
4934
|
+
});
|
|
4935
|
+
return {
|
|
4936
|
+
state: state10,
|
|
4937
|
+
promptKind: state10 === "blocked_on_prompt" || state10 === "idle_at_prompt" ? pane.promptKind : null,
|
|
4938
|
+
lastToolName: transcript.activity.lastToolName?.slice(0, TOOL_NAME_MAX) ?? null,
|
|
4939
|
+
lastToolAt: iso(transcript.activity.lastToolAtMs),
|
|
4940
|
+
lastCompletedTurnAt: iso(transcript.activity.lastCompletedTurnAtMs),
|
|
4941
|
+
transcriptMtime: iso(transcript.mtimeMs)
|
|
4942
|
+
};
|
|
4943
|
+
} catch (err) {
|
|
4944
|
+
args.log?.(`[session-activity] failed for '${args.codeName}': ${err.message}`);
|
|
4945
|
+
return null;
|
|
4946
|
+
}
|
|
4947
|
+
}
|
|
4948
|
+
|
|
4949
|
+
// src/lib/workflow-run-reconciler.ts
|
|
4950
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync12, statSync as statSync4 } from "fs";
|
|
4951
|
+
import { join as join19 } from "path";
|
|
4722
4952
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
4723
4953
|
var SETTLE_MS = 3e4;
|
|
4724
4954
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -4752,15 +4982,15 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
4752
4982
|
if (depth > MAX_SUBAGENT_DEPTH) return;
|
|
4753
4983
|
let entries;
|
|
4754
4984
|
try {
|
|
4755
|
-
entries =
|
|
4985
|
+
entries = readdirSync4(dir);
|
|
4756
4986
|
} catch {
|
|
4757
4987
|
return;
|
|
4758
4988
|
}
|
|
4759
4989
|
for (const name of entries) {
|
|
4760
|
-
const p =
|
|
4990
|
+
const p = join19(dir, name);
|
|
4761
4991
|
let st;
|
|
4762
4992
|
try {
|
|
4763
|
-
st =
|
|
4993
|
+
st = statSync4(p);
|
|
4764
4994
|
} catch {
|
|
4765
4995
|
continue;
|
|
4766
4996
|
}
|
|
@@ -4775,15 +5005,15 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
4775
5005
|
const out = [];
|
|
4776
5006
|
let entries;
|
|
4777
5007
|
try {
|
|
4778
|
-
entries =
|
|
5008
|
+
entries = readdirSync4(transcriptDir);
|
|
4779
5009
|
} catch {
|
|
4780
5010
|
return out;
|
|
4781
5011
|
}
|
|
4782
5012
|
for (const name of entries) {
|
|
4783
|
-
const path =
|
|
5013
|
+
const path = join19(transcriptDir, name);
|
|
4784
5014
|
let st;
|
|
4785
5015
|
try {
|
|
4786
|
-
st =
|
|
5016
|
+
st = statSync4(path);
|
|
4787
5017
|
} catch {
|
|
4788
5018
|
continue;
|
|
4789
5019
|
}
|
|
@@ -4792,7 +5022,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
4792
5022
|
continue;
|
|
4793
5023
|
}
|
|
4794
5024
|
if (st.isDirectory()) {
|
|
4795
|
-
collectJsonlRecursive(
|
|
5025
|
+
collectJsonlRecursive(join19(path, "subagents"), minMtimeMs, out, 0);
|
|
4796
5026
|
}
|
|
4797
5027
|
}
|
|
4798
5028
|
return out;
|
|
@@ -4881,8 +5111,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
4881
5111
|
}
|
|
4882
5112
|
|
|
4883
5113
|
// src/lib/conversation-evaluator.ts
|
|
4884
|
-
import { readdirSync as
|
|
4885
|
-
import { join as
|
|
5114
|
+
import { readdirSync as readdirSync5, readFileSync as readFileSync13, statSync as statSync5 } from "fs";
|
|
5115
|
+
import { join as join20 } from "path";
|
|
4886
5116
|
|
|
4887
5117
|
// src/lib/detect-meta-egress.ts
|
|
4888
5118
|
var REPOST_PREAMBLE_WINDOW = 200;
|
|
@@ -5362,12 +5592,12 @@ function readRecentTurns(dir, nowMs) {
|
|
|
5362
5592
|
const visit = (d) => {
|
|
5363
5593
|
let entries;
|
|
5364
5594
|
try {
|
|
5365
|
-
entries =
|
|
5595
|
+
entries = readdirSync5(d, { withFileTypes: true });
|
|
5366
5596
|
} catch {
|
|
5367
5597
|
return;
|
|
5368
5598
|
}
|
|
5369
5599
|
for (const ent of entries) {
|
|
5370
|
-
const full =
|
|
5600
|
+
const full = join20(d, ent.name);
|
|
5371
5601
|
if (ent.isDirectory()) {
|
|
5372
5602
|
visit(full);
|
|
5373
5603
|
continue;
|
|
@@ -5375,7 +5605,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
5375
5605
|
if (!ent.isFile() || !ent.name.endsWith(".jsonl")) continue;
|
|
5376
5606
|
let mtimeMs;
|
|
5377
5607
|
try {
|
|
5378
|
-
mtimeMs =
|
|
5608
|
+
mtimeMs = statSync5(full).mtimeMs;
|
|
5379
5609
|
} catch {
|
|
5380
5610
|
continue;
|
|
5381
5611
|
}
|
|
@@ -5755,17 +5985,17 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
5755
5985
|
|
|
5756
5986
|
// src/lib/tool-call-audit.ts
|
|
5757
5987
|
import { homedir as homedir11 } from "os";
|
|
5758
|
-
import { join as
|
|
5988
|
+
import { join as join25 } from "path";
|
|
5759
5989
|
|
|
5760
5990
|
// src/lib/agent-logging-mode.ts
|
|
5761
5991
|
import { readFileSync as readFileSync14 } from "fs";
|
|
5762
5992
|
import { homedir as homedir8 } from "os";
|
|
5763
|
-
import { join as
|
|
5993
|
+
import { join as join21 } from "path";
|
|
5764
5994
|
var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
|
|
5765
5995
|
function charterPath(codeName, homeDir) {
|
|
5766
5996
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
|
|
5767
5997
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
5768
|
-
return
|
|
5998
|
+
return join21(home, ".augmented", key, "provision", "CHARTER.md");
|
|
5769
5999
|
}
|
|
5770
6000
|
function readAgentLoggingMode(codeName, homeDir) {
|
|
5771
6001
|
let raw;
|
|
@@ -5796,13 +6026,13 @@ function loggingModeWithholdsTargets(reading) {
|
|
|
5796
6026
|
import { randomBytes } from "crypto";
|
|
5797
6027
|
import { existsSync as existsSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync15, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
5798
6028
|
import { homedir as homedir9 } from "os";
|
|
5799
|
-
import { dirname as dirname7, join as
|
|
6029
|
+
import { dirname as dirname7, join as join22 } from "path";
|
|
5800
6030
|
var SALT_BYTES = 32;
|
|
5801
6031
|
var SALT_RE = /^[0-9a-f]{64}$/;
|
|
5802
6032
|
function pathSaltPath(codeName, homeDir) {
|
|
5803
6033
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
|
|
5804
6034
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
5805
|
-
return
|
|
6035
|
+
return join22(home, ".augmented", key, "tool-call-path-salt");
|
|
5806
6036
|
}
|
|
5807
6037
|
function readToolCallPathSalt(codeName, homeDir) {
|
|
5808
6038
|
let file;
|
|
@@ -5836,11 +6066,11 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
5836
6066
|
}
|
|
5837
6067
|
|
|
5838
6068
|
// src/lib/tool-call-scan.ts
|
|
5839
|
-
import { statSync as
|
|
6069
|
+
import { statSync as statSync6 } from "fs";
|
|
5840
6070
|
|
|
5841
6071
|
// src/lib/tool-call-extractor.ts
|
|
5842
|
-
import { closeSync as closeSync2, fstatSync, openSync as openSync2, readFileSync as readFileSync16, readSync as readSync2, readdirSync as
|
|
5843
|
-
import { basename as basename2, join as
|
|
6072
|
+
import { closeSync as closeSync2, fstatSync, openSync as openSync2, readFileSync as readFileSync16, readSync as readSync2, readdirSync as readdirSync6 } from "fs";
|
|
6073
|
+
import { basename as basename2, join as join23, relative } from "path";
|
|
5844
6074
|
import { StringDecoder } from "string_decoder";
|
|
5845
6075
|
|
|
5846
6076
|
// src/lib/tool-call-redaction.ts
|
|
@@ -5969,7 +6199,7 @@ function redactToolTargetInner(toolName, input, ctx) {
|
|
|
5969
6199
|
var EXTRACTOR_VERSION = "e1";
|
|
5970
6200
|
function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
5971
6201
|
const files = [];
|
|
5972
|
-
const mainAbs =
|
|
6202
|
+
const mainAbs = join23(transcriptDir, `${sessionId}.jsonl`);
|
|
5973
6203
|
files.push({
|
|
5974
6204
|
absPath: mainAbs,
|
|
5975
6205
|
relPath: relative(projectsRoot, mainAbs),
|
|
@@ -5977,16 +6207,16 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
|
5977
6207
|
isSubagent: false,
|
|
5978
6208
|
subagentId: null
|
|
5979
6209
|
});
|
|
5980
|
-
const subDir =
|
|
6210
|
+
const subDir = join23(transcriptDir, sessionId, "subagents");
|
|
5981
6211
|
let entries;
|
|
5982
6212
|
try {
|
|
5983
|
-
entries =
|
|
6213
|
+
entries = readdirSync6(subDir);
|
|
5984
6214
|
} catch {
|
|
5985
6215
|
return files;
|
|
5986
6216
|
}
|
|
5987
6217
|
for (const name of entries) {
|
|
5988
6218
|
if (!name.endsWith(".jsonl")) continue;
|
|
5989
|
-
const abs =
|
|
6219
|
+
const abs = join23(subDir, name);
|
|
5990
6220
|
const stem = basename2(name, ".jsonl");
|
|
5991
6221
|
files.push({
|
|
5992
6222
|
absPath: abs,
|
|
@@ -6186,7 +6416,7 @@ function extractTranscriptWindow(file, opts, from) {
|
|
|
6186
6416
|
// src/lib/tool-call-cursor.ts
|
|
6187
6417
|
import { existsSync as existsSync5, readFileSync as readFileSync17 } from "fs";
|
|
6188
6418
|
import { homedir as homedir10 } from "os";
|
|
6189
|
-
import { join as
|
|
6419
|
+
import { join as join24 } from "path";
|
|
6190
6420
|
var COVERAGE_DISPOSITIONS = [
|
|
6191
6421
|
"ok",
|
|
6192
6422
|
"not_entitled",
|
|
@@ -6241,7 +6471,7 @@ function parseCursorKey(key) {
|
|
|
6241
6471
|
function cursorStatePath(codeName, homeDir) {
|
|
6242
6472
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
|
|
6243
6473
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
6244
|
-
return
|
|
6474
|
+
return join24(home, ".augmented", key, "tool-call-cursors.json");
|
|
6245
6475
|
}
|
|
6246
6476
|
function loadCursors(path) {
|
|
6247
6477
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -6390,7 +6620,7 @@ function nextCursor(args) {
|
|
|
6390
6620
|
};
|
|
6391
6621
|
}
|
|
6392
6622
|
function initialCursor(args) {
|
|
6393
|
-
const
|
|
6623
|
+
const iso2 = new Date(args.nowMs).toISOString();
|
|
6394
6624
|
return {
|
|
6395
6625
|
byteOffset: args.startByte,
|
|
6396
6626
|
lineOffset: args.startLine,
|
|
@@ -6406,8 +6636,8 @@ function initialCursor(args) {
|
|
|
6406
6636
|
runScopeId: null,
|
|
6407
6637
|
unpairedSince: null,
|
|
6408
6638
|
lastDisposition: "ok",
|
|
6409
|
-
lastScanAt:
|
|
6410
|
-
firstScanAt:
|
|
6639
|
+
lastScanAt: iso2,
|
|
6640
|
+
firstScanAt: iso2,
|
|
6411
6641
|
transcriptRelPath: args.transcriptRelPath
|
|
6412
6642
|
};
|
|
6413
6643
|
}
|
|
@@ -6463,7 +6693,7 @@ function chunk(items, size) {
|
|
|
6463
6693
|
}
|
|
6464
6694
|
function endOfFile(absPath) {
|
|
6465
6695
|
try {
|
|
6466
|
-
return { byteOffset:
|
|
6696
|
+
return { byteOffset: statSync6(absPath).size, lineOffset: 0 };
|
|
6467
6697
|
} catch {
|
|
6468
6698
|
return null;
|
|
6469
6699
|
}
|
|
@@ -6654,7 +6884,7 @@ async function maybeScanToolCalls(args) {
|
|
|
6654
6884
|
log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
|
|
6655
6885
|
}
|
|
6656
6886
|
const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir11());
|
|
6657
|
-
const projectsRoot = args.projectsRoot ??
|
|
6887
|
+
const projectsRoot = args.projectsRoot ?? join25(home, ".claude", "projects");
|
|
6658
6888
|
const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
|
|
6659
6889
|
const current = peekCurrentSession(codeName);
|
|
6660
6890
|
const sessionIds = current ? [current.sessionId] : [];
|
|
@@ -6685,9 +6915,9 @@ async function maybeScanToolCalls(args) {
|
|
|
6685
6915
|
// src/lib/activity-cache-monitor.ts
|
|
6686
6916
|
import { existsSync as existsSync6, readFileSync as readFileSync18 } from "fs";
|
|
6687
6917
|
import { homedir as homedir12 } from "os";
|
|
6688
|
-
import { join as
|
|
6918
|
+
import { join as join26 } from "path";
|
|
6689
6919
|
var MIN_CHECK_INTERVAL_MS8 = 6e4;
|
|
6690
|
-
var STATS_CACHE_PATH =
|
|
6920
|
+
var STATS_CACHE_PATH = join26(homedir12(), ".claude", "stats-cache.json");
|
|
6691
6921
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
6692
6922
|
var state8 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
6693
6923
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -6978,11 +7208,11 @@ function bundleFingerprint(files) {
|
|
|
6978
7208
|
}
|
|
6979
7209
|
|
|
6980
7210
|
// src/lib/self-update-device-state-hold.ts
|
|
6981
|
-
import { statSync as
|
|
7211
|
+
import { statSync as statSync7 } from "fs";
|
|
6982
7212
|
import { platform as osPlatform } from "os";
|
|
6983
7213
|
function realStat(path) {
|
|
6984
7214
|
try {
|
|
6985
|
-
return { isFile:
|
|
7215
|
+
return { isFile: statSync7(path).isFile() };
|
|
6986
7216
|
} catch (err) {
|
|
6987
7217
|
return { errno: err?.code ?? "UNKNOWN" };
|
|
6988
7218
|
}
|
|
@@ -7058,14 +7288,14 @@ import {
|
|
|
7058
7288
|
existsSync as existsSync7,
|
|
7059
7289
|
mkdirSync as mkdirSync7,
|
|
7060
7290
|
readFileSync as readFileSync19,
|
|
7061
|
-
readdirSync as
|
|
7291
|
+
readdirSync as readdirSync7,
|
|
7062
7292
|
renameSync as renameSync5,
|
|
7063
7293
|
rmSync as rmSync3,
|
|
7064
|
-
statSync as
|
|
7294
|
+
statSync as statSync8,
|
|
7065
7295
|
utimesSync,
|
|
7066
7296
|
writeFileSync as writeFileSync8
|
|
7067
7297
|
} from "fs";
|
|
7068
|
-
import { join as
|
|
7298
|
+
import { join as join27 } from "path";
|
|
7069
7299
|
var KNOWLEDGE_FETCH_CHUNK = 100;
|
|
7070
7300
|
var CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
7071
7301
|
var SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -7074,7 +7304,7 @@ function knowledgeHash(content) {
|
|
|
7074
7304
|
return createHash9("sha256").update(content, "utf8").digest("hex");
|
|
7075
7305
|
}
|
|
7076
7306
|
function cachePath(cacheDir, hash) {
|
|
7077
|
-
return
|
|
7307
|
+
return join27(cacheDir, hash);
|
|
7078
7308
|
}
|
|
7079
7309
|
function readCachedKnowledge(cacheDir, hash) {
|
|
7080
7310
|
const path = cachePath(cacheDir, hash);
|
|
@@ -7107,10 +7337,10 @@ function sweepKnowledgeCache(cacheDir, now = Date.now()) {
|
|
|
7107
7337
|
lastSweepAt = now;
|
|
7108
7338
|
try {
|
|
7109
7339
|
if (!existsSync7(cacheDir)) return;
|
|
7110
|
-
for (const name of
|
|
7111
|
-
const path =
|
|
7340
|
+
for (const name of readdirSync7(cacheDir)) {
|
|
7341
|
+
const path = join27(cacheDir, name);
|
|
7112
7342
|
try {
|
|
7113
|
-
if (now -
|
|
7343
|
+
if (now - statSync8(path).mtimeMs > CACHE_TTL_MS) rmSync3(path, { force: true });
|
|
7114
7344
|
} catch {
|
|
7115
7345
|
}
|
|
7116
7346
|
}
|
|
@@ -7161,14 +7391,14 @@ import {
|
|
|
7161
7391
|
existsSync as existsSync8,
|
|
7162
7392
|
mkdirSync as mkdirSync8,
|
|
7163
7393
|
readFileSync as readFileSync20,
|
|
7164
|
-
readdirSync as
|
|
7394
|
+
readdirSync as readdirSync8,
|
|
7165
7395
|
renameSync as renameSync6,
|
|
7166
7396
|
rmSync as rmSync4,
|
|
7167
|
-
statSync as
|
|
7397
|
+
statSync as statSync9,
|
|
7168
7398
|
utimesSync as utimesSync2,
|
|
7169
7399
|
writeFileSync as writeFileSync9
|
|
7170
7400
|
} from "fs";
|
|
7171
|
-
import { join as
|
|
7401
|
+
import { join as join28 } from "path";
|
|
7172
7402
|
var MEMORY_FETCH_CHUNK = 100;
|
|
7173
7403
|
var CACHE_TTL_MS2 = 30 * 24 * 60 * 60 * 1e3;
|
|
7174
7404
|
var SWEEP_INTERVAL_MS2 = 24 * 60 * 60 * 1e3;
|
|
@@ -7177,7 +7407,7 @@ function memoryHash(content) {
|
|
|
7177
7407
|
return createHash10("sha256").update(content, "utf8").digest("hex");
|
|
7178
7408
|
}
|
|
7179
7409
|
function cachePath2(cacheDir, hash) {
|
|
7180
|
-
return
|
|
7410
|
+
return join28(cacheDir, hash);
|
|
7181
7411
|
}
|
|
7182
7412
|
function readCachedMemory(cacheDir, hash) {
|
|
7183
7413
|
const path = cachePath2(cacheDir, hash);
|
|
@@ -7210,10 +7440,10 @@ function sweepMemoryCache(cacheDir, now = Date.now()) {
|
|
|
7210
7440
|
lastSweepAt2.set(cacheDir, now);
|
|
7211
7441
|
try {
|
|
7212
7442
|
if (!existsSync8(cacheDir)) return;
|
|
7213
|
-
for (const name of
|
|
7214
|
-
const path =
|
|
7443
|
+
for (const name of readdirSync8(cacheDir)) {
|
|
7444
|
+
const path = join28(cacheDir, name);
|
|
7215
7445
|
try {
|
|
7216
|
-
if (now -
|
|
7446
|
+
if (now - statSync9(path).mtimeMs > CACHE_TTL_MS2) rmSync4(path, { force: true });
|
|
7217
7447
|
} catch {
|
|
7218
7448
|
}
|
|
7219
7449
|
}
|
|
@@ -7270,14 +7500,14 @@ import {
|
|
|
7270
7500
|
existsSync as existsSync9,
|
|
7271
7501
|
mkdirSync as mkdirSync9,
|
|
7272
7502
|
readFileSync as readFileSync21,
|
|
7273
|
-
readdirSync as
|
|
7503
|
+
readdirSync as readdirSync9,
|
|
7274
7504
|
renameSync as renameSync7,
|
|
7275
7505
|
rmSync as rmSync5,
|
|
7276
|
-
statSync as
|
|
7506
|
+
statSync as statSync10,
|
|
7277
7507
|
utimesSync as utimesSync3,
|
|
7278
7508
|
writeFileSync as writeFileSync10
|
|
7279
7509
|
} from "fs";
|
|
7280
|
-
import { join as
|
|
7510
|
+
import { join as join29 } from "path";
|
|
7281
7511
|
var SKILL_FETCH_CHUNK = 100;
|
|
7282
7512
|
var CACHE_TTL_MS3 = 30 * 24 * 60 * 60 * 1e3;
|
|
7283
7513
|
var SWEEP_INTERVAL_MS3 = 24 * 60 * 60 * 1e3;
|
|
@@ -7286,7 +7516,7 @@ function skillHash(content) {
|
|
|
7286
7516
|
return createHash11("sha256").update(content, "utf8").digest("hex");
|
|
7287
7517
|
}
|
|
7288
7518
|
function cachePath3(cacheDir, hash) {
|
|
7289
|
-
return
|
|
7519
|
+
return join29(cacheDir, hash);
|
|
7290
7520
|
}
|
|
7291
7521
|
function readCachedSkill(cacheDir, hash) {
|
|
7292
7522
|
const path = cachePath3(cacheDir, hash);
|
|
@@ -7319,10 +7549,10 @@ function sweepSkillCache(cacheDir, now = Date.now()) {
|
|
|
7319
7549
|
lastSweepAt3 = now;
|
|
7320
7550
|
try {
|
|
7321
7551
|
if (!existsSync9(cacheDir)) return;
|
|
7322
|
-
for (const name of
|
|
7323
|
-
const path =
|
|
7552
|
+
for (const name of readdirSync9(cacheDir)) {
|
|
7553
|
+
const path = join29(cacheDir, name);
|
|
7324
7554
|
try {
|
|
7325
|
-
if (now -
|
|
7555
|
+
if (now - statSync10(path).mtimeMs > CACHE_TTL_MS3) rmSync5(path, { force: true });
|
|
7326
7556
|
} catch {
|
|
7327
7557
|
}
|
|
7328
7558
|
}
|
|
@@ -7650,10 +7880,10 @@ function resolveConditionalResponse(wire, hasCachedBody) {
|
|
|
7650
7880
|
|
|
7651
7881
|
// src/lib/channel-hash-cache.ts
|
|
7652
7882
|
import { existsSync as existsSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync11 } from "fs";
|
|
7653
|
-
import { join as
|
|
7883
|
+
import { join as join30 } from "path";
|
|
7654
7884
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
7655
7885
|
function getChannelHashCacheFile(configDir) {
|
|
7656
|
-
return
|
|
7886
|
+
return join30(configDir, CACHE_FILENAME);
|
|
7657
7887
|
}
|
|
7658
7888
|
function loadChannelHashCache(target, configDir) {
|
|
7659
7889
|
const path = getChannelHashCacheFile(configDir);
|
|
@@ -7681,7 +7911,7 @@ function saveChannelHashCache(source, configDir) {
|
|
|
7681
7911
|
|
|
7682
7912
|
// src/lib/sender-policy-baseline.ts
|
|
7683
7913
|
import { existsSync as existsSync11, readFileSync as readFileSync23 } from "fs";
|
|
7684
|
-
import { join as
|
|
7914
|
+
import { join as join31 } from "path";
|
|
7685
7915
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
7686
7916
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
7687
7917
|
var BASELINE_CONCERNS = [
|
|
@@ -7728,7 +7958,7 @@ function createDeliveryBaselineMaps() {
|
|
|
7728
7958
|
};
|
|
7729
7959
|
}
|
|
7730
7960
|
function getSenderPolicyBaselineFile(configDir) {
|
|
7731
|
-
return
|
|
7961
|
+
return join31(configDir, BASELINE_FILENAME);
|
|
7732
7962
|
}
|
|
7733
7963
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
7734
7964
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
@@ -7785,7 +8015,7 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
|
|
|
7785
8015
|
|
|
7786
8016
|
// src/lib/stuck-streak-store.ts
|
|
7787
8017
|
import { existsSync as existsSync12, readFileSync as readFileSync24 } from "fs";
|
|
7788
|
-
import { join as
|
|
8018
|
+
import { join as join32 } from "path";
|
|
7789
8019
|
var STORE_FILENAME = "stuck-streaks.json";
|
|
7790
8020
|
var STUCK_STREAK_STORE_VERSION = 1;
|
|
7791
8021
|
var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
|
|
@@ -7793,7 +8023,7 @@ function createStuckStreakMaps() {
|
|
|
7793
8023
|
return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
|
|
7794
8024
|
}
|
|
7795
8025
|
function getStuckStreakStoreFile(configDir) {
|
|
7796
|
-
return
|
|
8026
|
+
return join32(configDir, STORE_FILENAME);
|
|
7797
8027
|
}
|
|
7798
8028
|
function isValidPersistedStreak(value) {
|
|
7799
8029
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
@@ -7878,13 +8108,13 @@ function pruneStuckStreaksToAgents(maps, activeAgentIds) {
|
|
|
7878
8108
|
}
|
|
7879
8109
|
|
|
7880
8110
|
// src/lib/claude-device-state.ts
|
|
7881
|
-
import { readFileSync as readFileSync25, statSync as
|
|
8111
|
+
import { readFileSync as readFileSync25, statSync as statSync11 } from "fs";
|
|
7882
8112
|
function claudeDeviceStatePath(env = process.env) {
|
|
7883
8113
|
return effectiveClaudeJsonPath(void 0, env);
|
|
7884
8114
|
}
|
|
7885
8115
|
function probeClaudeDeviceStatePresence(path = claudeDeviceStatePath()) {
|
|
7886
8116
|
try {
|
|
7887
|
-
return
|
|
8117
|
+
return statSync11(path).isFile() ? { present: true } : { present: false, reason: "not-a-file" };
|
|
7888
8118
|
} catch (err) {
|
|
7889
8119
|
return {
|
|
7890
8120
|
present: false,
|
|
@@ -7894,7 +8124,7 @@ function probeClaudeDeviceStatePresence(path = claudeDeviceStatePath()) {
|
|
|
7894
8124
|
}
|
|
7895
8125
|
function checkClaudeDeviceState(path = claudeDeviceStatePath()) {
|
|
7896
8126
|
try {
|
|
7897
|
-
if (!
|
|
8127
|
+
if (!statSync11(path).isFile()) return { usable: false, reason: "not-a-file" };
|
|
7898
8128
|
} catch (err) {
|
|
7899
8129
|
return {
|
|
7900
8130
|
usable: false,
|
|
@@ -8581,32 +8811,32 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
8581
8811
|
}
|
|
8582
8812
|
|
|
8583
8813
|
// src/lib/manager/integration-skill-cache.ts
|
|
8584
|
-
import { join as
|
|
8814
|
+
import { join as join33 } from "path";
|
|
8585
8815
|
function integrationSkillHashKey(agentId, skillId) {
|
|
8586
8816
|
return `plugin-skill:${agentId}:${skillId}`;
|
|
8587
8817
|
}
|
|
8588
|
-
function shouldWriteIntegrationSkill(
|
|
8589
|
-
return
|
|
8818
|
+
function shouldWriteIntegrationSkill(cache3, agentId, skillId, contentHash) {
|
|
8819
|
+
return cache3.get(integrationSkillHashKey(agentId, skillId)) !== contentHash;
|
|
8590
8820
|
}
|
|
8591
|
-
function rememberIntegrationSkill(
|
|
8592
|
-
|
|
8821
|
+
function rememberIntegrationSkill(cache3, agentId, skillId, contentHash) {
|
|
8822
|
+
cache3.set(integrationSkillHashKey(agentId, skillId), contentHash);
|
|
8593
8823
|
}
|
|
8594
|
-
function forgetIntegrationSkill(
|
|
8595
|
-
|
|
8824
|
+
function forgetIntegrationSkill(cache3, agentId, skillId) {
|
|
8825
|
+
cache3.delete(integrationSkillHashKey(agentId, skillId));
|
|
8596
8826
|
}
|
|
8597
8827
|
function removeIntegrationSkillFolder(opts) {
|
|
8598
8828
|
forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
|
|
8599
8829
|
for (const dir of opts.dirs) {
|
|
8600
|
-
opts.removeDir(
|
|
8830
|
+
opts.removeDir(join33(dir, opts.entry));
|
|
8601
8831
|
}
|
|
8602
8832
|
}
|
|
8603
8833
|
|
|
8604
8834
|
// src/lib/manager/managed-skill-manifest.ts
|
|
8605
8835
|
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync26, writeFileSync as writeFileSync12 } from "fs";
|
|
8606
|
-
import { dirname as dirname8, join as
|
|
8836
|
+
import { dirname as dirname8, join as join34 } from "path";
|
|
8607
8837
|
var MANIFEST_VERSION = 1;
|
|
8608
8838
|
function managedSkillManifestPath(agentRootDir) {
|
|
8609
|
-
return
|
|
8839
|
+
return join34(agentRootDir, "managed-skills.json");
|
|
8610
8840
|
}
|
|
8611
8841
|
function readManagedSkillManifest(path) {
|
|
8612
8842
|
try {
|
|
@@ -8741,7 +8971,7 @@ function resolveModelChain(refreshData) {
|
|
|
8741
8971
|
|
|
8742
8972
|
// src/lib/manager/claude-auth.ts
|
|
8743
8973
|
import { chmodSync as chmodSync2, existsSync as existsSync14, lstatSync as lstatSync3, mkdirSync as mkdirSync11, rmSync as rmSync6 } from "fs";
|
|
8744
|
-
import { join as
|
|
8974
|
+
import { join as join35 } from "path";
|
|
8745
8975
|
import { homedir as homedir13 } from "os";
|
|
8746
8976
|
async function applyClaudeAuthToEnv(childEnv, label, options = {}) {
|
|
8747
8977
|
const apiKey = getApiKey();
|
|
@@ -8760,7 +8990,7 @@ async function applyClaudeAuthToEnv(childEnv, label, options = {}) {
|
|
|
8760
8990
|
}
|
|
8761
8991
|
const claudeDir = claudeConfigDirForChild(childEnv);
|
|
8762
8992
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
8763
|
-
const p =
|
|
8993
|
+
const p = join35(claudeDir, filename);
|
|
8764
8994
|
if (existsSync14(p)) {
|
|
8765
8995
|
try {
|
|
8766
8996
|
rmSync6(p, { force: true });
|
|
@@ -8775,7 +9005,7 @@ async function applyClaudeAuthToEnv(childEnv, label, options = {}) {
|
|
|
8775
9005
|
return { isolated: false };
|
|
8776
9006
|
}
|
|
8777
9007
|
function claudeConfigDirForChild(childEnv) {
|
|
8778
|
-
return childEnv.CLAUDE_CONFIG_DIR?.trim() ||
|
|
9008
|
+
return childEnv.CLAUDE_CONFIG_DIR?.trim() || join35(homedir13(), ".claude");
|
|
8779
9009
|
}
|
|
8780
9010
|
function ensurePrivateConfigDir(dir, platform4 = process.platform, chmod = chmodSync2) {
|
|
8781
9011
|
mkdirSync11(dir, { recursive: true, mode: 448 });
|
|
@@ -8791,7 +9021,7 @@ function ensurePrivateConfigDir(dir, platform4 = process.platform, chmod = chmod
|
|
|
8791
9021
|
}
|
|
8792
9022
|
}
|
|
8793
9023
|
function oneShotIsolatedConfigDir() {
|
|
8794
|
-
return
|
|
9024
|
+
return join35(homedir13(), ".augmented", "claude-oneshot");
|
|
8795
9025
|
}
|
|
8796
9026
|
|
|
8797
9027
|
// src/lib/claude-runtime-auth-probe.ts
|
|
@@ -9137,11 +9367,11 @@ function formatBoardForPrompt(items, template) {
|
|
|
9137
9367
|
|
|
9138
9368
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
9139
9369
|
import { existsSync as existsSync15, readFileSync as readFileSync27, writeFileSync as writeFileSync13 } from "fs";
|
|
9140
|
-
import { join as
|
|
9370
|
+
import { join as join36 } from "path";
|
|
9141
9371
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
9142
9372
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
9143
9373
|
function getKanbanNudgeStateFile(configDir) {
|
|
9144
|
-
return
|
|
9374
|
+
return join36(configDir, CACHE_FILENAME2);
|
|
9145
9375
|
}
|
|
9146
9376
|
function loadKanbanNudgeState(target, configDir) {
|
|
9147
9377
|
const path = getKanbanNudgeStateFile(configDir);
|
|
@@ -9768,7 +9998,7 @@ function closeSessionRunForCode(codeName, outcome, reason) {
|
|
|
9768
9998
|
import { createHash as createHash15 } from "crypto";
|
|
9769
9999
|
import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync12, readFileSync as readFileSync28, unlinkSync as unlinkSync3 } from "fs";
|
|
9770
10000
|
import { homedir as homedir14 } from "os";
|
|
9771
|
-
import { join as
|
|
10001
|
+
import { join as join37, dirname as dirname9 } from "path";
|
|
9772
10002
|
|
|
9773
10003
|
// src/lib/manager/scheduler/notify.ts
|
|
9774
10004
|
import { createHash as createHash14 } from "crypto";
|
|
@@ -10127,7 +10357,7 @@ function resolveScheduledSlackTarget(task) {
|
|
|
10127
10357
|
}
|
|
10128
10358
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
10129
10359
|
try {
|
|
10130
|
-
const file =
|
|
10360
|
+
const file = join37(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
10131
10361
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
10132
10362
|
const tmp = `${file}.tmp`;
|
|
10133
10363
|
writeFileSync14(tmp, JSON.stringify(marker), "utf8");
|
|
@@ -10137,7 +10367,7 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
10137
10367
|
}
|
|
10138
10368
|
}
|
|
10139
10369
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
10140
|
-
const file =
|
|
10370
|
+
const file = join37(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
10141
10371
|
try {
|
|
10142
10372
|
const raw = JSON.parse(readFileSync28(file, "utf8"));
|
|
10143
10373
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
@@ -10359,11 +10589,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
10359
10589
|
// src/lib/manager/scheduler/execution.ts
|
|
10360
10590
|
import { createHash as createHash16 } from "crypto";
|
|
10361
10591
|
import { homedir as homedir15 } from "os";
|
|
10362
|
-
import { join as
|
|
10592
|
+
import { join as join39 } from "path";
|
|
10363
10593
|
|
|
10364
10594
|
// src/lib/agent-serving-probe.ts
|
|
10365
|
-
import { readFileSync as readFileSync29, readdirSync as
|
|
10366
|
-
import { join as
|
|
10595
|
+
import { readFileSync as readFileSync29, readdirSync as readdirSync10, statSync as statSync12 } from "fs";
|
|
10596
|
+
import { join as join38 } from "path";
|
|
10367
10597
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
10368
10598
|
function probeRateLimit(args) {
|
|
10369
10599
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
@@ -10372,16 +10602,16 @@ function probeRateLimit(args) {
|
|
|
10372
10602
|
const dir = args.transcriptDir ?? sessionTranscriptDir(args.projectDir);
|
|
10373
10603
|
let entries;
|
|
10374
10604
|
try {
|
|
10375
|
-
entries =
|
|
10605
|
+
entries = readdirSync10(dir);
|
|
10376
10606
|
} catch {
|
|
10377
10607
|
return UNKNOWN_RATE_LIMIT;
|
|
10378
10608
|
}
|
|
10379
10609
|
let newest = UNKNOWN_RATE_LIMIT;
|
|
10380
10610
|
for (const name of entries) {
|
|
10381
10611
|
if (!name.endsWith(".jsonl")) continue;
|
|
10382
|
-
const path =
|
|
10612
|
+
const path = join38(dir, name);
|
|
10383
10613
|
try {
|
|
10384
|
-
const st =
|
|
10614
|
+
const st = statSync12(path);
|
|
10385
10615
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
10386
10616
|
} catch {
|
|
10387
10617
|
continue;
|
|
@@ -10450,7 +10680,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
10450
10680
|
|
|
10451
10681
|
// src/lib/manager/scheduler/execution.ts
|
|
10452
10682
|
function claudePidFilePath() {
|
|
10453
|
-
return
|
|
10683
|
+
return join39(homedir15(), ".augmented", "manager-claude-pids.json");
|
|
10454
10684
|
}
|
|
10455
10685
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
10456
10686
|
function registerClaudeSpawn(record) {
|
|
@@ -10691,8 +10921,8 @@ var BlockedPromptReportCadence = class {
|
|
|
10691
10921
|
};
|
|
10692
10922
|
|
|
10693
10923
|
// src/lib/occupancy-gate.ts
|
|
10694
|
-
import { closeSync as closeSync3, openSync as openSync3, readdirSync as
|
|
10695
|
-
import { join as
|
|
10924
|
+
import { closeSync as closeSync3, openSync as openSync3, readdirSync as readdirSync11, readSync as readSync3, statSync as statSync13 } from "fs";
|
|
10925
|
+
import { join as join40 } from "path";
|
|
10696
10926
|
function rostersMeasuredZero(mode, attested, runtimeRunning) {
|
|
10697
10927
|
return mode === "enforce" && attested && runtimeRunning;
|
|
10698
10928
|
}
|
|
@@ -10701,12 +10931,12 @@ var MAX_RECORD_ALIGN_BYTES = 8 * 1024 * 1024;
|
|
|
10701
10931
|
var GATE_MAX_BUCKET_AGE_MS = 30 * 6e4;
|
|
10702
10932
|
var MAX_BRACKET_DEFERRAL_MS = 25 * 6e4;
|
|
10703
10933
|
var TRANSCRIPT_MTIME_WINDOW_MS4 = GATE_MAX_BUCKET_AGE_MS + DEFAULT_NEIGHBOURHOOD_MS + 6e4;
|
|
10704
|
-
var
|
|
10934
|
+
var cache2 = /* @__PURE__ */ new Map();
|
|
10705
10935
|
var brackets = /* @__PURE__ */ new Map();
|
|
10706
10936
|
function readAlignedTail(path, tailBytes, maxAlignBytes) {
|
|
10707
10937
|
let fd = null;
|
|
10708
10938
|
try {
|
|
10709
|
-
const size =
|
|
10939
|
+
const size = statSync13(path).size;
|
|
10710
10940
|
if (size <= 0) return { content: "", complete: true, truncated: false };
|
|
10711
10941
|
fd = openSync3(path, "r");
|
|
10712
10942
|
let readStart = Math.max(0, size - tailBytes);
|
|
@@ -10776,26 +11006,26 @@ function candidateTranscriptPaths(dir) {
|
|
|
10776
11006
|
const paths = [];
|
|
10777
11007
|
let top;
|
|
10778
11008
|
try {
|
|
10779
|
-
top =
|
|
11009
|
+
top = readdirSync11(dir);
|
|
10780
11010
|
} catch {
|
|
10781
11011
|
return { paths, complete: false };
|
|
10782
11012
|
}
|
|
10783
11013
|
let complete = true;
|
|
10784
11014
|
for (const name of top) {
|
|
10785
11015
|
if (name.endsWith(".jsonl")) {
|
|
10786
|
-
paths.push(
|
|
11016
|
+
paths.push(join40(dir, name));
|
|
10787
11017
|
continue;
|
|
10788
11018
|
}
|
|
10789
|
-
const subDir =
|
|
11019
|
+
const subDir = join40(dir, name, "subagents");
|
|
10790
11020
|
let subs;
|
|
10791
11021
|
try {
|
|
10792
|
-
subs =
|
|
11022
|
+
subs = readdirSync11(subDir);
|
|
10793
11023
|
} catch (err) {
|
|
10794
11024
|
if (!isAbsentDirError(err)) complete = false;
|
|
10795
11025
|
continue;
|
|
10796
11026
|
}
|
|
10797
11027
|
for (const sub of subs) {
|
|
10798
|
-
if (sub.endsWith(".jsonl")) paths.push(
|
|
11028
|
+
if (sub.endsWith(".jsonl")) paths.push(join40(subDir, sub));
|
|
10799
11029
|
}
|
|
10800
11030
|
}
|
|
10801
11031
|
return { paths, complete };
|
|
@@ -10836,7 +11066,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
10836
11066
|
const tailBytes = opts.tailBytes ?? TAIL_BYTES;
|
|
10837
11067
|
const maxAlignBytes = opts.maxAlignBytes ?? MAX_RECORD_ALIGN_BYTES;
|
|
10838
11068
|
const sinceMs = nowMs - TRANSCRIPT_MTIME_WINDOW_MS4;
|
|
10839
|
-
const agentCache =
|
|
11069
|
+
const agentCache = cache2.get(codeName) ?? /* @__PURE__ */ new Map();
|
|
10840
11070
|
const nextCache = /* @__PURE__ */ new Map();
|
|
10841
11071
|
const all = /* @__PURE__ */ new Set();
|
|
10842
11072
|
const eventsByPath = /* @__PURE__ */ new Map();
|
|
@@ -10850,7 +11080,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
10850
11080
|
for (const path of paths) {
|
|
10851
11081
|
let st;
|
|
10852
11082
|
try {
|
|
10853
|
-
st =
|
|
11083
|
+
st = statSync13(path);
|
|
10854
11084
|
} catch (err) {
|
|
10855
11085
|
if (!isAbsentDirError(err)) complete = false;
|
|
10856
11086
|
continue;
|
|
@@ -10889,7 +11119,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
10889
11119
|
}
|
|
10890
11120
|
for (const t of turns) all.add(t);
|
|
10891
11121
|
}
|
|
10892
|
-
|
|
11122
|
+
cache2.set(codeName, nextCache);
|
|
10893
11123
|
const { toolCallBrackets, openToolCalls } = foldToolCallBrackets(codeName, eventsByPath, nowMs);
|
|
10894
11124
|
return {
|
|
10895
11125
|
turns: [...all].sort((a, b) => a - b),
|
|
@@ -10956,7 +11186,7 @@ function qualifyBuckets(buckets, qualifying, mode, nowMs, neighbourhoodMs = DEFA
|
|
|
10956
11186
|
}
|
|
10957
11187
|
|
|
10958
11188
|
// src/lib/pane-occupancy-sampler.ts
|
|
10959
|
-
import { statSync as
|
|
11189
|
+
import { statSync as statSync14 } from "fs";
|
|
10960
11190
|
var SAMPLE_INTERVAL_MS = 1e4;
|
|
10961
11191
|
var IDLE_GAP_MS = 12e4;
|
|
10962
11192
|
var POST_IDLE_CREDIT_MS = 6e4;
|
|
@@ -10970,7 +11200,7 @@ function hasFreshPaneObservation(codeName, nowMs, maxAgeMs = OBSERVATION_FRESH_M
|
|
|
10970
11200
|
}
|
|
10971
11201
|
function paneMtimeMs(codeName) {
|
|
10972
11202
|
try {
|
|
10973
|
-
return
|
|
11203
|
+
return statSync14(paneLogPath(codeName)).mtimeMs;
|
|
10974
11204
|
} catch {
|
|
10975
11205
|
return null;
|
|
10976
11206
|
}
|
|
@@ -12433,7 +12663,7 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
12433
12663
|
import { createHash as createHash19 } from "crypto";
|
|
12434
12664
|
import { existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync31, renameSync as renameSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
|
|
12435
12665
|
import { randomUUID } from "crypto";
|
|
12436
|
-
import { join as
|
|
12666
|
+
import { join as join41 } from "path";
|
|
12437
12667
|
|
|
12438
12668
|
// src/lib/telegram-ingest.ts
|
|
12439
12669
|
import https2 from "https";
|
|
@@ -13086,7 +13316,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
13086
13316
|
let filePath;
|
|
13087
13317
|
try {
|
|
13088
13318
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
13089
|
-
filePath =
|
|
13319
|
+
filePath = join41(dir, "telegram-getupdates-offset-opencode.json");
|
|
13090
13320
|
} catch {
|
|
13091
13321
|
dir = null;
|
|
13092
13322
|
filePath = null;
|
|
@@ -13370,24 +13600,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
13370
13600
|
}
|
|
13371
13601
|
|
|
13372
13602
|
// src/lib/restart-flags.ts
|
|
13373
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync14, readdirSync as
|
|
13603
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync14, readdirSync as readdirSync12, readFileSync as readFileSync32, renameSync as renameSync10, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
|
|
13374
13604
|
import { homedir as homedir16 } from "os";
|
|
13375
|
-
import { join as
|
|
13605
|
+
import { join as join42 } from "path";
|
|
13376
13606
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
13377
13607
|
function restartFlagsDir() {
|
|
13378
|
-
return
|
|
13608
|
+
return join42(homedir16(), ".augmented", "restart-flags");
|
|
13379
13609
|
}
|
|
13380
13610
|
function flagPath(codeName) {
|
|
13381
|
-
return
|
|
13611
|
+
return join42(restartFlagsDir(), `${codeName}.flag`);
|
|
13382
13612
|
}
|
|
13383
13613
|
function readRestartFlags() {
|
|
13384
13614
|
const dir = restartFlagsDir();
|
|
13385
13615
|
if (!existsSync18(dir)) return [];
|
|
13386
13616
|
const out = [];
|
|
13387
|
-
for (const entry of
|
|
13617
|
+
for (const entry of readdirSync12(dir)) {
|
|
13388
13618
|
if (!entry.endsWith(".flag")) continue;
|
|
13389
13619
|
try {
|
|
13390
|
-
const raw = readFileSync32(
|
|
13620
|
+
const raw = readFileSync32(join42(dir, entry), "utf8");
|
|
13391
13621
|
const parsed = JSON.parse(raw);
|
|
13392
13622
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
13393
13623
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -13505,8 +13735,8 @@ async function sendError(flag, opts, text) {
|
|
|
13505
13735
|
}
|
|
13506
13736
|
|
|
13507
13737
|
// src/lib/restart-context.ts
|
|
13508
|
-
import { readdirSync as
|
|
13509
|
-
import { dirname as dirname10, join as
|
|
13738
|
+
import { readdirSync as readdirSync13, readFileSync as readFileSync33, writeFileSync as writeFileSync17, mkdirSync as mkdirSync15, unlinkSync as unlinkSync5 } from "fs";
|
|
13739
|
+
import { dirname as dirname10, join as join43 } from "path";
|
|
13510
13740
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
13511
13741
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
13512
13742
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -13518,10 +13748,10 @@ function augmentedAgentDir(codeName) {
|
|
|
13518
13748
|
return dirname10(getProjectDir(codeName));
|
|
13519
13749
|
}
|
|
13520
13750
|
function slackPendingInboundDir(codeName) {
|
|
13521
|
-
return
|
|
13751
|
+
return join43(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
13522
13752
|
}
|
|
13523
13753
|
function slackRestartContextDir(codeName) {
|
|
13524
|
-
return
|
|
13754
|
+
return join43(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
13525
13755
|
}
|
|
13526
13756
|
function sanitizeTopic(raw) {
|
|
13527
13757
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -13556,7 +13786,7 @@ function computeRestartContextHints(markers, allTurns, nowMs, reconstruct = reco
|
|
|
13556
13786
|
}
|
|
13557
13787
|
function safeReaddir(dir) {
|
|
13558
13788
|
try {
|
|
13559
|
-
return
|
|
13789
|
+
return readdirSync13(dir);
|
|
13560
13790
|
} catch {
|
|
13561
13791
|
return [];
|
|
13562
13792
|
}
|
|
@@ -13581,7 +13811,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
13581
13811
|
if (!filename.endsWith(".json")) continue;
|
|
13582
13812
|
if (freshFilenames.has(filename)) continue;
|
|
13583
13813
|
try {
|
|
13584
|
-
unlinkSync5(
|
|
13814
|
+
unlinkSync5(join43(ctxDir, filename));
|
|
13585
13815
|
} catch {
|
|
13586
13816
|
}
|
|
13587
13817
|
}
|
|
@@ -13602,7 +13832,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
13602
13832
|
}
|
|
13603
13833
|
const markers = [];
|
|
13604
13834
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
13605
|
-
const parsed = readStrandedMarker(
|
|
13835
|
+
const parsed = readStrandedMarker(join43(markerDir, filename));
|
|
13606
13836
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
13607
13837
|
}
|
|
13608
13838
|
if (markers.length === 0) {
|
|
@@ -13616,7 +13846,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
13616
13846
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
13617
13847
|
for (const { filename, hint } of hints) {
|
|
13618
13848
|
try {
|
|
13619
|
-
writeHintFile(
|
|
13849
|
+
writeHintFile(join43(ctxDir, filename), ctxDir, hint);
|
|
13620
13850
|
freshFilenames.add(filename);
|
|
13621
13851
|
} catch (err) {
|
|
13622
13852
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -14410,7 +14640,7 @@ async function runDangerousRmBackstop(agentId, codeName, pane) {
|
|
|
14410
14640
|
return;
|
|
14411
14641
|
}
|
|
14412
14642
|
const policy = readRmPolicyText(
|
|
14413
|
-
() => readFileSync34(
|
|
14643
|
+
() => readFileSync34(join44(getFramework("claude-code").getAgentDir(codeName), RM_POLICY_RELATIVE_PATH), "utf-8")
|
|
14414
14644
|
);
|
|
14415
14645
|
const decision = decideDangerousRm(action.prompt, policy, {
|
|
14416
14646
|
isolated: isolationMode(codeName) === "docker"
|
|
@@ -15131,7 +15361,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
15131
15361
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
15132
15362
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
15133
15363
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
15134
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
15364
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-ZT6ITMYI.js");
|
|
15135
15365
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
15136
15366
|
if (newest === null) return null;
|
|
15137
15367
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -15328,7 +15558,7 @@ function performLazyDayRolloverReset(codeName, agentTimezone) {
|
|
|
15328
15558
|
}
|
|
15329
15559
|
function paneLogAgeSecondsFor(codeName) {
|
|
15330
15560
|
try {
|
|
15331
|
-
const mtimeMs =
|
|
15561
|
+
const mtimeMs = statSync15(paneLogPath(codeName)).mtimeMs;
|
|
15332
15562
|
return Math.max(0, Math.floor((Date.now() - mtimeMs) / 1e3));
|
|
15333
15563
|
} catch (err) {
|
|
15334
15564
|
if (err?.code === "ENOENT") return null;
|
|
@@ -15500,7 +15730,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
15500
15730
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
15501
15731
|
function projectMcpHash(_codeName, projectDir) {
|
|
15502
15732
|
try {
|
|
15503
|
-
const raw = readFileSync34(
|
|
15733
|
+
const raw = readFileSync34(join44(projectDir, ".mcp.json"), "utf-8");
|
|
15504
15734
|
return createHash20("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
15505
15735
|
} catch {
|
|
15506
15736
|
return null;
|
|
@@ -15508,7 +15738,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
15508
15738
|
}
|
|
15509
15739
|
function projectMcpKeys(_codeName, projectDir) {
|
|
15510
15740
|
try {
|
|
15511
|
-
const raw = readFileSync34(
|
|
15741
|
+
const raw = readFileSync34(join44(projectDir, ".mcp.json"), "utf-8");
|
|
15512
15742
|
const parsed = JSON.parse(raw);
|
|
15513
15743
|
const servers = parsed.mcpServers;
|
|
15514
15744
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -15526,7 +15756,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
15526
15756
|
else runningMcpServerKeys.delete(codeName);
|
|
15527
15757
|
let launchStructure = null;
|
|
15528
15758
|
try {
|
|
15529
|
-
const raw = readFileSync34(
|
|
15759
|
+
const raw = readFileSync34(join44(projectDir, ".mcp.json"), "utf-8");
|
|
15530
15760
|
launchStructure = managedMcpStructureHashFromFile(
|
|
15531
15761
|
JSON.parse(raw),
|
|
15532
15762
|
isManagedMcpServerKey
|
|
@@ -15663,7 +15893,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
15663
15893
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
15664
15894
|
let mcpJsonForRebind = null;
|
|
15665
15895
|
try {
|
|
15666
|
-
mcpJsonForRebind = JSON.parse(readFileSync34(
|
|
15896
|
+
mcpJsonForRebind = JSON.parse(readFileSync34(join44(projectDir, ".mcp.json"), "utf-8"));
|
|
15667
15897
|
} catch {
|
|
15668
15898
|
mcpJsonForRebind = null;
|
|
15669
15899
|
}
|
|
@@ -15812,7 +16042,7 @@ function shouldInjectChannelSecrets(agentId) {
|
|
|
15812
16042
|
function projectChannelSecretHash(projectDir) {
|
|
15813
16043
|
try {
|
|
15814
16044
|
const entries = parseEnvIntegrations(
|
|
15815
|
-
readFileSync34(
|
|
16045
|
+
readFileSync34(join44(projectDir, ".env.integrations"), "utf-8")
|
|
15816
16046
|
);
|
|
15817
16047
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
15818
16048
|
} catch {
|
|
@@ -15928,7 +16158,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
15928
16158
|
var lastVersionCheckAt = 0;
|
|
15929
16159
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
15930
16160
|
var lastResponsivenessProbeAt = 0;
|
|
15931
|
-
var agtCliVersion = true ? "0.28.
|
|
16161
|
+
var agtCliVersion = true ? "0.28.1179" : "dev";
|
|
15932
16162
|
function resolveBrewPath(execFileSync3) {
|
|
15933
16163
|
try {
|
|
15934
16164
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -16171,6 +16401,82 @@ async function diskNodeVersion() {
|
|
|
16171
16401
|
}
|
|
16172
16402
|
var hostNodeObservation = null;
|
|
16173
16403
|
var hostNodeObservedAt = 0;
|
|
16404
|
+
var lastKeyRotationHandled = null;
|
|
16405
|
+
var pendingKeyRotationAck = null;
|
|
16406
|
+
function setPendingKeyRotationAck(next) {
|
|
16407
|
+
const prevMemory = pendingKeyRotationAck;
|
|
16408
|
+
const prevState = state9.pendingKeyRotationAck ?? null;
|
|
16409
|
+
pendingKeyRotationAck = next?.prefix ?? null;
|
|
16410
|
+
state9.pendingKeyRotationAck = next;
|
|
16411
|
+
try {
|
|
16412
|
+
atomicWriteFileSync(getStateFile(), JSON.stringify(state9, null, 2));
|
|
16413
|
+
return true;
|
|
16414
|
+
} catch (err) {
|
|
16415
|
+
log(`[key-rotation] could not persist the pending ack: ${err.message}`);
|
|
16416
|
+
if (next !== null) {
|
|
16417
|
+
pendingKeyRotationAck = prevMemory;
|
|
16418
|
+
state9.pendingKeyRotationAck = prevState;
|
|
16419
|
+
return false;
|
|
16420
|
+
}
|
|
16421
|
+
return true;
|
|
16422
|
+
}
|
|
16423
|
+
}
|
|
16424
|
+
var keyRotationRetryAfter = 0;
|
|
16425
|
+
var KEY_ROTATION_RETRY_MS = 5 * 6e4;
|
|
16426
|
+
var heldRotatedKey = null;
|
|
16427
|
+
function persistRotatedHostKey(rawKey) {
|
|
16428
|
+
const apiUrl = process.env["AGT_HOST"]?.trim();
|
|
16429
|
+
if (!apiUrl) {
|
|
16430
|
+
log("[key-rotation] AGT_HOST is not set, so the env channels cannot be rewritten");
|
|
16431
|
+
return false;
|
|
16432
|
+
}
|
|
16433
|
+
const consoleUrl = process.env["AGT_CONSOLE_URL"] ?? readEtcEnvironmentValue("AGT_CONSOLE_URL");
|
|
16434
|
+
let supervisor;
|
|
16435
|
+
try {
|
|
16436
|
+
supervisor = rewriteSupervisorApiKey(rawKey, void 0, getApiKey() ?? void 0);
|
|
16437
|
+
} catch (err) {
|
|
16438
|
+
log(`[key-rotation] supervisor env rewrite threw: ${err?.message ?? String(err)}`);
|
|
16439
|
+
return false;
|
|
16440
|
+
}
|
|
16441
|
+
for (const path of supervisor.rewritten) {
|
|
16442
|
+
log(`[key-rotation] rewrote AGT_API_KEY in ${path}`);
|
|
16443
|
+
}
|
|
16444
|
+
for (const f of supervisor.failed) {
|
|
16445
|
+
log(`[key-rotation] ${f.path} holds AGT_API_KEY and could NOT be rewritten: ${f.error}`);
|
|
16446
|
+
}
|
|
16447
|
+
for (const path of supervisor.rolledBack ?? []) {
|
|
16448
|
+
log(`[key-rotation] put ${path} back to the running key, because another channel failed`);
|
|
16449
|
+
}
|
|
16450
|
+
if (supervisor.failed.length > 0) {
|
|
16451
|
+
log(
|
|
16452
|
+
`[key-rotation] ${supervisor.failed.length} supervisor channel(s) would still hand out the OUTGOING key - the rotation is abandoned, not acked, so that key keeps working. Retrying after the backoff.`
|
|
16453
|
+
);
|
|
16454
|
+
return false;
|
|
16455
|
+
}
|
|
16456
|
+
if (supervisor.rewritten.length > 0) {
|
|
16457
|
+
let wroteEtcEnvironment = false;
|
|
16458
|
+
try {
|
|
16459
|
+
wroteEtcEnvironment = writeEtcEnvironment(apiUrl, rawKey, consoleUrl);
|
|
16460
|
+
} catch (err) {
|
|
16461
|
+
log(`[key-rotation] /etc/environment write threw: ${err?.message ?? String(err)}`);
|
|
16462
|
+
}
|
|
16463
|
+
try {
|
|
16464
|
+
if (!writeProfileDScript(apiUrl, rawKey, consoleUrl)) {
|
|
16465
|
+
log("[key-rotation] /etc/profile.d/agt.sh was not written; it is read by login shells, not by the manager");
|
|
16466
|
+
}
|
|
16467
|
+
} catch (err) {
|
|
16468
|
+
log(`[key-rotation] /etc/profile.d write threw (non-fatal): ${err?.message ?? String(err)}`);
|
|
16469
|
+
}
|
|
16470
|
+
if (!wroteEtcEnvironment) {
|
|
16471
|
+
log("[key-rotation] /etc/environment was not rewritten; the supervisor channel has the new key, so a restart is safe, but an SSM session and a re-bootstrap will read the old one");
|
|
16472
|
+
}
|
|
16473
|
+
return true;
|
|
16474
|
+
}
|
|
16475
|
+
log(
|
|
16476
|
+
`[key-rotation] no supervisor env channel holds AGT_API_KEY (${supervisor.keyless.length > 0 ? `present but keyless: ${supervisor.keyless.join(", ")}` : "none installed"}) - nothing would hand the new key to the next manager start, so the rotation is abandoned, not acked`
|
|
16477
|
+
);
|
|
16478
|
+
return false;
|
|
16479
|
+
}
|
|
16174
16480
|
function invalidateHostNodeObservation(pathVersion) {
|
|
16175
16481
|
hostNodeObservedAt = 0;
|
|
16176
16482
|
if (pathVersion !== void 0 && hostNodeObservation) {
|
|
@@ -16412,7 +16718,7 @@ function runAsync(cmd, args, opts) {
|
|
|
16412
16718
|
});
|
|
16413
16719
|
}
|
|
16414
16720
|
function claudeManagedSettingsPath() {
|
|
16415
|
-
return
|
|
16721
|
+
return join44(CLAUDE_MANAGED_SETTINGS_DIR, "managed-settings.json");
|
|
16416
16722
|
}
|
|
16417
16723
|
var MANAGED_SETTINGS_KEYS = ["channelsEnabled", "enableAllProjectMcpServers"];
|
|
16418
16724
|
var MANAGED_SETTINGS_ENV = { DISABLE_AUTOUPDATER: "1" };
|
|
@@ -16490,7 +16796,7 @@ async function ensureOpencodeBinary() {
|
|
|
16490
16796
|
try {
|
|
16491
16797
|
const prefix = execFileSync3("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
16492
16798
|
if (prefix) {
|
|
16493
|
-
const npmBin =
|
|
16799
|
+
const npmBin = join44(prefix, "bin");
|
|
16494
16800
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
16495
16801
|
if (!current.includes(npmBin)) {
|
|
16496
16802
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -16630,7 +16936,7 @@ async function maybeUpgradeClaudeCode() {
|
|
|
16630
16936
|
}
|
|
16631
16937
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
16632
16938
|
function selfUpdateAppliedMarkerPath() {
|
|
16633
|
-
return
|
|
16939
|
+
return join44(homedir17(), ".augmented", ".last-self-update-applied");
|
|
16634
16940
|
}
|
|
16635
16941
|
var selfUpdateUpToDateLogged = false;
|
|
16636
16942
|
var selfUpdatePinnedLogged = false;
|
|
@@ -16681,7 +16987,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
16681
16987
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
16682
16988
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
16683
16989
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
16684
|
-
const markerPath =
|
|
16990
|
+
const markerPath = join44(homedir17(), ".augmented", ".last-update-check");
|
|
16685
16991
|
if (!force) {
|
|
16686
16992
|
try {
|
|
16687
16993
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -17185,12 +17491,12 @@ async function checkClaudeAuth() {
|
|
|
17185
17491
|
var evalEmptyMcpConfigPath = null;
|
|
17186
17492
|
function ensureEvalEmptyMcpConfig() {
|
|
17187
17493
|
if (evalEmptyMcpConfigPath && existsSync19(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
17188
|
-
const dir =
|
|
17494
|
+
const dir = join44(homedir17(), ".augmented");
|
|
17189
17495
|
try {
|
|
17190
17496
|
mkdirSync16(dir, { recursive: true });
|
|
17191
17497
|
} catch {
|
|
17192
17498
|
}
|
|
17193
|
-
const p =
|
|
17499
|
+
const p = join44(dir, ".eval-empty-mcp.json");
|
|
17194
17500
|
writeFileSync18(p, JSON.stringify({ mcpServers: {} }));
|
|
17195
17501
|
evalEmptyMcpConfigPath = p;
|
|
17196
17502
|
return p;
|
|
@@ -17281,10 +17587,10 @@ function resolveConversationEvalBackend() {
|
|
|
17281
17587
|
return conversationEvalBackend;
|
|
17282
17588
|
}
|
|
17283
17589
|
function getStateFile() {
|
|
17284
|
-
return
|
|
17590
|
+
return join44(config?.configDir ?? join44(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
17285
17591
|
}
|
|
17286
17592
|
function channelHashCacheDir() {
|
|
17287
|
-
return config?.configDir ??
|
|
17593
|
+
return config?.configDir ?? join44(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
17288
17594
|
}
|
|
17289
17595
|
function loadChannelHashCache2() {
|
|
17290
17596
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -17497,7 +17803,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
17497
17803
|
var _channelQuarantineStore = null;
|
|
17498
17804
|
function channelQuarantineStore() {
|
|
17499
17805
|
if (!_channelQuarantineStore) {
|
|
17500
|
-
const dir = config?.configDir ??
|
|
17806
|
+
const dir = config?.configDir ?? join44(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
17501
17807
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
17502
17808
|
}
|
|
17503
17809
|
return _channelQuarantineStore;
|
|
@@ -17505,7 +17811,7 @@ function channelQuarantineStore() {
|
|
|
17505
17811
|
var _channelResumeHistoryStore = null;
|
|
17506
17812
|
function channelResumeHistoryStore() {
|
|
17507
17813
|
if (!_channelResumeHistoryStore) {
|
|
17508
|
-
const dir = config?.configDir ??
|
|
17814
|
+
const dir = config?.configDir ?? join44(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
17509
17815
|
_channelResumeHistoryStore = new ChannelResumeHistoryStore(defaultResumeHistoryPath(dir));
|
|
17510
17816
|
}
|
|
17511
17817
|
return _channelResumeHistoryStore;
|
|
@@ -17530,14 +17836,24 @@ function claudeMdSizeFor(codeName) {
|
|
|
17530
17836
|
logClaudeMdGraftTransition(codeName, report, log);
|
|
17531
17837
|
return report;
|
|
17532
17838
|
}
|
|
17839
|
+
function sessionActivityFor(codeName, pane) {
|
|
17840
|
+
return buildSessionActivityReport({
|
|
17841
|
+
codeName,
|
|
17842
|
+
transcriptDir: sessionTranscriptDir(getProjectDir(codeName)),
|
|
17843
|
+
sessionId: getSessionState(codeName)?.currentSessionId ?? null,
|
|
17844
|
+
tmuxAlive: pane.tmuxAlive,
|
|
17845
|
+
screenCapture: pane.screenCapture,
|
|
17846
|
+
log: (msg) => console.error(msg)
|
|
17847
|
+
});
|
|
17848
|
+
}
|
|
17533
17849
|
function forwardedToolsFor(codeName) {
|
|
17534
17850
|
if (!config?.configDir) return null;
|
|
17535
|
-
return readForwardedToolsReport(
|
|
17851
|
+
return readForwardedToolsReport(join44(config.configDir, codeName));
|
|
17536
17852
|
}
|
|
17537
17853
|
var _hostFlagStore = null;
|
|
17538
17854
|
function hostFlagStore() {
|
|
17539
17855
|
if (!_hostFlagStore) {
|
|
17540
|
-
const dir = config?.configDir ??
|
|
17856
|
+
const dir = config?.configDir ?? join44(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
17541
17857
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
17542
17858
|
}
|
|
17543
17859
|
return _hostFlagStore;
|
|
@@ -17610,13 +17926,13 @@ function parseSkillFrontmatter(content) {
|
|
|
17610
17926
|
return out;
|
|
17611
17927
|
}
|
|
17612
17928
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
17613
|
-
const { readdirSync:
|
|
17614
|
-
const skillsDir =
|
|
17615
|
-
const claudeMdPath =
|
|
17929
|
+
const { readdirSync: readdirSync15, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync19 } = await import("fs");
|
|
17930
|
+
const skillsDir = join44(configDir, codeName, "project", ".claude", "skills");
|
|
17931
|
+
const claudeMdPath = join44(configDir, codeName, "project", "CLAUDE.md");
|
|
17616
17932
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
17617
17933
|
const entries = [];
|
|
17618
|
-
for (const dir of
|
|
17619
|
-
const skillFile =
|
|
17934
|
+
for (const dir of readdirSync15(skillsDir).sort()) {
|
|
17935
|
+
const skillFile = join44(skillsDir, dir, "SKILL.md");
|
|
17620
17936
|
if (!ex(skillFile)) continue;
|
|
17621
17937
|
try {
|
|
17622
17938
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -17740,10 +18056,10 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
17740
18056
|
if (codeNames.length === 0) return;
|
|
17741
18057
|
void (async () => {
|
|
17742
18058
|
try {
|
|
17743
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18059
|
+
const { collectDiagnostics } = await import("../persistent-session-34QXCPJK.js");
|
|
17744
18060
|
await api.post("/host/heartbeat", {
|
|
17745
18061
|
host_id: hostId,
|
|
17746
|
-
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
18062
|
+
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor, sessionActivityFor)
|
|
17747
18063
|
});
|
|
17748
18064
|
} catch (err) {
|
|
17749
18065
|
log(`[restart] post-respawn diagnostics flush failed: ${err.message}`);
|
|
@@ -17883,9 +18199,9 @@ async function pollCycleInner() {
|
|
|
17883
18199
|
}
|
|
17884
18200
|
try {
|
|
17885
18201
|
const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
|
|
17886
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18202
|
+
const { collectDiagnostics } = await import("../persistent-session-34QXCPJK.js");
|
|
17887
18203
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
17888
|
-
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor) : void 0;
|
|
18204
|
+
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor, sessionActivityFor) : void 0;
|
|
17889
18205
|
let tailscaleHostname;
|
|
17890
18206
|
try {
|
|
17891
18207
|
const { execSync: es } = await import("child_process");
|
|
@@ -17963,6 +18279,14 @@ async function pollCycleInner() {
|
|
|
17963
18279
|
hostNodePin,
|
|
17964
18280
|
hostNodePin ? hostNodeConvergence.stateOf(hostNodePin) : null
|
|
17965
18281
|
),
|
|
18282
|
+
// ENG-11642: ack a rotated key. Carries the PREFIX, never the key.
|
|
18283
|
+
//
|
|
18284
|
+
// Sent on this authenticated heartbeat on purpose: by the time it goes
|
|
18285
|
+
// out the request is already signed with the NEW key, so the ack and
|
|
18286
|
+
// "the new key works" are the same fact rather than two claims. The API
|
|
18287
|
+
// treats this as permission to expire the outgoing key, so it must not
|
|
18288
|
+
// be possible to ack with a key that cannot authenticate.
|
|
18289
|
+
...pendingKeyRotationAck ? { key_rotation_adopted_prefix: pendingKeyRotationAck } : {},
|
|
17966
18290
|
agent_diagnostics: agentDiagnostics,
|
|
17967
18291
|
hostname: tailscaleHostname,
|
|
17968
18292
|
os_username: osUsername,
|
|
@@ -18085,9 +18409,52 @@ async function pollCycleInner() {
|
|
|
18085
18409
|
hostFlagStore().applyNotifyDispatchByAgent(hbResp?.notify_dispatch_by_agent);
|
|
18086
18410
|
hostFlagStore().applyBooleanFlagsByAgent(hbResp?.feature_flags_by_agent);
|
|
18087
18411
|
setConfigHash(hbResp?.config_hash ?? null);
|
|
18412
|
+
const ackDecision = nextPendingAck(pendingKeyRotationAck, hbResp);
|
|
18413
|
+
if (ackDecision.log) log(ackDecision.log);
|
|
18414
|
+
if (pendingKeyRotationAck !== null && ackDecision.pending === null) {
|
|
18415
|
+
setPendingKeyRotationAck(null);
|
|
18416
|
+
}
|
|
18417
|
+
const rotationRequestedAt = hbResp?.key_rotation_requested_at ?? null;
|
|
18418
|
+
if (shouldMintReplacementKey(rotationRequestedAt) && !alreadyHandledRotationRequest(rotationRequestedAt, lastKeyRotationHandled) && Date.now() >= keyRotationRetryAfter) {
|
|
18419
|
+
const outcome = await adoptRotatedHostKey({
|
|
18420
|
+
mint: async () => {
|
|
18421
|
+
const current = getApiKey();
|
|
18422
|
+
if (!current) return null;
|
|
18423
|
+
return mintRotatedHostKey(current);
|
|
18424
|
+
},
|
|
18425
|
+
preflightPersist: () => supervisorChannelsRefusing(void 0, {
|
|
18426
|
+
runningKeys: [
|
|
18427
|
+
getApiKey() ?? "",
|
|
18428
|
+
...heldRotatedKey && heldRotatedKey.requestedAt === rotationRequestedAt ? [heldRotatedKey.minted.rawKey] : []
|
|
18429
|
+
]
|
|
18430
|
+
}),
|
|
18431
|
+
held: heldRotatedKey && heldRotatedKey.requestedAt === rotationRequestedAt ? heldRotatedKey.minted : void 0,
|
|
18432
|
+
persist: (rawKey) => persistRotatedHostKey(rawKey),
|
|
18433
|
+
onPersisted: (prefix) => rotationRequestedAt ? setPendingKeyRotationAck({ prefix, requestedAt: rotationRequestedAt }) : true,
|
|
18434
|
+
adoptInProcess: (rawKey) => adoptHostKeyInProcess(rawKey),
|
|
18435
|
+
log
|
|
18436
|
+
});
|
|
18437
|
+
if (outcome.status === "error" && outcome.held && pendingKeyRotationAck === outcome.held.prefix) {
|
|
18438
|
+
setPendingKeyRotationAck(null);
|
|
18439
|
+
}
|
|
18440
|
+
heldRotatedKey = (outcome.status === "persist-failed" || outcome.status === "error" || outcome.status === "persist-refused") && outcome.held && rotationRequestedAt ? { requestedAt: rotationRequestedAt, minted: outcome.held } : null;
|
|
18441
|
+
if (outcome.status === "mint-refused") {
|
|
18442
|
+
lastKeyRotationHandled = rotationRequestedAt;
|
|
18443
|
+
} else if (outcome.status === "adopted") {
|
|
18444
|
+
lastKeyRotationHandled = rotationRequestedAt;
|
|
18445
|
+
setPendingKeyRotationAck(
|
|
18446
|
+
rotationRequestedAt ? { prefix: outcome.prefix, requestedAt: rotationRequestedAt } : null
|
|
18447
|
+
);
|
|
18448
|
+
} else {
|
|
18449
|
+
keyRotationRetryAfter = Date.now() + KEY_ROTATION_RETRY_MS;
|
|
18450
|
+
log(
|
|
18451
|
+
`[key-rotation] attempt did not complete (${outcome.status}); retrying after ${Math.round(KEY_ROTATION_RETRY_MS / 6e4)}m. The current key stays in force.`
|
|
18452
|
+
);
|
|
18453
|
+
}
|
|
18454
|
+
}
|
|
18088
18455
|
try {
|
|
18089
18456
|
const desiredClaudeCodeVersion = hbResp?.desired_claude_code_version?.trim();
|
|
18090
|
-
const { maybeUpdateClaudeCode, shouldRunClaudeCodeUpdater } = await import("../claude-code-updater-
|
|
18457
|
+
const { maybeUpdateClaudeCode, shouldRunClaudeCodeUpdater } = await import("../claude-code-updater-LL7KVAU3.js");
|
|
18091
18458
|
const securityFloor = currentSecurityFloor();
|
|
18092
18459
|
claudeUpdaterInFlight = true;
|
|
18093
18460
|
if (desiredClaudeCodeVersion && (claudePairLoop.busy || claudePairingInProgress())) {
|
|
@@ -18122,7 +18489,7 @@ async function pollCycleInner() {
|
|
|
18122
18489
|
collectPanelessActivityProbes,
|
|
18123
18490
|
getResponsivenessIntervalMs,
|
|
18124
18491
|
occupancyQualificationClassifications
|
|
18125
|
-
} = await import("../responsiveness-probe-
|
|
18492
|
+
} = await import("../responsiveness-probe-ZT6ITMYI.js");
|
|
18126
18493
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
18127
18494
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
18128
18495
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -18239,7 +18606,7 @@ async function pollCycleInner() {
|
|
|
18239
18606
|
collectResponsivenessProbes,
|
|
18240
18607
|
livePendingInboundOldestAgeSeconds,
|
|
18241
18608
|
parkPendingInbound
|
|
18242
|
-
} = await import("../responsiveness-probe-
|
|
18609
|
+
} = await import("../responsiveness-probe-ZT6ITMYI.js");
|
|
18243
18610
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
|
|
18244
18611
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
18245
18612
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -18331,10 +18698,10 @@ async function pollCycleInner() {
|
|
|
18331
18698
|
const paneTail = readFileSync34(paneLogPath(codeName), "utf8").slice(-65536);
|
|
18332
18699
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
18333
18700
|
if (transient) {
|
|
18334
|
-
const wedgeHome =
|
|
18701
|
+
const wedgeHome = join44(homedir17(), ".augmented", codeName);
|
|
18335
18702
|
if (existsSync19(wedgeHome)) {
|
|
18336
18703
|
atomicWriteFileSync(
|
|
18337
|
-
|
|
18704
|
+
join44(wedgeHome, "watchdog-give-up.json"),
|
|
18338
18705
|
JSON.stringify({
|
|
18339
18706
|
gave_up_at: wedgeNow.toISOString(),
|
|
18340
18707
|
reason: "transient_overload"
|
|
@@ -18396,7 +18763,7 @@ async function pollCycleInner() {
|
|
|
18396
18763
|
try {
|
|
18397
18764
|
const {
|
|
18398
18765
|
AlertHeartbeat,
|
|
18399
|
-
classifyPane,
|
|
18766
|
+
classifyPane: classifyPane2,
|
|
18400
18767
|
decidePaneFatalAction,
|
|
18401
18768
|
pruneRestartHistory,
|
|
18402
18769
|
resolvePaneFatalConfig
|
|
@@ -18439,7 +18806,7 @@ async function pollCycleInner() {
|
|
|
18439
18806
|
} catch {
|
|
18440
18807
|
pane = null;
|
|
18441
18808
|
}
|
|
18442
|
-
const verdict =
|
|
18809
|
+
const verdict = classifyPane2(pane);
|
|
18443
18810
|
const kind = verdict.kind;
|
|
18444
18811
|
if (!verdict.transcriptBanner) bannerBeat.clear(codeName);
|
|
18445
18812
|
if (kind === null) {
|
|
@@ -18525,7 +18892,7 @@ async function pollCycleInner() {
|
|
|
18525
18892
|
}
|
|
18526
18893
|
}
|
|
18527
18894
|
);
|
|
18528
|
-
const { parkPendingInbound } = await import("../responsiveness-probe-
|
|
18895
|
+
const { parkPendingInbound } = await import("../responsiveness-probe-ZT6ITMYI.js");
|
|
18529
18896
|
const { parked, deadLettered } = parkPendingInbound(codeName, new Date(fatalNowMs));
|
|
18530
18897
|
paneFatalStreak.delete(codeName);
|
|
18531
18898
|
paneFatalRestarts.set(codeName, [...history, fatalNowMs]);
|
|
@@ -18556,7 +18923,7 @@ async function pollCycleInner() {
|
|
|
18556
18923
|
TRANSCRIPT_MOUNT_ESCALATION_REFRESH_MS,
|
|
18557
18924
|
bindSourceEscalations
|
|
18558
18925
|
} = await import("../transcript-mount-health-OHE6IVJV.js");
|
|
18559
|
-
const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-
|
|
18926
|
+
const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-34QXCPJK.js");
|
|
18560
18927
|
const mountConfig = resolveTranscriptMountConfig();
|
|
18561
18928
|
const liveAgents = agentState.persistentSessionAgents;
|
|
18562
18929
|
for (const tracked of [
|
|
@@ -18625,7 +18992,7 @@ async function pollCycleInner() {
|
|
|
18625
18992
|
{ containerPath: src.projects, hostPath: src.mask },
|
|
18626
18993
|
{ containerPath: src.own, hostPath: src.own }
|
|
18627
18994
|
],
|
|
18628
|
-
stat: (path) =>
|
|
18995
|
+
stat: (path) => statSync15(path)
|
|
18629
18996
|
});
|
|
18630
18997
|
if (verdict.state !== "orphaned") {
|
|
18631
18998
|
transcriptMountStreak.delete(codeName);
|
|
@@ -18721,7 +19088,7 @@ async function pollCycleInner() {
|
|
|
18721
19088
|
}
|
|
18722
19089
|
try {
|
|
18723
19090
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
|
|
18724
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
19091
|
+
const { probeSessionAuth } = await import("../session-auth-dead-KAHV2ES2.js");
|
|
18725
19092
|
const observations = [];
|
|
18726
19093
|
const pendingCacheCommits = [];
|
|
18727
19094
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -19226,7 +19593,7 @@ async function pollCycleInner() {
|
|
|
19226
19593
|
`[drain-flush] FAILED for '${prev.codeName}': ${err.message} \u2014 proceeding to teardown; this session was NOT shipped (ENG-9491)`
|
|
19227
19594
|
);
|
|
19228
19595
|
}
|
|
19229
|
-
const agentDir =
|
|
19596
|
+
const agentDir = join44(adapter.getAgentDir(prev.codeName), "provision");
|
|
19230
19597
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
19231
19598
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
19232
19599
|
}
|
|
@@ -19305,10 +19672,10 @@ async function pollCycleInner() {
|
|
|
19305
19672
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
19306
19673
|
// the watchdog, never fails the poll cycle.
|
|
19307
19674
|
signalGiveUp: (codeName) => {
|
|
19308
|
-
const dir =
|
|
19675
|
+
const dir = join44(homedir17(), ".augmented", codeName);
|
|
19309
19676
|
if (!existsSync19(dir)) return;
|
|
19310
19677
|
atomicWriteFileSync(
|
|
19311
|
-
|
|
19678
|
+
join44(dir, "watchdog-give-up.json"),
|
|
19312
19679
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
19313
19680
|
);
|
|
19314
19681
|
},
|
|
@@ -19336,17 +19703,17 @@ async function pollCycleInner() {
|
|
|
19336
19703
|
const dir = getFramework("claude-code").getAgentDir(codeName);
|
|
19337
19704
|
if (!existsSync19(dir)) return;
|
|
19338
19705
|
atomicWriteFileSync(
|
|
19339
|
-
|
|
19706
|
+
join44(dir, "blocked-prompt.json"),
|
|
19340
19707
|
JSON.stringify({ kind, last_seen_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
19341
19708
|
);
|
|
19342
19709
|
},
|
|
19343
19710
|
clearBlockedPromptLiveness: (codeName) => {
|
|
19344
|
-
const file =
|
|
19711
|
+
const file = join44(getFramework("claude-code").getAgentDir(codeName), "blocked-prompt.json");
|
|
19345
19712
|
if (existsSync19(file)) rmSync8(file, { force: true });
|
|
19346
19713
|
},
|
|
19347
19714
|
refreshUsageLimitLiveness: (codeName) => {
|
|
19348
19715
|
const dir = getFramework("claude-code").getAgentDir(codeName);
|
|
19349
|
-
const file =
|
|
19716
|
+
const file = join44(dir, "watchdog-give-up.json");
|
|
19350
19717
|
if (!existsSync19(file)) return;
|
|
19351
19718
|
try {
|
|
19352
19719
|
const raw = JSON.parse(readFileSync34(file, "utf8"));
|
|
@@ -19360,7 +19727,7 @@ async function pollCycleInner() {
|
|
|
19360
19727
|
const dir = getFramework("claude-code").getAgentDir(codeName);
|
|
19361
19728
|
if (!existsSync19(dir)) return;
|
|
19362
19729
|
atomicWriteFileSync(
|
|
19363
|
-
|
|
19730
|
+
join44(dir, "watchdog-give-up.json"),
|
|
19364
19731
|
JSON.stringify({
|
|
19365
19732
|
gave_up_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19366
19733
|
reason: "usage_limit",
|
|
@@ -19635,7 +20002,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19635
20002
|
}
|
|
19636
20003
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19637
20004
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
19638
|
-
let agentDir =
|
|
20005
|
+
let agentDir = join44(adapter.getAgentDir(agent.code_name), "provision");
|
|
19639
20006
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
19640
20007
|
forgetChannelSyncState(agent.agent_id);
|
|
19641
20008
|
reapLegacyTokenFileEdgeWarned(agent.code_name, log);
|
|
@@ -19783,7 +20150,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19783
20150
|
if (refreshData.knowledge_manifest) {
|
|
19784
20151
|
const resolved = await resolveKnowledgeFromManifest({
|
|
19785
20152
|
manifest: refreshData.knowledge_manifest,
|
|
19786
|
-
cacheDir:
|
|
20153
|
+
cacheDir: join44(config.configDir, "_knowledge"),
|
|
19787
20154
|
delivery: refreshData.agent?.knowledge_delivery ?? "both",
|
|
19788
20155
|
fetchContents: async (hashes) => {
|
|
19789
20156
|
const res = await api.post(
|
|
@@ -19800,7 +20167,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19800
20167
|
const resolvedSkills = await resolveSkillsFromManifest({
|
|
19801
20168
|
globals: refreshData.global_skills_manifest ?? [],
|
|
19802
20169
|
shared: refreshData.shared_skills_manifest ?? [],
|
|
19803
|
-
cacheDir:
|
|
20170
|
+
cacheDir: join44(config.configDir, "_skills"),
|
|
19804
20171
|
fetchContents: async (hashes) => {
|
|
19805
20172
|
const res = await api.post(
|
|
19806
20173
|
"/host/skills/contents",
|
|
@@ -19818,7 +20185,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19818
20185
|
if (refreshData.integration_skills_manifest) {
|
|
19819
20186
|
const resolvedIntegrationSkills = await resolveIntegrationSkillsFromManifest({
|
|
19820
20187
|
manifest: refreshData.integration_skills_manifest,
|
|
19821
|
-
cacheDir:
|
|
20188
|
+
cacheDir: join44(config.configDir, "_skills"),
|
|
19822
20189
|
fetchContents: async (hashes) => {
|
|
19823
20190
|
const res = await api.post(
|
|
19824
20191
|
"/host/skills/contents",
|
|
@@ -19880,7 +20247,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19880
20247
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
19881
20248
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
19882
20249
|
const frameworkAdapter = getFramework(frameworkId);
|
|
19883
|
-
agentDir =
|
|
20250
|
+
agentDir = join44(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
19884
20251
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
19885
20252
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
19886
20253
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -19939,7 +20306,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19939
20306
|
const changedFiles = [];
|
|
19940
20307
|
mkdirSync16(agentDir, { recursive: true });
|
|
19941
20308
|
for (const artifact of artifacts) {
|
|
19942
|
-
const filePath =
|
|
20309
|
+
const filePath = join44(agentDir, artifact.relativePath);
|
|
19943
20310
|
let existingHash;
|
|
19944
20311
|
let newHash;
|
|
19945
20312
|
let writeContent = artifact.content;
|
|
@@ -19958,7 +20325,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19958
20325
|
};
|
|
19959
20326
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
19960
20327
|
try {
|
|
19961
|
-
const projectClaudeMd =
|
|
20328
|
+
const projectClaudeMd = join44(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
19962
20329
|
const existing = readFileSync34(projectClaudeMd, "utf-8");
|
|
19963
20330
|
existingHash = sha256(stripDynamicSections(existing));
|
|
19964
20331
|
} catch {
|
|
@@ -20009,12 +20376,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20009
20376
|
}
|
|
20010
20377
|
}
|
|
20011
20378
|
if (changedFiles.length > 0) {
|
|
20012
|
-
const isFirst = !existsSync19(
|
|
20379
|
+
const isFirst = !existsSync19(join44(agentDir, "CHARTER.md"));
|
|
20013
20380
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
20014
20381
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
20015
20382
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
20016
20383
|
for (const file of changedFiles) {
|
|
20017
|
-
const filePath =
|
|
20384
|
+
const filePath = join44(agentDir, file.relativePath);
|
|
20018
20385
|
mkdirSync16(dirname11(filePath), { recursive: true });
|
|
20019
20386
|
if (file.relativePath === ".mcp.json") {
|
|
20020
20387
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -20023,12 +20390,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20023
20390
|
}
|
|
20024
20391
|
}
|
|
20025
20392
|
try {
|
|
20026
|
-
const provSkillsDir =
|
|
20393
|
+
const provSkillsDir = join44(agentDir, ".claude", "skills");
|
|
20027
20394
|
if (existsSync19(provSkillsDir)) {
|
|
20028
|
-
for (const folder of
|
|
20395
|
+
for (const folder of readdirSync14(provSkillsDir)) {
|
|
20029
20396
|
if (folder.startsWith("knowledge-")) {
|
|
20030
20397
|
try {
|
|
20031
|
-
rmSync8(
|
|
20398
|
+
rmSync8(join44(provSkillsDir, folder), { recursive: true });
|
|
20032
20399
|
} catch {
|
|
20033
20400
|
}
|
|
20034
20401
|
}
|
|
@@ -20041,7 +20408,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20041
20408
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
20042
20409
|
const hashes = /* @__PURE__ */ new Map();
|
|
20043
20410
|
for (const file of trackedFiles2) {
|
|
20044
|
-
const h = hashFile(
|
|
20411
|
+
const h = hashFile(join44(agentDir, file));
|
|
20045
20412
|
if (h) hashes.set(file, h);
|
|
20046
20413
|
}
|
|
20047
20414
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -20059,14 +20426,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20059
20426
|
}
|
|
20060
20427
|
if (Array.isArray(refreshData.workflows)) {
|
|
20061
20428
|
try {
|
|
20062
|
-
const provWorkflowsDir =
|
|
20429
|
+
const provWorkflowsDir = join44(agentDir, ".claude", "workflows");
|
|
20063
20430
|
if (existsSync19(provWorkflowsDir)) {
|
|
20064
20431
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
20065
|
-
for (const file of
|
|
20432
|
+
for (const file of readdirSync14(provWorkflowsDir)) {
|
|
20066
20433
|
if (!file.endsWith(".js")) continue;
|
|
20067
20434
|
if (expected.has(file)) continue;
|
|
20068
20435
|
try {
|
|
20069
|
-
rmSync8(
|
|
20436
|
+
rmSync8(join44(provWorkflowsDir, file));
|
|
20070
20437
|
} catch {
|
|
20071
20438
|
}
|
|
20072
20439
|
}
|
|
@@ -20148,7 +20515,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20148
20515
|
if (written && existsSync19(agentDir)) {
|
|
20149
20516
|
const driftedFiles = [];
|
|
20150
20517
|
for (const [file, expectedHash] of written) {
|
|
20151
|
-
const localHash = hashFile(
|
|
20518
|
+
const localHash = hashFile(join44(agentDir, file));
|
|
20152
20519
|
if (localHash && localHash !== expectedHash) {
|
|
20153
20520
|
driftedFiles.push(file);
|
|
20154
20521
|
}
|
|
@@ -20159,7 +20526,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20159
20526
|
try {
|
|
20160
20527
|
const localHashes = {};
|
|
20161
20528
|
for (const file of driftedFiles) {
|
|
20162
|
-
localHashes[file] = hashFile(
|
|
20529
|
+
localHashes[file] = hashFile(join44(agentDir, file));
|
|
20163
20530
|
}
|
|
20164
20531
|
await api.post("/host/drift", {
|
|
20165
20532
|
agent_id: agent.agent_id,
|
|
@@ -20444,7 +20811,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20444
20811
|
const addedChannels = [...restartDecision.added];
|
|
20445
20812
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
20446
20813
|
try {
|
|
20447
|
-
const agentAugmentedDir =
|
|
20814
|
+
const agentAugmentedDir = join44(homedir17(), ".augmented", agent.code_name);
|
|
20448
20815
|
mkdirSync16(agentAugmentedDir, { recursive: true });
|
|
20449
20816
|
const markerJson = JSON.stringify({
|
|
20450
20817
|
version: 1,
|
|
@@ -20452,7 +20819,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20452
20819
|
added: addedChannels
|
|
20453
20820
|
});
|
|
20454
20821
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
20455
|
-
atomicWriteFileSync(
|
|
20822
|
+
atomicWriteFileSync(join44(agentAugmentedDir, file), markerJson);
|
|
20456
20823
|
}
|
|
20457
20824
|
} catch (err) {
|
|
20458
20825
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -20751,18 +21118,18 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20751
21118
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
20752
21119
|
try {
|
|
20753
21120
|
const agentProvisionDir = agentDir;
|
|
20754
|
-
const projectDir =
|
|
21121
|
+
const projectDir = join44(homedir17(), ".augmented", agent.code_name, "project");
|
|
20755
21122
|
mkdirSync16(agentProvisionDir, { recursive: true });
|
|
20756
21123
|
mkdirSync16(projectDir, { recursive: true });
|
|
20757
|
-
const provisionMcpPath =
|
|
20758
|
-
const projectMcpPath =
|
|
21124
|
+
const provisionMcpPath = join44(agentProvisionDir, ".mcp.json");
|
|
21125
|
+
const projectMcpPath = join44(projectDir, ".mcp.json");
|
|
20759
21126
|
let mcpConfig = { mcpServers: {} };
|
|
20760
21127
|
try {
|
|
20761
21128
|
mcpConfig = JSON.parse(readFileSync34(provisionMcpPath, "utf-8"));
|
|
20762
21129
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
20763
21130
|
} catch {
|
|
20764
21131
|
}
|
|
20765
|
-
const localDirectChatChannel =
|
|
21132
|
+
const localDirectChatChannel = join44(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
20766
21133
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
20767
21134
|
const directChatTz = (() => {
|
|
20768
21135
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -20788,7 +21155,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20788
21155
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
20789
21156
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
20790
21157
|
// so it byte-matches the broker readers' path.
|
|
20791
|
-
AGT_TURN_INITIATOR_FILE:
|
|
21158
|
+
AGT_TURN_INITIATOR_FILE: join44(
|
|
20792
21159
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
20793
21160
|
".current-turn-initiator.json"
|
|
20794
21161
|
)
|
|
@@ -20808,7 +21175,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20808
21175
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
20809
21176
|
}
|
|
20810
21177
|
}
|
|
20811
|
-
const staleChannelsPath =
|
|
21178
|
+
const staleChannelsPath = join44(projectDir, ".mcp-channels.json");
|
|
20812
21179
|
if (existsSync19(staleChannelsPath)) {
|
|
20813
21180
|
try {
|
|
20814
21181
|
rmSync8(staleChannelsPath, { force: true });
|
|
@@ -20918,7 +21285,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20918
21285
|
}
|
|
20919
21286
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
20920
21287
|
try {
|
|
20921
|
-
const probeProjectDir =
|
|
21288
|
+
const probeProjectDir = join44(homedir17(), ".augmented", agent.code_name, "project");
|
|
20922
21289
|
let probeSet = integrations;
|
|
20923
21290
|
const fetchQuarantined = async () => {
|
|
20924
21291
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -20978,7 +21345,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
20978
21345
|
const forceDue = attemptsLeft > 0;
|
|
20979
21346
|
let probeRan = false;
|
|
20980
21347
|
try {
|
|
20981
|
-
const probeProjectDir =
|
|
21348
|
+
const probeProjectDir = join44(homedir17(), ".augmented", agent.code_name, "project");
|
|
20982
21349
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
20983
21350
|
} catch (err) {
|
|
20984
21351
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -21056,8 +21423,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
21056
21423
|
const intHash = computeIntegrationsHash(integrations);
|
|
21057
21424
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
21058
21425
|
if (intHash !== prevIntHash) {
|
|
21059
|
-
const projectDir =
|
|
21060
|
-
const envIntPath =
|
|
21426
|
+
const projectDir = join44(homedir17(), ".augmented", agent.code_name, "project");
|
|
21427
|
+
const envIntPath = join44(projectDir, ".env.integrations");
|
|
21061
21428
|
let preWriteEnv;
|
|
21062
21429
|
try {
|
|
21063
21430
|
preWriteEnv = readFileSync34(envIntPath, "utf-8");
|
|
@@ -21080,7 +21447,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
21080
21447
|
}
|
|
21081
21448
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
21082
21449
|
try {
|
|
21083
|
-
const projectMcpPath =
|
|
21450
|
+
const projectMcpPath = join44(projectDir, ".mcp.json");
|
|
21084
21451
|
const postWriteEnv = readFileSync34(envIntPath, "utf-8");
|
|
21085
21452
|
const mcpContent = readFileSync34(projectMcpPath, "utf-8");
|
|
21086
21453
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
@@ -21384,23 +21751,23 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
21384
21751
|
}
|
|
21385
21752
|
}
|
|
21386
21753
|
try {
|
|
21387
|
-
const { readdirSync:
|
|
21754
|
+
const { readdirSync: readdirSync15, rmSync: rmSync9 } = await import("fs");
|
|
21388
21755
|
const { homedir: homedir18 } = await import("os");
|
|
21389
21756
|
const frameworkId2 = frameworkAdapter.id;
|
|
21390
21757
|
const candidateSkillDirs = [
|
|
21391
21758
|
// Claude Code — framework runtime tree
|
|
21392
|
-
|
|
21759
|
+
join44(homedir18(), ".augmented", agent.code_name, "skills"),
|
|
21393
21760
|
// Claude Code — project tree
|
|
21394
|
-
|
|
21761
|
+
join44(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
21395
21762
|
// Defensive: legacy provision-side path, not currently an
|
|
21396
21763
|
// install target but cheap to sweep.
|
|
21397
|
-
|
|
21764
|
+
join44(agentDir, ".claude", "skills")
|
|
21398
21765
|
];
|
|
21399
21766
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync19(d));
|
|
21400
21767
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
21401
21768
|
for (const dir of existingDirs) {
|
|
21402
21769
|
try {
|
|
21403
|
-
for (const entry of
|
|
21770
|
+
for (const entry of readdirSync15(dir)) {
|
|
21404
21771
|
if (entry.startsWith("plugin-") || entry.startsWith("integration-")) {
|
|
21405
21772
|
discoveredEntries.add(entry);
|
|
21406
21773
|
}
|
|
@@ -21437,7 +21804,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
21437
21804
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
21438
21805
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
21439
21806
|
const manifestPath = managedSkillManifestPath(
|
|
21440
|
-
|
|
21807
|
+
join44(homedir17(), ".augmented", agent.code_name)
|
|
21441
21808
|
);
|
|
21442
21809
|
const prevIds = /* @__PURE__ */ new Set([
|
|
21443
21810
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -21457,15 +21824,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
21457
21824
|
}
|
|
21458
21825
|
if (plan.removes.length) {
|
|
21459
21826
|
const globalSkillDirs = [
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
|
|
21827
|
+
join44(homedir17(), ".augmented", agent.code_name, "skills"),
|
|
21828
|
+
join44(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
21829
|
+
join44(agentDir, ".claude", "skills")
|
|
21463
21830
|
];
|
|
21464
21831
|
for (const id of plan.removes) {
|
|
21465
21832
|
let prunedAny = false;
|
|
21466
21833
|
for (const dir of globalSkillDirs) {
|
|
21467
|
-
const p =
|
|
21468
|
-
if (existsSync19(p) && existsSync19(
|
|
21834
|
+
const p = join44(dir, id);
|
|
21835
|
+
if (existsSync19(p) && existsSync19(join44(p, "SKILL.md"))) {
|
|
21469
21836
|
rmSync8(p, { recursive: true, force: true });
|
|
21470
21837
|
prunedAny = true;
|
|
21471
21838
|
}
|
|
@@ -21735,7 +22102,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
21735
22102
|
const sess = getSessionState(agent.code_name);
|
|
21736
22103
|
let mcpJsonParsed = null;
|
|
21737
22104
|
try {
|
|
21738
|
-
const mcpPath =
|
|
22105
|
+
const mcpPath = join44(getProjectDir(agent.code_name), ".mcp.json");
|
|
21739
22106
|
mcpJsonParsed = JSON.parse(readFileSync34(mcpPath, "utf-8"));
|
|
21740
22107
|
} catch {
|
|
21741
22108
|
}
|
|
@@ -22249,7 +22616,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
22249
22616
|
if (trackedFiles.length > 0 && existsSync19(agentDir)) {
|
|
22250
22617
|
const hashes = /* @__PURE__ */ new Map();
|
|
22251
22618
|
for (const file of trackedFiles) {
|
|
22252
|
-
const h = hashFile(
|
|
22619
|
+
const h = hashFile(join44(agentDir, file));
|
|
22253
22620
|
if (h) hashes.set(file, h);
|
|
22254
22621
|
}
|
|
22255
22622
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -22264,7 +22631,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
22264
22631
|
refreshData.agent.onboarding_state
|
|
22265
22632
|
);
|
|
22266
22633
|
const obStep = obState.step;
|
|
22267
|
-
const markerPath =
|
|
22634
|
+
const markerPath = join44(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
22268
22635
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
22269
22636
|
const obContactRaw = refreshData.agent.manager_last_contacted_at;
|
|
22270
22637
|
const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
|
|
@@ -22380,7 +22747,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
22380
22747
|
}
|
|
22381
22748
|
stopOpencodeSlackIngest(codeName, log);
|
|
22382
22749
|
stopOpencodeTelegramIngest(codeName, log);
|
|
22383
|
-
const opencodeProjectDir =
|
|
22750
|
+
const opencodeProjectDir = join44(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
22384
22751
|
const serveEnv = {
|
|
22385
22752
|
AGT_HOST: requireHost(),
|
|
22386
22753
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -22440,8 +22807,8 @@ async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refres
|
|
|
22440
22807
|
});
|
|
22441
22808
|
}
|
|
22442
22809
|
const projectDir = getProjectDir(codeName);
|
|
22443
|
-
const mcpConfigPath =
|
|
22444
|
-
const claudeMdPath =
|
|
22810
|
+
const mcpConfigPath = join44(projectDir, ".mcp.json");
|
|
22811
|
+
const claudeMdPath = join44(projectDir, "CLAUDE.md");
|
|
22445
22812
|
if (restartBreaker.isTripped(codeName)) {
|
|
22446
22813
|
const trip = restartBreaker.getTrip(codeName);
|
|
22447
22814
|
return {
|
|
@@ -23410,7 +23777,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
23410
23777
|
try {
|
|
23411
23778
|
const freshId = rotateSessionForWedge(codeName);
|
|
23412
23779
|
consecutiveWedgeCycles.delete(codeName);
|
|
23413
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
23780
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-ZT6ITMYI.js");
|
|
23414
23781
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
23415
23782
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
23416
23783
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -23453,10 +23820,10 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
23453
23820
|
void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
|
|
23454
23821
|
void (async () => {
|
|
23455
23822
|
try {
|
|
23456
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
23823
|
+
const { collectDiagnostics } = await import("../persistent-session-34QXCPJK.js");
|
|
23457
23824
|
await api.post("/host/heartbeat", {
|
|
23458
23825
|
host_id: hostId,
|
|
23459
|
-
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
23826
|
+
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor, sessionActivityFor)
|
|
23460
23827
|
});
|
|
23461
23828
|
} catch (err) {
|
|
23462
23829
|
log(`[restart-lane] post-respawn diagnostics flush failed for '${codeName}': ${err.message}`);
|
|
@@ -23504,10 +23871,10 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
23504
23871
|
}
|
|
23505
23872
|
try {
|
|
23506
23873
|
const hostId = await getHostId();
|
|
23507
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
23874
|
+
const { collectDiagnostics } = await import("../persistent-session-34QXCPJK.js");
|
|
23508
23875
|
await api.post("/host/heartbeat", {
|
|
23509
23876
|
host_id: hostId,
|
|
23510
|
-
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
23877
|
+
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor, sessionActivityFor)
|
|
23511
23878
|
});
|
|
23512
23879
|
} catch (err) {
|
|
23513
23880
|
log(`[fast-mcp-respawn] post-respawn diagnostics flush failed for '${codeName}': ${err.message}`);
|
|
@@ -24206,7 +24573,7 @@ async function processClaudePairSessions(agents) {
|
|
|
24206
24573
|
snapshotPairConfig,
|
|
24207
24574
|
// ENG-11659: result -> report body + the manager.log line that records it.
|
|
24208
24575
|
planPairStartReport
|
|
24209
|
-
} = await import("../claude-pair-runtime-
|
|
24576
|
+
} = await import("../claude-pair-runtime-R5MNSUM7.js");
|
|
24210
24577
|
const { resetClaudeSignin, describeSigninResetForLog, describeSigninResetFailure } = await import("../claude-signin-reset-6IJMMVYG.js");
|
|
24211
24578
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
24212
24579
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
@@ -24497,10 +24864,10 @@ var lastLocalFileHash = /* @__PURE__ */ new Map();
|
|
|
24497
24864
|
var lastMemoriesBody = /* @__PURE__ */ new Map();
|
|
24498
24865
|
var memoryManifests = /* @__PURE__ */ new Map();
|
|
24499
24866
|
function memoryRetirementDir(configDir, codeName) {
|
|
24500
|
-
return
|
|
24867
|
+
return join44(configDir, "_memory-retirement", codeName);
|
|
24501
24868
|
}
|
|
24502
24869
|
function memoryManifestPath(configDir, codeName) {
|
|
24503
|
-
return
|
|
24870
|
+
return join44(memoryRetirementDir(configDir, codeName), "manifest.json");
|
|
24504
24871
|
}
|
|
24505
24872
|
function loadMemoryManifest(agentId, configDir, codeName) {
|
|
24506
24873
|
const cached = memoryManifests.get(agentId);
|
|
@@ -24535,7 +24902,7 @@ function saveMemoryManifest(agentId, configDir, codeName) {
|
|
|
24535
24902
|
}
|
|
24536
24903
|
}
|
|
24537
24904
|
function retiredMemoryDir(configDir, codeName) {
|
|
24538
|
-
return
|
|
24905
|
+
return join44(memoryRetirementDir(configDir, codeName), "retired");
|
|
24539
24906
|
}
|
|
24540
24907
|
var RETIRED_MEMORY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
24541
24908
|
var lastRetirementReport = /* @__PURE__ */ new Map();
|
|
@@ -24614,7 +24981,7 @@ function applyMemoryTombstones(opts) {
|
|
|
24614
24981
|
log2(`[memory-retire] ${agent.code_name}: KEPT '${tomb.name}' \u2014 no write record, not ours to remove`);
|
|
24615
24982
|
continue;
|
|
24616
24983
|
}
|
|
24617
|
-
const filePath =
|
|
24984
|
+
const filePath = join44(memoryDir, entry.file);
|
|
24618
24985
|
if (!existsSync19(filePath)) {
|
|
24619
24986
|
outcomes.already_gone++;
|
|
24620
24987
|
delete manifest[tomb.name];
|
|
@@ -24634,9 +25001,9 @@ function applyMemoryTombstones(opts) {
|
|
|
24634
25001
|
const destDir = retiredMemoryDir(configDir, agent.code_name);
|
|
24635
25002
|
mkdirSync16(destDir, { recursive: true });
|
|
24636
25003
|
const stamp = Date.now();
|
|
24637
|
-
let dest =
|
|
25004
|
+
let dest = join44(destDir, `${entry.file}.${stamp}.retired`);
|
|
24638
25005
|
for (let n = 1; existsSync19(dest); n++) {
|
|
24639
|
-
dest =
|
|
25006
|
+
dest = join44(destDir, `${entry.file}.${stamp}-${n}.retired`);
|
|
24640
25007
|
}
|
|
24641
25008
|
renameSync11(filePath, dest);
|
|
24642
25009
|
try {
|
|
@@ -24673,11 +25040,11 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
24673
25040
|
const cutoff = Date.now() - RETIRED_MEMORY_TTL_MS;
|
|
24674
25041
|
let reaped = 0;
|
|
24675
25042
|
try {
|
|
24676
|
-
for (const file of
|
|
25043
|
+
for (const file of readdirSync14(dir)) {
|
|
24677
25044
|
if (!file.endsWith(".retired")) continue;
|
|
24678
|
-
const path =
|
|
25045
|
+
const path = join44(dir, file);
|
|
24679
25046
|
try {
|
|
24680
|
-
if (
|
|
25047
|
+
if (statSync15(path).mtimeMs < cutoff) {
|
|
24681
25048
|
unlinkSync6(path);
|
|
24682
25049
|
reaped++;
|
|
24683
25050
|
}
|
|
@@ -24690,8 +25057,8 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
24690
25057
|
if (reaped > 0) log2(`[memory-retire] ${codeName}: reaped ${reaped} retired memory file(s) past TTL`);
|
|
24691
25058
|
}
|
|
24692
25059
|
async function syncMemories(agent, configDir, log2) {
|
|
24693
|
-
const projectDir =
|
|
24694
|
-
const memoryDir =
|
|
25060
|
+
const projectDir = join44(configDir, agent.code_name, "project");
|
|
25061
|
+
const memoryDir = join44(projectDir, "memory");
|
|
24695
25062
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
24696
25063
|
if (isFreshSync) {
|
|
24697
25064
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -24719,10 +25086,10 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
24719
25086
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
24720
25087
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
24721
25088
|
const changedMemories = [];
|
|
24722
|
-
for (const file of
|
|
25089
|
+
for (const file of readdirSync14(memoryDir)) {
|
|
24723
25090
|
if (!file.endsWith(".md")) continue;
|
|
24724
25091
|
try {
|
|
24725
|
-
const raw = readFileSync34(
|
|
25092
|
+
const raw = readFileSync34(join44(memoryDir, file), "utf-8");
|
|
24726
25093
|
const fileHash = createHash20("sha256").update(raw).digest("hex").slice(0, 16);
|
|
24727
25094
|
currentHashes.set(file, fileHash);
|
|
24728
25095
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -24747,7 +25114,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
24747
25114
|
} catch (err) {
|
|
24748
25115
|
for (const mem of changedMemories) {
|
|
24749
25116
|
for (const [file] of currentHashes) {
|
|
24750
|
-
const parsed = parseMemoryFile(readFileSync34(
|
|
25117
|
+
const parsed = parseMemoryFile(readFileSync34(join44(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
24751
25118
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
24752
25119
|
}
|
|
24753
25120
|
}
|
|
@@ -24773,7 +25140,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
24773
25140
|
}
|
|
24774
25141
|
}
|
|
24775
25142
|
async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
24776
|
-
const localFiles = existsSync19(memoryDir) ?
|
|
25143
|
+
const localFiles = existsSync19(memoryDir) ? readdirSync14(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
24777
25144
|
const localListHash = createHash20("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
24778
25145
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
24779
25146
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
@@ -24828,7 +25195,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
24828
25195
|
// Per-agent, not host-wide: memories are agent-private, so a shared
|
|
24829
25196
|
// store would buy almost no dedupe while exposing one agent's content
|
|
24830
25197
|
// to every other agent on the host. See memory-cache.ts's header.
|
|
24831
|
-
cacheDir:
|
|
25198
|
+
cacheDir: join44(configDir, agent.code_name, "_memory_bodies"),
|
|
24832
25199
|
fetchContents: async (hashes) => {
|
|
24833
25200
|
const res = await api.post(
|
|
24834
25201
|
"/host/memories/contents",
|
|
@@ -24866,7 +25233,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
24866
25233
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
24867
25234
|
const slug = rawSlug || `memory-${i}`;
|
|
24868
25235
|
const fileName = `${slug}.md`;
|
|
24869
|
-
const filePath =
|
|
25236
|
+
const filePath = join44(memoryDir, fileName);
|
|
24870
25237
|
const desired = `---
|
|
24871
25238
|
name: ${JSON.stringify(mem.name)}
|
|
24872
25239
|
type: ${mem.type}
|
|
@@ -24904,7 +25271,7 @@ ${mem.content}
|
|
|
24904
25271
|
if (manifestDirty) saveMemoryManifest(agent.agent_id, configDir, agent.code_name);
|
|
24905
25272
|
}
|
|
24906
25273
|
if (written > 0 || overwritten > 0) {
|
|
24907
|
-
const updatedFiles =
|
|
25274
|
+
const updatedFiles = readdirSync14(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
24908
25275
|
lastLocalFileHash.set(agent.agent_id, createHash20("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
24909
25276
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
24910
25277
|
}
|
|
@@ -25304,12 +25671,19 @@ function startManager(opts) {
|
|
|
25304
25671
|
log(`[startup] rehydrated update-request ack at ${state9.lastUpdateRequestProcessedAt} (ENG-6692)`);
|
|
25305
25672
|
}
|
|
25306
25673
|
}
|
|
25674
|
+
const pendingAck = parsed.pendingKeyRotationAck;
|
|
25675
|
+
if (pendingAck && typeof pendingAck.prefix === "string" && typeof pendingAck.requestedAt === "string") {
|
|
25676
|
+
state9.pendingKeyRotationAck = pendingAck;
|
|
25677
|
+
pendingKeyRotationAck = pendingAck.prefix;
|
|
25678
|
+
lastKeyRotationHandled = pendingAck.requestedAt;
|
|
25679
|
+
log(`[startup] rehydrated pending key-rotation ack for ${pendingAck.prefix} (ENG-11642)`);
|
|
25680
|
+
}
|
|
25307
25681
|
}
|
|
25308
25682
|
} catch (err) {
|
|
25309
25683
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
25310
25684
|
}
|
|
25311
25685
|
log(
|
|
25312
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
25686
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join44(homedir17(), ".augmented", "manager.log")}`
|
|
25313
25687
|
);
|
|
25314
25688
|
deployMcpAssets();
|
|
25315
25689
|
reapOrphanChannelMcps({ log });
|
|
@@ -25435,14 +25809,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
25435
25809
|
}
|
|
25436
25810
|
}
|
|
25437
25811
|
function deployMcpAssets() {
|
|
25438
|
-
const targetDir =
|
|
25812
|
+
const targetDir = join44(homedir17(), ".augmented", "_mcp");
|
|
25439
25813
|
mkdirSync16(targetDir, { recursive: true });
|
|
25440
25814
|
const moduleDir = dirname11(fileURLToPath2(import.meta.url));
|
|
25441
25815
|
let mcpSourceDir = "";
|
|
25442
25816
|
let dir = moduleDir;
|
|
25443
25817
|
for (let i = 0; i < 6; i++) {
|
|
25444
|
-
const candidate =
|
|
25445
|
-
if (existsSync19(
|
|
25818
|
+
const candidate = join44(dir, "dist", "mcp");
|
|
25819
|
+
if (existsSync19(join44(candidate, "index.js"))) {
|
|
25446
25820
|
mcpSourceDir = candidate;
|
|
25447
25821
|
break;
|
|
25448
25822
|
}
|
|
@@ -25542,8 +25916,8 @@ function deployMcpAssets() {
|
|
|
25542
25916
|
// natural session restart.
|
|
25543
25917
|
"computer-use-proxy.js"
|
|
25544
25918
|
]) {
|
|
25545
|
-
const src =
|
|
25546
|
-
const dst =
|
|
25919
|
+
const src = join44(mcpSourceDir, file);
|
|
25920
|
+
const dst = join44(targetDir, file);
|
|
25547
25921
|
if (!existsSync19(src)) continue;
|
|
25548
25922
|
attemptedFiles.push(file);
|
|
25549
25923
|
const before = fileHash(dst);
|
|
@@ -25569,14 +25943,14 @@ function deployMcpAssets() {
|
|
|
25569
25943
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
25570
25944
|
restartRunningChannelMcps(changedBasenames);
|
|
25571
25945
|
}
|
|
25572
|
-
const localMcpPath =
|
|
25946
|
+
const localMcpPath = join44(targetDir, "index.js");
|
|
25573
25947
|
try {
|
|
25574
|
-
const agentsDir =
|
|
25948
|
+
const agentsDir = join44(homedir17(), ".augmented", "agents");
|
|
25575
25949
|
if (existsSync19(agentsDir)) {
|
|
25576
|
-
for (const entry of
|
|
25950
|
+
for (const entry of readdirSync14(agentsDir, { withFileTypes: true })) {
|
|
25577
25951
|
if (!entry.isDirectory()) continue;
|
|
25578
25952
|
for (const subdir of ["provision", "project"]) {
|
|
25579
|
-
const mcpJsonPath =
|
|
25953
|
+
const mcpJsonPath = join44(agentsDir, entry.name, subdir, ".mcp.json");
|
|
25580
25954
|
try {
|
|
25581
25955
|
const raw = readFileSync34(mcpJsonPath, "utf-8");
|
|
25582
25956
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|