@integrity-labs/agt-cli 0.28.907 → 0.28.909
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 +5 -5
- package/dist/{chunk-I2PUWPUR.js → chunk-4M4POU6Q.js} +2 -2
- package/dist/{chunk-N47GH7MJ.js → chunk-7WKTBFAD.js} +4 -4
- package/dist/chunk-7WKTBFAD.js.map +1 -0
- package/dist/{chunk-GBQRH5RE.js → chunk-A2GUODU3.js} +4 -4
- package/dist/{claude-pair-runtime-A36CKF54.js → claude-pair-runtime-UYWAQW3F.js} +2 -2
- package/dist/lib/manager-worker.js +307 -198
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +3 -3
- package/dist/mcp/index.js +3 -3
- package/dist/mcp/origami.js +3 -3
- package/dist/mcp/slack-channel.js +3 -3
- package/dist/mcp/telegram-channel.js +3 -3
- package/dist/{persistent-session-ZOEBA7KM.js → persistent-session-A2IB5WGW.js} +3 -3
- package/dist/{responsiveness-probe-BNQIJAFF.js → responsiveness-probe-3M3556MN.js} +3 -3
- package/dist/{session-auth-dead-TAAZTRTD.js → session-auth-dead-MRZ3A2N5.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-N47GH7MJ.js.map +0 -1
- /package/dist/{chunk-I2PUWPUR.js.map → chunk-4M4POU6Q.js.map} +0 -0
- /package/dist/{chunk-GBQRH5RE.js.map → chunk-A2GUODU3.js.map} +0 -0
- /package/dist/{claude-pair-runtime-A36CKF54.js.map → claude-pair-runtime-UYWAQW3F.js.map} +0 -0
- /package/dist/{persistent-session-ZOEBA7KM.js.map → persistent-session-A2IB5WGW.js.map} +0 -0
- /package/dist/{responsiveness-probe-BNQIJAFF.js.map → responsiveness-probe-3M3556MN.js.map} +0 -0
- /package/dist/{session-auth-dead-TAAZTRTD.js.map → session-auth-dead-MRZ3A2N5.js.map} +0 -0
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
safeWriteJsonAtomic,
|
|
64
64
|
setConfigHash,
|
|
65
65
|
tripClass
|
|
66
|
-
} from "../chunk-
|
|
66
|
+
} from "../chunk-A2GUODU3.js";
|
|
67
67
|
import {
|
|
68
68
|
getProjectDir as getProjectDir2,
|
|
69
69
|
getReadyTasks,
|
|
@@ -136,7 +136,7 @@ import {
|
|
|
136
136
|
takeZombieDetection,
|
|
137
137
|
toOpencodeModel,
|
|
138
138
|
writeEgressAllowlist
|
|
139
|
-
} from "../chunk-
|
|
139
|
+
} from "../chunk-4M4POU6Q.js";
|
|
140
140
|
import {
|
|
141
141
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
142
142
|
AnchorSessionClient,
|
|
@@ -231,14 +231,14 @@ import {
|
|
|
231
231
|
subagentActivityAgeSeconds,
|
|
232
232
|
sumTranscriptUsageInWindow,
|
|
233
233
|
transcriptActivityAgeSeconds
|
|
234
|
-
} from "../chunk-
|
|
234
|
+
} from "../chunk-7WKTBFAD.js";
|
|
235
235
|
import {
|
|
236
236
|
reapOrphanChannelMcps
|
|
237
237
|
} from "../chunk-XWVM4KPK.js";
|
|
238
238
|
|
|
239
239
|
// src/lib/manager-worker.ts
|
|
240
240
|
import { createHash as createHash20 } from "crypto";
|
|
241
|
-
import { readFileSync as
|
|
241
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync18, mkdirSync as mkdirSync15, existsSync as existsSync19, rmSync as rmSync8, readdirSync as readdirSync12, statSync as statSync12, unlinkSync as unlinkSync6, renameSync as renameSync11, utimesSync as utimesSync4 } from "fs";
|
|
242
242
|
|
|
243
243
|
// src/lib/atomic-file-replace.ts
|
|
244
244
|
import { copyFileSync, renameSync, unlinkSync } from "fs";
|
|
@@ -264,8 +264,8 @@ function defaultUnique() {
|
|
|
264
264
|
|
|
265
265
|
// src/lib/manager-worker.ts
|
|
266
266
|
import { execFileSync as syncExecFile } from "child_process";
|
|
267
|
-
import { join as
|
|
268
|
-
import { homedir as
|
|
267
|
+
import { join as join42, dirname as dirname11, delimiter as pathDelimiter } from "path";
|
|
268
|
+
import { homedir as homedir18 } from "os";
|
|
269
269
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
270
270
|
|
|
271
271
|
// ../../packages/core/dist/provisioning/channel-policy-env.js
|
|
@@ -1858,11 +1858,11 @@ function isPathInsideDir(candidate, dir) {
|
|
|
1858
1858
|
}
|
|
1859
1859
|
function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
1860
1860
|
const existsSync20 = deps.existsSync ?? nodeExistsSync;
|
|
1861
|
-
const
|
|
1861
|
+
const readFileSync34 = deps.readFileSync ?? nodeReadFileSync;
|
|
1862
1862
|
const mcpDir = deps.mcpDir ?? getSharedMcpDir();
|
|
1863
1863
|
let parsed;
|
|
1864
1864
|
try {
|
|
1865
|
-
parsed = JSON.parse(
|
|
1865
|
+
parsed = JSON.parse(readFileSync34(mcpConfigPath, "utf-8"));
|
|
1866
1866
|
} catch {
|
|
1867
1867
|
return [];
|
|
1868
1868
|
}
|
|
@@ -6359,6 +6359,86 @@ function pruneStuckStreaksToAgents(maps, activeAgentIds) {
|
|
|
6359
6359
|
return dropped;
|
|
6360
6360
|
}
|
|
6361
6361
|
|
|
6362
|
+
// src/lib/claude-device-state.ts
|
|
6363
|
+
import { readFileSync as readFileSync24, statSync as statSync8 } from "fs";
|
|
6364
|
+
import { homedir as homedir13 } from "os";
|
|
6365
|
+
import { join as join30 } from "path";
|
|
6366
|
+
function claudeDeviceStatePath(env = process.env) {
|
|
6367
|
+
return join30(env.HOME?.trim() || homedir13(), ".claude.json");
|
|
6368
|
+
}
|
|
6369
|
+
function checkClaudeDeviceState(path = claudeDeviceStatePath()) {
|
|
6370
|
+
try {
|
|
6371
|
+
if (!statSync8(path).isFile()) return { usable: false, reason: "not-a-file" };
|
|
6372
|
+
} catch (err) {
|
|
6373
|
+
return {
|
|
6374
|
+
usable: false,
|
|
6375
|
+
reason: err?.code === "ENOENT" ? "missing" : "unreadable"
|
|
6376
|
+
};
|
|
6377
|
+
}
|
|
6378
|
+
let raw;
|
|
6379
|
+
try {
|
|
6380
|
+
raw = readFileSync24(path, "utf-8");
|
|
6381
|
+
} catch {
|
|
6382
|
+
return { usable: false, reason: "unreadable" };
|
|
6383
|
+
}
|
|
6384
|
+
let parsed;
|
|
6385
|
+
try {
|
|
6386
|
+
parsed = JSON.parse(raw);
|
|
6387
|
+
} catch {
|
|
6388
|
+
return { usable: false, reason: "unparseable" };
|
|
6389
|
+
}
|
|
6390
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
6391
|
+
return { usable: false, reason: "not-an-object" };
|
|
6392
|
+
}
|
|
6393
|
+
if (Object.keys(parsed).length === 0) return { usable: false, reason: "empty-object" };
|
|
6394
|
+
return { usable: true };
|
|
6395
|
+
}
|
|
6396
|
+
var DeviceStateRotationGate = class {
|
|
6397
|
+
constructor(check = () => checkClaudeDeviceState()) {
|
|
6398
|
+
this.check = check;
|
|
6399
|
+
}
|
|
6400
|
+
held = /* @__PURE__ */ new Map();
|
|
6401
|
+
/**
|
|
6402
|
+
* Ask before tearing `codeName`'s session down for a planned rotation.
|
|
6403
|
+
* Returns `ready: true` when the respawn can start; otherwise the rotation must
|
|
6404
|
+
* be skipped this tick. `firstHold` is true only on the tick a hold begins for
|
|
6405
|
+
* this agent, so the caller logs once per episode rather than every poll.
|
|
6406
|
+
*/
|
|
6407
|
+
mayRotate(codeName, nowMs) {
|
|
6408
|
+
const verdict = this.check();
|
|
6409
|
+
if (verdict.usable) {
|
|
6410
|
+
this.held.clear();
|
|
6411
|
+
return { ready: true };
|
|
6412
|
+
}
|
|
6413
|
+
const firstHold = !this.held.has(codeName);
|
|
6414
|
+
if (firstHold) this.held.set(codeName, nowMs);
|
|
6415
|
+
return { ready: false, reason: verdict.reason, firstHold };
|
|
6416
|
+
}
|
|
6417
|
+
/**
|
|
6418
|
+
* The value for the heartbeat. Re-checks the file while anything is held, so
|
|
6419
|
+
* the alert closes on the next heartbeat after the operator pairs the host,
|
|
6420
|
+
* not only when some agent's rollover next asks. Reads nothing when nothing is
|
|
6421
|
+
* held, so a healthy host pays no file read per heartbeat.
|
|
6422
|
+
*/
|
|
6423
|
+
heartbeatField() {
|
|
6424
|
+
if (this.held.size === 0) return null;
|
|
6425
|
+
const verdict = this.check();
|
|
6426
|
+
if (verdict.usable) {
|
|
6427
|
+
this.held.clear();
|
|
6428
|
+
return null;
|
|
6429
|
+
}
|
|
6430
|
+
return {
|
|
6431
|
+
reason: verdict.reason,
|
|
6432
|
+
deferred_agents: [...this.held.keys()].sort(),
|
|
6433
|
+
blocked_since: new Date(Math.min(...this.held.values())).toISOString()
|
|
6434
|
+
};
|
|
6435
|
+
}
|
|
6436
|
+
/** For tests and logs. */
|
|
6437
|
+
heldAgents() {
|
|
6438
|
+
return [...this.held.keys()].sort();
|
|
6439
|
+
}
|
|
6440
|
+
};
|
|
6441
|
+
|
|
6362
6442
|
// src/lib/channel-sweep.ts
|
|
6363
6443
|
import { execFileSync } from "child_process";
|
|
6364
6444
|
var CHANNEL_BASENAMES = [
|
|
@@ -6927,7 +7007,7 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
6927
7007
|
}
|
|
6928
7008
|
|
|
6929
7009
|
// src/lib/manager/integration-skill-cache.ts
|
|
6930
|
-
import { join as
|
|
7010
|
+
import { join as join31 } from "path";
|
|
6931
7011
|
function integrationSkillHashKey(agentId, skillId) {
|
|
6932
7012
|
return `plugin-skill:${agentId}:${skillId}`;
|
|
6933
7013
|
}
|
|
@@ -6943,21 +7023,21 @@ function forgetIntegrationSkill(cache2, agentId, skillId) {
|
|
|
6943
7023
|
function removeIntegrationSkillFolder(opts) {
|
|
6944
7024
|
forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
|
|
6945
7025
|
for (const dir of opts.dirs) {
|
|
6946
|
-
opts.removeDir(
|
|
7026
|
+
opts.removeDir(join31(dir, opts.entry));
|
|
6947
7027
|
}
|
|
6948
7028
|
}
|
|
6949
7029
|
|
|
6950
7030
|
// src/lib/manager/managed-skill-manifest.ts
|
|
6951
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as
|
|
6952
|
-
import { dirname as dirname8, join as
|
|
7031
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync25, writeFileSync as writeFileSync12 } from "fs";
|
|
7032
|
+
import { dirname as dirname8, join as join32 } from "path";
|
|
6953
7033
|
var MANIFEST_VERSION = 1;
|
|
6954
7034
|
function managedSkillManifestPath(agentRootDir) {
|
|
6955
|
-
return
|
|
7035
|
+
return join32(agentRootDir, "managed-skills.json");
|
|
6956
7036
|
}
|
|
6957
7037
|
function readManagedSkillManifest(path) {
|
|
6958
7038
|
try {
|
|
6959
7039
|
if (!existsSync13(path)) return /* @__PURE__ */ new Set();
|
|
6960
|
-
const parsed = JSON.parse(
|
|
7040
|
+
const parsed = JSON.parse(readFileSync25(path, "utf-8"));
|
|
6961
7041
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
6962
7042
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
6963
7043
|
} catch {
|
|
@@ -7087,8 +7167,8 @@ function resolveModelChain(refreshData) {
|
|
|
7087
7167
|
|
|
7088
7168
|
// src/lib/manager/claude-auth.ts
|
|
7089
7169
|
import { existsSync as existsSync14, rmSync as rmSync6 } from "fs";
|
|
7090
|
-
import { join as
|
|
7091
|
-
import { homedir as
|
|
7170
|
+
import { join as join33 } from "path";
|
|
7171
|
+
import { homedir as homedir14 } from "os";
|
|
7092
7172
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
7093
7173
|
const apiKey = getApiKey();
|
|
7094
7174
|
if (!apiKey) {
|
|
@@ -7100,9 +7180,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
7100
7180
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
7101
7181
|
}
|
|
7102
7182
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
7103
|
-
const claudeDir =
|
|
7183
|
+
const claudeDir = join33(homedir14(), ".claude");
|
|
7104
7184
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
7105
|
-
const p =
|
|
7185
|
+
const p = join33(claudeDir, filename);
|
|
7106
7186
|
if (existsSync14(p)) {
|
|
7107
7187
|
try {
|
|
7108
7188
|
rmSync6(p, { force: true });
|
|
@@ -7458,19 +7538,19 @@ function formatBoardForPrompt(items, template) {
|
|
|
7458
7538
|
}
|
|
7459
7539
|
|
|
7460
7540
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
7461
|
-
import { existsSync as existsSync15, readFileSync as
|
|
7462
|
-
import { join as
|
|
7541
|
+
import { existsSync as existsSync15, readFileSync as readFileSync26, writeFileSync as writeFileSync13 } from "fs";
|
|
7542
|
+
import { join as join34 } from "path";
|
|
7463
7543
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
7464
7544
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
7465
7545
|
function getKanbanNudgeStateFile(configDir) {
|
|
7466
|
-
return
|
|
7546
|
+
return join34(configDir, CACHE_FILENAME2);
|
|
7467
7547
|
}
|
|
7468
7548
|
function loadKanbanNudgeState(target, configDir) {
|
|
7469
7549
|
const path = getKanbanNudgeStateFile(configDir);
|
|
7470
7550
|
if (!existsSync15(path)) return;
|
|
7471
7551
|
let parsed;
|
|
7472
7552
|
try {
|
|
7473
|
-
parsed = JSON.parse(
|
|
7553
|
+
parsed = JSON.parse(readFileSync26(path, "utf-8"));
|
|
7474
7554
|
} catch {
|
|
7475
7555
|
return;
|
|
7476
7556
|
}
|
|
@@ -8088,9 +8168,9 @@ function closeSessionRunForCode(codeName, outcome, reason) {
|
|
|
8088
8168
|
|
|
8089
8169
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
8090
8170
|
import { createHash as createHash15 } from "crypto";
|
|
8091
|
-
import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as
|
|
8092
|
-
import { homedir as
|
|
8093
|
-
import { join as
|
|
8171
|
+
import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as readFileSync27, unlinkSync as unlinkSync3 } from "fs";
|
|
8172
|
+
import { homedir as homedir15 } from "os";
|
|
8173
|
+
import { join as join35, dirname as dirname9 } from "path";
|
|
8094
8174
|
|
|
8095
8175
|
// src/lib/manager/scheduler/notify.ts
|
|
8096
8176
|
import { createHash as createHash14 } from "crypto";
|
|
@@ -8449,7 +8529,7 @@ function resolveScheduledSlackTarget(task) {
|
|
|
8449
8529
|
}
|
|
8450
8530
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
8451
8531
|
try {
|
|
8452
|
-
const file =
|
|
8532
|
+
const file = join35(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
8453
8533
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
8454
8534
|
const tmp = `${file}.tmp`;
|
|
8455
8535
|
writeFileSync14(tmp, JSON.stringify(marker), "utf8");
|
|
@@ -8459,9 +8539,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
8459
8539
|
}
|
|
8460
8540
|
}
|
|
8461
8541
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
8462
|
-
const file =
|
|
8542
|
+
const file = join35(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
8463
8543
|
try {
|
|
8464
|
-
const raw = JSON.parse(
|
|
8544
|
+
const raw = JSON.parse(readFileSync27(file, "utf8"));
|
|
8465
8545
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
8466
8546
|
unlinkSync3(file);
|
|
8467
8547
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -8521,7 +8601,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
8521
8601
|
return false;
|
|
8522
8602
|
}
|
|
8523
8603
|
try {
|
|
8524
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
8604
|
+
const doorbell = directChatDoorbellPath(agentId, homedir15());
|
|
8525
8605
|
mkdirSync11(dirname9(doorbell), { recursive: true });
|
|
8526
8606
|
writeFileSync14(doorbell, String(Date.now()));
|
|
8527
8607
|
} catch (err) {
|
|
@@ -8673,12 +8753,12 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
8673
8753
|
|
|
8674
8754
|
// src/lib/manager/scheduler/execution.ts
|
|
8675
8755
|
import { createHash as createHash16 } from "crypto";
|
|
8676
|
-
import { homedir as
|
|
8677
|
-
import { join as
|
|
8756
|
+
import { homedir as homedir16 } from "os";
|
|
8757
|
+
import { join as join37 } from "path";
|
|
8678
8758
|
|
|
8679
8759
|
// src/lib/agent-serving-probe.ts
|
|
8680
|
-
import { readFileSync as
|
|
8681
|
-
import { join as
|
|
8760
|
+
import { readFileSync as readFileSync28, readdirSync as readdirSync8, statSync as statSync9 } from "fs";
|
|
8761
|
+
import { join as join36 } from "path";
|
|
8682
8762
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
8683
8763
|
function probeRateLimit(args) {
|
|
8684
8764
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
@@ -8694,16 +8774,16 @@ function probeRateLimit(args) {
|
|
|
8694
8774
|
let newest = UNKNOWN_RATE_LIMIT;
|
|
8695
8775
|
for (const name of entries) {
|
|
8696
8776
|
if (!name.endsWith(".jsonl")) continue;
|
|
8697
|
-
const path =
|
|
8777
|
+
const path = join36(dir, name);
|
|
8698
8778
|
try {
|
|
8699
|
-
const st =
|
|
8779
|
+
const st = statSync9(path);
|
|
8700
8780
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
8701
8781
|
} catch {
|
|
8702
8782
|
continue;
|
|
8703
8783
|
}
|
|
8704
8784
|
let content;
|
|
8705
8785
|
try {
|
|
8706
|
-
content =
|
|
8786
|
+
content = readFileSync28(path, "utf-8");
|
|
8707
8787
|
} catch {
|
|
8708
8788
|
continue;
|
|
8709
8789
|
}
|
|
@@ -8765,7 +8845,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
8765
8845
|
|
|
8766
8846
|
// src/lib/manager/scheduler/execution.ts
|
|
8767
8847
|
function claudePidFilePath() {
|
|
8768
|
-
return
|
|
8848
|
+
return join37(homedir16(), ".augmented", "manager-claude-pids.json");
|
|
8769
8849
|
}
|
|
8770
8850
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
8771
8851
|
function registerClaudeSpawn(record) {
|
|
@@ -8835,8 +8915,8 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
8835
8915
|
}
|
|
8836
8916
|
|
|
8837
8917
|
// src/lib/occupancy-gate.ts
|
|
8838
|
-
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync9, readSync as readSync2, statSync as
|
|
8839
|
-
import { join as
|
|
8918
|
+
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync9, readSync as readSync2, statSync as statSync10 } from "fs";
|
|
8919
|
+
import { join as join38 } from "path";
|
|
8840
8920
|
function rostersMeasuredZero(mode, attested, runtimeRunning) {
|
|
8841
8921
|
return mode === "enforce" && attested && runtimeRunning;
|
|
8842
8922
|
}
|
|
@@ -8850,7 +8930,7 @@ var brackets = /* @__PURE__ */ new Map();
|
|
|
8850
8930
|
function readAlignedTail(path, tailBytes, maxAlignBytes) {
|
|
8851
8931
|
let fd = null;
|
|
8852
8932
|
try {
|
|
8853
|
-
const size =
|
|
8933
|
+
const size = statSync10(path).size;
|
|
8854
8934
|
if (size <= 0) return { content: "", complete: true, truncated: false };
|
|
8855
8935
|
fd = openSync2(path, "r");
|
|
8856
8936
|
let readStart = Math.max(0, size - tailBytes);
|
|
@@ -8927,10 +9007,10 @@ function candidateTranscriptPaths(dir) {
|
|
|
8927
9007
|
let complete = true;
|
|
8928
9008
|
for (const name of top) {
|
|
8929
9009
|
if (name.endsWith(".jsonl")) {
|
|
8930
|
-
paths.push(
|
|
9010
|
+
paths.push(join38(dir, name));
|
|
8931
9011
|
continue;
|
|
8932
9012
|
}
|
|
8933
|
-
const subDir =
|
|
9013
|
+
const subDir = join38(dir, name, "subagents");
|
|
8934
9014
|
let subs;
|
|
8935
9015
|
try {
|
|
8936
9016
|
subs = readdirSync9(subDir);
|
|
@@ -8939,7 +9019,7 @@ function candidateTranscriptPaths(dir) {
|
|
|
8939
9019
|
continue;
|
|
8940
9020
|
}
|
|
8941
9021
|
for (const sub of subs) {
|
|
8942
|
-
if (sub.endsWith(".jsonl")) paths.push(
|
|
9022
|
+
if (sub.endsWith(".jsonl")) paths.push(join38(subDir, sub));
|
|
8943
9023
|
}
|
|
8944
9024
|
}
|
|
8945
9025
|
return { paths, complete };
|
|
@@ -8994,7 +9074,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
8994
9074
|
for (const path of paths) {
|
|
8995
9075
|
let st;
|
|
8996
9076
|
try {
|
|
8997
|
-
st =
|
|
9077
|
+
st = statSync10(path);
|
|
8998
9078
|
} catch (err) {
|
|
8999
9079
|
if (!isAbsentDirError(err)) complete = false;
|
|
9000
9080
|
continue;
|
|
@@ -9100,7 +9180,7 @@ function qualifyBuckets(buckets, qualifying, mode, nowMs, neighbourhoodMs = DEFA
|
|
|
9100
9180
|
}
|
|
9101
9181
|
|
|
9102
9182
|
// src/lib/pane-occupancy-sampler.ts
|
|
9103
|
-
import { statSync as
|
|
9183
|
+
import { statSync as statSync11 } from "fs";
|
|
9104
9184
|
var SAMPLE_INTERVAL_MS = 1e4;
|
|
9105
9185
|
var IDLE_GAP_MS = 12e4;
|
|
9106
9186
|
var POST_IDLE_CREDIT_MS = 6e4;
|
|
@@ -9114,7 +9194,7 @@ function hasFreshPaneObservation(codeName, nowMs, maxAgeMs = OBSERVATION_FRESH_M
|
|
|
9114
9194
|
}
|
|
9115
9195
|
function paneMtimeMs(codeName) {
|
|
9116
9196
|
try {
|
|
9117
|
-
return
|
|
9197
|
+
return statSync11(paneLogPath(codeName)).mtimeMs;
|
|
9118
9198
|
} catch {
|
|
9119
9199
|
return null;
|
|
9120
9200
|
}
|
|
@@ -9165,7 +9245,7 @@ function stopPaneOccupancySampler() {
|
|
|
9165
9245
|
}
|
|
9166
9246
|
|
|
9167
9247
|
// src/lib/pid-pressure-sampler.ts
|
|
9168
|
-
import { existsSync as existsSync16, readFileSync as
|
|
9248
|
+
import { existsSync as existsSync16, readFileSync as readFileSync29 } from "fs";
|
|
9169
9249
|
var SAMPLE_INTERVAL_MS2 = 3e4;
|
|
9170
9250
|
function warnFraction() {
|
|
9171
9251
|
const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
|
|
@@ -9178,7 +9258,7 @@ function configuredCeiling() {
|
|
|
9178
9258
|
}
|
|
9179
9259
|
function readTextReal(path) {
|
|
9180
9260
|
try {
|
|
9181
|
-
return
|
|
9261
|
+
return readFileSync29(path, "utf-8");
|
|
9182
9262
|
} catch {
|
|
9183
9263
|
return null;
|
|
9184
9264
|
}
|
|
@@ -10495,9 +10575,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
10495
10575
|
|
|
10496
10576
|
// src/lib/opencode-telegram-ingest.ts
|
|
10497
10577
|
import { createHash as createHash19 } from "crypto";
|
|
10498
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as
|
|
10578
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as readFileSync30, renameSync as renameSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
|
|
10499
10579
|
import { randomUUID } from "crypto";
|
|
10500
|
-
import { join as
|
|
10580
|
+
import { join as join39 } from "path";
|
|
10501
10581
|
|
|
10502
10582
|
// src/lib/telegram-ingest.ts
|
|
10503
10583
|
import https2 from "https";
|
|
@@ -11054,7 +11134,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
11054
11134
|
let filePath;
|
|
11055
11135
|
try {
|
|
11056
11136
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
11057
|
-
filePath =
|
|
11137
|
+
filePath = join39(dir, "telegram-getupdates-offset-opencode.json");
|
|
11058
11138
|
} catch {
|
|
11059
11139
|
dir = null;
|
|
11060
11140
|
filePath = null;
|
|
@@ -11063,7 +11143,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
11063
11143
|
load() {
|
|
11064
11144
|
if (!filePath) return 0;
|
|
11065
11145
|
try {
|
|
11066
|
-
const parsed = JSON.parse(
|
|
11146
|
+
const parsed = JSON.parse(readFileSync30(filePath, "utf-8"));
|
|
11067
11147
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
11068
11148
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
11069
11149
|
return 0;
|
|
@@ -11337,15 +11417,15 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
11337
11417
|
}
|
|
11338
11418
|
|
|
11339
11419
|
// src/lib/restart-flags.ts
|
|
11340
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as
|
|
11341
|
-
import { homedir as
|
|
11342
|
-
import { join as
|
|
11420
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as readFileSync31, renameSync as renameSync10, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
|
|
11421
|
+
import { homedir as homedir17 } from "os";
|
|
11422
|
+
import { join as join40 } from "path";
|
|
11343
11423
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
11344
11424
|
function restartFlagsDir() {
|
|
11345
|
-
return
|
|
11425
|
+
return join40(homedir17(), ".augmented", "restart-flags");
|
|
11346
11426
|
}
|
|
11347
11427
|
function flagPath(codeName) {
|
|
11348
|
-
return
|
|
11428
|
+
return join40(restartFlagsDir(), `${codeName}.flag`);
|
|
11349
11429
|
}
|
|
11350
11430
|
function readRestartFlags() {
|
|
11351
11431
|
const dir = restartFlagsDir();
|
|
@@ -11354,7 +11434,7 @@ function readRestartFlags() {
|
|
|
11354
11434
|
for (const entry of readdirSync10(dir)) {
|
|
11355
11435
|
if (!entry.endsWith(".flag")) continue;
|
|
11356
11436
|
try {
|
|
11357
|
-
const raw =
|
|
11437
|
+
const raw = readFileSync31(join40(dir, entry), "utf8");
|
|
11358
11438
|
const parsed = JSON.parse(raw);
|
|
11359
11439
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
11360
11440
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -11472,8 +11552,8 @@ async function sendError(flag, opts, text) {
|
|
|
11472
11552
|
}
|
|
11473
11553
|
|
|
11474
11554
|
// src/lib/restart-context.ts
|
|
11475
|
-
import { readdirSync as readdirSync11, readFileSync as
|
|
11476
|
-
import { dirname as dirname10, join as
|
|
11555
|
+
import { readdirSync as readdirSync11, readFileSync as readFileSync32, writeFileSync as writeFileSync17, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "fs";
|
|
11556
|
+
import { dirname as dirname10, join as join41 } from "path";
|
|
11477
11557
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
11478
11558
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
11479
11559
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -11485,10 +11565,10 @@ function augmentedAgentDir(codeName) {
|
|
|
11485
11565
|
return dirname10(getProjectDir(codeName));
|
|
11486
11566
|
}
|
|
11487
11567
|
function slackPendingInboundDir(codeName) {
|
|
11488
|
-
return
|
|
11568
|
+
return join41(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
11489
11569
|
}
|
|
11490
11570
|
function slackRestartContextDir(codeName) {
|
|
11491
|
-
return
|
|
11571
|
+
return join41(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
11492
11572
|
}
|
|
11493
11573
|
function sanitizeTopic(raw) {
|
|
11494
11574
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -11530,7 +11610,7 @@ function safeReaddir(dir) {
|
|
|
11530
11610
|
}
|
|
11531
11611
|
function readStrandedMarker(path) {
|
|
11532
11612
|
try {
|
|
11533
|
-
const parsed = JSON.parse(
|
|
11613
|
+
const parsed = JSON.parse(readFileSync32(path, "utf-8"));
|
|
11534
11614
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
11535
11615
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
11536
11616
|
}
|
|
@@ -11548,7 +11628,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
11548
11628
|
if (!filename.endsWith(".json")) continue;
|
|
11549
11629
|
if (freshFilenames.has(filename)) continue;
|
|
11550
11630
|
try {
|
|
11551
|
-
unlinkSync5(
|
|
11631
|
+
unlinkSync5(join41(ctxDir, filename));
|
|
11552
11632
|
} catch {
|
|
11553
11633
|
}
|
|
11554
11634
|
}
|
|
@@ -11569,7 +11649,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
11569
11649
|
}
|
|
11570
11650
|
const markers = [];
|
|
11571
11651
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
11572
|
-
const parsed = readStrandedMarker(
|
|
11652
|
+
const parsed = readStrandedMarker(join41(markerDir, filename));
|
|
11573
11653
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
11574
11654
|
}
|
|
11575
11655
|
if (markers.length === 0) {
|
|
@@ -11583,7 +11663,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
11583
11663
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
11584
11664
|
for (const { filename, hint } of hints) {
|
|
11585
11665
|
try {
|
|
11586
|
-
writeHintFile(
|
|
11666
|
+
writeHintFile(join41(ctxDir, filename), ctxDir, hint);
|
|
11587
11667
|
freshFilenames.add(filename);
|
|
11588
11668
|
} catch (err) {
|
|
11589
11669
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -13053,7 +13133,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
13053
13133
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
13054
13134
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
13055
13135
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
13056
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
13136
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-3M3556MN.js");
|
|
13057
13137
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
13058
13138
|
if (newest === null) return null;
|
|
13059
13139
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -13094,6 +13174,7 @@ function decideDayRolloverAction(i) {
|
|
|
13094
13174
|
if (age !== null && age !== void 0 && age < graceSec && heldMin < maxHoldMin) {
|
|
13095
13175
|
return "inbound-wait";
|
|
13096
13176
|
}
|
|
13177
|
+
if (i.deviceStateReady === false) return "defer-device-state";
|
|
13097
13178
|
return "force-reset";
|
|
13098
13179
|
}
|
|
13099
13180
|
function classifyLazyDayRolloverReset(i) {
|
|
@@ -13101,7 +13182,19 @@ function classifyLazyDayRolloverReset(i) {
|
|
|
13101
13182
|
if (!i.sessionHealthy) return "clear-stale";
|
|
13102
13183
|
if (!i.staleForToday) return "clear-stale";
|
|
13103
13184
|
if (!i.hasCurrent) return "skip";
|
|
13104
|
-
|
|
13185
|
+
if (!i.idle) return "skip";
|
|
13186
|
+
return i.deviceStateReady === false ? "defer-device-state" : "reset";
|
|
13187
|
+
}
|
|
13188
|
+
var deviceStateRotationGate = new DeviceStateRotationGate();
|
|
13189
|
+
function deviceStateAllowsRollover(codeName, path) {
|
|
13190
|
+
const gate = deviceStateRotationGate.mayRotate(codeName, Date.now());
|
|
13191
|
+
if (gate.ready) return true;
|
|
13192
|
+
if (gate.firstHold) {
|
|
13193
|
+
log(
|
|
13194
|
+
`[persistent-session] Day rollover for '${codeName}' HELD (${path}) \u2014 the host's ~/.claude.json is not usable (${gate.reason}), so a fresh session would land on the login picker. Keeping the working session; the rotation runs the first tick the file is usable again. Pair the host from the Hosts page. (further holds this episode are not logged) [ENG-10351]`
|
|
13195
|
+
);
|
|
13196
|
+
}
|
|
13197
|
+
return false;
|
|
13105
13198
|
}
|
|
13106
13199
|
function resolveEffectiveAgentTimezone(inputs) {
|
|
13107
13200
|
const orgTierTz = cachedMaintenanceWindow?.timezone ?? null;
|
|
@@ -13130,18 +13223,22 @@ function performLazyDayRolloverReset(codeName, agentTimezone) {
|
|
|
13130
13223
|
const sessionHealthy = flagged && isSessionHealthy(codeName);
|
|
13131
13224
|
const staleForToday = flagged ? isStaleForToday(codeName, /* @__PURE__ */ new Date(), agentTimezone ?? void 0) : false;
|
|
13132
13225
|
const current = flagged && sessionHealthy && staleForToday ? peekCurrentSession(codeName) : null;
|
|
13133
|
-
const
|
|
13226
|
+
const lazyInputs = {
|
|
13134
13227
|
flagged,
|
|
13135
13228
|
staleForToday,
|
|
13136
13229
|
sessionHealthy,
|
|
13137
13230
|
hasCurrent: current !== null,
|
|
13138
13231
|
idle: current ? isAgentIdle(getProjectDir(codeName), current.sessionId) : false
|
|
13139
|
-
}
|
|
13232
|
+
};
|
|
13233
|
+
let outcome = classifyLazyDayRolloverReset(lazyInputs);
|
|
13234
|
+
if (outcome === "reset" && !deviceStateAllowsRollover(codeName, "lazy-reset")) {
|
|
13235
|
+
outcome = classifyLazyDayRolloverReset({ ...lazyInputs, deviceStateReady: false });
|
|
13236
|
+
}
|
|
13140
13237
|
if (outcome === "clear-stale") {
|
|
13141
13238
|
pendingDayRolloverReset.delete(codeName);
|
|
13142
13239
|
return false;
|
|
13143
13240
|
}
|
|
13144
|
-
if (outcome
|
|
13241
|
+
if (outcome !== "reset" || !current) return false;
|
|
13145
13242
|
log(
|
|
13146
13243
|
`[persistent-session] Day rollover for '${codeName}' (yesterday=${current.date}) \u2014 first real trigger after an idle rollover; minting a fresh session now (deferred boot, paid alongside real work) [ENG-8461]`
|
|
13147
13244
|
);
|
|
@@ -13153,7 +13250,7 @@ function performLazyDayRolloverReset(codeName, agentTimezone) {
|
|
|
13153
13250
|
}
|
|
13154
13251
|
function paneLogAgeSecondsFor(codeName) {
|
|
13155
13252
|
try {
|
|
13156
|
-
const mtimeMs =
|
|
13253
|
+
const mtimeMs = statSync12(paneLogPath(codeName)).mtimeMs;
|
|
13157
13254
|
return Math.max(0, Math.floor((Date.now() - mtimeMs) / 1e3));
|
|
13158
13255
|
} catch (err) {
|
|
13159
13256
|
if (err?.code === "ENOENT") return null;
|
|
@@ -13303,7 +13400,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
13303
13400
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
13304
13401
|
function projectMcpHash(_codeName, projectDir) {
|
|
13305
13402
|
try {
|
|
13306
|
-
const raw =
|
|
13403
|
+
const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
|
|
13307
13404
|
return createHash20("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
13308
13405
|
} catch {
|
|
13309
13406
|
return null;
|
|
@@ -13311,7 +13408,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
13311
13408
|
}
|
|
13312
13409
|
function projectMcpKeys(_codeName, projectDir) {
|
|
13313
13410
|
try {
|
|
13314
|
-
const raw =
|
|
13411
|
+
const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
|
|
13315
13412
|
const parsed = JSON.parse(raw);
|
|
13316
13413
|
const servers = parsed.mcpServers;
|
|
13317
13414
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -13329,7 +13426,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
13329
13426
|
else runningMcpServerKeys.delete(codeName);
|
|
13330
13427
|
let launchStructure = null;
|
|
13331
13428
|
try {
|
|
13332
|
-
const raw =
|
|
13429
|
+
const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
|
|
13333
13430
|
launchStructure = managedMcpStructureHashFromFile(
|
|
13334
13431
|
JSON.parse(raw),
|
|
13335
13432
|
isManagedMcpServerKey
|
|
@@ -13464,7 +13561,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
13464
13561
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
13465
13562
|
let mcpJsonForRebind = null;
|
|
13466
13563
|
try {
|
|
13467
|
-
mcpJsonForRebind = JSON.parse(
|
|
13564
|
+
mcpJsonForRebind = JSON.parse(readFileSync33(join42(projectDir, ".mcp.json"), "utf-8"));
|
|
13468
13565
|
} catch {
|
|
13469
13566
|
mcpJsonForRebind = null;
|
|
13470
13567
|
}
|
|
@@ -13612,7 +13709,7 @@ function shouldInjectChannelSecrets(agentId) {
|
|
|
13612
13709
|
function projectChannelSecretHash(projectDir) {
|
|
13613
13710
|
try {
|
|
13614
13711
|
const entries = parseEnvIntegrations(
|
|
13615
|
-
|
|
13712
|
+
readFileSync33(join42(projectDir, ".env.integrations"), "utf-8")
|
|
13616
13713
|
);
|
|
13617
13714
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
13618
13715
|
} catch {
|
|
@@ -13721,7 +13818,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
13721
13818
|
var lastVersionCheckAt = 0;
|
|
13722
13819
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
13723
13820
|
var lastResponsivenessProbeAt = 0;
|
|
13724
|
-
var agtCliVersion = true ? "0.28.
|
|
13821
|
+
var agtCliVersion = true ? "0.28.909" : "dev";
|
|
13725
13822
|
function resolveBrewPath(execFileSync2) {
|
|
13726
13823
|
try {
|
|
13727
13824
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -14055,7 +14152,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
14055
14152
|
try {
|
|
14056
14153
|
let settings = {};
|
|
14057
14154
|
if (existsSync19(path)) {
|
|
14058
|
-
const raw =
|
|
14155
|
+
const raw = readFileSync33(path, "utf-8").trim();
|
|
14059
14156
|
if (raw) {
|
|
14060
14157
|
let parsed;
|
|
14061
14158
|
try {
|
|
@@ -14111,7 +14208,7 @@ async function ensureOpencodeBinary() {
|
|
|
14111
14208
|
try {
|
|
14112
14209
|
const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
14113
14210
|
if (prefix) {
|
|
14114
|
-
const npmBin =
|
|
14211
|
+
const npmBin = join42(prefix, "bin");
|
|
14115
14212
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
14116
14213
|
if (!current.includes(npmBin)) {
|
|
14117
14214
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -14251,7 +14348,7 @@ async function maybeUpgradeClaudeCode() {
|
|
|
14251
14348
|
}
|
|
14252
14349
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
14253
14350
|
function selfUpdateAppliedMarkerPath() {
|
|
14254
|
-
return
|
|
14351
|
+
return join42(homedir18(), ".augmented", ".last-self-update-applied");
|
|
14255
14352
|
}
|
|
14256
14353
|
var selfUpdateUpToDateLogged = false;
|
|
14257
14354
|
var selfUpdatePinnedLogged = false;
|
|
@@ -14302,7 +14399,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
14302
14399
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
14303
14400
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
14304
14401
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
14305
|
-
const markerPath =
|
|
14402
|
+
const markerPath = join42(homedir18(), ".augmented", ".last-update-check");
|
|
14306
14403
|
if (!force) {
|
|
14307
14404
|
try {
|
|
14308
14405
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -14709,7 +14806,7 @@ async function runClaudeRuntimeAuthProbe() {
|
|
|
14709
14806
|
];
|
|
14710
14807
|
try {
|
|
14711
14808
|
const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
14712
|
-
cwd:
|
|
14809
|
+
cwd: homedir18(),
|
|
14713
14810
|
timeout: RUNTIME_AUTH_PROBE_TIMEOUT_MS,
|
|
14714
14811
|
stdin: "ignore",
|
|
14715
14812
|
env: childEnv,
|
|
@@ -14749,7 +14846,7 @@ async function runHostUsageCommand() {
|
|
|
14749
14846
|
""
|
|
14750
14847
|
];
|
|
14751
14848
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
14752
|
-
cwd:
|
|
14849
|
+
cwd: homedir18(),
|
|
14753
14850
|
timeout: HOST_USAGE_POLL_TIMEOUT_MS,
|
|
14754
14851
|
stdin: "ignore",
|
|
14755
14852
|
env: childEnv,
|
|
@@ -14796,12 +14893,12 @@ async function checkClaudeAuth() {
|
|
|
14796
14893
|
var evalEmptyMcpConfigPath = null;
|
|
14797
14894
|
function ensureEvalEmptyMcpConfig() {
|
|
14798
14895
|
if (evalEmptyMcpConfigPath && existsSync19(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
14799
|
-
const dir =
|
|
14896
|
+
const dir = join42(homedir18(), ".augmented");
|
|
14800
14897
|
try {
|
|
14801
14898
|
mkdirSync15(dir, { recursive: true });
|
|
14802
14899
|
} catch {
|
|
14803
14900
|
}
|
|
14804
|
-
const p =
|
|
14901
|
+
const p = join42(dir, ".eval-empty-mcp.json");
|
|
14805
14902
|
writeFileSync18(p, JSON.stringify({ mcpServers: {} }));
|
|
14806
14903
|
evalEmptyMcpConfigPath = p;
|
|
14807
14904
|
return p;
|
|
@@ -14827,7 +14924,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
14827
14924
|
""
|
|
14828
14925
|
];
|
|
14829
14926
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
14830
|
-
cwd:
|
|
14927
|
+
cwd: homedir18(),
|
|
14831
14928
|
timeout: 12e4,
|
|
14832
14929
|
stdin: "ignore",
|
|
14833
14930
|
env: childEnv,
|
|
@@ -14896,10 +14993,10 @@ function resolveConversationEvalBackend() {
|
|
|
14896
14993
|
return conversationEvalBackend;
|
|
14897
14994
|
}
|
|
14898
14995
|
function getStateFile() {
|
|
14899
|
-
return
|
|
14996
|
+
return join42(config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
14900
14997
|
}
|
|
14901
14998
|
function channelHashCacheDir() {
|
|
14902
|
-
return config?.configDir ??
|
|
14999
|
+
return config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
14903
15000
|
}
|
|
14904
15001
|
function loadChannelHashCache2() {
|
|
14905
15002
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -15112,7 +15209,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
15112
15209
|
var _channelQuarantineStore = null;
|
|
15113
15210
|
function channelQuarantineStore() {
|
|
15114
15211
|
if (!_channelQuarantineStore) {
|
|
15115
|
-
const dir = config?.configDir ??
|
|
15212
|
+
const dir = config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
15116
15213
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
15117
15214
|
}
|
|
15118
15215
|
return _channelQuarantineStore;
|
|
@@ -15128,12 +15225,12 @@ function claudeMdSizeFor(codeName) {
|
|
|
15128
15225
|
}
|
|
15129
15226
|
function forwardedToolsFor(codeName) {
|
|
15130
15227
|
if (!config?.configDir) return null;
|
|
15131
|
-
return readForwardedToolsReport(
|
|
15228
|
+
return readForwardedToolsReport(join42(config.configDir, codeName));
|
|
15132
15229
|
}
|
|
15133
15230
|
var _hostFlagStore = null;
|
|
15134
15231
|
function hostFlagStore() {
|
|
15135
15232
|
if (!_hostFlagStore) {
|
|
15136
|
-
const dir = config?.configDir ??
|
|
15233
|
+
const dir = config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
15137
15234
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
15138
15235
|
}
|
|
15139
15236
|
return _hostFlagStore;
|
|
@@ -15207,12 +15304,12 @@ function parseSkillFrontmatter(content) {
|
|
|
15207
15304
|
}
|
|
15208
15305
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
15209
15306
|
const { readdirSync: readdirSync13, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync19 } = await import("fs");
|
|
15210
|
-
const skillsDir =
|
|
15211
|
-
const claudeMdPath =
|
|
15307
|
+
const skillsDir = join42(configDir, codeName, "project", ".claude", "skills");
|
|
15308
|
+
const claudeMdPath = join42(configDir, codeName, "project", "CLAUDE.md");
|
|
15212
15309
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
15213
15310
|
const entries = [];
|
|
15214
15311
|
for (const dir of readdirSync13(skillsDir).sort()) {
|
|
15215
|
-
const skillFile =
|
|
15312
|
+
const skillFile = join42(skillsDir, dir, "SKILL.md");
|
|
15216
15313
|
if (!ex(skillFile)) continue;
|
|
15217
15314
|
try {
|
|
15218
15315
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -15311,7 +15408,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
15311
15408
|
if (codeNames.length === 0) return;
|
|
15312
15409
|
void (async () => {
|
|
15313
15410
|
try {
|
|
15314
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15411
|
+
const { collectDiagnostics } = await import("../persistent-session-A2IB5WGW.js");
|
|
15315
15412
|
await api.post("/host/heartbeat", {
|
|
15316
15413
|
host_id: hostId,
|
|
15317
15414
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -15453,7 +15550,7 @@ async function pollCycleInner() {
|
|
|
15453
15550
|
}
|
|
15454
15551
|
try {
|
|
15455
15552
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
15456
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15553
|
+
const { collectDiagnostics } = await import("../persistent-session-A2IB5WGW.js");
|
|
15457
15554
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
15458
15555
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
15459
15556
|
let tailscaleHostname;
|
|
@@ -15570,6 +15667,12 @@ async function pollCycleInner() {
|
|
|
15570
15667
|
// customer agents had been dark for three minutes. Bounding the retry
|
|
15571
15668
|
// without this would fix the CPU and leave the blindness.
|
|
15572
15669
|
realtime_rebind_stuck: stuckRealtimeRebinds(realtimeRebindFailures, Date.now()),
|
|
15670
|
+
// ENG-10351: ONE host-level verdict for rotations held because the
|
|
15671
|
+
// host's ~/.claude.json is not usable. ALWAYS sent: `null` is the
|
|
15672
|
+
// affirmative all-clear that lets the API close the alert on the edge,
|
|
15673
|
+
// and an absent field means an older CLI. Re-checks the file while a
|
|
15674
|
+
// hold exists, so pairing the host closes the alert on the next beat.
|
|
15675
|
+
claude_device_state_rotation_blocked: deviceStateRotationGate.heartbeatField(),
|
|
15573
15676
|
// ENG-6251: capability advertisement — the flags schema version this
|
|
15574
15677
|
// CLI compiled with, so the admin UI can show flip reach across a
|
|
15575
15678
|
// mixed-CLI fleet (an older CLI sends an older fingerprint).
|
|
@@ -15622,7 +15725,7 @@ async function pollCycleInner() {
|
|
|
15622
15725
|
collectPanelessActivityProbes,
|
|
15623
15726
|
getResponsivenessIntervalMs,
|
|
15624
15727
|
occupancyQualificationClassifications
|
|
15625
|
-
} = await import("../responsiveness-probe-
|
|
15728
|
+
} = await import("../responsiveness-probe-3M3556MN.js");
|
|
15626
15729
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
15627
15730
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
15628
15731
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -15739,7 +15842,7 @@ async function pollCycleInner() {
|
|
|
15739
15842
|
collectResponsivenessProbes,
|
|
15740
15843
|
livePendingInboundOldestAgeSeconds,
|
|
15741
15844
|
parkPendingInbound
|
|
15742
|
-
} = await import("../responsiveness-probe-
|
|
15845
|
+
} = await import("../responsiveness-probe-3M3556MN.js");
|
|
15743
15846
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
15744
15847
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
15745
15848
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -15828,13 +15931,13 @@ async function pollCycleInner() {
|
|
|
15828
15931
|
);
|
|
15829
15932
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
15830
15933
|
try {
|
|
15831
|
-
const paneTail =
|
|
15934
|
+
const paneTail = readFileSync33(paneLogPath(codeName), "utf8").slice(-65536);
|
|
15832
15935
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
15833
15936
|
if (transient) {
|
|
15834
|
-
const wedgeHome =
|
|
15937
|
+
const wedgeHome = join42(homedir18(), ".augmented", codeName);
|
|
15835
15938
|
if (existsSync19(wedgeHome)) {
|
|
15836
15939
|
atomicWriteFileSync(
|
|
15837
|
-
|
|
15940
|
+
join42(wedgeHome, "watchdog-give-up.json"),
|
|
15838
15941
|
JSON.stringify({
|
|
15839
15942
|
gave_up_at: wedgeNow.toISOString(),
|
|
15840
15943
|
reason: "transient_overload"
|
|
@@ -15895,7 +15998,7 @@ async function pollCycleInner() {
|
|
|
15895
15998
|
}
|
|
15896
15999
|
try {
|
|
15897
16000
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
|
|
15898
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
16001
|
+
const { probeSessionAuth } = await import("../session-auth-dead-MRZ3A2N5.js");
|
|
15899
16002
|
const observations = [];
|
|
15900
16003
|
const pendingCacheCommits = [];
|
|
15901
16004
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -16169,7 +16272,7 @@ async function pollCycleInner() {
|
|
|
16169
16272
|
`[drain-flush] FAILED for '${prev.codeName}': ${err.message} \u2014 proceeding to teardown; this session was NOT shipped (ENG-9491)`
|
|
16170
16273
|
);
|
|
16171
16274
|
}
|
|
16172
|
-
const agentDir =
|
|
16275
|
+
const agentDir = join42(adapter.getAgentDir(prev.codeName), "provision");
|
|
16173
16276
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
16174
16277
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
16175
16278
|
}
|
|
@@ -16256,10 +16359,10 @@ async function pollCycleInner() {
|
|
|
16256
16359
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
16257
16360
|
// the watchdog, never fails the poll cycle.
|
|
16258
16361
|
signalGiveUp: (codeName) => {
|
|
16259
|
-
const dir =
|
|
16362
|
+
const dir = join42(homedir18(), ".augmented", codeName);
|
|
16260
16363
|
if (!existsSync19(dir)) return;
|
|
16261
16364
|
atomicWriteFileSync(
|
|
16262
|
-
|
|
16365
|
+
join42(dir, "watchdog-give-up.json"),
|
|
16263
16366
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
16264
16367
|
);
|
|
16265
16368
|
},
|
|
@@ -16280,7 +16383,7 @@ async function pollCycleInner() {
|
|
|
16280
16383
|
const dir = getFramework("claude-code").getAgentDir(codeName);
|
|
16281
16384
|
if (!existsSync19(dir)) return;
|
|
16282
16385
|
atomicWriteFileSync(
|
|
16283
|
-
|
|
16386
|
+
join42(dir, "watchdog-give-up.json"),
|
|
16284
16387
|
JSON.stringify({
|
|
16285
16388
|
gave_up_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16286
16389
|
reason: "usage_limit",
|
|
@@ -16548,7 +16651,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16548
16651
|
}
|
|
16549
16652
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
16550
16653
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
16551
|
-
let agentDir =
|
|
16654
|
+
let agentDir = join42(adapter.getAgentDir(agent.code_name), "provision");
|
|
16552
16655
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
16553
16656
|
forgetChannelSyncState(agent.agent_id);
|
|
16554
16657
|
if (previousKnownStatus !== agent.status) {
|
|
@@ -16695,7 +16798,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16695
16798
|
if (refreshData.knowledge_manifest) {
|
|
16696
16799
|
const resolved = await resolveKnowledgeFromManifest({
|
|
16697
16800
|
manifest: refreshData.knowledge_manifest,
|
|
16698
|
-
cacheDir:
|
|
16801
|
+
cacheDir: join42(config.configDir, "_knowledge"),
|
|
16699
16802
|
delivery: refreshData.agent?.knowledge_delivery ?? "both",
|
|
16700
16803
|
fetchContents: async (hashes) => {
|
|
16701
16804
|
const res = await api.post(
|
|
@@ -16712,7 +16815,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16712
16815
|
const resolvedSkills = await resolveSkillsFromManifest({
|
|
16713
16816
|
globals: refreshData.global_skills_manifest ?? [],
|
|
16714
16817
|
shared: refreshData.shared_skills_manifest ?? [],
|
|
16715
|
-
cacheDir:
|
|
16818
|
+
cacheDir: join42(config.configDir, "_skills"),
|
|
16716
16819
|
fetchContents: async (hashes) => {
|
|
16717
16820
|
const res = await api.post(
|
|
16718
16821
|
"/host/skills/contents",
|
|
@@ -16730,7 +16833,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16730
16833
|
if (refreshData.integration_skills_manifest) {
|
|
16731
16834
|
const resolvedIntegrationSkills = await resolveIntegrationSkillsFromManifest({
|
|
16732
16835
|
manifest: refreshData.integration_skills_manifest,
|
|
16733
|
-
cacheDir:
|
|
16836
|
+
cacheDir: join42(config.configDir, "_skills"),
|
|
16734
16837
|
fetchContents: async (hashes) => {
|
|
16735
16838
|
const res = await api.post(
|
|
16736
16839
|
"/host/skills/contents",
|
|
@@ -16792,7 +16895,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16792
16895
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
16793
16896
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
16794
16897
|
const frameworkAdapter = getFramework(frameworkId);
|
|
16795
|
-
agentDir =
|
|
16898
|
+
agentDir = join42(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
16796
16899
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
16797
16900
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
16798
16901
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -16851,7 +16954,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16851
16954
|
const changedFiles = [];
|
|
16852
16955
|
mkdirSync15(agentDir, { recursive: true });
|
|
16853
16956
|
for (const artifact of artifacts) {
|
|
16854
|
-
const filePath =
|
|
16957
|
+
const filePath = join42(agentDir, artifact.relativePath);
|
|
16855
16958
|
let existingHash;
|
|
16856
16959
|
let newHash;
|
|
16857
16960
|
let writeContent = artifact.content;
|
|
@@ -16870,8 +16973,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16870
16973
|
};
|
|
16871
16974
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
16872
16975
|
try {
|
|
16873
|
-
const projectClaudeMd =
|
|
16874
|
-
const existing =
|
|
16976
|
+
const projectClaudeMd = join42(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
16977
|
+
const existing = readFileSync33(projectClaudeMd, "utf-8");
|
|
16875
16978
|
existingHash = sha256(stripDynamicSections(existing));
|
|
16876
16979
|
} catch {
|
|
16877
16980
|
existingHash = null;
|
|
@@ -16889,7 +16992,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16889
16992
|
const generatorKeys = Object.keys(generatorServers);
|
|
16890
16993
|
let existingRaw = "";
|
|
16891
16994
|
try {
|
|
16892
|
-
existingRaw =
|
|
16995
|
+
existingRaw = readFileSync33(filePath, "utf-8");
|
|
16893
16996
|
} catch {
|
|
16894
16997
|
}
|
|
16895
16998
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -16905,7 +17008,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16905
17008
|
} else if (artifact.relativePath === "opencode.json") {
|
|
16906
17009
|
let existingRaw = null;
|
|
16907
17010
|
try {
|
|
16908
|
-
existingRaw =
|
|
17011
|
+
existingRaw = readFileSync33(filePath, "utf-8");
|
|
16909
17012
|
} catch {
|
|
16910
17013
|
}
|
|
16911
17014
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -16921,12 +17024,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16921
17024
|
}
|
|
16922
17025
|
}
|
|
16923
17026
|
if (changedFiles.length > 0) {
|
|
16924
|
-
const isFirst = !existsSync19(
|
|
17027
|
+
const isFirst = !existsSync19(join42(agentDir, "CHARTER.md"));
|
|
16925
17028
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
16926
17029
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
16927
17030
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
16928
17031
|
for (const file of changedFiles) {
|
|
16929
|
-
const filePath =
|
|
17032
|
+
const filePath = join42(agentDir, file.relativePath);
|
|
16930
17033
|
mkdirSync15(dirname11(filePath), { recursive: true });
|
|
16931
17034
|
if (file.relativePath === ".mcp.json") {
|
|
16932
17035
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -16935,12 +17038,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16935
17038
|
}
|
|
16936
17039
|
}
|
|
16937
17040
|
try {
|
|
16938
|
-
const provSkillsDir =
|
|
17041
|
+
const provSkillsDir = join42(agentDir, ".claude", "skills");
|
|
16939
17042
|
if (existsSync19(provSkillsDir)) {
|
|
16940
17043
|
for (const folder of readdirSync12(provSkillsDir)) {
|
|
16941
17044
|
if (folder.startsWith("knowledge-")) {
|
|
16942
17045
|
try {
|
|
16943
|
-
rmSync8(
|
|
17046
|
+
rmSync8(join42(provSkillsDir, folder), { recursive: true });
|
|
16944
17047
|
} catch {
|
|
16945
17048
|
}
|
|
16946
17049
|
}
|
|
@@ -16953,7 +17056,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16953
17056
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
16954
17057
|
const hashes = /* @__PURE__ */ new Map();
|
|
16955
17058
|
for (const file of trackedFiles2) {
|
|
16956
|
-
const h = hashFile(
|
|
17059
|
+
const h = hashFile(join42(agentDir, file));
|
|
16957
17060
|
if (h) hashes.set(file, h);
|
|
16958
17061
|
}
|
|
16959
17062
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -16971,14 +17074,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16971
17074
|
}
|
|
16972
17075
|
if (Array.isArray(refreshData.workflows)) {
|
|
16973
17076
|
try {
|
|
16974
|
-
const provWorkflowsDir =
|
|
17077
|
+
const provWorkflowsDir = join42(agentDir, ".claude", "workflows");
|
|
16975
17078
|
if (existsSync19(provWorkflowsDir)) {
|
|
16976
17079
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
16977
17080
|
for (const file of readdirSync12(provWorkflowsDir)) {
|
|
16978
17081
|
if (!file.endsWith(".js")) continue;
|
|
16979
17082
|
if (expected.has(file)) continue;
|
|
16980
17083
|
try {
|
|
16981
|
-
rmSync8(
|
|
17084
|
+
rmSync8(join42(provWorkflowsDir, file));
|
|
16982
17085
|
} catch {
|
|
16983
17086
|
}
|
|
16984
17087
|
}
|
|
@@ -17060,7 +17163,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17060
17163
|
if (written && existsSync19(agentDir)) {
|
|
17061
17164
|
const driftedFiles = [];
|
|
17062
17165
|
for (const [file, expectedHash] of written) {
|
|
17063
|
-
const localHash = hashFile(
|
|
17166
|
+
const localHash = hashFile(join42(agentDir, file));
|
|
17064
17167
|
if (localHash && localHash !== expectedHash) {
|
|
17065
17168
|
driftedFiles.push(file);
|
|
17066
17169
|
}
|
|
@@ -17071,7 +17174,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17071
17174
|
try {
|
|
17072
17175
|
const localHashes = {};
|
|
17073
17176
|
for (const file of driftedFiles) {
|
|
17074
|
-
localHashes[file] = hashFile(
|
|
17177
|
+
localHashes[file] = hashFile(join42(agentDir, file));
|
|
17075
17178
|
}
|
|
17076
17179
|
await api.post("/host/drift", {
|
|
17077
17180
|
agent_id: agent.agent_id,
|
|
@@ -17349,7 +17452,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17349
17452
|
const addedChannels = [...restartDecision.added];
|
|
17350
17453
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
17351
17454
|
try {
|
|
17352
|
-
const agentAugmentedDir =
|
|
17455
|
+
const agentAugmentedDir = join42(homedir18(), ".augmented", agent.code_name);
|
|
17353
17456
|
mkdirSync15(agentAugmentedDir, { recursive: true });
|
|
17354
17457
|
const markerJson = JSON.stringify({
|
|
17355
17458
|
version: 1,
|
|
@@ -17357,7 +17460,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17357
17460
|
added: addedChannels
|
|
17358
17461
|
});
|
|
17359
17462
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
17360
|
-
atomicWriteFileSync(
|
|
17463
|
+
atomicWriteFileSync(join42(agentAugmentedDir, file), markerJson);
|
|
17361
17464
|
}
|
|
17362
17465
|
} catch (err) {
|
|
17363
17466
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -17656,18 +17759,18 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17656
17759
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
17657
17760
|
try {
|
|
17658
17761
|
const agentProvisionDir = agentDir;
|
|
17659
|
-
const projectDir =
|
|
17762
|
+
const projectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
|
|
17660
17763
|
mkdirSync15(agentProvisionDir, { recursive: true });
|
|
17661
17764
|
mkdirSync15(projectDir, { recursive: true });
|
|
17662
|
-
const provisionMcpPath =
|
|
17663
|
-
const projectMcpPath =
|
|
17765
|
+
const provisionMcpPath = join42(agentProvisionDir, ".mcp.json");
|
|
17766
|
+
const projectMcpPath = join42(projectDir, ".mcp.json");
|
|
17664
17767
|
let mcpConfig = { mcpServers: {} };
|
|
17665
17768
|
try {
|
|
17666
|
-
mcpConfig = JSON.parse(
|
|
17769
|
+
mcpConfig = JSON.parse(readFileSync33(provisionMcpPath, "utf-8"));
|
|
17667
17770
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
17668
17771
|
} catch {
|
|
17669
17772
|
}
|
|
17670
|
-
const localDirectChatChannel =
|
|
17773
|
+
const localDirectChatChannel = join42(homedir18(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
17671
17774
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
17672
17775
|
const directChatTz = (() => {
|
|
17673
17776
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -17693,7 +17796,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17693
17796
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
17694
17797
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
17695
17798
|
// so it byte-matches the broker readers' path.
|
|
17696
|
-
AGT_TURN_INITIATOR_FILE:
|
|
17799
|
+
AGT_TURN_INITIATOR_FILE: join42(
|
|
17697
17800
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
17698
17801
|
".current-turn-initiator.json"
|
|
17699
17802
|
)
|
|
@@ -17713,7 +17816,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17713
17816
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
17714
17817
|
}
|
|
17715
17818
|
}
|
|
17716
|
-
const staleChannelsPath =
|
|
17819
|
+
const staleChannelsPath = join42(projectDir, ".mcp-channels.json");
|
|
17717
17820
|
if (existsSync19(staleChannelsPath)) {
|
|
17718
17821
|
try {
|
|
17719
17822
|
rmSync8(staleChannelsPath, { force: true });
|
|
@@ -17826,7 +17929,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17826
17929
|
}
|
|
17827
17930
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
17828
17931
|
try {
|
|
17829
|
-
const probeProjectDir =
|
|
17932
|
+
const probeProjectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
|
|
17830
17933
|
let probeSet = integrations;
|
|
17831
17934
|
const fetchQuarantined = async () => {
|
|
17832
17935
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -17886,7 +17989,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17886
17989
|
const forceDue = attemptsLeft > 0;
|
|
17887
17990
|
let probeRan = false;
|
|
17888
17991
|
try {
|
|
17889
|
-
const probeProjectDir =
|
|
17992
|
+
const probeProjectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
|
|
17890
17993
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
17891
17994
|
} catch (err) {
|
|
17892
17995
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -17963,11 +18066,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17963
18066
|
const intHash = computeIntegrationsHash(integrations);
|
|
17964
18067
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
17965
18068
|
if (intHash !== prevIntHash) {
|
|
17966
|
-
const projectDir =
|
|
17967
|
-
const envIntPath =
|
|
18069
|
+
const projectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
|
|
18070
|
+
const envIntPath = join42(projectDir, ".env.integrations");
|
|
17968
18071
|
let preWriteEnv;
|
|
17969
18072
|
try {
|
|
17970
|
-
preWriteEnv =
|
|
18073
|
+
preWriteEnv = readFileSync33(envIntPath, "utf-8");
|
|
17971
18074
|
} catch {
|
|
17972
18075
|
preWriteEnv = void 0;
|
|
17973
18076
|
}
|
|
@@ -17986,9 +18089,9 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17986
18089
|
}
|
|
17987
18090
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
17988
18091
|
try {
|
|
17989
|
-
const projectMcpPath =
|
|
17990
|
-
const postWriteEnv =
|
|
17991
|
-
const mcpContent =
|
|
18092
|
+
const projectMcpPath = join42(projectDir, ".mcp.json");
|
|
18093
|
+
const postWriteEnv = readFileSync33(envIntPath, "utf-8");
|
|
18094
|
+
const mcpContent = readFileSync33(projectMcpPath, "utf-8");
|
|
17992
18095
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
17993
18096
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
17994
18097
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -18287,16 +18390,16 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18287
18390
|
}
|
|
18288
18391
|
try {
|
|
18289
18392
|
const { readdirSync: readdirSync13, rmSync: rmSync9 } = await import("fs");
|
|
18290
|
-
const { homedir:
|
|
18393
|
+
const { homedir: homedir19 } = await import("os");
|
|
18291
18394
|
const frameworkId2 = frameworkAdapter.id;
|
|
18292
18395
|
const candidateSkillDirs = [
|
|
18293
18396
|
// Claude Code — framework runtime tree
|
|
18294
|
-
|
|
18397
|
+
join42(homedir19(), ".augmented", agent.code_name, "skills"),
|
|
18295
18398
|
// Claude Code — project tree
|
|
18296
|
-
|
|
18399
|
+
join42(homedir19(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
18297
18400
|
// Defensive: legacy provision-side path, not currently an
|
|
18298
18401
|
// install target but cheap to sweep.
|
|
18299
|
-
|
|
18402
|
+
join42(agentDir, ".claude", "skills")
|
|
18300
18403
|
];
|
|
18301
18404
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync19(d));
|
|
18302
18405
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
@@ -18339,7 +18442,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18339
18442
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
18340
18443
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
18341
18444
|
const manifestPath = managedSkillManifestPath(
|
|
18342
|
-
|
|
18445
|
+
join42(homedir18(), ".augmented", agent.code_name)
|
|
18343
18446
|
);
|
|
18344
18447
|
const prevIds = /* @__PURE__ */ new Set([
|
|
18345
18448
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -18359,15 +18462,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18359
18462
|
}
|
|
18360
18463
|
if (plan.removes.length) {
|
|
18361
18464
|
const globalSkillDirs = [
|
|
18362
|
-
|
|
18363
|
-
|
|
18364
|
-
|
|
18465
|
+
join42(homedir18(), ".augmented", agent.code_name, "skills"),
|
|
18466
|
+
join42(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
18467
|
+
join42(agentDir, ".claude", "skills")
|
|
18365
18468
|
];
|
|
18366
18469
|
for (const id of plan.removes) {
|
|
18367
18470
|
let prunedAny = false;
|
|
18368
18471
|
for (const dir of globalSkillDirs) {
|
|
18369
|
-
const p =
|
|
18370
|
-
if (existsSync19(p) && existsSync19(
|
|
18472
|
+
const p = join42(dir, id);
|
|
18473
|
+
if (existsSync19(p) && existsSync19(join42(p, "SKILL.md"))) {
|
|
18371
18474
|
rmSync8(p, { recursive: true, force: true });
|
|
18372
18475
|
prunedAny = true;
|
|
18373
18476
|
}
|
|
@@ -18623,8 +18726,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18623
18726
|
const sess = getSessionState(agent.code_name);
|
|
18624
18727
|
let mcpJsonParsed = null;
|
|
18625
18728
|
try {
|
|
18626
|
-
const mcpPath =
|
|
18627
|
-
mcpJsonParsed = JSON.parse(
|
|
18729
|
+
const mcpPath = join42(getProjectDir(agent.code_name), ".mcp.json");
|
|
18730
|
+
mcpJsonParsed = JSON.parse(readFileSync33(mcpPath, "utf-8"));
|
|
18628
18731
|
} catch {
|
|
18629
18732
|
}
|
|
18630
18733
|
const computerUseIsolated = isolationMode(agent.code_name) === "docker";
|
|
@@ -19116,7 +19219,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
19116
19219
|
if (trackedFiles.length > 0 && existsSync19(agentDir)) {
|
|
19117
19220
|
const hashes = /* @__PURE__ */ new Map();
|
|
19118
19221
|
for (const file of trackedFiles) {
|
|
19119
|
-
const h = hashFile(
|
|
19222
|
+
const h = hashFile(join42(agentDir, file));
|
|
19120
19223
|
if (h) hashes.set(file, h);
|
|
19121
19224
|
}
|
|
19122
19225
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -19131,7 +19234,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
19131
19234
|
refreshData.agent.onboarding_state
|
|
19132
19235
|
);
|
|
19133
19236
|
const obStep = obState.step;
|
|
19134
|
-
const markerPath =
|
|
19237
|
+
const markerPath = join42(homedir18(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
19135
19238
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
19136
19239
|
const obContactRaw = refreshData.agent.manager_last_contacted_at;
|
|
19137
19240
|
const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
|
|
@@ -19246,7 +19349,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
19246
19349
|
}
|
|
19247
19350
|
stopOpencodeSlackIngest(codeName, log);
|
|
19248
19351
|
stopOpencodeTelegramIngest(codeName, log);
|
|
19249
|
-
const opencodeProjectDir =
|
|
19352
|
+
const opencodeProjectDir = join42(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
19250
19353
|
const serveEnv = {
|
|
19251
19354
|
AGT_HOST: requireHost(),
|
|
19252
19355
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -19306,8 +19409,8 @@ async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refres
|
|
|
19306
19409
|
});
|
|
19307
19410
|
}
|
|
19308
19411
|
const projectDir = getProjectDir(codeName);
|
|
19309
|
-
const mcpConfigPath =
|
|
19310
|
-
const claudeMdPath =
|
|
19412
|
+
const mcpConfigPath = join42(projectDir, ".mcp.json");
|
|
19413
|
+
const claudeMdPath = join42(projectDir, "CLAUDE.md");
|
|
19311
19414
|
if (restartBreaker.isTripped(codeName)) {
|
|
19312
19415
|
const trip = restartBreaker.getTrip(codeName);
|
|
19313
19416
|
return {
|
|
@@ -19544,7 +19647,7 @@ async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refres
|
|
|
19544
19647
|
const overdueMin = rolloverCurrent ? minutesSinceLocalMidnight(/* @__PURE__ */ new Date(), agentTimezone) : 0;
|
|
19545
19648
|
const rolloverMayForce = staleForToday && rolloverSessionHealthy && rolloverCurrent !== null && overdueMin >= DAY_ROLLOVER_FORCE_GRACE_MIN;
|
|
19546
19649
|
const rolloverInboundAgeSec = rolloverMayForce ? await channelInboundActivityAgeSecondsFor(codeName) : null;
|
|
19547
|
-
const
|
|
19650
|
+
const rolloverInputs = {
|
|
19548
19651
|
staleForToday,
|
|
19549
19652
|
sessionHealthy: rolloverSessionHealthy,
|
|
19550
19653
|
hasCurrent: rolloverCurrent !== null,
|
|
@@ -19555,7 +19658,11 @@ async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refres
|
|
|
19555
19658
|
inboundGraceSec: DAY_ROLLOVER_INBOUND_GRACE_SEC,
|
|
19556
19659
|
inboundDeferredMin: inboundHeldMinutesFor(codeName),
|
|
19557
19660
|
inboundDeferMaxMin: DAY_ROLLOVER_INBOUND_DEFER_MAX_MIN
|
|
19558
|
-
}
|
|
19661
|
+
};
|
|
19662
|
+
let rolloverDecision = decideDayRolloverAction(rolloverInputs);
|
|
19663
|
+
if (rolloverDecision === "force-reset" && !deviceStateAllowsRollover(codeName, "force-reset")) {
|
|
19664
|
+
rolloverDecision = decideDayRolloverAction({ ...rolloverInputs, deviceStateReady: false });
|
|
19665
|
+
}
|
|
19559
19666
|
if (rolloverDecision === "defer-idle" && rolloverCurrent) {
|
|
19560
19667
|
if (!pendingDayRolloverReset.has(codeName)) {
|
|
19561
19668
|
pendingDayRolloverReset.add(codeName);
|
|
@@ -19582,6 +19689,8 @@ async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refres
|
|
|
19582
19689
|
);
|
|
19583
19690
|
}
|
|
19584
19691
|
dayRolloverDeferred = true;
|
|
19692
|
+
} else if (rolloverDecision === "defer-device-state" && rolloverCurrent) {
|
|
19693
|
+
dayRolloverDeferred = true;
|
|
19585
19694
|
} else if (rolloverDecision === "busy-wait" && rolloverCurrent) {
|
|
19586
19695
|
log(
|
|
19587
19696
|
`[persistent-session] Day rollover for '${codeName}' deferred \u2014 agent still active on session ${rolloverCurrent.sessionId} (${overdueMin}m past boundary, will force at ${DAY_ROLLOVER_FORCE_GRACE_MIN}m)`
|
|
@@ -20153,7 +20262,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20153
20262
|
try {
|
|
20154
20263
|
const freshId = rotateSessionForWedge(codeName);
|
|
20155
20264
|
consecutiveWedgeCycles.delete(codeName);
|
|
20156
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
20265
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-3M3556MN.js");
|
|
20157
20266
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
20158
20267
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
20159
20268
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -20196,7 +20305,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20196
20305
|
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}`));
|
|
20197
20306
|
void (async () => {
|
|
20198
20307
|
try {
|
|
20199
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20308
|
+
const { collectDiagnostics } = await import("../persistent-session-A2IB5WGW.js");
|
|
20200
20309
|
await api.post("/host/heartbeat", {
|
|
20201
20310
|
host_id: hostId,
|
|
20202
20311
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -20247,7 +20356,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
20247
20356
|
}
|
|
20248
20357
|
try {
|
|
20249
20358
|
const hostId = await getHostId();
|
|
20250
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20359
|
+
const { collectDiagnostics } = await import("../persistent-session-A2IB5WGW.js");
|
|
20251
20360
|
await api.post("/host/heartbeat", {
|
|
20252
20361
|
host_id: hostId,
|
|
20253
20362
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -20653,7 +20762,7 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
20653
20762
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
20654
20763
|
if (useDoorbell) {
|
|
20655
20764
|
try {
|
|
20656
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
20765
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir18());
|
|
20657
20766
|
mkdirSync15(dirname11(doorbell), { recursive: true });
|
|
20658
20767
|
writeFileSync18(doorbell, String(Date.now()));
|
|
20659
20768
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
@@ -20782,7 +20891,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
20782
20891
|
}
|
|
20783
20892
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
20784
20893
|
try {
|
|
20785
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
20894
|
+
const doorbell = directChatDoorbellPath(agentId, homedir18());
|
|
20786
20895
|
mkdirSync15(dirname11(doorbell), { recursive: true });
|
|
20787
20896
|
writeFileSync18(doorbell, String(Date.now()));
|
|
20788
20897
|
} catch (err) {
|
|
@@ -20889,7 +20998,7 @@ async function processClaudePairSessions(agents) {
|
|
|
20889
20998
|
killPairSession,
|
|
20890
20999
|
pairTmuxSession,
|
|
20891
21000
|
finalizeClaudePairOnboarding
|
|
20892
|
-
} = await import("../claude-pair-runtime-
|
|
21001
|
+
} = await import("../claude-pair-runtime-UYWAQW3F.js");
|
|
20893
21002
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
20894
21003
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
20895
21004
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -21119,17 +21228,17 @@ var lastLocalFileHash = /* @__PURE__ */ new Map();
|
|
|
21119
21228
|
var lastMemoriesBody = /* @__PURE__ */ new Map();
|
|
21120
21229
|
var memoryManifests = /* @__PURE__ */ new Map();
|
|
21121
21230
|
function memoryRetirementDir(configDir, codeName) {
|
|
21122
|
-
return
|
|
21231
|
+
return join42(configDir, "_memory-retirement", codeName);
|
|
21123
21232
|
}
|
|
21124
21233
|
function memoryManifestPath(configDir, codeName) {
|
|
21125
|
-
return
|
|
21234
|
+
return join42(memoryRetirementDir(configDir, codeName), "manifest.json");
|
|
21126
21235
|
}
|
|
21127
21236
|
function loadMemoryManifest(agentId, configDir, codeName) {
|
|
21128
21237
|
const cached = memoryManifests.get(agentId);
|
|
21129
21238
|
if (cached) return cached;
|
|
21130
21239
|
let manifest = {};
|
|
21131
21240
|
try {
|
|
21132
|
-
const raw =
|
|
21241
|
+
const raw = readFileSync33(memoryManifestPath(configDir, codeName), "utf-8");
|
|
21133
21242
|
const parsed = JSON.parse(raw);
|
|
21134
21243
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
21135
21244
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -21157,7 +21266,7 @@ function saveMemoryManifest(agentId, configDir, codeName) {
|
|
|
21157
21266
|
}
|
|
21158
21267
|
}
|
|
21159
21268
|
function retiredMemoryDir(configDir, codeName) {
|
|
21160
|
-
return
|
|
21269
|
+
return join42(memoryRetirementDir(configDir, codeName), "retired");
|
|
21161
21270
|
}
|
|
21162
21271
|
var RETIRED_MEMORY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
21163
21272
|
var lastRetirementReport = /* @__PURE__ */ new Map();
|
|
@@ -21236,7 +21345,7 @@ function applyMemoryTombstones(opts) {
|
|
|
21236
21345
|
log2(`[memory-retire] ${agent.code_name}: KEPT '${tomb.name}' \u2014 no write record, not ours to remove`);
|
|
21237
21346
|
continue;
|
|
21238
21347
|
}
|
|
21239
|
-
const filePath =
|
|
21348
|
+
const filePath = join42(memoryDir, entry.file);
|
|
21240
21349
|
if (!existsSync19(filePath)) {
|
|
21241
21350
|
outcomes.already_gone++;
|
|
21242
21351
|
delete manifest[tomb.name];
|
|
@@ -21244,7 +21353,7 @@ function applyMemoryTombstones(opts) {
|
|
|
21244
21353
|
continue;
|
|
21245
21354
|
}
|
|
21246
21355
|
try {
|
|
21247
|
-
const actual = createHash20("sha256").update(
|
|
21356
|
+
const actual = createHash20("sha256").update(readFileSync33(filePath)).digest("hex");
|
|
21248
21357
|
if (actual !== entry.sha) {
|
|
21249
21358
|
outcomes.kept_modified++;
|
|
21250
21359
|
outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
|
|
@@ -21256,9 +21365,9 @@ function applyMemoryTombstones(opts) {
|
|
|
21256
21365
|
const destDir = retiredMemoryDir(configDir, agent.code_name);
|
|
21257
21366
|
mkdirSync15(destDir, { recursive: true });
|
|
21258
21367
|
const stamp = Date.now();
|
|
21259
|
-
let dest =
|
|
21368
|
+
let dest = join42(destDir, `${entry.file}.${stamp}.retired`);
|
|
21260
21369
|
for (let n = 1; existsSync19(dest); n++) {
|
|
21261
|
-
dest =
|
|
21370
|
+
dest = join42(destDir, `${entry.file}.${stamp}-${n}.retired`);
|
|
21262
21371
|
}
|
|
21263
21372
|
renameSync11(filePath, dest);
|
|
21264
21373
|
try {
|
|
@@ -21297,9 +21406,9 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
21297
21406
|
try {
|
|
21298
21407
|
for (const file of readdirSync12(dir)) {
|
|
21299
21408
|
if (!file.endsWith(".retired")) continue;
|
|
21300
|
-
const path =
|
|
21409
|
+
const path = join42(dir, file);
|
|
21301
21410
|
try {
|
|
21302
|
-
if (
|
|
21411
|
+
if (statSync12(path).mtimeMs < cutoff) {
|
|
21303
21412
|
unlinkSync6(path);
|
|
21304
21413
|
reaped++;
|
|
21305
21414
|
}
|
|
@@ -21312,8 +21421,8 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
21312
21421
|
if (reaped > 0) log2(`[memory-retire] ${codeName}: reaped ${reaped} retired memory file(s) past TTL`);
|
|
21313
21422
|
}
|
|
21314
21423
|
async function syncMemories(agent, configDir, log2) {
|
|
21315
|
-
const projectDir =
|
|
21316
|
-
const memoryDir =
|
|
21424
|
+
const projectDir = join42(configDir, agent.code_name, "project");
|
|
21425
|
+
const memoryDir = join42(projectDir, "memory");
|
|
21317
21426
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
21318
21427
|
if (isFreshSync) {
|
|
21319
21428
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -21344,7 +21453,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
21344
21453
|
for (const file of readdirSync12(memoryDir)) {
|
|
21345
21454
|
if (!file.endsWith(".md")) continue;
|
|
21346
21455
|
try {
|
|
21347
|
-
const raw =
|
|
21456
|
+
const raw = readFileSync33(join42(memoryDir, file), "utf-8");
|
|
21348
21457
|
const fileHash = createHash20("sha256").update(raw).digest("hex").slice(0, 16);
|
|
21349
21458
|
currentHashes.set(file, fileHash);
|
|
21350
21459
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -21369,7 +21478,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
21369
21478
|
} catch (err) {
|
|
21370
21479
|
for (const mem of changedMemories) {
|
|
21371
21480
|
for (const [file] of currentHashes) {
|
|
21372
|
-
const parsed = parseMemoryFile(
|
|
21481
|
+
const parsed = parseMemoryFile(readFileSync33(join42(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
21373
21482
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
21374
21483
|
}
|
|
21375
21484
|
}
|
|
@@ -21450,7 +21559,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
21450
21559
|
// Per-agent, not host-wide: memories are agent-private, so a shared
|
|
21451
21560
|
// store would buy almost no dedupe while exposing one agent's content
|
|
21452
21561
|
// to every other agent on the host. See memory-cache.ts's header.
|
|
21453
|
-
cacheDir:
|
|
21562
|
+
cacheDir: join42(configDir, agent.code_name, "_memory_bodies"),
|
|
21454
21563
|
fetchContents: async (hashes) => {
|
|
21455
21564
|
const res = await api.post(
|
|
21456
21565
|
"/host/memories/contents",
|
|
@@ -21488,7 +21597,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
21488
21597
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
21489
21598
|
const slug = rawSlug || `memory-${i}`;
|
|
21490
21599
|
const fileName = `${slug}.md`;
|
|
21491
|
-
const filePath =
|
|
21600
|
+
const filePath = join42(memoryDir, fileName);
|
|
21492
21601
|
const desired = `---
|
|
21493
21602
|
name: ${JSON.stringify(mem.name)}
|
|
21494
21603
|
type: ${mem.type}
|
|
@@ -21508,7 +21617,7 @@ ${mem.content}
|
|
|
21508
21617
|
if (existsSync19(filePath)) {
|
|
21509
21618
|
let existing = "";
|
|
21510
21619
|
try {
|
|
21511
|
-
existing =
|
|
21620
|
+
existing = readFileSync33(filePath, "utf-8");
|
|
21512
21621
|
} catch {
|
|
21513
21622
|
}
|
|
21514
21623
|
if (existing === desired) {
|
|
@@ -21874,7 +21983,7 @@ function startManager(opts) {
|
|
|
21874
21983
|
try {
|
|
21875
21984
|
const stateFile = getStateFile();
|
|
21876
21985
|
if (existsSync19(stateFile)) {
|
|
21877
|
-
const raw =
|
|
21986
|
+
const raw = readFileSync33(stateFile, "utf-8");
|
|
21878
21987
|
const parsed = JSON.parse(raw);
|
|
21879
21988
|
if (Array.isArray(parsed.agents)) {
|
|
21880
21989
|
state8.agents = parsed.agents;
|
|
@@ -21901,7 +22010,7 @@ function startManager(opts) {
|
|
|
21901
22010
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
21902
22011
|
}
|
|
21903
22012
|
log(
|
|
21904
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
22013
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join42(homedir18(), ".augmented", "manager.log")}`
|
|
21905
22014
|
);
|
|
21906
22015
|
deployMcpAssets();
|
|
21907
22016
|
reapOrphanChannelMcps({ log });
|
|
@@ -21930,7 +22039,7 @@ async function reapOrphanedClaudePids() {
|
|
|
21930
22039
|
const looksLikeClaude = (pid) => {
|
|
21931
22040
|
if (process.platform !== "linux") return true;
|
|
21932
22041
|
try {
|
|
21933
|
-
const comm =
|
|
22042
|
+
const comm = readFileSync33(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
21934
22043
|
return comm.includes("claude");
|
|
21935
22044
|
} catch {
|
|
21936
22045
|
return false;
|
|
@@ -22027,14 +22136,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
22027
22136
|
}
|
|
22028
22137
|
}
|
|
22029
22138
|
function deployMcpAssets() {
|
|
22030
|
-
const targetDir =
|
|
22139
|
+
const targetDir = join42(homedir18(), ".augmented", "_mcp");
|
|
22031
22140
|
mkdirSync15(targetDir, { recursive: true });
|
|
22032
22141
|
const moduleDir = dirname11(fileURLToPath2(import.meta.url));
|
|
22033
22142
|
let mcpSourceDir = "";
|
|
22034
22143
|
let dir = moduleDir;
|
|
22035
22144
|
for (let i = 0; i < 6; i++) {
|
|
22036
|
-
const candidate =
|
|
22037
|
-
if (existsSync19(
|
|
22145
|
+
const candidate = join42(dir, "dist", "mcp");
|
|
22146
|
+
if (existsSync19(join42(candidate, "index.js"))) {
|
|
22038
22147
|
mcpSourceDir = candidate;
|
|
22039
22148
|
break;
|
|
22040
22149
|
}
|
|
@@ -22052,7 +22161,7 @@ function deployMcpAssets() {
|
|
|
22052
22161
|
const fileHash = (p) => {
|
|
22053
22162
|
try {
|
|
22054
22163
|
if (!existsSync19(p)) return null;
|
|
22055
|
-
return createHash20("sha256").update(
|
|
22164
|
+
return createHash20("sha256").update(readFileSync33(p)).digest("hex");
|
|
22056
22165
|
} catch {
|
|
22057
22166
|
return null;
|
|
22058
22167
|
}
|
|
@@ -22134,8 +22243,8 @@ function deployMcpAssets() {
|
|
|
22134
22243
|
// natural session restart.
|
|
22135
22244
|
"computer-use-proxy.js"
|
|
22136
22245
|
]) {
|
|
22137
|
-
const src =
|
|
22138
|
-
const dst =
|
|
22246
|
+
const src = join42(mcpSourceDir, file);
|
|
22247
|
+
const dst = join42(targetDir, file);
|
|
22139
22248
|
if (!existsSync19(src)) continue;
|
|
22140
22249
|
attemptedFiles.push(file);
|
|
22141
22250
|
const before = fileHash(dst);
|
|
@@ -22161,16 +22270,16 @@ function deployMcpAssets() {
|
|
|
22161
22270
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
22162
22271
|
restartRunningChannelMcps(changedBasenames);
|
|
22163
22272
|
}
|
|
22164
|
-
const localMcpPath =
|
|
22273
|
+
const localMcpPath = join42(targetDir, "index.js");
|
|
22165
22274
|
try {
|
|
22166
|
-
const agentsDir =
|
|
22275
|
+
const agentsDir = join42(homedir18(), ".augmented", "agents");
|
|
22167
22276
|
if (existsSync19(agentsDir)) {
|
|
22168
22277
|
for (const entry of readdirSync12(agentsDir, { withFileTypes: true })) {
|
|
22169
22278
|
if (!entry.isDirectory()) continue;
|
|
22170
22279
|
for (const subdir of ["provision", "project"]) {
|
|
22171
|
-
const mcpJsonPath =
|
|
22280
|
+
const mcpJsonPath = join42(agentsDir, entry.name, subdir, ".mcp.json");
|
|
22172
22281
|
try {
|
|
22173
|
-
const raw =
|
|
22282
|
+
const raw = readFileSync33(mcpJsonPath, "utf-8");
|
|
22174
22283
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
22175
22284
|
const mcpConfig = JSON.parse(raw);
|
|
22176
22285
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|