@adhdev/daemon-standalone 1.0.58-rc.18 → 1.0.58-rc.20
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/index.js +1458 -1042
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/mcp-server/index.js +13 -5
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -31672,9 +31672,9 @@ var require_streamx = __commonJS({
|
|
|
31672
31672
|
}
|
|
31673
31673
|
});
|
|
31674
31674
|
|
|
31675
|
-
//
|
|
31675
|
+
// ../../node_modules/tar-stream/node_modules/b4a/index.js
|
|
31676
31676
|
var require_b4a2 = __commonJS({
|
|
31677
|
-
"
|
|
31677
|
+
"../../node_modules/tar-stream/node_modules/b4a/index.js"(exports2, module2) {
|
|
31678
31678
|
"use strict";
|
|
31679
31679
|
function isBuffer(value) {
|
|
31680
31680
|
return Buffer.isBuffer(value) || value instanceof Uint8Array;
|
|
@@ -31830,9 +31830,9 @@ var require_b4a2 = __commonJS({
|
|
|
31830
31830
|
}
|
|
31831
31831
|
});
|
|
31832
31832
|
|
|
31833
|
-
//
|
|
31833
|
+
// ../../node_modules/tar-stream/headers.js
|
|
31834
31834
|
var require_headers = __commonJS({
|
|
31835
|
-
"
|
|
31835
|
+
"../../node_modules/tar-stream/headers.js"(exports2) {
|
|
31836
31836
|
"use strict";
|
|
31837
31837
|
var b4a = require_b4a2();
|
|
31838
31838
|
var ZEROS = "0000000000000000000";
|
|
@@ -32093,9 +32093,9 @@ var require_headers = __commonJS({
|
|
|
32093
32093
|
}
|
|
32094
32094
|
});
|
|
32095
32095
|
|
|
32096
|
-
//
|
|
32096
|
+
// ../../node_modules/tar-stream/extract.js
|
|
32097
32097
|
var require_extract = __commonJS({
|
|
32098
|
-
"
|
|
32098
|
+
"../../node_modules/tar-stream/extract.js"(exports2, module2) {
|
|
32099
32099
|
"use strict";
|
|
32100
32100
|
var { Writable, Readable, getStreamError } = require_streamx();
|
|
32101
32101
|
var FIFO = require_fast_fifo();
|
|
@@ -32438,9 +32438,9 @@ var require_extract = __commonJS({
|
|
|
32438
32438
|
}
|
|
32439
32439
|
});
|
|
32440
32440
|
|
|
32441
|
-
//
|
|
32441
|
+
// ../../node_modules/tar-stream/constants.js
|
|
32442
32442
|
var require_constants = __commonJS({
|
|
32443
|
-
"
|
|
32443
|
+
"../../node_modules/tar-stream/constants.js"(exports2, module2) {
|
|
32444
32444
|
"use strict";
|
|
32445
32445
|
var constants = {
|
|
32446
32446
|
// just for envs without fs
|
|
@@ -32459,9 +32459,9 @@ var require_constants = __commonJS({
|
|
|
32459
32459
|
}
|
|
32460
32460
|
});
|
|
32461
32461
|
|
|
32462
|
-
//
|
|
32462
|
+
// ../../node_modules/tar-stream/pack.js
|
|
32463
32463
|
var require_pack = __commonJS({
|
|
32464
|
-
"
|
|
32464
|
+
"../../node_modules/tar-stream/pack.js"(exports2, module2) {
|
|
32465
32465
|
"use strict";
|
|
32466
32466
|
var { Readable, Writable, getStreamError } = require_streamx();
|
|
32467
32467
|
var b4a = require_b4a2();
|
|
@@ -32694,9 +32694,9 @@ var require_pack = __commonJS({
|
|
|
32694
32694
|
}
|
|
32695
32695
|
});
|
|
32696
32696
|
|
|
32697
|
-
//
|
|
32697
|
+
// ../../node_modules/tar-stream/index.js
|
|
32698
32698
|
var require_tar_stream = __commonJS({
|
|
32699
|
-
"
|
|
32699
|
+
"../../node_modules/tar-stream/index.js"(exports2) {
|
|
32700
32700
|
"use strict";
|
|
32701
32701
|
exports2.extract = require_extract();
|
|
32702
32702
|
exports2.pack = require_pack();
|
|
@@ -32939,9 +32939,9 @@ var require_pump = __commonJS({
|
|
|
32939
32939
|
}
|
|
32940
32940
|
});
|
|
32941
32941
|
|
|
32942
|
-
//
|
|
32942
|
+
// ../../node_modules/tar-fs/index.js
|
|
32943
32943
|
var require_tar_fs = __commonJS({
|
|
32944
|
-
"
|
|
32944
|
+
"../../node_modules/tar-fs/index.js"(exports2) {
|
|
32945
32945
|
"use strict";
|
|
32946
32946
|
var tar = require_tar_stream();
|
|
32947
32947
|
var pump = require_pump();
|
|
@@ -36885,10 +36885,10 @@ var require_dist3 = __commonJS({
|
|
|
36885
36885
|
}
|
|
36886
36886
|
function getDaemonBuildInfo() {
|
|
36887
36887
|
if (cached2) return cached2;
|
|
36888
|
-
const commit = readInjected(true ? "
|
|
36889
|
-
const commitShort = readInjected(true ? "
|
|
36890
|
-
const version2 = readInjected(true ? "1.0.58-rc.
|
|
36891
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
36888
|
+
const commit = readInjected(true ? "079b401790e71ed1ad71665990e7acd3747efd78" : void 0) ?? "unknown";
|
|
36889
|
+
const commitShort = readInjected(true ? "079b4017" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
36890
|
+
const version2 = readInjected(true ? "1.0.58-rc.20" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
36891
|
+
const builtAt = readInjected(true ? "2026-08-26T18:21:35.498Z" : void 0);
|
|
36892
36892
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
36893
36893
|
return cached2;
|
|
36894
36894
|
}
|
|
@@ -61612,7 +61612,7 @@ ${rendered}`, "utf-8");
|
|
|
61612
61612
|
allowAutoPublishSubmoduleMainCommits: args.allowAutoPublishSubmoduleMainCommits === true
|
|
61613
61613
|
});
|
|
61614
61614
|
}
|
|
61615
|
-
const earlyBlockers = collectPreflightBlockers(current, requestedBranch);
|
|
61615
|
+
const earlyBlockers = collectPreflightBlockers(current, requestedBranch, updateSubmodules);
|
|
61616
61616
|
if (earlyBlockers.length > 0) {
|
|
61617
61617
|
const blockCode = chooseBlockCode(current, earlyBlockers);
|
|
61618
61618
|
const result2 = {
|
|
@@ -62058,7 +62058,7 @@ ${rendered}`, "utf-8");
|
|
|
62058
62058
|
const aheadOnly = /* @__PURE__ */ new Set(["branch_has_local_commits"]);
|
|
62059
62059
|
return blockers.every((reason) => aheadOnly.has(reason));
|
|
62060
62060
|
}
|
|
62061
|
-
function collectPreflightBlockers(status, requestedBranch) {
|
|
62061
|
+
function collectPreflightBlockers(status, requestedBranch, updateSubmodules) {
|
|
62062
62062
|
const blockers = [];
|
|
62063
62063
|
if (!status.isGitRepo) blockers.push("not_git_repo");
|
|
62064
62064
|
if (!status.branch) blockers.push("detached_head_or_unknown_branch");
|
|
@@ -62067,12 +62067,16 @@ ${rendered}`, "utf-8");
|
|
|
62067
62067
|
if (status.upstreamStatus !== "fresh") blockers.push("upstream_not_fresh");
|
|
62068
62068
|
if (status.hasConflicts) blockers.push("conflicts_present");
|
|
62069
62069
|
if (status.staged > 0) blockers.push("staged_changes_present");
|
|
62070
|
-
|
|
62070
|
+
const tolerateGitlinkDriftAlone = updateSubmodules === true;
|
|
62071
|
+
const pureDriftSubmoduleCount = tolerateGitlinkDriftAlone ? (Array.isArray(status.submodules) ? status.submodules : []).filter(
|
|
62072
|
+
(submodule) => submodule.outOfSync && !submodule.dirty && !submodule.error
|
|
62073
|
+
).length : 0;
|
|
62074
|
+
if (status.modified - pureDriftSubmoduleCount > 0) blockers.push("modified_changes_present");
|
|
62071
62075
|
if (status.untracked > 0) blockers.push("untracked_changes_present");
|
|
62072
62076
|
if (status.deleted > 0) blockers.push("deleted_changes_present");
|
|
62073
62077
|
if (status.renamed > 0) blockers.push("renamed_changes_present");
|
|
62074
62078
|
if (status.stashCount > 0) blockers.push("stash_entries_present");
|
|
62075
|
-
blockers.push(...collectSubmoduleBlockers(status, "pre"));
|
|
62079
|
+
blockers.push(...collectSubmoduleBlockers(status, "pre", tolerateGitlinkDriftAlone));
|
|
62076
62080
|
if (status.ahead > 0 && status.behind > 0) {
|
|
62077
62081
|
blockers.push("branch_diverged_from_upstream");
|
|
62078
62082
|
blockers.push("branch_has_local_commits");
|
|
@@ -62092,13 +62096,14 @@ ${rendered}`, "utf-8");
|
|
|
62092
62096
|
blockers.push(...collectSubmoduleBlockers(status, "post"));
|
|
62093
62097
|
return blockers;
|
|
62094
62098
|
}
|
|
62095
|
-
function collectSubmoduleBlockers(status, phase) {
|
|
62099
|
+
function collectSubmoduleBlockers(status, phase, tolerateGitlinkDriftAlone = false) {
|
|
62096
62100
|
const submodules = Array.isArray(status.submodules) ? status.submodules : [];
|
|
62097
62101
|
const blockers = [];
|
|
62098
62102
|
for (const submodule of submodules) {
|
|
62099
62103
|
if (submodule.error) blockers.push(`${phase}_submodule_status_error:${submodule.path}`);
|
|
62100
62104
|
if (submodule.dirty) blockers.push(`${phase}_submodule_dirty:${submodule.path}`);
|
|
62101
|
-
|
|
62105
|
+
const outOfSyncIsToleratedDrift = tolerateGitlinkDriftAlone && submodule.outOfSync && !submodule.dirty && !submodule.error;
|
|
62106
|
+
if (submodule.outOfSync && !outOfSyncIsToleratedDrift) blockers.push(`${phase}_submodule_out_of_sync:${submodule.path}`);
|
|
62102
62107
|
}
|
|
62103
62108
|
return blockers;
|
|
62104
62109
|
}
|
|
@@ -65167,6 +65172,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65167
65172
|
const fresh = isQuotaSnapshotFresh(facts, quota, policy, now);
|
|
65168
65173
|
const confidence = quota.status === "ok" && fresh ? CONFIDENCE_CURRENT : isStructurallyUnmeasurable(quota) ? CONFIDENCE_RETAINED_STRUCTURAL : CONFIDENCE_RETAINED_AGED;
|
|
65169
65174
|
const window = axis === "session" ? quota.session : quota.weekly;
|
|
65175
|
+
if (!isWindowTrustworthy(window, facts, quota, policy, now)) return void 0;
|
|
65170
65176
|
const remaining = remainingPercent(window);
|
|
65171
65177
|
if (remaining === void 0) return void 0;
|
|
65172
65178
|
const resetsAt = Number(window?.resetsAt);
|
|
@@ -65259,11 +65265,18 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65259
65265
|
}
|
|
65260
65266
|
return `QUOTA GATE: skipping recovery relaunch for node ${nodeId} \u2014 ${cause} and the node has no gate-clear alternative${taskId ? `; task ${taskId}` : ""} stays queued until a quota window resets`;
|
|
65261
65267
|
}
|
|
65262
|
-
function quotaRiskSnapshotForCandidates(node, orderedProviderTypes, policy, now = Date.now(), context) {
|
|
65268
|
+
function quotaRiskSnapshotForCandidates(node, orderedProviderTypes, policy, now = Date.now(), context, ranking) {
|
|
65269
|
+
const resolvedRanking = ranking ?? rankProvidersByQuotaGate(node, orderedProviderTypes, policy, now, context);
|
|
65270
|
+
const evidenceByProvider = new Map(
|
|
65271
|
+
(resolvedRanking.rankingEvidence ?? []).map((evidence) => [evidence.providerType, evidence])
|
|
65272
|
+
);
|
|
65263
65273
|
return orderedProviderTypes.map((providerType) => {
|
|
65264
|
-
const
|
|
65274
|
+
const evidence = evidenceByProvider.get(providerType);
|
|
65275
|
+
const axis = evidence?.axis ?? (resolvedRanking.sessionAxisActive ? "session" : "weekly");
|
|
65276
|
+
const w = expiryRiskForRanking(node, providerType, axis, policy, now, context);
|
|
65265
65277
|
return {
|
|
65266
65278
|
providerType,
|
|
65279
|
+
axis,
|
|
65267
65280
|
...w ? {
|
|
65268
65281
|
remainingPercent: w.remainingPercent,
|
|
65269
65282
|
risk: w.risk,
|
|
@@ -66186,8 +66199,8 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66186
66199
|
});
|
|
66187
66200
|
function buildProviderSelectionDiagnostics(args) {
|
|
66188
66201
|
const now = args.now ?? Date.now();
|
|
66189
|
-
const riskSnapshot = quotaRiskSnapshotForCandidates(args.node, args.ranked.clear, args.quotaRouting, now, args.quotaFactsContext);
|
|
66190
|
-
const allRisks = quotaRiskSnapshotForCandidates(args.node, args.candidateSlots.map((candidate) => candidate.providerType), args.quotaRouting, now, args.quotaFactsContext);
|
|
66202
|
+
const riskSnapshot = quotaRiskSnapshotForCandidates(args.node, args.ranked.clear, args.quotaRouting, now, args.quotaFactsContext, args.ranked);
|
|
66203
|
+
const allRisks = quotaRiskSnapshotForCandidates(args.node, args.candidateSlots.map((candidate) => candidate.providerType), args.quotaRouting, now, args.quotaFactsContext, args.ranked);
|
|
66191
66204
|
const riskByProvider = new Map(allRisks.map((snapshot) => [snapshot.providerType, snapshot]));
|
|
66192
66205
|
const scoreDetails = args.task ? args.usableSlots.map((candidate, selectionRank) => {
|
|
66193
66206
|
const selectionCapacity = slotCapacityRemaining(
|
|
@@ -69108,7 +69121,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
69108
69121
|
if (policy.maxBehind !== void 0 && behind > policy.maxBehind) return false;
|
|
69109
69122
|
if (policy.requireCleanSubmodules) {
|
|
69110
69123
|
const submodules = Array.isArray(dryRun.current?.submodules) ? dryRun.current.submodules : [];
|
|
69111
|
-
if (submodules.some((submodule) => submodule?.dirty || submodule?.
|
|
69124
|
+
if (submodules.some((submodule) => submodule?.dirty || submodule?.error)) return false;
|
|
69112
69125
|
}
|
|
69113
69126
|
return true;
|
|
69114
69127
|
}
|
|
@@ -69147,9 +69160,12 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
69147
69160
|
inlineMesh: mesh,
|
|
69148
69161
|
...submoduleIgnorePaths ? { submoduleIgnorePaths } : {},
|
|
69149
69162
|
trigger: args.trigger,
|
|
69150
|
-
//
|
|
69151
|
-
//
|
|
69152
|
-
|
|
69163
|
+
// Mirror the manual mesh_fast_forward_node update_submodules behavior: if the
|
|
69164
|
+
// ff-only merge moves a submodule gitlink, run `git submodule update --init
|
|
69165
|
+
// --recursive` in the same cycle so the checkout never drifts from the gitlink.
|
|
69166
|
+
// Without this, drift accumulates and self-blocks every subsequent auto-ff
|
|
69167
|
+
// (collectPreflightBlockers treats out-of-sync submodules as a hard blocker).
|
|
69168
|
+
updateSubmodules: true
|
|
69153
69169
|
};
|
|
69154
69170
|
try {
|
|
69155
69171
|
const remoteDry = await dispatchMeshCommand(args.daemonId, "fast_forward_mesh_node", {
|
|
@@ -69183,7 +69199,9 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
69183
69199
|
workspace: args.workspace,
|
|
69184
69200
|
execute: false,
|
|
69185
69201
|
dryRun: true,
|
|
69186
|
-
updateSubmodules:
|
|
69202
|
+
// See delegateRemoteAutoFastForward's updateSubmodules comment: mirrors the
|
|
69203
|
+
// manual tool so a gitlink-moving ff cannot leave the submodule drifted.
|
|
69204
|
+
updateSubmodules: true,
|
|
69187
69205
|
submoduleIgnorePaths,
|
|
69188
69206
|
trigger: args.trigger
|
|
69189
69207
|
});
|
|
@@ -69194,7 +69212,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
69194
69212
|
workspace: args.workspace,
|
|
69195
69213
|
execute: true,
|
|
69196
69214
|
dryRun: false,
|
|
69197
|
-
updateSubmodules:
|
|
69215
|
+
updateSubmodules: true,
|
|
69198
69216
|
submoduleIgnorePaths,
|
|
69199
69217
|
trigger: args.trigger
|
|
69200
69218
|
});
|
|
@@ -69295,6 +69313,10 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
69295
69313
|
...baseBranch ? { branch: baseBranch } : {},
|
|
69296
69314
|
mode: "merge",
|
|
69297
69315
|
execute: true,
|
|
69316
|
+
// Same gitlink-drift-prevention rationale as executeLocalAutoFastForward /
|
|
69317
|
+
// delegateRemoteAutoFastForward — this path pushed the base branch itself,
|
|
69318
|
+
// so a submodule gitlink bump here is exactly as likely.
|
|
69319
|
+
updateSubmodules: true,
|
|
69298
69320
|
trigger: "refine_post_push_catchup",
|
|
69299
69321
|
allowAutoPublishSubmoduleMainCommits: mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true
|
|
69300
69322
|
});
|
|
@@ -69829,33 +69851,6 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
69829
69851
|
targetPinGeneratingCreditMs = /* @__PURE__ */ new Map();
|
|
69830
69852
|
}
|
|
69831
69853
|
});
|
|
69832
|
-
function selectQuotaBusyFallback(args) {
|
|
69833
|
-
const { clearOrder, candidates, busyProviderType, probe } = args;
|
|
69834
|
-
const slotByProvider = /* @__PURE__ */ new Map();
|
|
69835
|
-
for (const candidate of candidates) {
|
|
69836
|
-
if (!slotByProvider.has(candidate.providerType)) {
|
|
69837
|
-
slotByProvider.set(candidate.providerType, candidate);
|
|
69838
|
-
}
|
|
69839
|
-
}
|
|
69840
|
-
const skipped = [];
|
|
69841
|
-
const seen = /* @__PURE__ */ new Set([busyProviderType]);
|
|
69842
|
-
for (const providerType of clearOrder) {
|
|
69843
|
-
if (seen.has(providerType)) continue;
|
|
69844
|
-
seen.add(providerType);
|
|
69845
|
-
const candidate = slotByProvider.get(providerType);
|
|
69846
|
-
if (!candidate) continue;
|
|
69847
|
-
if (probe(candidate)) {
|
|
69848
|
-
return { outcome: "fallback", candidate, skipped };
|
|
69849
|
-
}
|
|
69850
|
-
skipped.push(providerType);
|
|
69851
|
-
}
|
|
69852
|
-
return { outcome: "exhausted", skipped };
|
|
69853
|
-
}
|
|
69854
|
-
var init_mesh_quota_fallback = __esm2({
|
|
69855
|
-
"src/mesh/mesh-quota-fallback.ts"() {
|
|
69856
|
-
"use strict";
|
|
69857
|
-
}
|
|
69858
|
-
});
|
|
69859
69854
|
function localCoordinatorDaemonId() {
|
|
69860
69855
|
return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
|
|
69861
69856
|
}
|
|
@@ -70304,6 +70299,167 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
70304
70299
|
init_mesh_difficulty_floor();
|
|
70305
70300
|
}
|
|
70306
70301
|
});
|
|
70302
|
+
function liveSessionsForNode(components, meshId, nodeId) {
|
|
70303
|
+
try {
|
|
70304
|
+
const instances = components.instanceManager?.getByCategory?.("cli") || [];
|
|
70305
|
+
const sessions = [];
|
|
70306
|
+
for (const inst of instances) {
|
|
70307
|
+
const state = inst.getState?.();
|
|
70308
|
+
if (!state) continue;
|
|
70309
|
+
const settings = state.settings || {};
|
|
70310
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) continue;
|
|
70311
|
+
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
70312
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) continue;
|
|
70313
|
+
const status = readNonEmptyString(state.status).toLowerCase();
|
|
70314
|
+
if (isTerminalSessionStatus(status)) continue;
|
|
70315
|
+
const sessionId = readNonEmptyString(state.instanceId);
|
|
70316
|
+
if (!sessionId) continue;
|
|
70317
|
+
sessions.push({
|
|
70318
|
+
sessionId,
|
|
70319
|
+
...readNonEmptyString(settings.providerType) ? { providerType: String(settings.providerType) } : {}
|
|
70320
|
+
});
|
|
70321
|
+
}
|
|
70322
|
+
return sessions;
|
|
70323
|
+
} catch (e) {
|
|
70324
|
+
LOG2.warn("MeshQueue", `Live-session lookup failed for node ${nodeId} (mesh ${meshId}): ${e?.message || e}`);
|
|
70325
|
+
return [];
|
|
70326
|
+
}
|
|
70327
|
+
}
|
|
70328
|
+
function buildDispatchFailedPinnedNotice(opts) {
|
|
70329
|
+
const { taskId, targetSessionId, nodeId, error: error48, liveSessions } = opts;
|
|
70330
|
+
const errorLine = error48 ? ` (${error48})` : "";
|
|
70331
|
+
const others = liveSessions.filter((s2) => !sessionIdsEquivalent(s2.sessionId, targetSessionId));
|
|
70332
|
+
const liveList = others.length > 0 ? `Other live session(s) currently on node '${nodeId}': ${others.map((s2) => `${s2.sessionId}${s2.providerType ? ` (${s2.providerType})` : ""}`).join(", ")}.` : `No other live session was found on node '${nodeId}' at notification time.`;
|
|
70333
|
+
return `[System] Dispatch to pinned session '${targetSessionId}' failed for task ${taskId}${errorLine} and the task returned to pending, STILL PINNED to that same session \u2014 it will keep retrying against it (with backoff) until it either succeeds or a slower liveness backstop (dead-target grace / pin TTL, up to 15min) clears the pin. Do not send a fresh task to '${targetSessionId}' \u2014 it just failed to accept one.
|
|
70334
|
+
${liveList}
|
|
70335
|
+
If the pin is stale (session is actually gone), re-target now instead of waiting: mesh_queue_requeue(task_id='${taskId}', target_session_id=<live session id>) to re-pin, or mesh_queue_requeue(task_id='${taskId}', clear_target_session=true) to let any compatible session on the node claim it. If this looks transient (session mid-boot/reconnect), no action is needed \u2014 the retry will likely succeed on its own.`;
|
|
70336
|
+
}
|
|
70337
|
+
function notifyCoordinatorOfPinnedDispatchFailure(components, opts) {
|
|
70338
|
+
const targetSessionId = readNonEmptyString(opts.targetSessionId);
|
|
70339
|
+
if (!targetSessionId) return;
|
|
70340
|
+
const liveSessions = liveSessionsForNode(components, opts.meshId, opts.nodeId);
|
|
70341
|
+
const coordinatorMessage = buildDispatchFailedPinnedNotice({
|
|
70342
|
+
taskId: opts.taskId,
|
|
70343
|
+
targetSessionId,
|
|
70344
|
+
nodeId: opts.nodeId,
|
|
70345
|
+
error: opts.error,
|
|
70346
|
+
liveSessions
|
|
70347
|
+
});
|
|
70348
|
+
const targetCoordinatorDaemonId = readNonEmptyString(opts.sourceCoordinatorDaemonId) || readNonEmptyString(loadConfig2().machineId);
|
|
70349
|
+
const targetCoordinatorSessionId = readNonEmptyString(opts.sourceCoordinatorSessionId);
|
|
70350
|
+
LOG2.warn("MeshQueue", `COORD-NOTIFY-STUCK: dispatch of pinned task ${opts.taskId} to session ${targetSessionId} (node ${opts.nodeId}, mesh ${opts.meshId}) failed and requeued with pin intact.`);
|
|
70351
|
+
try {
|
|
70352
|
+
queuePendingMeshCoordinatorEvent({
|
|
70353
|
+
event: "mesh:dispatch_blocked",
|
|
70354
|
+
meshId: opts.meshId,
|
|
70355
|
+
nodeLabel: opts.nodeId,
|
|
70356
|
+
nodeId: opts.nodeId,
|
|
70357
|
+
metadataEvent: {
|
|
70358
|
+
source: "mesh_pinned_dispatch_failed",
|
|
70359
|
+
taskId: opts.taskId,
|
|
70360
|
+
reason: DISPATCH_FAILED_PINNED_REASON,
|
|
70361
|
+
targetSessionId,
|
|
70362
|
+
liveSessionIds: liveSessions.map((s2) => s2.sessionId),
|
|
70363
|
+
coordinatorMessage
|
|
70364
|
+
},
|
|
70365
|
+
coordinatorMessage,
|
|
70366
|
+
queuedAt: Date.now(),
|
|
70367
|
+
...targetCoordinatorDaemonId ? { targetCoordinatorDaemonId } : {},
|
|
70368
|
+
...targetCoordinatorSessionId ? { targetCoordinatorSessionId } : {}
|
|
70369
|
+
});
|
|
70370
|
+
} catch (e) {
|
|
70371
|
+
LOG2.warn("MeshQueue", `Failed to surface pinned-dispatch-failure notification for task ${opts.taskId} (mesh ${opts.meshId}): ${e?.message || e}`);
|
|
70372
|
+
}
|
|
70373
|
+
}
|
|
70374
|
+
function buildReclaimedPinnedNotice(opts) {
|
|
70375
|
+
const { taskId, targetSessionId, nodeId, reclaimReason, silentForMs, liveSessions } = opts;
|
|
70376
|
+
const silentMin = Math.round(silentForMs / 6e4);
|
|
70377
|
+
const others = liveSessions.filter((s2) => !sessionIdsEquivalent(s2.sessionId, targetSessionId));
|
|
70378
|
+
const liveList = others.length > 0 ? `Other live session(s) currently on node '${nodeId}': ${others.map((s2) => `${s2.sessionId}${s2.providerType ? ` (${s2.providerType})` : ""}`).join(", ")}.` : `No other live session was found on node '${nodeId}' at notification time.`;
|
|
70379
|
+
return `[System] Task ${taskId} was reclaimed from pinned session '${targetSessionId}' (node '${nodeId}') after ${silentMin}min with no confirmed progress (${reclaimReason}), and returned to pending STILL PINNED to that same session \u2014 it will keep re-offering itself ONLY to '${targetSessionId}' and to nothing else. If that session is actually gone or wedged, it will keep failing silently until you act.
|
|
70380
|
+
${liveList}
|
|
70381
|
+
Re-target now if the pin is stale: mesh_queue_requeue(task_id='${taskId}', target_session_id=<live session id>) to re-pin, or mesh_queue_requeue(task_id='${taskId}', clear_target_session=true) to let any compatible session on the node claim it. If '${targetSessionId}' is expected to reconnect and resume, no action is needed.`;
|
|
70382
|
+
}
|
|
70383
|
+
function notifyCoordinatorOfPinnedReclaim(components, opts) {
|
|
70384
|
+
const targetSessionId = readNonEmptyString(opts.targetSessionId);
|
|
70385
|
+
if (!targetSessionId) return;
|
|
70386
|
+
const liveSessions = liveSessionsForNode(components, opts.meshId, opts.nodeId);
|
|
70387
|
+
const coordinatorMessage = buildReclaimedPinnedNotice({
|
|
70388
|
+
taskId: opts.taskId,
|
|
70389
|
+
targetSessionId,
|
|
70390
|
+
nodeId: opts.nodeId,
|
|
70391
|
+
reclaimReason: opts.reclaimReason,
|
|
70392
|
+
silentForMs: opts.silentForMs,
|
|
70393
|
+
liveSessions
|
|
70394
|
+
});
|
|
70395
|
+
const targetCoordinatorDaemonId = readNonEmptyString(opts.sourceCoordinatorDaemonId) || readNonEmptyString(loadConfig2().machineId);
|
|
70396
|
+
const targetCoordinatorSessionId = readNonEmptyString(opts.sourceCoordinatorSessionId);
|
|
70397
|
+
LOG2.warn("MeshQueue", `COORD-NOTIFY-STUCK: pinned task ${opts.taskId} reclaimed from session ${targetSessionId} (node ${opts.nodeId}, mesh ${opts.meshId}) after ${Math.round(opts.silentForMs / 6e4)}min silence and requeued with pin intact.`);
|
|
70398
|
+
try {
|
|
70399
|
+
queuePendingMeshCoordinatorEvent({
|
|
70400
|
+
event: "mesh:dispatch_blocked",
|
|
70401
|
+
meshId: opts.meshId,
|
|
70402
|
+
nodeLabel: opts.nodeId,
|
|
70403
|
+
nodeId: opts.nodeId,
|
|
70404
|
+
metadataEvent: {
|
|
70405
|
+
source: "mesh_pinned_stranded_reclaim",
|
|
70406
|
+
taskId: opts.taskId,
|
|
70407
|
+
reason: RECLAIMED_PINNED_REASON,
|
|
70408
|
+
targetSessionId,
|
|
70409
|
+
liveSessionIds: liveSessions.map((s2) => s2.sessionId),
|
|
70410
|
+
coordinatorMessage
|
|
70411
|
+
},
|
|
70412
|
+
coordinatorMessage,
|
|
70413
|
+
queuedAt: Date.now(),
|
|
70414
|
+
...targetCoordinatorDaemonId ? { targetCoordinatorDaemonId } : {},
|
|
70415
|
+
...targetCoordinatorSessionId ? { targetCoordinatorSessionId } : {}
|
|
70416
|
+
});
|
|
70417
|
+
} catch (e) {
|
|
70418
|
+
LOG2.warn("MeshQueue", `Failed to surface pinned-reclaim notification for task ${opts.taskId} (mesh ${opts.meshId}): ${e?.message || e}`);
|
|
70419
|
+
}
|
|
70420
|
+
}
|
|
70421
|
+
var DISPATCH_FAILED_PINNED_REASON;
|
|
70422
|
+
var RECLAIMED_PINNED_REASON;
|
|
70423
|
+
var init_mesh_dispatch_failed_notify = __esm2({
|
|
70424
|
+
"src/mesh/mesh-dispatch-failed-notify.ts"() {
|
|
70425
|
+
"use strict";
|
|
70426
|
+
init_logger();
|
|
70427
|
+
init_dist();
|
|
70428
|
+
init_mesh_events_utils();
|
|
70429
|
+
init_mesh_events_pending();
|
|
70430
|
+
init_config();
|
|
70431
|
+
init_mesh_candidacy_predicates();
|
|
70432
|
+
DISPATCH_FAILED_PINNED_REASON = "pinned_session_dispatch_failed";
|
|
70433
|
+
RECLAIMED_PINNED_REASON = "pinned_session_reclaimed_stranded";
|
|
70434
|
+
}
|
|
70435
|
+
});
|
|
70436
|
+
function selectQuotaBusyFallback(args) {
|
|
70437
|
+
const { clearOrder, candidates, busyProviderType, probe } = args;
|
|
70438
|
+
const slotByProvider = /* @__PURE__ */ new Map();
|
|
70439
|
+
for (const candidate of candidates) {
|
|
70440
|
+
if (!slotByProvider.has(candidate.providerType)) {
|
|
70441
|
+
slotByProvider.set(candidate.providerType, candidate);
|
|
70442
|
+
}
|
|
70443
|
+
}
|
|
70444
|
+
const skipped = [];
|
|
70445
|
+
const seen = /* @__PURE__ */ new Set([busyProviderType]);
|
|
70446
|
+
for (const providerType of clearOrder) {
|
|
70447
|
+
if (seen.has(providerType)) continue;
|
|
70448
|
+
seen.add(providerType);
|
|
70449
|
+
const candidate = slotByProvider.get(providerType);
|
|
70450
|
+
if (!candidate) continue;
|
|
70451
|
+
if (probe(candidate)) {
|
|
70452
|
+
return { outcome: "fallback", candidate, skipped };
|
|
70453
|
+
}
|
|
70454
|
+
skipped.push(providerType);
|
|
70455
|
+
}
|
|
70456
|
+
return { outcome: "exhausted", skipped };
|
|
70457
|
+
}
|
|
70458
|
+
var init_mesh_quota_fallback = __esm2({
|
|
70459
|
+
"src/mesh/mesh-quota-fallback.ts"() {
|
|
70460
|
+
"use strict";
|
|
70461
|
+
}
|
|
70462
|
+
});
|
|
70307
70463
|
function localCoordinatorDaemonId2() {
|
|
70308
70464
|
return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
|
|
70309
70465
|
}
|
|
@@ -70591,6 +70747,16 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
70591
70747
|
});
|
|
70592
70748
|
if (requeued?.status === "failed") {
|
|
70593
70749
|
LOG2.error("MeshQueue", `Task ${ctx.task.id} (mesh ${ctx.meshId}) failed after repeated dispatch failures to node ${ctx.nodeId} \u2014 the worker never started it: ${requeued.cancelReason || "dispatch_never_started"}. Dependents were unblocked.`);
|
|
70750
|
+
} else if (requeued?.status === "pending" && readNonEmptyString(requeued.targetSessionId)) {
|
|
70751
|
+
notifyCoordinatorOfPinnedDispatchFailure(ctx.components, {
|
|
70752
|
+
meshId: ctx.meshId,
|
|
70753
|
+
taskId: ctx.task.id,
|
|
70754
|
+
targetSessionId: requeued.targetSessionId,
|
|
70755
|
+
nodeId: ctx.nodeId,
|
|
70756
|
+
error: e?.message,
|
|
70757
|
+
sourceCoordinatorSessionId: ctx.sourceCoordinatorSessionId,
|
|
70758
|
+
sourceCoordinatorDaemonId: ctx.sourceCoordinatorDaemonId
|
|
70759
|
+
});
|
|
70594
70760
|
}
|
|
70595
70761
|
}
|
|
70596
70762
|
try {
|
|
@@ -70862,6 +71028,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
70862
71028
|
providerType,
|
|
70863
71029
|
task,
|
|
70864
71030
|
transport: "remote",
|
|
71031
|
+
components,
|
|
70865
71032
|
...sourceCoordinatorSessionId ? { sourceCoordinatorSessionId } : {},
|
|
70866
71033
|
...localDaemonIdForDispatch ? { sourceCoordinatorDaemonId: localDaemonIdForDispatch } : {},
|
|
70867
71034
|
...routingDecision ? { routingDecision } : {}
|
|
@@ -70933,6 +71100,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
70933
71100
|
providerType,
|
|
70934
71101
|
task,
|
|
70935
71102
|
transport: "local",
|
|
71103
|
+
components,
|
|
70936
71104
|
...readNonEmptyString(task.sourceCoordinatorSessionId) ? { sourceCoordinatorSessionId: readNonEmptyString(task.sourceCoordinatorSessionId) } : {},
|
|
70937
71105
|
...localCoordinatorDaemonId2() ? { sourceCoordinatorDaemonId: localCoordinatorDaemonId2() } : {},
|
|
70938
71106
|
...routingDecision ? { routingDecision } : {}
|
|
@@ -71734,6 +71902,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
71734
71902
|
init_mesh_auto_fast_forward();
|
|
71735
71903
|
init_mesh_skip_notify();
|
|
71736
71904
|
init_mesh_task_parking();
|
|
71905
|
+
init_mesh_dispatch_failed_notify();
|
|
71737
71906
|
init_mesh_scheduling_fitness();
|
|
71738
71907
|
init_mesh_queue_observability();
|
|
71739
71908
|
init_mesh_routing_decision();
|
|
@@ -79491,6 +79660,17 @@ ${cleanBody}`;
|
|
|
79491
79660
|
meshId,
|
|
79492
79661
|
event: "agent:generating_completed"
|
|
79493
79662
|
}, `delivered ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s ${reclaimReason} \u2192 ${reclaimedLost.status}`);
|
|
79663
|
+
if (reclaimedLost.status === "pending" && readNonEmptyString(reclaimedLost.targetSessionId) && row.assignedNodeId) {
|
|
79664
|
+
notifyCoordinatorOfPinnedReclaim(components, {
|
|
79665
|
+
meshId,
|
|
79666
|
+
taskId: row.id,
|
|
79667
|
+
targetSessionId: reclaimedLost.targetSessionId,
|
|
79668
|
+
nodeId: row.assignedNodeId,
|
|
79669
|
+
reclaimReason,
|
|
79670
|
+
silentForMs: nowMs - dispatchedAtMs,
|
|
79671
|
+
...readNonEmptyString(row.sourceCoordinatorSessionId) ? { sourceCoordinatorSessionId: row.sourceCoordinatorSessionId } : {}
|
|
79672
|
+
});
|
|
79673
|
+
}
|
|
79494
79674
|
}
|
|
79495
79675
|
continue;
|
|
79496
79676
|
}
|
|
@@ -79645,6 +79825,7 @@ ${cleanBody}`;
|
|
|
79645
79825
|
init_mesh_event_forwarding();
|
|
79646
79826
|
init_mesh_turn_ledger();
|
|
79647
79827
|
init_mesh_turn_presentation();
|
|
79828
|
+
init_mesh_dispatch_failed_notify();
|
|
79648
79829
|
ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
|
|
79649
79830
|
DELIVERED_NO_TURN_DEADLINE_MS = 15 * 6e4;
|
|
79650
79831
|
NATIVE_SOURCE_ACTIVITY_STALE_MS = 10 * 6e4;
|
|
@@ -81347,6 +81528,78 @@ ${cleanBody}`;
|
|
|
81347
81528
|
WHOLE_SCREEN = -1;
|
|
81348
81529
|
}
|
|
81349
81530
|
});
|
|
81531
|
+
var mesh_refine_executor_liveness_exports = {};
|
|
81532
|
+
__export2(mesh_refine_executor_liveness_exports, {
|
|
81533
|
+
buildRefineExecutorStamp: () => buildRefineExecutorStamp,
|
|
81534
|
+
currentRefineExecutorBootId: () => currentRefineExecutorBootId,
|
|
81535
|
+
evaluateRefineExecutorLiveness: () => evaluateRefineExecutorLiveness,
|
|
81536
|
+
readRefineExecutorStamp: () => readRefineExecutorStamp
|
|
81537
|
+
});
|
|
81538
|
+
function buildRefineExecutorStamp(nowIso) {
|
|
81539
|
+
return {
|
|
81540
|
+
host: (0, import_node_os2.hostname)(),
|
|
81541
|
+
pid: process.pid,
|
|
81542
|
+
bootId: BOOT_ID,
|
|
81543
|
+
stampedAt: nowIso ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
81544
|
+
};
|
|
81545
|
+
}
|
|
81546
|
+
function currentRefineExecutorBootId() {
|
|
81547
|
+
return BOOT_ID;
|
|
81548
|
+
}
|
|
81549
|
+
function defaultIsPidAlive(pid) {
|
|
81550
|
+
try {
|
|
81551
|
+
process.kill(pid, 0);
|
|
81552
|
+
return true;
|
|
81553
|
+
} catch (e) {
|
|
81554
|
+
if (e?.code === "ESRCH") return false;
|
|
81555
|
+
return true;
|
|
81556
|
+
}
|
|
81557
|
+
}
|
|
81558
|
+
function evaluateRefineExecutorLiveness(stamp2, opts = {}) {
|
|
81559
|
+
const s2 = stamp2;
|
|
81560
|
+
if (!s2 || typeof s2 !== "object") {
|
|
81561
|
+
return { liveness: "unknown", reason: "no_executor_stamp" };
|
|
81562
|
+
}
|
|
81563
|
+
const pid = typeof s2.pid === "number" && Number.isInteger(s2.pid) && s2.pid > 0 ? s2.pid : void 0;
|
|
81564
|
+
const host = typeof s2.host === "string" && s2.host.trim() ? s2.host.trim() : void 0;
|
|
81565
|
+
if (!pid || !host) {
|
|
81566
|
+
return { liveness: "unknown", reason: "incomplete_executor_stamp" };
|
|
81567
|
+
}
|
|
81568
|
+
const localHost = opts.localHost ?? (0, import_node_os2.hostname)();
|
|
81569
|
+
if (host !== localHost) {
|
|
81570
|
+
return { liveness: "unknown", reason: `executor_stamp_from_other_host:${host}` };
|
|
81571
|
+
}
|
|
81572
|
+
const localBootId = opts.localBootId ?? BOOT_ID;
|
|
81573
|
+
const localPid = opts.localPid ?? process.pid;
|
|
81574
|
+
if (pid === localPid && s2.bootId && s2.bootId === localBootId) {
|
|
81575
|
+
return { liveness: "alive", reason: "executor_is_this_process" };
|
|
81576
|
+
}
|
|
81577
|
+
if (pid === localPid && s2.bootId && s2.bootId !== localBootId) {
|
|
81578
|
+
return { liveness: "dead", reason: "executor_pid_recycled_by_this_process" };
|
|
81579
|
+
}
|
|
81580
|
+
const probe = opts.isPidAlive ?? defaultIsPidAlive;
|
|
81581
|
+
let alive;
|
|
81582
|
+
try {
|
|
81583
|
+
alive = probe(pid);
|
|
81584
|
+
} catch {
|
|
81585
|
+
return { liveness: "unknown", reason: "liveness_probe_failed" };
|
|
81586
|
+
}
|
|
81587
|
+
return alive ? { liveness: "alive", reason: `executor_pid_${pid}_alive` } : { liveness: "dead", reason: `executor_pid_${pid}_gone` };
|
|
81588
|
+
}
|
|
81589
|
+
function readRefineExecutorStamp(payload) {
|
|
81590
|
+
const stamp2 = payload?.refineJob?.executor ?? payload?.executor;
|
|
81591
|
+
if (!stamp2 || typeof stamp2 !== "object") return void 0;
|
|
81592
|
+
return stamp2;
|
|
81593
|
+
}
|
|
81594
|
+
var import_node_os2;
|
|
81595
|
+
var BOOT_ID;
|
|
81596
|
+
var init_mesh_refine_executor_liveness = __esm2({
|
|
81597
|
+
"src/mesh/mesh-refine-executor-liveness.ts"() {
|
|
81598
|
+
"use strict";
|
|
81599
|
+
import_node_os2 = require("os");
|
|
81600
|
+
BOOT_ID = `${process.pid}-${Date.now().toString(36)}-${Math.floor(Math.random() * 1e9).toString(36)}`;
|
|
81601
|
+
}
|
|
81602
|
+
});
|
|
81350
81603
|
var pty_transport_exports = {};
|
|
81351
81604
|
__export2(pty_transport_exports, {
|
|
81352
81605
|
NodePtyTransportFactory: () => NodePtyTransportFactory,
|
|
@@ -86435,78 +86688,6 @@ ${excerpt}` : "\n--- git output ---\n(none captured)");
|
|
|
86435
86688
|
waitQueue = [];
|
|
86436
86689
|
}
|
|
86437
86690
|
});
|
|
86438
|
-
var mesh_refine_executor_liveness_exports = {};
|
|
86439
|
-
__export2(mesh_refine_executor_liveness_exports, {
|
|
86440
|
-
buildRefineExecutorStamp: () => buildRefineExecutorStamp,
|
|
86441
|
-
currentRefineExecutorBootId: () => currentRefineExecutorBootId,
|
|
86442
|
-
evaluateRefineExecutorLiveness: () => evaluateRefineExecutorLiveness,
|
|
86443
|
-
readRefineExecutorStamp: () => readRefineExecutorStamp
|
|
86444
|
-
});
|
|
86445
|
-
function buildRefineExecutorStamp(nowIso) {
|
|
86446
|
-
return {
|
|
86447
|
-
host: (0, import_node_os2.hostname)(),
|
|
86448
|
-
pid: process.pid,
|
|
86449
|
-
bootId: BOOT_ID,
|
|
86450
|
-
stampedAt: nowIso ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
86451
|
-
};
|
|
86452
|
-
}
|
|
86453
|
-
function currentRefineExecutorBootId() {
|
|
86454
|
-
return BOOT_ID;
|
|
86455
|
-
}
|
|
86456
|
-
function defaultIsPidAlive(pid) {
|
|
86457
|
-
try {
|
|
86458
|
-
process.kill(pid, 0);
|
|
86459
|
-
return true;
|
|
86460
|
-
} catch (e) {
|
|
86461
|
-
if (e?.code === "ESRCH") return false;
|
|
86462
|
-
return true;
|
|
86463
|
-
}
|
|
86464
|
-
}
|
|
86465
|
-
function evaluateRefineExecutorLiveness(stamp2, opts = {}) {
|
|
86466
|
-
const s2 = stamp2;
|
|
86467
|
-
if (!s2 || typeof s2 !== "object") {
|
|
86468
|
-
return { liveness: "unknown", reason: "no_executor_stamp" };
|
|
86469
|
-
}
|
|
86470
|
-
const pid = typeof s2.pid === "number" && Number.isInteger(s2.pid) && s2.pid > 0 ? s2.pid : void 0;
|
|
86471
|
-
const host = typeof s2.host === "string" && s2.host.trim() ? s2.host.trim() : void 0;
|
|
86472
|
-
if (!pid || !host) {
|
|
86473
|
-
return { liveness: "unknown", reason: "incomplete_executor_stamp" };
|
|
86474
|
-
}
|
|
86475
|
-
const localHost = opts.localHost ?? (0, import_node_os2.hostname)();
|
|
86476
|
-
if (host !== localHost) {
|
|
86477
|
-
return { liveness: "unknown", reason: `executor_stamp_from_other_host:${host}` };
|
|
86478
|
-
}
|
|
86479
|
-
const localBootId = opts.localBootId ?? BOOT_ID;
|
|
86480
|
-
const localPid = opts.localPid ?? process.pid;
|
|
86481
|
-
if (pid === localPid && s2.bootId && s2.bootId === localBootId) {
|
|
86482
|
-
return { liveness: "alive", reason: "executor_is_this_process" };
|
|
86483
|
-
}
|
|
86484
|
-
if (pid === localPid && s2.bootId && s2.bootId !== localBootId) {
|
|
86485
|
-
return { liveness: "dead", reason: "executor_pid_recycled_by_this_process" };
|
|
86486
|
-
}
|
|
86487
|
-
const probe = opts.isPidAlive ?? defaultIsPidAlive;
|
|
86488
|
-
let alive;
|
|
86489
|
-
try {
|
|
86490
|
-
alive = probe(pid);
|
|
86491
|
-
} catch {
|
|
86492
|
-
return { liveness: "unknown", reason: "liveness_probe_failed" };
|
|
86493
|
-
}
|
|
86494
|
-
return alive ? { liveness: "alive", reason: `executor_pid_${pid}_alive` } : { liveness: "dead", reason: `executor_pid_${pid}_gone` };
|
|
86495
|
-
}
|
|
86496
|
-
function readRefineExecutorStamp(payload) {
|
|
86497
|
-
const stamp2 = payload?.refineJob?.executor ?? payload?.executor;
|
|
86498
|
-
if (!stamp2 || typeof stamp2 !== "object") return void 0;
|
|
86499
|
-
return stamp2;
|
|
86500
|
-
}
|
|
86501
|
-
var import_node_os2;
|
|
86502
|
-
var BOOT_ID;
|
|
86503
|
-
var init_mesh_refine_executor_liveness = __esm2({
|
|
86504
|
-
"src/mesh/mesh-refine-executor-liveness.ts"() {
|
|
86505
|
-
"use strict";
|
|
86506
|
-
import_node_os2 = require("os");
|
|
86507
|
-
BOOT_ID = `${process.pid}-${Date.now().toString(36)}-${Math.floor(Math.random() * 1e9).toString(36)}`;
|
|
86508
|
-
}
|
|
86509
|
-
});
|
|
86510
86691
|
function resolveRefineResumeDispatchGraceMs() {
|
|
86511
86692
|
return resolveTunedReconcileMs("MESH_REFINE_RESUME_DISPATCH_GRACE_MS", 6e4, 0, 10 * 6e4);
|
|
86512
86693
|
}
|
|
@@ -88702,29 +88883,6 @@ ${e?.stderr || ""}`;
|
|
|
88702
88883
|
RETRYABLE_BASE_MOVEMENT_CODES = /* @__PURE__ */ new Set(["base_moved", "base_locked", "base_cas_undeterminable"]);
|
|
88703
88884
|
}
|
|
88704
88885
|
});
|
|
88705
|
-
var channel_migration_exports = {};
|
|
88706
|
-
__export2(channel_migration_exports, {
|
|
88707
|
-
migrateProviderChannelConfig: () => migrateProviderChannelConfig
|
|
88708
|
-
});
|
|
88709
|
-
function migrateProviderChannelConfig(env2 = process.env) {
|
|
88710
|
-
const config2 = loadConfig2();
|
|
88711
|
-
const existing = (config2.providerChannel ?? "").trim();
|
|
88712
|
-
if (existing) {
|
|
88713
|
-
return { migrated: false, channel: existing === "preview" ? "preview" : "stable" };
|
|
88714
|
-
}
|
|
88715
|
-
const durableEnv = { ...env2 };
|
|
88716
|
-
delete durableEnv[PROVIDER_CHANNEL_ENV_VAR];
|
|
88717
|
-
const channel = resolveProviderChannel(void 0, durableEnv, config2.updateChannel);
|
|
88718
|
-
updateConfig({ providerChannel: channel });
|
|
88719
|
-
return { migrated: true, channel };
|
|
88720
|
-
}
|
|
88721
|
-
var init_channel_migration = __esm2({
|
|
88722
|
-
"src/providers/channel/channel-migration.ts"() {
|
|
88723
|
-
"use strict";
|
|
88724
|
-
init_config();
|
|
88725
|
-
init_contract();
|
|
88726
|
-
}
|
|
88727
|
-
});
|
|
88728
88886
|
var require_canonicalize = __commonJS2({
|
|
88729
88887
|
"../../vendor/seqscribe/node_modules/canonicalize/lib/canonicalize.js"(exports22, module22) {
|
|
88730
88888
|
"use strict";
|
|
@@ -88760,6 +88918,29 @@ ${e?.stderr || ""}`;
|
|
|
88760
88918
|
};
|
|
88761
88919
|
}
|
|
88762
88920
|
});
|
|
88921
|
+
var channel_migration_exports = {};
|
|
88922
|
+
__export2(channel_migration_exports, {
|
|
88923
|
+
migrateProviderChannelConfig: () => migrateProviderChannelConfig
|
|
88924
|
+
});
|
|
88925
|
+
function migrateProviderChannelConfig(env2 = process.env) {
|
|
88926
|
+
const config2 = loadConfig2();
|
|
88927
|
+
const existing = (config2.providerChannel ?? "").trim();
|
|
88928
|
+
if (existing) {
|
|
88929
|
+
return { migrated: false, channel: existing === "preview" ? "preview" : "stable" };
|
|
88930
|
+
}
|
|
88931
|
+
const durableEnv = { ...env2 };
|
|
88932
|
+
delete durableEnv[PROVIDER_CHANNEL_ENV_VAR];
|
|
88933
|
+
const channel = resolveProviderChannel(void 0, durableEnv, config2.updateChannel);
|
|
88934
|
+
updateConfig({ providerChannel: channel });
|
|
88935
|
+
return { migrated: true, channel };
|
|
88936
|
+
}
|
|
88937
|
+
var init_channel_migration = __esm2({
|
|
88938
|
+
"src/providers/channel/channel-migration.ts"() {
|
|
88939
|
+
"use strict";
|
|
88940
|
+
init_config();
|
|
88941
|
+
init_contract();
|
|
88942
|
+
}
|
|
88943
|
+
});
|
|
88763
88944
|
var index_exports = {};
|
|
88764
88945
|
__export2(index_exports, {
|
|
88765
88946
|
ADHDEV_AUTHORITY_ID: () => ADHDEV_AUTHORITY_ID,
|
|
@@ -103862,6 +104043,170 @@ ${marker}`,
|
|
|
103862
104043
|
appendUpgradeLog(`Stale staging cleanup skipped (${error48?.code || "error"}): ${error48?.message || String(error48)}`);
|
|
103863
104044
|
}
|
|
103864
104045
|
}
|
|
104046
|
+
function resolvePosixBinNames(packageName) {
|
|
104047
|
+
const base = packageName.startsWith("@") ? packageName.split("/")[1] : packageName;
|
|
104048
|
+
const names = [base];
|
|
104049
|
+
if (packageName === "@adhdev/daemon-standalone") {
|
|
104050
|
+
names.push("adhdev-standalone");
|
|
104051
|
+
}
|
|
104052
|
+
return names;
|
|
104053
|
+
}
|
|
104054
|
+
function smokeTestInstalledBins(prefix, packageName) {
|
|
104055
|
+
const binDir = path33.join(prefix, "bin");
|
|
104056
|
+
const names = resolvePosixBinNames(packageName);
|
|
104057
|
+
const baseShim = path33.join(binDir, names[0]);
|
|
104058
|
+
if (!fs26.existsSync(baseShim)) {
|
|
104059
|
+
throw new Error(`installed CLI shim is missing: ${baseShim}`);
|
|
104060
|
+
}
|
|
104061
|
+
for (const name of names) {
|
|
104062
|
+
const shimPath = path33.join(binDir, name);
|
|
104063
|
+
if (!fs26.existsSync(shimPath)) continue;
|
|
104064
|
+
(0, import_child_process8.execFileSync)(shimPath, ["--version"], {
|
|
104065
|
+
encoding: "utf8",
|
|
104066
|
+
stdio: "pipe",
|
|
104067
|
+
timeout: 3e4,
|
|
104068
|
+
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
104069
|
+
});
|
|
104070
|
+
}
|
|
104071
|
+
}
|
|
104072
|
+
function backupPosixInstall(options) {
|
|
104073
|
+
try {
|
|
104074
|
+
fs26.mkdirSync(options.configDir, { recursive: true });
|
|
104075
|
+
const backupDir = fs26.mkdtempSync(path33.join(options.configDir, "upgrade-backup-"));
|
|
104076
|
+
fs26.cpSync(options.packageRoot, path33.join(backupDir, "package"), { recursive: true });
|
|
104077
|
+
const binShims = [];
|
|
104078
|
+
const binDir = path33.join(options.installPrefix, "bin");
|
|
104079
|
+
for (const name of resolvePosixBinNames(options.packageName)) {
|
|
104080
|
+
const shim = path33.join(binDir, name);
|
|
104081
|
+
if (fs26.existsSync(shim)) {
|
|
104082
|
+
fs26.cpSync(shim, path33.join(backupDir, `bin-${name}`), { recursive: true });
|
|
104083
|
+
binShims.push(shim);
|
|
104084
|
+
}
|
|
104085
|
+
}
|
|
104086
|
+
return { backupDir, packageRoot: options.packageRoot, binShims };
|
|
104087
|
+
} catch (error48) {
|
|
104088
|
+
appendUpgradeLog(`Install backup failed (${error48?.code || "error"}): ${error48?.message || String(error48)} \u2014 proceeding without a rollback snapshot`, options.configDir);
|
|
104089
|
+
return null;
|
|
104090
|
+
}
|
|
104091
|
+
}
|
|
104092
|
+
function restorePosixInstall(backup) {
|
|
104093
|
+
fs26.rmSync(backup.packageRoot, { recursive: true, force: true });
|
|
104094
|
+
fs26.cpSync(path33.join(backup.backupDir, "package"), backup.packageRoot, { recursive: true });
|
|
104095
|
+
for (const shim of backup.binShims) {
|
|
104096
|
+
fs26.cpSync(path33.join(backup.backupDir, `bin-${path33.basename(shim)}`), shim, { recursive: true });
|
|
104097
|
+
}
|
|
104098
|
+
}
|
|
104099
|
+
function runPosixInPlaceUpgrade(options) {
|
|
104100
|
+
const { payload, installCommand, restartArgv } = options;
|
|
104101
|
+
const configDir = getConfigDir2();
|
|
104102
|
+
const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
|
|
104103
|
+
const { packageRoot, installPrefix } = installCommand.surface;
|
|
104104
|
+
try {
|
|
104105
|
+
for (const entry of fs26.readdirSync(configDir)) {
|
|
104106
|
+
if (entry.startsWith("upgrade-preflight-")) {
|
|
104107
|
+
safeRemoveStaleEntry(path33.join(configDir, entry), "Removed stale pre-flight staging prefix");
|
|
104108
|
+
}
|
|
104109
|
+
}
|
|
104110
|
+
} catch {
|
|
104111
|
+
}
|
|
104112
|
+
const preflightPrefix = (() => {
|
|
104113
|
+
fs26.mkdirSync(configDir, { recursive: true });
|
|
104114
|
+
return fs26.mkdtempSync(path33.join(configDir, "upgrade-preflight-"));
|
|
104115
|
+
})();
|
|
104116
|
+
try {
|
|
104117
|
+
appendUpgradeLog(`Pre-flight: installing ${spec} into throwaway prefix ${preflightPrefix}`);
|
|
104118
|
+
execNpmCommandSync(
|
|
104119
|
+
["install", "-g", spec, "--prefix", preflightPrefix],
|
|
104120
|
+
{
|
|
104121
|
+
encoding: "utf8",
|
|
104122
|
+
stdio: "pipe",
|
|
104123
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
104124
|
+
env: buildInstallEnvWithNodeOnPath()
|
|
104125
|
+
},
|
|
104126
|
+
installCommand.surface
|
|
104127
|
+
);
|
|
104128
|
+
smokeTestInstalledBins(preflightPrefix, payload.packageName);
|
|
104129
|
+
appendUpgradeLog(`Pre-flight smoke gate passed for ${spec}`);
|
|
104130
|
+
} catch (error48) {
|
|
104131
|
+
const detail = error48?.message || String(error48);
|
|
104132
|
+
appendUpgradeLog(`Pre-flight smoke gate FAILED for ${spec}: ${detail} \u2014 existing install left untouched`);
|
|
104133
|
+
emitUpgradeFailureNotice([
|
|
104134
|
+
`adhdev ${spec} was NOT installed: the package installs but its CLI does not run (\`--version\` failed).`,
|
|
104135
|
+
`Detail: ${detail}`,
|
|
104136
|
+
"Your previous version is untouched and the daemon was restarted on it.",
|
|
104137
|
+
"This is a broken published package \u2014 retry once a fixed version is published."
|
|
104138
|
+
], configDir, { targetVersion: payload.targetVersion });
|
|
104139
|
+
spawnDetachedDaemonRestart(restartArgv, payload.cwd);
|
|
104140
|
+
throw new Error(`Pre-flight smoke gate failed for ${spec}: ${detail}`);
|
|
104141
|
+
} finally {
|
|
104142
|
+
safeRemoveStaleEntry(preflightPrefix, "Removed pre-flight staging prefix");
|
|
104143
|
+
}
|
|
104144
|
+
const backup = packageRoot && installPrefix ? backupPosixInstall({ packageRoot, installPrefix, packageName: payload.packageName, configDir }) : null;
|
|
104145
|
+
if (backup) {
|
|
104146
|
+
appendUpgradeLog(`Backed up current install to ${backup.backupDir}`);
|
|
104147
|
+
} else {
|
|
104148
|
+
appendUpgradeLog("No rollback snapshot available (package root unresolved or backup failed); relying on the pre-flight gate alone");
|
|
104149
|
+
}
|
|
104150
|
+
const rollbackAndRestart = (cause) => {
|
|
104151
|
+
if (backup) {
|
|
104152
|
+
try {
|
|
104153
|
+
restorePosixInstall(backup);
|
|
104154
|
+
appendUpgradeLog("Rollback restored the previous install");
|
|
104155
|
+
safeRemoveStaleEntry(backup.backupDir, "Removed upgrade backup after rollback");
|
|
104156
|
+
} catch (error48) {
|
|
104157
|
+
appendUpgradeLog(`ROLLBACK FAILED (${error48?.code || "error"}): ${error48?.message || String(error48)} \u2014 snapshot retained at ${backup.backupDir}`);
|
|
104158
|
+
emitUpgradeFailureNotice([
|
|
104159
|
+
`adhdev ${spec} install failed (${cause}) AND the automatic rollback failed.`,
|
|
104160
|
+
`A snapshot of the previous working install is preserved at: ${backup.backupDir}`,
|
|
104161
|
+
"To recover manually, reinstall the previous version:",
|
|
104162
|
+
` ${buildManualRecoveryCommand(installCommand)}`
|
|
104163
|
+
], configDir, { targetVersion: payload.targetVersion });
|
|
104164
|
+
spawnDetachedDaemonRestart(restartArgv, payload.cwd);
|
|
104165
|
+
throw new Error(`Install failed and rollback failed for ${spec}: ${cause}`);
|
|
104166
|
+
}
|
|
104167
|
+
}
|
|
104168
|
+
emitUpgradeFailureNotice([
|
|
104169
|
+
`adhdev ${spec} install failed (${cause}); the previous version was ${backup ? "restored" : "left as-is (no snapshot available)"}.`,
|
|
104170
|
+
`The daemon was restarted on the previous version. See ${getUpgradeLogPath(configDir)} for the full trace.`,
|
|
104171
|
+
"To retry manually:",
|
|
104172
|
+
` ${buildManualRecoveryCommand(installCommand)}`
|
|
104173
|
+
], configDir, { targetVersion: payload.targetVersion });
|
|
104174
|
+
spawnDetachedDaemonRestart(restartArgv, payload.cwd);
|
|
104175
|
+
};
|
|
104176
|
+
let installOutput = "";
|
|
104177
|
+
try {
|
|
104178
|
+
installOutput = String((0, import_child_process8.execFileSync)(
|
|
104179
|
+
installCommand.command,
|
|
104180
|
+
installCommand.args,
|
|
104181
|
+
{
|
|
104182
|
+
encoding: "utf8",
|
|
104183
|
+
stdio: "pipe",
|
|
104184
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
104185
|
+
env: buildInstallEnvWithNodeOnPath(),
|
|
104186
|
+
...installCommand.execOptions
|
|
104187
|
+
}
|
|
104188
|
+
));
|
|
104189
|
+
} catch (error48) {
|
|
104190
|
+
rollbackAndRestart(`npm install exited non-zero: ${error48?.message || String(error48)}`);
|
|
104191
|
+
throw error48;
|
|
104192
|
+
}
|
|
104193
|
+
if (installOutput.trim()) {
|
|
104194
|
+
appendUpgradeLog(installOutput.trim());
|
|
104195
|
+
}
|
|
104196
|
+
if (installPrefix) {
|
|
104197
|
+
try {
|
|
104198
|
+
smokeTestInstalledBins(installPrefix, payload.packageName);
|
|
104199
|
+
} catch (error48) {
|
|
104200
|
+
rollbackAndRestart(`installed CLI failed its --version smoke test: ${error48?.message || String(error48)}`);
|
|
104201
|
+
throw error48;
|
|
104202
|
+
}
|
|
104203
|
+
}
|
|
104204
|
+
if (backup) {
|
|
104205
|
+
safeRemoveStaleEntry(backup.backupDir, "Removed upgrade backup after successful install");
|
|
104206
|
+
}
|
|
104207
|
+
spawnDetachedDaemonRestart(restartArgv, payload.cwd);
|
|
104208
|
+
clearUpgradeFailureNotice();
|
|
104209
|
+
}
|
|
103865
104210
|
function spawnDetachedDaemonUpgradeHelper(payload) {
|
|
103866
104211
|
const env2 = buildUpgradeHelperChildEnv(payload);
|
|
103867
104212
|
const child = (0, import_child_process9.spawn)(process.execPath, process.argv.slice(1), {
|
|
@@ -103986,6 +104331,10 @@ ${marker}`,
|
|
|
103986
104331
|
}
|
|
103987
104332
|
await stopForeignNativeAddonHolders(installCommand.surface.packageRoot, { parentPid: payload.parentPid });
|
|
103988
104333
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
104334
|
+
if (process.platform !== "win32") {
|
|
104335
|
+
runPosixInPlaceUpgrade({ payload, installCommand, restartArgv });
|
|
104336
|
+
return;
|
|
104337
|
+
}
|
|
103989
104338
|
const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
|
|
103990
104339
|
appendUpgradeLog(`Installing ${spec}`);
|
|
103991
104340
|
const maxInstallAttempts = process.platform === "win32" ? 3 : 1;
|
|
@@ -104104,6 +104453,7 @@ ${marker}`,
|
|
|
104104
104453
|
init_build_info();
|
|
104105
104454
|
init_track_identity();
|
|
104106
104455
|
init_coordinator_registry();
|
|
104456
|
+
init_mesh_refine_executor_liveness();
|
|
104107
104457
|
init_types();
|
|
104108
104458
|
init_deps();
|
|
104109
104459
|
init_refresh();
|
|
@@ -104141,7 +104491,15 @@ ${marker}`,
|
|
|
104141
104491
|
// that omits this field must remain "unknown" to remote consumers.
|
|
104142
104492
|
daemonBuild: { ...getDaemonBuildInfo(), track: TRACK },
|
|
104143
104493
|
upgradeFailure: readUpgradeFailureNotice(),
|
|
104144
|
-
providerChannelStaleness: ctx.deps.providerLoader?.getChannelStalenessSnapshot?.() ?? null
|
|
104494
|
+
providerChannelStaleness: ctx.deps.providerLoader?.getChannelStalenessSnapshot?.() ?? null,
|
|
104495
|
+
// Per-process id, minted once at module load (mesh-refine-executor-
|
|
104496
|
+
// liveness.ts) — differs across a real process restart even if the
|
|
104497
|
+
// OS reissues the same pid, unlike daemonBuild.builtAt (build time,
|
|
104498
|
+
// not boot time) or machine uptime (survives a daemon restart
|
|
104499
|
+
// untouched). A coordinator that called restart_daemon_node can
|
|
104500
|
+
// read this before and after (per the clientHint retry delay) and
|
|
104501
|
+
// compare: same id means the daemon never actually exited/re-spawned.
|
|
104502
|
+
bootId: currentRefineExecutorBootId()
|
|
104145
104503
|
};
|
|
104146
104504
|
},
|
|
104147
104505
|
/**
|
|
@@ -104575,15 +104933,17 @@ ${marker}`,
|
|
|
104575
104933
|
if (direction !== null && direction < 0) {
|
|
104576
104934
|
LOG2.warn("Upgrade", `allowDowngrade set \u2014 proceeding with DOWNGRADE from v${runningVersion} to v${latest} on the ${TRACK} track`);
|
|
104577
104935
|
}
|
|
104936
|
+
const killSessionHost = args?.killSessionHost === true;
|
|
104578
104937
|
spawnDetachedDaemonUpgradeHelper({
|
|
104579
104938
|
packageName: pkgName,
|
|
104580
104939
|
targetVersion: latest,
|
|
104581
104940
|
parentPid: process.pid,
|
|
104582
104941
|
restartArgv: process.argv.slice(1),
|
|
104583
104942
|
cwd: process.cwd(),
|
|
104584
|
-
sessionHostAppName: resolveSessionHostAppName()
|
|
104943
|
+
sessionHostAppName: resolveSessionHostAppName(),
|
|
104944
|
+
killSessionHost
|
|
104585
104945
|
});
|
|
104586
|
-
LOG2.info("Upgrade", `Scheduled detached ${TRACK} upgrade to v${latest}`);
|
|
104946
|
+
LOG2.info("Upgrade", `Scheduled detached ${TRACK} upgrade to v${latest}${killSessionHost ? " (killSessionHost requested)" : ""}`);
|
|
104587
104947
|
setTimeout(() => {
|
|
104588
104948
|
LOG2.info("Upgrade", "Exiting daemon so detached upgrader can continue...");
|
|
104589
104949
|
process.exit(0);
|
|
@@ -104597,6 +104957,7 @@ ${marker}`,
|
|
|
104597
104957
|
npmTag,
|
|
104598
104958
|
outcome: "scheduled",
|
|
104599
104959
|
targetVersion: latest,
|
|
104960
|
+
killSessionHost,
|
|
104600
104961
|
// No `currentVersion` here on purpose: this response is about a
|
|
104601
104962
|
// SCHEDULED move, and daemon-upgrade-scheduled-intent.test.ts
|
|
104602
104963
|
// pins that it must not read as "already on the target". The
|
|
@@ -126232,12 +126593,12 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
126232
126593
|
warnings.push("forced restart over active sessions \u2014 in-flight turns were interrupted and the in-memory pendingOutboundQueue is permanently lost (no persistence/restore path).");
|
|
126233
126594
|
}
|
|
126234
126595
|
if (args.killSessionHost) {
|
|
126235
|
-
warnings.push("killSessionHost: the session-host process
|
|
126596
|
+
warnings.push("killSessionHost requested: the detached restart helper will attempt to stop the session-host process after this daemon exits \u2014 if it succeeds, ALL hosted CLI sessions on this machine are destroyed (hard refresh). This response cannot confirm the stop succeeded; check the daemon's upgrade log, or call get_status_metadata and compare bootId before/after, to verify.");
|
|
126236
126597
|
}
|
|
126237
126598
|
if (process.platform === "win32") {
|
|
126238
|
-
warnings.push("Windows: the daemon restart/upgrade path
|
|
126599
|
+
warnings.push("Windows: the daemon restart/upgrade path attempts to stop the session-host regardless of options \u2014 all hosted sessions are expected to terminate.");
|
|
126239
126600
|
} else {
|
|
126240
|
-
warnings.push("POSIX: hosted PTY sessions survive a plain daemon restart and rebind on next boot
|
|
126601
|
+
warnings.push("POSIX: hosted PTY sessions are expected to survive a plain daemon restart and rebind on next boot, unless killSessionHost was requested (and the stop attempt succeeds).");
|
|
126241
126602
|
}
|
|
126242
126603
|
return warnings;
|
|
126243
126604
|
}
|
|
@@ -126250,6 +126611,11 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
126250
126611
|
...result,
|
|
126251
126612
|
mode,
|
|
126252
126613
|
restarted: restarting,
|
|
126614
|
+
// HONESTY: what was REQUESTED, always reported regardless of outcome
|
|
126615
|
+
// (which this process cannot know — see restartWarnings). Do not
|
|
126616
|
+
// rename this to something implying success; sessionHostKillRequested
|
|
126617
|
+
// is the accurate name for "the flag was set and forwarded".
|
|
126618
|
+
sessionHostKillRequested: killSessionHost,
|
|
126253
126619
|
...restarting ? {
|
|
126254
126620
|
warnings: restartWarnings({ killSessionHost, forced: opts.forced }),
|
|
126255
126621
|
// MCP IPC has no automatic reconnect/retry — tell the caller when to
|
|
@@ -139000,835 +139366,69 @@ data: ${JSON.stringify(msg.data)}
|
|
|
139000
139366
|
};
|
|
139001
139367
|
}
|
|
139002
139368
|
init_require_whitelist();
|
|
139003
|
-
|
|
139004
|
-
|
|
139005
|
-
|
|
139006
|
-
|
|
139007
|
-
|
|
139008
|
-
|
|
139009
|
-
|
|
139010
|
-
|
|
139011
|
-
|
|
139012
|
-
|
|
139013
|
-
|
|
139014
|
-
|
|
139015
|
-
|
|
139369
|
+
var import_fs21 = require("fs");
|
|
139370
|
+
var import_path24 = require("path");
|
|
139371
|
+
init_config();
|
|
139372
|
+
init_logger();
|
|
139373
|
+
var FLEET_SECRET_FILE = "seqscribe-fleet-secret.json";
|
|
139374
|
+
function fleetSecretPath(env2) {
|
|
139375
|
+
return (0, import_path24.join)(getConfigDir2(env2), FLEET_SECRET_FILE);
|
|
139376
|
+
}
|
|
139377
|
+
function loadStoredFleetSecret(env2) {
|
|
139378
|
+
const path63 = fleetSecretPath(env2);
|
|
139379
|
+
if (!(0, import_fs21.existsSync)(path63)) return null;
|
|
139380
|
+
let raw;
|
|
139381
|
+
try {
|
|
139382
|
+
raw = (0, import_fs21.readFileSync)(path63, "utf-8");
|
|
139383
|
+
} catch (err) {
|
|
139384
|
+
LOG2.warn(
|
|
139385
|
+
"Seqscribe",
|
|
139386
|
+
`fleet secret file unreadable (${err instanceof Error ? err.message : String(err)}); ignoring it`
|
|
139387
|
+
);
|
|
139388
|
+
return null;
|
|
139016
139389
|
}
|
|
139017
139390
|
try {
|
|
139018
|
-
const
|
|
139019
|
-
|
|
139020
|
-
|
|
139021
|
-
|
|
139391
|
+
const parsed = JSON.parse(raw);
|
|
139392
|
+
if (parsed !== null && typeof parsed === "object" && typeof parsed.secret === "string" && parsed.secret.length > 0 && Number.isInteger(parsed.version) && parsed.version >= 1) {
|
|
139393
|
+
const { secret, version: version2 } = parsed;
|
|
139394
|
+
return { secret, version: version2 };
|
|
139022
139395
|
}
|
|
139023
139396
|
} catch {
|
|
139024
139397
|
}
|
|
139025
|
-
|
|
139026
|
-
|
|
139027
|
-
|
|
139028
|
-
|
|
139029
|
-
|
|
139030
|
-
|
|
139031
|
-
// factory from drifting (the launch path once dropped userDir/sourceMode).
|
|
139032
|
-
...providerLoaderConfigOptions(appConfig),
|
|
139033
|
-
// The boot path resolves sourceMode with an explicit 'normal' default
|
|
139034
|
-
// for the disableUpstream derivation above — keep that authoritative.
|
|
139035
|
-
sourceMode: providerSourceMode,
|
|
139036
|
-
// Enables the daemon-update = provider-activation stamp (option C):
|
|
139037
|
-
// a boot on a NEW daemon version runs one verified sync; same-version
|
|
139038
|
-
// boots stay network-free.
|
|
139039
|
-
daemonVersion: config2.statusVersion
|
|
139040
|
-
});
|
|
139041
|
-
providerLoader.loadAll();
|
|
139042
|
-
providerLoader.registerToDetector();
|
|
139043
|
-
const hasExplicitChannelSignal = Boolean(
|
|
139044
|
-
appConfig.providerChannel && appConfig.providerChannel.trim() || (process.env[PROVIDER_CHANNEL_ENV_VAR] ?? "").trim() || isPreviewReleaseChannel(appConfig.updateChannel)
|
|
139045
|
-
);
|
|
139046
|
-
const resolvedConfigDir = getConfigDir2();
|
|
139047
|
-
const channelMismatch = configDirChannelMismatch(resolvedConfigDir, providerLoader.channel, hasExplicitChannelSignal);
|
|
139048
|
-
if (channelMismatch) {
|
|
139049
|
-
LOG2.warn("Init", `Config dir looks like the ${channelMismatch.impliedTrack} track (${resolvedConfigDir}) but the resolved provider channel is '${channelMismatch.channel}'. This usually means the build-track stamp (__ADHDEV_BUILD_CHANNEL__) was absent for this process \u2014 e.g. running via tsx/ts-node instead of a built bundle \u2014 so provider-channel resolution fell through to its 'stable' default instead of following ADHDEV_CONFIG_DIR. Impact: providers installed under the OTHER channel's store will not be visible (can present as 0 providers loaded). Fix: set ADHDEV_PROVIDER_CHANNEL=${channelMismatch.impliedTrack} (or config.providerChannel) explicitly for this process, or run the built bundle instead of source.`);
|
|
139398
|
+
LOG2.warn("Seqscribe", "fleet secret file is malformed; ignoring it (provisional mode)");
|
|
139399
|
+
return null;
|
|
139400
|
+
}
|
|
139401
|
+
function storeFleetSecret(secret, version2, env2) {
|
|
139402
|
+
if (typeof secret !== "string" || secret.length === 0) {
|
|
139403
|
+
throw new Error("storeFleetSecret requires a non-empty secret string");
|
|
139050
139404
|
}
|
|
139051
|
-
|
|
139052
|
-
|
|
139053
|
-
|
|
139054
|
-
|
|
139055
|
-
|
|
139056
|
-
|
|
139057
|
-
|
|
139058
|
-
|
|
139059
|
-
|
|
139060
|
-
|
|
139061
|
-
|
|
139062
|
-
|
|
139063
|
-
if (firstSyncReport) return;
|
|
139064
|
-
const report = await providerLoader.maybeSyncVerifiedChannelOnDaemonUpdate();
|
|
139065
|
-
if (!report) return;
|
|
139066
|
-
if (report.status === "error") {
|
|
139067
|
-
LOG2.warn("Init", `Daemon-update channel sync failed (last-known-good preserved, retries next boot): ${report.errors.map((e) => e.code).join(", ") || "unknown"}`);
|
|
139068
|
-
} else if (report.activated.length > 0) {
|
|
139069
|
-
LOG2.info("Init", `Daemon-update channel sync activated ${report.activated.length} providers (${providerLoader.channel})`);
|
|
139070
|
-
providerLoader.registerToDetector();
|
|
139071
|
-
await refreshProviderAvailability();
|
|
139072
|
-
config2.onStatusChange?.();
|
|
139073
|
-
}
|
|
139074
|
-
}).catch((e) => LOG2.warn("Init", `Verified channel boot sync error: ${e?.message || e}`));
|
|
139075
|
-
const runStalenessProbe = async () => {
|
|
139076
|
-
try {
|
|
139077
|
-
const snap = await providerLoader.checkVerifiedChannelStaleness();
|
|
139078
|
-
if (snap.error) {
|
|
139079
|
-
LOG2.debug("Provider", `Channel staleness probe failed (kept previous snapshot): ${snap.error}`);
|
|
139080
|
-
} else if (snap.staleTypes.length > 0 || snap.newTypes.length > 0) {
|
|
139081
|
-
LOG2.info("Provider", `Channel staleness: ${snap.staleTypes.length} stale [${snap.staleTypes.join(", ")}], ${snap.newTypes.length} never-installed [${snap.newTypes.join(", ")}] (${snap.channel})`);
|
|
139082
|
-
config2.onStatusChange?.();
|
|
139083
|
-
}
|
|
139084
|
-
} catch (e) {
|
|
139085
|
-
LOG2.debug("Provider", `Channel staleness probe error: ${e?.message || e}`);
|
|
139086
|
-
}
|
|
139087
|
-
};
|
|
139088
|
-
const stalenessInitialTimer = setTimeout(() => {
|
|
139089
|
-
void runStalenessProbe();
|
|
139090
|
-
}, 10 * 6e4);
|
|
139091
|
-
stalenessInitialTimer.unref?.();
|
|
139092
|
-
const stalenessIntervalTimer = setInterval(() => {
|
|
139093
|
-
void runStalenessProbe();
|
|
139094
|
-
}, 24 * 60 * 6e4);
|
|
139095
|
-
stalenessIntervalTimer.unref?.();
|
|
139096
|
-
const providerStalenessProbe = {
|
|
139097
|
-
stop() {
|
|
139098
|
-
clearTimeout(stalenessInitialTimer);
|
|
139099
|
-
clearInterval(stalenessIntervalTimer);
|
|
139100
|
-
}
|
|
139101
|
-
};
|
|
139102
|
-
setDefaultProviderLoader(providerLoader);
|
|
139103
|
-
const versionArchive = new VersionArchive();
|
|
139104
|
-
providerLoader.setVersionArchive(versionArchive);
|
|
139105
|
-
setTimeout(() => {
|
|
139106
|
-
void detectAllVersions(providerLoader, versionArchive).then((versionResults) => {
|
|
139107
|
-
const installedProviders = versionResults.filter((v) => v.installed);
|
|
139108
|
-
const withVersion = installedProviders.filter((v) => v.version);
|
|
139109
|
-
LOG2.info("Init", `Provider versions: ${installedProviders.length} installed, ${withVersion.length} versioned`);
|
|
139110
|
-
for (const v of withVersion) {
|
|
139111
|
-
LOG2.info("Init", ` ${v.type} (${v.category}): v${v.version}${v.warning ? " \u26A0 " + v.warning : ""}`);
|
|
139112
|
-
}
|
|
139113
|
-
const noVersion = installedProviders.filter((v) => !v.version);
|
|
139114
|
-
if (noVersion.length > 0) {
|
|
139115
|
-
LOG2.warn("Init", ` ${noVersion.length} installed but version unknown: ${noVersion.map((v) => v.type).join(", ")}`);
|
|
139116
|
-
}
|
|
139117
|
-
}).catch(() => {
|
|
139118
|
-
});
|
|
139119
|
-
}, 0);
|
|
139120
|
-
const instanceManager = new ProviderInstanceManager();
|
|
139121
|
-
const cdpManagers = /* @__PURE__ */ new Map();
|
|
139122
|
-
const sessionRegistry = new SessionRegistry();
|
|
139123
|
-
setTranscriptClaimLivenessProbe((owner) => {
|
|
139124
|
-
const match = /^iid:(.+)$/.exec(owner);
|
|
139125
|
-
if (!match) return true;
|
|
139126
|
-
return sessionRegistry.get(match[1]) !== void 0;
|
|
139127
|
-
});
|
|
139128
|
-
const detectedIdesRef = { value: [] };
|
|
139129
|
-
let agentStreamManager = null;
|
|
139130
|
-
let poller = null;
|
|
139131
|
-
const refreshProviderAvailability = async (providerType) => {
|
|
139132
|
-
const targetProvider = providerType ? providerLoader.getMeta(providerLoader.resolveAlias(providerType)) : null;
|
|
139133
|
-
const targetCategory = targetProvider?.category;
|
|
139134
|
-
if (!providerType || targetCategory === "cli" || targetCategory === "acp") {
|
|
139135
|
-
if (providerType && targetProvider) {
|
|
139136
|
-
const detected = await detectCLI(targetProvider.type, providerLoader, { includeVersion: false });
|
|
139137
|
-
providerLoader.setCliDetectionResults([{
|
|
139138
|
-
id: targetProvider.type,
|
|
139139
|
-
installed: !!detected,
|
|
139140
|
-
path: detected?.path
|
|
139141
|
-
}], false);
|
|
139142
|
-
} else {
|
|
139143
|
-
providerLoader.setCliDetectionResults(await detectCLIs(providerLoader, { includeVersion: false }), true);
|
|
139144
|
-
}
|
|
139145
|
-
}
|
|
139146
|
-
if (!providerType || targetCategory === "ide") {
|
|
139147
|
-
detectedIdesRef.value = await detectIDEs(providerLoader);
|
|
139148
|
-
providerLoader.setIdeDetectionResults(detectedIdesRef.value, true);
|
|
139149
|
-
}
|
|
139150
|
-
};
|
|
139151
|
-
const cliManager = new DaemonCliManager({
|
|
139152
|
-
...config2.cliManagerDeps,
|
|
139153
|
-
getInstanceManager: () => instanceManager,
|
|
139154
|
-
getSessionRegistry: () => sessionRegistry
|
|
139155
|
-
}, providerLoader);
|
|
139156
|
-
LOG2.info("Init", "Detecting IDEs...");
|
|
139157
|
-
await refreshProviderAvailability();
|
|
139158
|
-
const installed = detectedIdesRef.value.filter((i) => i.installed);
|
|
139159
|
-
LOG2.info("Init", `Found ${installed.length} IDE(s): ${installed.map((i) => i.id).join(", ") || "none"}`);
|
|
139160
|
-
const cdpSetupContext = {
|
|
139161
|
-
providerLoader,
|
|
139162
|
-
instanceManager,
|
|
139163
|
-
cdpManagers,
|
|
139164
|
-
sessionRegistry
|
|
139165
|
-
};
|
|
139166
|
-
const cdpInitializer = new DaemonCdpInitializer({
|
|
139167
|
-
providerLoader,
|
|
139168
|
-
cdpManagers,
|
|
139169
|
-
enabledIdes: config2.enabledIdes || loadConfig2().enabledIdes || void 0,
|
|
139170
|
-
onConnected: async (ideType, manager, managerKey) => {
|
|
139171
|
-
await setupIdeInstance(cdpSetupContext, { ideType, manager, managerKey });
|
|
139172
|
-
await config2.onCdpManagerSetup?.(ideType, manager, managerKey);
|
|
139173
|
-
},
|
|
139174
|
-
onDisconnected: async (_ideType, _manager, managerKey) => {
|
|
139175
|
-
sessionRegistry.unregisterByManagerKey(managerKey);
|
|
139176
|
-
const instanceKey = `ide:${managerKey}`;
|
|
139177
|
-
const ideInstance = instanceManager.getInstance(instanceKey);
|
|
139178
|
-
if (ideInstance) {
|
|
139179
|
-
instanceManager.removeInstance(instanceKey);
|
|
139180
|
-
LOG2.info("IDE", `Instance removed after detach: ${instanceKey}`);
|
|
139181
|
-
}
|
|
139182
|
-
if (ideInstance?.getInstanceId) {
|
|
139183
|
-
agentStreamManager?.resetParentSession(ideInstance.getInstanceId());
|
|
139184
|
-
}
|
|
139185
|
-
config2.onStatusChange?.();
|
|
139186
|
-
}
|
|
139187
|
-
});
|
|
139188
|
-
await cdpInitializer.connectAll(detectedIdesRef.value);
|
|
139189
|
-
cdpInitializer.startPeriodicScan(config2.cdpScanIntervalMs ?? DEFAULT_CDP_SCAN_INTERVAL_MS);
|
|
139190
|
-
cdpInitializer.startDiscovery(DEFAULT_CDP_DISCOVERY_INTERVAL_MS);
|
|
139191
|
-
const commandHandler = new DaemonCommandHandler({
|
|
139192
|
-
cdpManagers,
|
|
139193
|
-
ideType: "unknown",
|
|
139194
|
-
adapters: cliManager.adapters,
|
|
139195
|
-
providerLoader,
|
|
139196
|
-
instanceManager,
|
|
139197
|
-
sessionRegistry,
|
|
139198
|
-
gitCommandServices: createDefaultGitCommandServices({
|
|
139199
|
-
// T7: fold this daemon's cached provider versions + build version onto the
|
|
139200
|
-
// git_status envelope so the mesh coordinator self-heals each node's
|
|
139201
|
-
// providerVersions/build (the blue version chips) — these are per-machine
|
|
139202
|
-
// RUNTIME facts (e.g. this node has claude-cli@2.1.168 while the
|
|
139203
|
-
// coordinator has @2.1.170), so they stay reported. Non-blocking: reads a
|
|
139204
|
-
// TTL cache, lazily refreshed. (setDefaultProviderLoader is registered
|
|
139205
|
-
// above so getCachedProviderVersions is not empty — see the 380556d3
|
|
139206
|
-
// version-chip lesson.)
|
|
139207
|
-
//
|
|
139208
|
-
// Slots are NOT reported: they are coordinator-owned config
|
|
139209
|
-
// (node.policy.slots for every node, resolved via
|
|
139210
|
-
// resolveNodeCapabilitySlots), not a per-machine runtime fact — the
|
|
139211
|
-
// reporter round-trip for slots was removed (REMOTE-NODE-SLOTS-
|
|
139212
|
-
// COORDINATOR-LOCAL fix).
|
|
139213
|
-
getReporterProviderVersions: () => {
|
|
139214
|
-
const providerVersions = getCachedProviderVersions(providerLoader);
|
|
139215
|
-
const daemonBuildVersion = getDaemonBuildInfo().version;
|
|
139216
|
-
return {
|
|
139217
|
-
...Object.keys(providerVersions).length > 0 ? { providerVersions } : {},
|
|
139218
|
-
...daemonBuildVersion && daemonBuildVersion !== "unknown" ? { daemonBuildVersion } : {}
|
|
139219
|
-
};
|
|
139220
|
-
}
|
|
139221
|
-
}),
|
|
139222
|
-
onProviderSettingChanged: async (providerType) => {
|
|
139223
|
-
await refreshProviderAvailability(providerType);
|
|
139224
|
-
config2.onStatusChange?.();
|
|
139225
|
-
},
|
|
139226
|
-
onProviderSourceConfigChanged: async () => {
|
|
139227
|
-
await refreshProviderAvailability();
|
|
139228
|
-
config2.onStatusChange?.();
|
|
139229
|
-
},
|
|
139230
|
-
onBeforeSendChat: config2.onBeforeSendChat
|
|
139231
|
-
});
|
|
139232
|
-
agentStreamManager = new DaemonAgentStreamManager(
|
|
139233
|
-
LOG2.forComponent("AgentStream").asLogFn(),
|
|
139234
|
-
providerLoader,
|
|
139235
|
-
sessionRegistry
|
|
139236
|
-
);
|
|
139237
|
-
commandHandler.setAgentStreamManager(agentStreamManager);
|
|
139238
|
-
const router = new DaemonCommandRouter({
|
|
139239
|
-
commandHandler,
|
|
139240
|
-
cliManager,
|
|
139241
|
-
cdpManagers,
|
|
139242
|
-
providerLoader,
|
|
139243
|
-
instanceManager,
|
|
139244
|
-
detectedIdes: detectedIdesRef,
|
|
139245
|
-
sessionRegistry,
|
|
139246
|
-
onCdpManagerCreated: async (ideType, manager) => {
|
|
139247
|
-
await setupIdeInstance(cdpSetupContext, { ideType, manager });
|
|
139248
|
-
await config2.onCdpManagerSetup?.(ideType, manager, ideType);
|
|
139249
|
-
},
|
|
139250
|
-
onIdeConnected: () => poller?.start(),
|
|
139251
|
-
onStatusChange: config2.onStatusChange,
|
|
139252
|
-
onMeshStateChange: config2.onMeshStateChange,
|
|
139253
|
-
onPostChatCommand: config2.onPostChatCommand,
|
|
139254
|
-
sessionHostControl: config2.sessionHostControl,
|
|
139255
|
-
statusInstanceId: config2.statusInstanceId,
|
|
139256
|
-
statusVersion: config2.statusVersion,
|
|
139257
|
-
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
139258
|
-
dispatchMeshCommand: config2.dispatchMeshCommand,
|
|
139259
|
-
updateLocalMeshOwnedSession: config2.updateLocalMeshOwnedSession,
|
|
139260
|
-
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG2.forComponent(`CDP:${ideType}`).asLogFn())
|
|
139261
|
-
});
|
|
139262
|
-
poller = new AgentStreamPoller({
|
|
139263
|
-
agentStreamManager,
|
|
139264
|
-
providerLoader,
|
|
139265
|
-
instanceManager,
|
|
139266
|
-
cdpManagers,
|
|
139267
|
-
sessionRegistry,
|
|
139268
|
-
onStreamsUpdated: config2.onStreamsUpdated
|
|
139405
|
+
if (!Number.isInteger(version2) || version2 < 1) {
|
|
139406
|
+
throw new Error("storeFleetSecret requires an integer version >= 1");
|
|
139407
|
+
}
|
|
139408
|
+
const dir = getConfigDir2(env2);
|
|
139409
|
+
if (!(0, import_fs21.existsSync)(dir)) {
|
|
139410
|
+
(0, import_fs21.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
139411
|
+
}
|
|
139412
|
+
const path63 = (0, import_path24.join)(dir, FLEET_SECRET_FILE);
|
|
139413
|
+
const tmp = `${path63}.tmp-${process.pid}`;
|
|
139414
|
+
(0, import_fs21.writeFileSync)(tmp, JSON.stringify({ secret, version: version2 }, null, 2), {
|
|
139415
|
+
encoding: "utf-8",
|
|
139416
|
+
mode: 384
|
|
139269
139417
|
});
|
|
139270
|
-
poller.start();
|
|
139271
|
-
instanceManager.startTicking(config2.tickIntervalMs ?? 5e3);
|
|
139272
|
-
const components = {
|
|
139273
|
-
providerLoader,
|
|
139274
|
-
instanceManager,
|
|
139275
|
-
cliManager,
|
|
139276
|
-
commandHandler,
|
|
139277
|
-
agentStreamManager,
|
|
139278
|
-
router,
|
|
139279
|
-
poller,
|
|
139280
|
-
cdpInitializer,
|
|
139281
|
-
cdpManagers,
|
|
139282
|
-
sessionRegistry,
|
|
139283
|
-
detectedIdes: detectedIdesRef,
|
|
139284
|
-
refreshProviderAvailability,
|
|
139285
|
-
dispatchMeshCommand: config2.dispatchMeshCommand,
|
|
139286
|
-
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
139287
|
-
onMeshCoordinatorEventForwarded: config2.onMeshCoordinatorEventForwarded,
|
|
139288
|
-
statusInstanceId: config2.statusInstanceId
|
|
139289
|
-
};
|
|
139290
|
-
setupMeshEventForwarding(components);
|
|
139291
139418
|
try {
|
|
139292
|
-
|
|
139293
|
-
} catch {
|
|
139294
|
-
}
|
|
139295
|
-
components.meshReconcileLoop = setupMeshReconcileLoop(components);
|
|
139296
|
-
components.quotaRefreshLoop = setupQuotaRefreshLoop(components);
|
|
139297
|
-
components.quotaEventRefresh = setupQuotaEventRefresh(components);
|
|
139298
|
-
components.providerStalenessProbe = providerStalenessProbe;
|
|
139299
|
-
setImmediate(() => {
|
|
139300
|
-
const isQuotaProviderEnabled = quotaProviderEnabledFromLoader(components.providerLoader);
|
|
139419
|
+
(0, import_fs21.renameSync)(tmp, path63);
|
|
139420
|
+
} catch (err) {
|
|
139301
139421
|
try {
|
|
139302
|
-
|
|
139422
|
+
(0, import_fs21.unlinkSync)(tmp);
|
|
139303
139423
|
} catch {
|
|
139304
139424
|
}
|
|
139305
|
-
|
|
139306
|
-
});
|
|
139307
|
-
setImmediate(() => void router.resumePendingRefineJobsOnStartup());
|
|
139308
|
-
components.eventLoopMonitor = startEventLoopMonitor();
|
|
139309
|
-
setImmediate(() => router.resumeDeferredRestartsOnStartup());
|
|
139310
|
-
return components;
|
|
139311
|
-
}
|
|
139312
|
-
async function startDaemonDevSupport2(options) {
|
|
139313
|
-
const devServer = new DevServer({
|
|
139314
|
-
providerLoader: options.components.providerLoader,
|
|
139315
|
-
cdpManagers: options.components.cdpManagers,
|
|
139316
|
-
instanceManager: options.components.instanceManager,
|
|
139317
|
-
cliManager: options.components.cliManager,
|
|
139318
|
-
logFn: options.logFn,
|
|
139319
|
-
onProviderSourceConfigChanged: async () => {
|
|
139320
|
-
await options.components.refreshProviderAvailability();
|
|
139321
|
-
}
|
|
139322
|
-
});
|
|
139323
|
-
await devServer.start();
|
|
139324
|
-
options.components.providerLoader.watch();
|
|
139325
|
-
return devServer;
|
|
139326
|
-
}
|
|
139327
|
-
async function shutdownDaemonComponents2(components) {
|
|
139328
|
-
const {
|
|
139329
|
-
poller,
|
|
139330
|
-
cdpInitializer,
|
|
139331
|
-
agentStreamManager,
|
|
139332
|
-
cliManager,
|
|
139333
|
-
instanceManager,
|
|
139334
|
-
cdpManagers,
|
|
139335
|
-
meshReconcileLoop,
|
|
139336
|
-
quotaRefreshLoop,
|
|
139337
|
-
quotaEventRefresh,
|
|
139338
|
-
providerStalenessProbe,
|
|
139339
|
-
eventLoopMonitor
|
|
139340
|
-
} = components;
|
|
139341
|
-
poller.stop();
|
|
139342
|
-
cdpInitializer.stop();
|
|
139343
|
-
try {
|
|
139344
|
-
eventLoopMonitor?.stop();
|
|
139345
|
-
} catch {
|
|
139346
|
-
}
|
|
139347
|
-
try {
|
|
139348
|
-
meshReconcileLoop?.stop();
|
|
139349
|
-
} catch {
|
|
139350
|
-
}
|
|
139351
|
-
try {
|
|
139352
|
-
quotaRefreshLoop?.stop();
|
|
139353
|
-
} catch {
|
|
139425
|
+
throw err;
|
|
139354
139426
|
}
|
|
139355
139427
|
try {
|
|
139356
|
-
|
|
139428
|
+
(0, import_fs21.chmodSync)(path63, 384);
|
|
139357
139429
|
} catch {
|
|
139358
139430
|
}
|
|
139359
|
-
|
|
139360
|
-
providerStalenessProbe?.stop();
|
|
139361
|
-
} catch {
|
|
139362
|
-
}
|
|
139363
|
-
try {
|
|
139364
|
-
if (agentStreamManager) {
|
|
139365
|
-
await agentStreamManager.dispose(cdpManagers);
|
|
139366
|
-
}
|
|
139367
|
-
} catch (e) {
|
|
139368
|
-
LOG2.warn("Shutdown", `AgentStream dispose: ${e?.message}`);
|
|
139369
|
-
}
|
|
139370
|
-
try {
|
|
139371
|
-
cliManager.detachAll();
|
|
139372
|
-
} catch {
|
|
139373
|
-
}
|
|
139374
|
-
try {
|
|
139375
|
-
instanceManager.removeByCategory("cli", { dispose: false });
|
|
139376
|
-
} catch {
|
|
139377
|
-
}
|
|
139378
|
-
try {
|
|
139379
|
-
instanceManager.disposeAll();
|
|
139380
|
-
} catch {
|
|
139381
|
-
}
|
|
139382
|
-
for (const m of cdpManagers.values()) {
|
|
139383
|
-
try {
|
|
139384
|
-
m.disconnect();
|
|
139385
|
-
} catch {
|
|
139386
|
-
}
|
|
139387
|
-
}
|
|
139388
|
-
cdpManagers.clear();
|
|
139389
|
-
try {
|
|
139390
|
-
MeshRuntimeStore.getInstance().vacuum();
|
|
139391
|
-
} catch {
|
|
139392
|
-
}
|
|
139393
|
-
}
|
|
139394
|
-
var import_http2 = require("http");
|
|
139395
|
-
var import_ws22 = require("ws");
|
|
139396
|
-
init_logger();
|
|
139397
|
-
init_ipc_protocol();
|
|
139398
|
-
function buildIpcStatusHttpResponse(method, url2, payload) {
|
|
139399
|
-
if (method && method.toUpperCase() !== "GET") {
|
|
139400
|
-
return { statusCode: 405, body: { ok: false, error: "method not allowed" } };
|
|
139401
|
-
}
|
|
139402
|
-
const path63 = url2 ? url2.split("?")[0] : url2;
|
|
139403
|
-
const KNOWN_ROUTES = ["/", "/status", "/health", "/api/v1/status", "/api/status"];
|
|
139404
|
-
if (path63 && !KNOWN_ROUTES.includes(path63)) {
|
|
139405
|
-
return { statusCode: 404, body: { ok: false, error: "not found" } };
|
|
139406
|
-
}
|
|
139407
|
-
return { statusCode: 200, body: payload };
|
|
139408
|
-
}
|
|
139409
|
-
async function startLocalIpcServer2(opts) {
|
|
139410
|
-
const logCategory = opts.logCategory || "IPC";
|
|
139411
|
-
const clients = /* @__PURE__ */ new Set();
|
|
139412
|
-
let httpServer = null;
|
|
139413
|
-
let wss = null;
|
|
139414
|
-
let listening = false;
|
|
139415
|
-
httpServer = (0, import_http2.createServer)((req, res) => {
|
|
139416
|
-
const payload = {
|
|
139417
|
-
ok: true,
|
|
139418
|
-
pid: process.pid,
|
|
139419
|
-
wsPath: DAEMON_WS_PATH2,
|
|
139420
|
-
port: opts.port,
|
|
139421
|
-
status: opts.buildStatusPayload()
|
|
139422
|
-
};
|
|
139423
|
-
const response = buildIpcStatusHttpResponse(req.method, req.url, payload);
|
|
139424
|
-
const body = JSON.stringify(response.body);
|
|
139425
|
-
res.writeHead(response.statusCode, {
|
|
139426
|
-
"Content-Type": "application/json",
|
|
139427
|
-
"Content-Length": Buffer.byteLength(body),
|
|
139428
|
-
"Connection": "close"
|
|
139429
|
-
});
|
|
139430
|
-
res.end(body);
|
|
139431
|
-
});
|
|
139432
|
-
wss = new import_ws22.WebSocketServer({ noServer: true });
|
|
139433
|
-
wss.on("connection", (ws) => handleConnection(ws));
|
|
139434
|
-
httpServer.on("upgrade", (req, socket, head) => {
|
|
139435
|
-
const wsUrl = new URL(req.url || "/", `http://${req.headers.host || "127.0.0.1"}`);
|
|
139436
|
-
if (wsUrl.pathname !== DAEMON_WS_PATH2) {
|
|
139437
|
-
socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
|
|
139438
|
-
socket.destroy();
|
|
139439
|
-
return;
|
|
139440
|
-
}
|
|
139441
|
-
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
139442
|
-
wss.emit("connection", ws, req);
|
|
139443
|
-
});
|
|
139444
|
-
});
|
|
139445
|
-
function handleConnection(ws) {
|
|
139446
|
-
clients.add(ws);
|
|
139447
|
-
sendWelcome(ws);
|
|
139448
|
-
opts.onClientConnected?.(ws);
|
|
139449
|
-
ws.on("message", (raw) => {
|
|
139450
|
-
void handleMessage(ws, raw.toString());
|
|
139451
|
-
});
|
|
139452
|
-
ws.on("close", () => {
|
|
139453
|
-
clients.delete(ws);
|
|
139454
|
-
opts.onClientDisconnected?.(ws);
|
|
139455
|
-
});
|
|
139456
|
-
ws.on("error", () => {
|
|
139457
|
-
clients.delete(ws);
|
|
139458
|
-
opts.onClientDisconnected?.(ws);
|
|
139459
|
-
});
|
|
139460
|
-
}
|
|
139461
|
-
function sendWelcome(ws) {
|
|
139462
|
-
try {
|
|
139463
|
-
ws.send(JSON.stringify({
|
|
139464
|
-
type: "daemon:welcome",
|
|
139465
|
-
payload: opts.buildWelcomePayload()
|
|
139466
|
-
}));
|
|
139467
|
-
} catch (error48) {
|
|
139468
|
-
LOG2.warn(logCategory, `Failed to send welcome: ${error48?.message || error48}`);
|
|
139469
|
-
}
|
|
139470
|
-
}
|
|
139471
|
-
async function handleMessage(ws, raw) {
|
|
139472
|
-
let msg;
|
|
139473
|
-
try {
|
|
139474
|
-
msg = JSON.parse(raw);
|
|
139475
|
-
} catch {
|
|
139476
|
-
return;
|
|
139477
|
-
}
|
|
139478
|
-
if (!msg || typeof msg !== "object") return;
|
|
139479
|
-
if (msg.type === "ext:register") {
|
|
139480
|
-
sendWelcome(ws);
|
|
139481
|
-
return;
|
|
139482
|
-
}
|
|
139483
|
-
if (msg.type !== "ext:command") return;
|
|
139484
|
-
const payload = msg.payload && typeof msg.payload === "object" ? msg.payload : {};
|
|
139485
|
-
const command = typeof payload.command === "string" ? payload.command : "";
|
|
139486
|
-
const args = payload.args && typeof payload.args === "object" ? payload.args : {};
|
|
139487
|
-
const requestId = typeof payload.requestId === "string" ? payload.requestId : typeof payload.messageId === "string" ? payload.messageId : `ipc-${Date.now()}`;
|
|
139488
|
-
if (!command) {
|
|
139489
|
-
ws.send(JSON.stringify({
|
|
139490
|
-
type: "ext:command_result",
|
|
139491
|
-
payload: { requestId, success: false, error: "command required" }
|
|
139492
|
-
}));
|
|
139493
|
-
return;
|
|
139494
|
-
}
|
|
139495
|
-
try {
|
|
139496
|
-
const result = await opts.handleCommand({ command, args, requestId, ws });
|
|
139497
|
-
ws.send(JSON.stringify({
|
|
139498
|
-
type: "ext:command_result",
|
|
139499
|
-
payload: {
|
|
139500
|
-
requestId,
|
|
139501
|
-
success: result.success,
|
|
139502
|
-
result: result.result,
|
|
139503
|
-
error: result.error,
|
|
139504
|
-
...result.extra || {}
|
|
139505
|
-
}
|
|
139506
|
-
}));
|
|
139507
|
-
} catch (error48) {
|
|
139508
|
-
ws.send(JSON.stringify({
|
|
139509
|
-
type: "ext:command_result",
|
|
139510
|
-
payload: {
|
|
139511
|
-
requestId,
|
|
139512
|
-
success: false,
|
|
139513
|
-
error: error48?.message || String(error48)
|
|
139514
|
-
}
|
|
139515
|
-
}));
|
|
139516
|
-
}
|
|
139517
|
-
}
|
|
139518
|
-
await new Promise((resolve31, reject) => {
|
|
139519
|
-
const onError = (error48) => {
|
|
139520
|
-
httpServer?.off("listening", onListening);
|
|
139521
|
-
reject(error48);
|
|
139522
|
-
};
|
|
139523
|
-
const onListening = () => {
|
|
139524
|
-
httpServer?.off("error", onError);
|
|
139525
|
-
listening = true;
|
|
139526
|
-
resolve31();
|
|
139527
|
-
};
|
|
139528
|
-
httpServer.once("error", onError);
|
|
139529
|
-
httpServer.once("listening", onListening);
|
|
139530
|
-
httpServer.listen(opts.port, "127.0.0.1");
|
|
139531
|
-
});
|
|
139532
|
-
LOG2.info(logCategory, `Local IPC listening on ws://127.0.0.1:${opts.port}${DAEMON_WS_PATH2}`);
|
|
139533
|
-
return {
|
|
139534
|
-
isListening: () => listening,
|
|
139535
|
-
broadcast(type2, payload) {
|
|
139536
|
-
const message = JSON.stringify({ type: type2, payload });
|
|
139537
|
-
for (const client of clients) {
|
|
139538
|
-
if (client.readyState !== import_ws22.WebSocket.OPEN) continue;
|
|
139539
|
-
try {
|
|
139540
|
-
client.send(message);
|
|
139541
|
-
} catch {
|
|
139542
|
-
}
|
|
139543
|
-
}
|
|
139544
|
-
},
|
|
139545
|
-
async close() {
|
|
139546
|
-
for (const client of clients) {
|
|
139547
|
-
try {
|
|
139548
|
-
client.close();
|
|
139549
|
-
} catch {
|
|
139550
|
-
}
|
|
139551
|
-
}
|
|
139552
|
-
clients.clear();
|
|
139553
|
-
await new Promise((resolve31) => {
|
|
139554
|
-
if (!httpServer) {
|
|
139555
|
-
resolve31();
|
|
139556
|
-
return;
|
|
139557
|
-
}
|
|
139558
|
-
httpServer.close(() => resolve31());
|
|
139559
|
-
});
|
|
139560
|
-
httpServer = null;
|
|
139561
|
-
wss = null;
|
|
139562
|
-
listening = false;
|
|
139563
|
-
}
|
|
139564
|
-
};
|
|
139565
|
-
}
|
|
139566
|
-
init_fsm_evaluator();
|
|
139567
|
-
init_fsm_loader();
|
|
139568
|
-
var crypto8 = __toESM2(require("crypto"));
|
|
139569
|
-
var import_node_fs10 = require("fs");
|
|
139570
|
-
var import_node_path6 = require("path");
|
|
139571
|
-
init_provider_cli_shared();
|
|
139572
|
-
var import_node_fs11 = require("fs");
|
|
139573
|
-
var import_node_path7 = require("path");
|
|
139574
|
-
init_manifest();
|
|
139575
|
-
var V1_PRIMITIVE_CATALOG = Object.freeze({
|
|
139576
|
-
acp: [
|
|
139577
|
-
"adhdev:acp/session-protocol@1"
|
|
139578
|
-
],
|
|
139579
|
-
tui: [
|
|
139580
|
-
"adhdev:tui/prompt-marker@1",
|
|
139581
|
-
"adhdev:tui/spinner@1",
|
|
139582
|
-
"adhdev:tui/settled-prompt@1",
|
|
139583
|
-
"adhdev:tui/assistant-block@1",
|
|
139584
|
-
"adhdev:tui/tool-block@1",
|
|
139585
|
-
"adhdev:tui/thinking-block@1",
|
|
139586
|
-
"adhdev:tui/user-echo@1",
|
|
139587
|
-
"adhdev:tui/modal@1",
|
|
139588
|
-
"adhdev:tui/modal-as-message@1",
|
|
139589
|
-
"adhdev:tui/footer-chrome@1",
|
|
139590
|
-
"adhdev:tui/welcome-screen@1",
|
|
139591
|
-
"adhdev:tui/visible-region@1",
|
|
139592
|
-
"adhdev:tui/cue-ordering@1",
|
|
139593
|
-
"adhdev:tui/dispatch-order@1",
|
|
139594
|
-
"adhdev:tui/index-finder@1",
|
|
139595
|
-
"adhdev:tui/status-downgrade@1",
|
|
139596
|
-
"adhdev:tui/approval-stitching@1",
|
|
139597
|
-
"adhdev:tui/approval-squash@1",
|
|
139598
|
-
"adhdev:tui/media-input@1",
|
|
139599
|
-
"adhdev:tui/session-id-extraction@1",
|
|
139600
|
-
"adhdev:tui/error-detection@1"
|
|
139601
|
-
],
|
|
139602
|
-
nativeHistory: [
|
|
139603
|
-
"adhdev:native-history/codex-rollout@1",
|
|
139604
|
-
"adhdev:native-history/claude-jsonl@1",
|
|
139605
|
-
"adhdev:native-history/anthropic-cli-transcript@1",
|
|
139606
|
-
"adhdev:native-history/hermes-session@1"
|
|
139607
|
-
],
|
|
139608
|
-
cliCapability: [
|
|
139609
|
-
"adhdev:cli/capability-list@1",
|
|
139610
|
-
"adhdev:cli/control-state@1",
|
|
139611
|
-
"adhdev:cli/capability-action@1",
|
|
139612
|
-
"adhdev:cli/control-toggle@1",
|
|
139613
|
-
"adhdev:cli/picker-open@1",
|
|
139614
|
-
"adhdev:cli/picker-set@1"
|
|
139615
|
-
],
|
|
139616
|
-
common: [
|
|
139617
|
-
"adhdev:common/setting-boolean@1",
|
|
139618
|
-
"adhdev:common/setting-number@1",
|
|
139619
|
-
"adhdev:common/setting-string@1",
|
|
139620
|
-
"adhdev:common/setting-select@1",
|
|
139621
|
-
"adhdev:common/capability-input@1",
|
|
139622
|
-
"adhdev:common/capability-output@1",
|
|
139623
|
-
"adhdev:common/capability-controls@1",
|
|
139624
|
-
"adhdev:common/auth-env-var@1",
|
|
139625
|
-
"adhdev:common/auth-cli-command@1",
|
|
139626
|
-
"adhdev:common/spawn@1",
|
|
139627
|
-
"adhdev:common/timeouts@1",
|
|
139628
|
-
"adhdev:common/resume@1",
|
|
139629
|
-
"adhdev:common/mesh-coordinator@1"
|
|
139630
|
-
],
|
|
139631
|
-
override: [
|
|
139632
|
-
"adhdev:override/cli-parse-session@1",
|
|
139633
|
-
"adhdev:override/cli-detect-status@1",
|
|
139634
|
-
"adhdev:override/cli-parse-approval@1",
|
|
139635
|
-
"adhdev:override/cli-parse-output@1",
|
|
139636
|
-
"adhdev:override/cli-read-native-history@1",
|
|
139637
|
-
"adhdev:override/cli-list-native-history@1",
|
|
139638
|
-
"adhdev:override/cli-capability-handler@1"
|
|
139639
|
-
]
|
|
139640
|
-
});
|
|
139641
|
-
var V1_ALL_PRIMITIVES = Object.freeze(
|
|
139642
|
-
Object.values(V1_PRIMITIVE_CATALOG).flat()
|
|
139643
|
-
);
|
|
139644
|
-
var V1_CONTRACT_VERSION = "1.0.0";
|
|
139645
|
-
var fs65 = __toESM2(require("fs"));
|
|
139646
|
-
var import_chalk2 = __toESM2((init_source(), __toCommonJS(source_exports)));
|
|
139647
|
-
init_dist();
|
|
139648
|
-
var CLAUDE_NO_API_LINE = "Claude has no quota API \u2014 adhdev borrows your statusLine to read it.";
|
|
139649
|
-
var CLAUDE_WRAP_NOT_REPLACE_LINE = "Install wraps (not replaces) your statusline, so nothing is lost.";
|
|
139650
|
-
function windowCue(quota) {
|
|
139651
|
-
if (quota.metadata?.failureKind === "no-data" && (quota.session || quota.weekly)) return "stale";
|
|
139652
|
-
if (quota.metadata?.lastGoodWindows === true) return "refreshing";
|
|
139653
|
-
return void 0;
|
|
139654
|
-
}
|
|
139655
|
-
function formatWindow(label, window, cue = void 0) {
|
|
139656
|
-
if (!window) {
|
|
139657
|
-
return ` ${label.padEnd(8)} ${import_chalk2.default.gray("not reported")}`;
|
|
139658
|
-
}
|
|
139659
|
-
const percent = `${window.usedPercent.toFixed(1)}%`;
|
|
139660
|
-
const bar = renderBar(window.usedPercent);
|
|
139661
|
-
const reset = window.resetsAt === null ? "" : import_chalk2.default.gray(` resets ${formatRelative(window.resetsAt)}`);
|
|
139662
|
-
const marker = cue === "refreshing" ? import_chalk2.default.gray(" (refreshing)") : cue === "stale" ? import_chalk2.default.gray(" (stale)") : "";
|
|
139663
|
-
return ` ${label.padEnd(8)} ${bar} ${percent.padStart(6)} used${reset}${marker}`;
|
|
139664
|
-
}
|
|
139665
|
-
function renderBar(usedPercent) {
|
|
139666
|
-
const width = 20;
|
|
139667
|
-
const filled = Math.round(Math.min(100, Math.max(0, usedPercent)) / 100 * width);
|
|
139668
|
-
const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
|
|
139669
|
-
if (usedPercent >= 90) return import_chalk2.default.red(bar);
|
|
139670
|
-
if (usedPercent >= 70) return import_chalk2.default.yellow(bar);
|
|
139671
|
-
return import_chalk2.default.green(bar);
|
|
139672
|
-
}
|
|
139673
|
-
function formatRelative(atMs) {
|
|
139674
|
-
const deltaMs = atMs - Date.now();
|
|
139675
|
-
if (deltaMs <= 0) {
|
|
139676
|
-
return "now";
|
|
139677
|
-
}
|
|
139678
|
-
const minutes = Math.round(deltaMs / 6e4);
|
|
139679
|
-
if (minutes < 60) return `in ${minutes}m`;
|
|
139680
|
-
const hours = Math.floor(minutes / 60);
|
|
139681
|
-
if (hours < 24) return `in ${hours}h ${minutes % 60}m`;
|
|
139682
|
-
return `in ${Math.floor(hours / 24)}d ${hours % 24}h`;
|
|
139683
|
-
}
|
|
139684
|
-
function truncate(value, max) {
|
|
139685
|
-
return value.length <= max ? value : `${value.slice(0, max - 1)}\u2026`;
|
|
139686
|
-
}
|
|
139687
|
-
function formatAgo(atMs) {
|
|
139688
|
-
const deltaMs = Date.now() - atMs;
|
|
139689
|
-
if (deltaMs <= 0) return "just now";
|
|
139690
|
-
const minutes = Math.round(deltaMs / 6e4);
|
|
139691
|
-
if (minutes < 1) return "just now";
|
|
139692
|
-
if (minutes < 60) return `${minutes}m ago`;
|
|
139693
|
-
const hours = Math.floor(minutes / 60);
|
|
139694
|
-
if (hours < 24) return `${hours}h ${minutes % 60}m ago`;
|
|
139695
|
-
return `${Math.floor(hours / 24)}d ${hours % 24}h ago`;
|
|
139696
|
-
}
|
|
139697
|
-
function printQuota2(name, quota) {
|
|
139698
|
-
console.log();
|
|
139699
|
-
const account = formatQuotaAccount(quota);
|
|
139700
|
-
console.log(account ? `${import_chalk2.default.bold(name)} ${import_chalk2.default.gray(account)}` : import_chalk2.default.bold(name));
|
|
139701
|
-
if (quota.status === "ok" || quota.session || quota.weekly) {
|
|
139702
|
-
const cue = windowCue(quota);
|
|
139703
|
-
console.log(formatWindow("5 hour", quota.session, cue));
|
|
139704
|
-
console.log(formatWindow("7 day", quota.weekly, cue));
|
|
139705
|
-
}
|
|
139706
|
-
if (quota.error) {
|
|
139707
|
-
const tone = quota.status === "unavailable" ? import_chalk2.default.gray : import_chalk2.default.yellow;
|
|
139708
|
-
console.log(` ${tone(quota.error)}`);
|
|
139709
|
-
if (quota.provider === "claude-cli" && quota.error.includes("claude:install")) {
|
|
139710
|
-
console.log(` ${import_chalk2.default.gray(CLAUDE_NO_API_LINE)}`);
|
|
139711
|
-
console.log(` ${import_chalk2.default.gray(CLAUDE_WRAP_NOT_REPLACE_LINE)}`);
|
|
139712
|
-
}
|
|
139713
|
-
}
|
|
139714
|
-
console.log();
|
|
139715
|
-
}
|
|
139716
|
-
function printQuotaRefreshOutcome2(entries) {
|
|
139717
|
-
console.log();
|
|
139718
|
-
if (entries.length === 0) {
|
|
139719
|
-
console.log(import_chalk2.default.gray(" Nothing to refresh."));
|
|
139720
|
-
console.log();
|
|
139721
|
-
return;
|
|
139722
|
-
}
|
|
139723
|
-
const refreshed = entries.filter((e) => e.outcome === "refreshed");
|
|
139724
|
-
if (refreshed.length > 0) {
|
|
139725
|
-
console.log(import_chalk2.default.green(`\u2713 Refreshed ${refreshed.map((e) => e.provider).join(", ")}`));
|
|
139726
|
-
}
|
|
139727
|
-
for (const entry of entries) {
|
|
139728
|
-
if (entry.outcome === "refreshed") continue;
|
|
139729
|
-
if (entry.outcome === "cooldown") {
|
|
139730
|
-
console.log(import_chalk2.default.yellow(`\u2022 ${entry.provider}: rate-limited \u2014 not re-probed`));
|
|
139731
|
-
if (typeof entry.retryAtMs === "number" && Number.isFinite(entry.retryAtMs)) {
|
|
139732
|
-
console.log(import_chalk2.default.gray(` Retrying no earlier than ${formatRelative(entry.retryAtMs)}.`));
|
|
139733
|
-
}
|
|
139734
|
-
console.log(import_chalk2.default.gray(" The numbers shown are the last good reading."));
|
|
139735
|
-
console.log(import_chalk2.default.gray(" Re-probing now would extend the provider's own throttle."));
|
|
139736
|
-
continue;
|
|
139737
|
-
}
|
|
139738
|
-
console.log(import_chalk2.default.gray(`\u2022 ${entry.provider}: ${entry.reason || entry.outcome}`));
|
|
139739
|
-
}
|
|
139740
|
-
console.log();
|
|
139741
|
-
}
|
|
139742
|
-
function printClaudeInstallResult2(result) {
|
|
139743
|
-
console.log();
|
|
139744
|
-
console.log(
|
|
139745
|
-
import_chalk2.default.green(
|
|
139746
|
-
result.outcome === "repaired" ? "\u2713 Claude Code quota reporting repaired" : result.outcome === "reinstalled" ? "\u2713 Claude Code quota reporting re-installed" : result.outcome === "wrapped" ? "\u2713 Claude Code quota reporting installed around your statusline" : "\u2713 Claude Code quota reporting installed"
|
|
139747
|
-
)
|
|
139748
|
-
);
|
|
139749
|
-
if (result.outcome === "repaired") {
|
|
139750
|
-
console.log(import_chalk2.default.gray(" Your statusLine pointed at a script that no longer exists:"));
|
|
139751
|
-
console.log(import_chalk2.default.gray(` ${truncate(result.repairedFrom ?? "unknown path", 100)}`));
|
|
139752
|
-
console.log(import_chalk2.default.gray(" It now points at the current wrapper."));
|
|
139753
|
-
}
|
|
139754
|
-
if (result.originalCommand) {
|
|
139755
|
-
console.log(import_chalk2.default.gray(" Your existing statusline is preserved and still runs:"));
|
|
139756
|
-
console.log(import_chalk2.default.gray(` ${truncate(result.originalCommand, 100)}`));
|
|
139757
|
-
console.log(import_chalk2.default.gray(` Backup: ${result.paths.backupFile}`));
|
|
139758
|
-
} else if (result.outcome === "installed") {
|
|
139759
|
-
console.log(import_chalk2.default.gray(" You had no statusline configured; one was not added."));
|
|
139760
|
-
}
|
|
139761
|
-
if (result.volatileWrapperReason) {
|
|
139762
|
-
console.log(
|
|
139763
|
-
import_chalk2.default.yellow(` ! The wrapper was written under ${result.volatileWrapperReason}.`)
|
|
139764
|
-
);
|
|
139765
|
-
console.log(import_chalk2.default.gray(` ${result.paths.wrapperFile}`));
|
|
139766
|
-
console.log(import_chalk2.default.gray(" Claude Code will fail to load it once that path is gone;"));
|
|
139767
|
-
console.log(import_chalk2.default.gray(" re-run `adhdev quota claude:install` from a normal install to fix."));
|
|
139768
|
-
}
|
|
139769
|
-
console.log();
|
|
139770
|
-
console.log(import_chalk2.default.gray(" Open a Claude Code session, then run `adhdev quota claude`."));
|
|
139771
|
-
console.log(import_chalk2.default.gray(" Undo any time with `adhdev quota claude:uninstall`."));
|
|
139772
|
-
console.log();
|
|
139773
|
-
}
|
|
139774
|
-
function printClaudeUninstallResult2(result) {
|
|
139775
|
-
console.log();
|
|
139776
|
-
if (result.outcome === "restored") {
|
|
139777
|
-
console.log(import_chalk2.default.green("\u2713 Your original statusline has been restored"));
|
|
139778
|
-
} else if (result.outcome === "removed") {
|
|
139779
|
-
console.log(import_chalk2.default.green("\u2713 Claude Code quota reporting removed"));
|
|
139780
|
-
console.log(import_chalk2.default.gray(" You had no statusline before install, so none was left behind."));
|
|
139781
|
-
} else {
|
|
139782
|
-
console.log(import_chalk2.default.yellow("\u2022 Claude Code quota reporting was not installed"));
|
|
139783
|
-
console.log(import_chalk2.default.gray(" Your statusLine setting was left untouched."));
|
|
139784
|
-
}
|
|
139785
|
-
console.log();
|
|
139786
|
-
}
|
|
139787
|
-
function printClaudeStatuslineStatus2(status) {
|
|
139788
|
-
console.log();
|
|
139789
|
-
if (status.installed) {
|
|
139790
|
-
console.log(import_chalk2.default.green("\u2713 Installed"));
|
|
139791
|
-
console.log(
|
|
139792
|
-
import_chalk2.default.gray(
|
|
139793
|
-
status.wrappedCommand ? ` Wrapping your statusline: ${truncate(status.wrappedCommand, 100)}` : " You had no statusline before install."
|
|
139794
|
-
)
|
|
139795
|
-
);
|
|
139796
|
-
console.log(import_chalk2.default.gray(` Wrapper: ${status.paths.wrapperFile}`));
|
|
139797
|
-
console.log(import_chalk2.default.gray(` Backup: ${status.paths.backupFile}`));
|
|
139798
|
-
let snapshotMtimeMs = null;
|
|
139799
|
-
try {
|
|
139800
|
-
snapshotMtimeMs = fs65.statSync(status.paths.snapshotFile).mtimeMs;
|
|
139801
|
-
} catch {
|
|
139802
|
-
}
|
|
139803
|
-
console.log(import_chalk2.default.gray(
|
|
139804
|
-
snapshotMtimeMs === null ? " Last snapshot: none yet \u2014 open a Claude Code session to record one" : ` Last snapshot: ${formatAgo(snapshotMtimeMs)} (${status.paths.snapshotFile})`
|
|
139805
|
-
));
|
|
139806
|
-
console.log(import_chalk2.default.gray(" Undo with `adhdev quota claude:uninstall`."));
|
|
139807
|
-
} else if (status.failureKind === "wrapper-missing") {
|
|
139808
|
-
console.log(import_chalk2.default.red("\u2717 Broken \u2014 the configured wrapper no longer exists"));
|
|
139809
|
-
console.log(import_chalk2.default.gray(` statusLine points at: ${truncate(status.danglingWrapperPath ?? "unknown path", 100)}`));
|
|
139810
|
-
console.log(import_chalk2.default.gray(" Claude Code runs that command every prompt and it fails, so"));
|
|
139811
|
-
console.log(import_chalk2.default.gray(" no quota is being captured and your statusline is blank."));
|
|
139812
|
-
if (status.wrappedCommand) {
|
|
139813
|
-
console.log(import_chalk2.default.gray(` Your own statusline is still recorded: ${truncate(status.wrappedCommand, 80)}`));
|
|
139814
|
-
}
|
|
139815
|
-
console.log(import_chalk2.default.gray(" Repair with `adhdev quota claude:install`."));
|
|
139816
|
-
console.log(import_chalk2.default.gray(" Or clear it with `adhdev quota claude:uninstall`."));
|
|
139817
|
-
} else {
|
|
139818
|
-
console.log(import_chalk2.default.yellow("\u2022 Not installed"));
|
|
139819
|
-
if (status.foreignStatusLine) {
|
|
139820
|
-
console.log(import_chalk2.default.gray(" You have your own statusLine configured; install would wrap it."));
|
|
139821
|
-
}
|
|
139822
|
-
console.log(import_chalk2.default.gray(` ${CLAUDE_NO_API_LINE}`));
|
|
139823
|
-
console.log(import_chalk2.default.gray(` ${CLAUDE_WRAP_NOT_REPLACE_LINE}`));
|
|
139824
|
-
console.log(import_chalk2.default.gray(" Set up with `adhdev quota claude:install`."));
|
|
139825
|
-
}
|
|
139826
|
-
console.log();
|
|
139827
|
-
}
|
|
139828
|
-
function printQuotaInstallError2(message) {
|
|
139829
|
-
console.error(import_chalk2.default.red(`
|
|
139830
|
-
\u2717 ${message}
|
|
139831
|
-
`));
|
|
139431
|
+
LOG2.info("Seqscribe", `fleet secret stored (v${version2})`);
|
|
139832
139432
|
}
|
|
139833
139433
|
var import_fs22 = require("fs");
|
|
139834
139434
|
var import_path25 = require("path");
|
|
@@ -145648,70 +145248,6 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
145648
145248
|
const authority = createFleetAuthority({ secret });
|
|
145649
145249
|
return { authority, hooks: authority };
|
|
145650
145250
|
}
|
|
145651
|
-
var import_fs21 = require("fs");
|
|
145652
|
-
var import_path24 = require("path");
|
|
145653
|
-
init_config();
|
|
145654
|
-
init_logger();
|
|
145655
|
-
var FLEET_SECRET_FILE = "seqscribe-fleet-secret.json";
|
|
145656
|
-
function fleetSecretPath(env2) {
|
|
145657
|
-
return (0, import_path24.join)(getConfigDir2(env2), FLEET_SECRET_FILE);
|
|
145658
|
-
}
|
|
145659
|
-
function loadStoredFleetSecret(env2) {
|
|
145660
|
-
const path63 = fleetSecretPath(env2);
|
|
145661
|
-
if (!(0, import_fs21.existsSync)(path63)) return null;
|
|
145662
|
-
let raw;
|
|
145663
|
-
try {
|
|
145664
|
-
raw = (0, import_fs21.readFileSync)(path63, "utf-8");
|
|
145665
|
-
} catch (err) {
|
|
145666
|
-
LOG2.warn(
|
|
145667
|
-
"Seqscribe",
|
|
145668
|
-
`fleet secret file unreadable (${err instanceof Error ? err.message : String(err)}); ignoring it`
|
|
145669
|
-
);
|
|
145670
|
-
return null;
|
|
145671
|
-
}
|
|
145672
|
-
try {
|
|
145673
|
-
const parsed = JSON.parse(raw);
|
|
145674
|
-
if (parsed !== null && typeof parsed === "object" && typeof parsed.secret === "string" && parsed.secret.length > 0 && Number.isInteger(parsed.version) && parsed.version >= 1) {
|
|
145675
|
-
const { secret, version: version2 } = parsed;
|
|
145676
|
-
return { secret, version: version2 };
|
|
145677
|
-
}
|
|
145678
|
-
} catch {
|
|
145679
|
-
}
|
|
145680
|
-
LOG2.warn("Seqscribe", "fleet secret file is malformed; ignoring it (provisional mode)");
|
|
145681
|
-
return null;
|
|
145682
|
-
}
|
|
145683
|
-
function storeFleetSecret(secret, version2, env2) {
|
|
145684
|
-
if (typeof secret !== "string" || secret.length === 0) {
|
|
145685
|
-
throw new Error("storeFleetSecret requires a non-empty secret string");
|
|
145686
|
-
}
|
|
145687
|
-
if (!Number.isInteger(version2) || version2 < 1) {
|
|
145688
|
-
throw new Error("storeFleetSecret requires an integer version >= 1");
|
|
145689
|
-
}
|
|
145690
|
-
const dir = getConfigDir2(env2);
|
|
145691
|
-
if (!(0, import_fs21.existsSync)(dir)) {
|
|
145692
|
-
(0, import_fs21.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
145693
|
-
}
|
|
145694
|
-
const path63 = (0, import_path24.join)(dir, FLEET_SECRET_FILE);
|
|
145695
|
-
const tmp = `${path63}.tmp-${process.pid}`;
|
|
145696
|
-
(0, import_fs21.writeFileSync)(tmp, JSON.stringify({ secret, version: version2 }, null, 2), {
|
|
145697
|
-
encoding: "utf-8",
|
|
145698
|
-
mode: 384
|
|
145699
|
-
});
|
|
145700
|
-
try {
|
|
145701
|
-
(0, import_fs21.renameSync)(tmp, path63);
|
|
145702
|
-
} catch (err) {
|
|
145703
|
-
try {
|
|
145704
|
-
(0, import_fs21.unlinkSync)(tmp);
|
|
145705
|
-
} catch {
|
|
145706
|
-
}
|
|
145707
|
-
throw err;
|
|
145708
|
-
}
|
|
145709
|
-
try {
|
|
145710
|
-
(0, import_fs21.chmodSync)(path63, 384);
|
|
145711
|
-
} catch {
|
|
145712
|
-
}
|
|
145713
|
-
LOG2.info("Seqscribe", `fleet secret stored (v${version2})`);
|
|
145714
|
-
}
|
|
145715
145251
|
var TOPIC_SEGMENT_UNSAFE = /[^a-z0-9_-]+/g;
|
|
145716
145252
|
function sanitizeSegment(raw, fallback) {
|
|
145717
145253
|
const cleaned = raw.toLowerCase().replace(TOPIC_SEGMENT_UNSAFE, "_").replace(/^_+|_+$/g, "");
|
|
@@ -145912,6 +145448,860 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
145912
145448
|
close
|
|
145913
145449
|
};
|
|
145914
145450
|
}
|
|
145451
|
+
function tryOpenDaemonSeqscribeNode(options = {}) {
|
|
145452
|
+
const env2 = options.env ?? process.env;
|
|
145453
|
+
try {
|
|
145454
|
+
return openSeqscribeNode({
|
|
145455
|
+
daemonId: options.daemonId,
|
|
145456
|
+
...options.dbPath ? { dbPath: options.dbPath } : {},
|
|
145457
|
+
env: env2,
|
|
145458
|
+
storedFleetSecret: loadStoredFleetSecret(env2)?.secret ?? null
|
|
145459
|
+
});
|
|
145460
|
+
} catch (error48) {
|
|
145461
|
+
LOG2.warn(
|
|
145462
|
+
"Seqscribe",
|
|
145463
|
+
`node unavailable; daemon will continue without replication: ${error48 instanceof Error ? error48.message : String(error48)}`
|
|
145464
|
+
);
|
|
145465
|
+
return void 0;
|
|
145466
|
+
}
|
|
145467
|
+
}
|
|
145468
|
+
async function initDaemonComponents2(config2) {
|
|
145469
|
+
applyProcessHardening();
|
|
145470
|
+
installProviderProcessShim();
|
|
145471
|
+
installGlobalInterceptor();
|
|
145472
|
+
loadMeshCoordinatorRegistry();
|
|
145473
|
+
const upgradeFailureNotice = readUpgradeFailureNotice();
|
|
145474
|
+
if (upgradeFailureNotice) {
|
|
145475
|
+
const age = upgradeFailureNotice.ageLabel ? `${upgradeFailureNotice.ageLabel}, recorded ${upgradeFailureNotice.recordedAt}` : "recorded at an unknown time";
|
|
145476
|
+
const target = upgradeFailureNotice.targetVersion ? `, attempted target v${upgradeFailureNotice.targetVersion}` : "";
|
|
145477
|
+
const running = (config2.statusVersion || "").trim().replace(/^v/, "");
|
|
145478
|
+
const supersededHint = upgradeFailureNotice.targetVersion && running && upgradeFailureNotice.targetVersion.replace(/^v/, "") !== running ? ` This notice targets a DIFFERENT version than the one now running (v${running}) \u2014 it is most likely a stale record of an earlier attempt, not a report about this boot.` : "";
|
|
145479
|
+
LOG2.warn("Upgrade", `Previous daemon upgrade FAILED and was rolled back \u2014 this daemon is running the previous version. Notice (${age}${target}) at ${upgradeFailureNotice.noticePath}:
|
|
145480
|
+
${upgradeFailureNotice.notice}${supersededHint}`);
|
|
145481
|
+
}
|
|
145482
|
+
try {
|
|
145483
|
+
const { migrateProviderChannelConfig: migrateProviderChannelConfig2 } = await Promise.resolve().then(() => (init_channel_migration(), channel_migration_exports));
|
|
145484
|
+
const migration = migrateProviderChannelConfig2();
|
|
145485
|
+
if (migration.migrated) {
|
|
145486
|
+
LOG2.info("Providers", `Recorded explicit providerChannel=${migration.channel} in config (migrated from build-track/updateChannel derivation)`);
|
|
145487
|
+
}
|
|
145488
|
+
} catch {
|
|
145489
|
+
}
|
|
145490
|
+
const appConfig = loadConfig2();
|
|
145491
|
+
const providerSourceMode = appConfig.providerSourceMode || "normal";
|
|
145492
|
+
const disableUpstream = providerSourceMode === "no-upstream";
|
|
145493
|
+
const providerLoader = new ProviderLoader({
|
|
145494
|
+
logFn: config2.providerLogFn,
|
|
145495
|
+
// Shared config projection — keeps this site, launch.ts, and the CLI
|
|
145496
|
+
// factory from drifting (the launch path once dropped userDir/sourceMode).
|
|
145497
|
+
...providerLoaderConfigOptions(appConfig),
|
|
145498
|
+
// The boot path resolves sourceMode with an explicit 'normal' default
|
|
145499
|
+
// for the disableUpstream derivation above — keep that authoritative.
|
|
145500
|
+
sourceMode: providerSourceMode,
|
|
145501
|
+
// Enables the daemon-update = provider-activation stamp (option C):
|
|
145502
|
+
// a boot on a NEW daemon version runs one verified sync; same-version
|
|
145503
|
+
// boots stay network-free.
|
|
145504
|
+
daemonVersion: config2.statusVersion
|
|
145505
|
+
});
|
|
145506
|
+
providerLoader.loadAll();
|
|
145507
|
+
providerLoader.registerToDetector();
|
|
145508
|
+
const hasExplicitChannelSignal = Boolean(
|
|
145509
|
+
appConfig.providerChannel && appConfig.providerChannel.trim() || (process.env[PROVIDER_CHANNEL_ENV_VAR] ?? "").trim() || isPreviewReleaseChannel(appConfig.updateChannel)
|
|
145510
|
+
);
|
|
145511
|
+
const resolvedConfigDir = getConfigDir2();
|
|
145512
|
+
const channelMismatch = configDirChannelMismatch(resolvedConfigDir, providerLoader.channel, hasExplicitChannelSignal);
|
|
145513
|
+
if (channelMismatch) {
|
|
145514
|
+
LOG2.warn("Init", `Config dir looks like the ${channelMismatch.impliedTrack} track (${resolvedConfigDir}) but the resolved provider channel is '${channelMismatch.channel}'. This usually means the build-track stamp (__ADHDEV_BUILD_CHANNEL__) was absent for this process \u2014 e.g. running via tsx/ts-node instead of a built bundle \u2014 so provider-channel resolution fell through to its 'stable' default instead of following ADHDEV_CONFIG_DIR. Impact: providers installed under the OTHER channel's store will not be visible (can present as 0 providers loaded). Fix: set ADHDEV_PROVIDER_CHANNEL=${channelMismatch.impliedTrack} (or config.providerChannel) explicitly for this process, or run the built bundle instead of source.`);
|
|
145515
|
+
}
|
|
145516
|
+
void providerLoader.maybeFirstSyncVerifiedChannel().then(async (report) => {
|
|
145517
|
+
if (!report) return null;
|
|
145518
|
+
if (report.status === "error") {
|
|
145519
|
+
LOG2.warn("Init", `Verified channel first-sync failed (last-known-good preserved): ${report.errors.map((e) => e.code).join(", ") || "unknown"}`);
|
|
145520
|
+
} else if (report.activated.length > 0) {
|
|
145521
|
+
LOG2.info("Init", `Verified channel first-sync activated ${report.activated.length} providers (${providerLoader.channel})`);
|
|
145522
|
+
providerLoader.registerToDetector();
|
|
145523
|
+
await refreshProviderAvailability();
|
|
145524
|
+
config2.onStatusChange?.();
|
|
145525
|
+
}
|
|
145526
|
+
return report;
|
|
145527
|
+
}).then(async (firstSyncReport) => {
|
|
145528
|
+
if (firstSyncReport) return;
|
|
145529
|
+
const report = await providerLoader.maybeSyncVerifiedChannelOnDaemonUpdate();
|
|
145530
|
+
if (!report) return;
|
|
145531
|
+
if (report.status === "error") {
|
|
145532
|
+
LOG2.warn("Init", `Daemon-update channel sync failed (last-known-good preserved, retries next boot): ${report.errors.map((e) => e.code).join(", ") || "unknown"}`);
|
|
145533
|
+
} else if (report.activated.length > 0) {
|
|
145534
|
+
LOG2.info("Init", `Daemon-update channel sync activated ${report.activated.length} providers (${providerLoader.channel})`);
|
|
145535
|
+
providerLoader.registerToDetector();
|
|
145536
|
+
await refreshProviderAvailability();
|
|
145537
|
+
config2.onStatusChange?.();
|
|
145538
|
+
}
|
|
145539
|
+
}).catch((e) => LOG2.warn("Init", `Verified channel boot sync error: ${e?.message || e}`));
|
|
145540
|
+
const runStalenessProbe = async () => {
|
|
145541
|
+
try {
|
|
145542
|
+
const snap = await providerLoader.checkVerifiedChannelStaleness();
|
|
145543
|
+
if (snap.error) {
|
|
145544
|
+
LOG2.debug("Provider", `Channel staleness probe failed (kept previous snapshot): ${snap.error}`);
|
|
145545
|
+
} else if (snap.staleTypes.length > 0 || snap.newTypes.length > 0) {
|
|
145546
|
+
LOG2.info("Provider", `Channel staleness: ${snap.staleTypes.length} stale [${snap.staleTypes.join(", ")}], ${snap.newTypes.length} never-installed [${snap.newTypes.join(", ")}] (${snap.channel})`);
|
|
145547
|
+
config2.onStatusChange?.();
|
|
145548
|
+
}
|
|
145549
|
+
} catch (e) {
|
|
145550
|
+
LOG2.debug("Provider", `Channel staleness probe error: ${e?.message || e}`);
|
|
145551
|
+
}
|
|
145552
|
+
};
|
|
145553
|
+
const stalenessInitialTimer = setTimeout(() => {
|
|
145554
|
+
void runStalenessProbe();
|
|
145555
|
+
}, 10 * 6e4);
|
|
145556
|
+
stalenessInitialTimer.unref?.();
|
|
145557
|
+
const stalenessIntervalTimer = setInterval(() => {
|
|
145558
|
+
void runStalenessProbe();
|
|
145559
|
+
}, 24 * 60 * 6e4);
|
|
145560
|
+
stalenessIntervalTimer.unref?.();
|
|
145561
|
+
const providerStalenessProbe = {
|
|
145562
|
+
stop() {
|
|
145563
|
+
clearTimeout(stalenessInitialTimer);
|
|
145564
|
+
clearInterval(stalenessIntervalTimer);
|
|
145565
|
+
}
|
|
145566
|
+
};
|
|
145567
|
+
setDefaultProviderLoader(providerLoader);
|
|
145568
|
+
const versionArchive = new VersionArchive();
|
|
145569
|
+
providerLoader.setVersionArchive(versionArchive);
|
|
145570
|
+
setTimeout(() => {
|
|
145571
|
+
void detectAllVersions(providerLoader, versionArchive).then((versionResults) => {
|
|
145572
|
+
const installedProviders = versionResults.filter((v) => v.installed);
|
|
145573
|
+
const withVersion = installedProviders.filter((v) => v.version);
|
|
145574
|
+
LOG2.info("Init", `Provider versions: ${installedProviders.length} installed, ${withVersion.length} versioned`);
|
|
145575
|
+
for (const v of withVersion) {
|
|
145576
|
+
LOG2.info("Init", ` ${v.type} (${v.category}): v${v.version}${v.warning ? " \u26A0 " + v.warning : ""}`);
|
|
145577
|
+
}
|
|
145578
|
+
const noVersion = installedProviders.filter((v) => !v.version);
|
|
145579
|
+
if (noVersion.length > 0) {
|
|
145580
|
+
LOG2.warn("Init", ` ${noVersion.length} installed but version unknown: ${noVersion.map((v) => v.type).join(", ")}`);
|
|
145581
|
+
}
|
|
145582
|
+
}).catch(() => {
|
|
145583
|
+
});
|
|
145584
|
+
}, 0);
|
|
145585
|
+
const instanceManager = new ProviderInstanceManager();
|
|
145586
|
+
const cdpManagers = /* @__PURE__ */ new Map();
|
|
145587
|
+
const sessionRegistry = new SessionRegistry();
|
|
145588
|
+
setTranscriptClaimLivenessProbe((owner) => {
|
|
145589
|
+
const match = /^iid:(.+)$/.exec(owner);
|
|
145590
|
+
if (!match) return true;
|
|
145591
|
+
return sessionRegistry.get(match[1]) !== void 0;
|
|
145592
|
+
});
|
|
145593
|
+
const detectedIdesRef = { value: [] };
|
|
145594
|
+
let agentStreamManager = null;
|
|
145595
|
+
let poller = null;
|
|
145596
|
+
const refreshProviderAvailability = async (providerType) => {
|
|
145597
|
+
const targetProvider = providerType ? providerLoader.getMeta(providerLoader.resolveAlias(providerType)) : null;
|
|
145598
|
+
const targetCategory = targetProvider?.category;
|
|
145599
|
+
if (!providerType || targetCategory === "cli" || targetCategory === "acp") {
|
|
145600
|
+
if (providerType && targetProvider) {
|
|
145601
|
+
const detected = await detectCLI(targetProvider.type, providerLoader, { includeVersion: false });
|
|
145602
|
+
providerLoader.setCliDetectionResults([{
|
|
145603
|
+
id: targetProvider.type,
|
|
145604
|
+
installed: !!detected,
|
|
145605
|
+
path: detected?.path
|
|
145606
|
+
}], false);
|
|
145607
|
+
} else {
|
|
145608
|
+
providerLoader.setCliDetectionResults(await detectCLIs(providerLoader, { includeVersion: false }), true);
|
|
145609
|
+
}
|
|
145610
|
+
}
|
|
145611
|
+
if (!providerType || targetCategory === "ide") {
|
|
145612
|
+
detectedIdesRef.value = await detectIDEs(providerLoader);
|
|
145613
|
+
providerLoader.setIdeDetectionResults(detectedIdesRef.value, true);
|
|
145614
|
+
}
|
|
145615
|
+
};
|
|
145616
|
+
const cliManager = new DaemonCliManager({
|
|
145617
|
+
...config2.cliManagerDeps,
|
|
145618
|
+
getInstanceManager: () => instanceManager,
|
|
145619
|
+
getSessionRegistry: () => sessionRegistry
|
|
145620
|
+
}, providerLoader);
|
|
145621
|
+
LOG2.info("Init", "Detecting IDEs...");
|
|
145622
|
+
await refreshProviderAvailability();
|
|
145623
|
+
const installed = detectedIdesRef.value.filter((i) => i.installed);
|
|
145624
|
+
LOG2.info("Init", `Found ${installed.length} IDE(s): ${installed.map((i) => i.id).join(", ") || "none"}`);
|
|
145625
|
+
const cdpSetupContext = {
|
|
145626
|
+
providerLoader,
|
|
145627
|
+
instanceManager,
|
|
145628
|
+
cdpManagers,
|
|
145629
|
+
sessionRegistry
|
|
145630
|
+
};
|
|
145631
|
+
const cdpInitializer = new DaemonCdpInitializer({
|
|
145632
|
+
providerLoader,
|
|
145633
|
+
cdpManagers,
|
|
145634
|
+
enabledIdes: config2.enabledIdes || loadConfig2().enabledIdes || void 0,
|
|
145635
|
+
onConnected: async (ideType, manager, managerKey) => {
|
|
145636
|
+
await setupIdeInstance(cdpSetupContext, { ideType, manager, managerKey });
|
|
145637
|
+
await config2.onCdpManagerSetup?.(ideType, manager, managerKey);
|
|
145638
|
+
},
|
|
145639
|
+
onDisconnected: async (_ideType, _manager, managerKey) => {
|
|
145640
|
+
sessionRegistry.unregisterByManagerKey(managerKey);
|
|
145641
|
+
const instanceKey = `ide:${managerKey}`;
|
|
145642
|
+
const ideInstance = instanceManager.getInstance(instanceKey);
|
|
145643
|
+
if (ideInstance) {
|
|
145644
|
+
instanceManager.removeInstance(instanceKey);
|
|
145645
|
+
LOG2.info("IDE", `Instance removed after detach: ${instanceKey}`);
|
|
145646
|
+
}
|
|
145647
|
+
if (ideInstance?.getInstanceId) {
|
|
145648
|
+
agentStreamManager?.resetParentSession(ideInstance.getInstanceId());
|
|
145649
|
+
}
|
|
145650
|
+
config2.onStatusChange?.();
|
|
145651
|
+
}
|
|
145652
|
+
});
|
|
145653
|
+
await cdpInitializer.connectAll(detectedIdesRef.value);
|
|
145654
|
+
cdpInitializer.startPeriodicScan(config2.cdpScanIntervalMs ?? DEFAULT_CDP_SCAN_INTERVAL_MS);
|
|
145655
|
+
cdpInitializer.startDiscovery(DEFAULT_CDP_DISCOVERY_INTERVAL_MS);
|
|
145656
|
+
const commandHandler = new DaemonCommandHandler({
|
|
145657
|
+
cdpManagers,
|
|
145658
|
+
ideType: "unknown",
|
|
145659
|
+
adapters: cliManager.adapters,
|
|
145660
|
+
providerLoader,
|
|
145661
|
+
instanceManager,
|
|
145662
|
+
sessionRegistry,
|
|
145663
|
+
gitCommandServices: createDefaultGitCommandServices({
|
|
145664
|
+
// T7: fold this daemon's cached provider versions + build version onto the
|
|
145665
|
+
// git_status envelope so the mesh coordinator self-heals each node's
|
|
145666
|
+
// providerVersions/build (the blue version chips) — these are per-machine
|
|
145667
|
+
// RUNTIME facts (e.g. this node has claude-cli@2.1.168 while the
|
|
145668
|
+
// coordinator has @2.1.170), so they stay reported. Non-blocking: reads a
|
|
145669
|
+
// TTL cache, lazily refreshed. (setDefaultProviderLoader is registered
|
|
145670
|
+
// above so getCachedProviderVersions is not empty — see the 380556d3
|
|
145671
|
+
// version-chip lesson.)
|
|
145672
|
+
//
|
|
145673
|
+
// Slots are NOT reported: they are coordinator-owned config
|
|
145674
|
+
// (node.policy.slots for every node, resolved via
|
|
145675
|
+
// resolveNodeCapabilitySlots), not a per-machine runtime fact — the
|
|
145676
|
+
// reporter round-trip for slots was removed (REMOTE-NODE-SLOTS-
|
|
145677
|
+
// COORDINATOR-LOCAL fix).
|
|
145678
|
+
getReporterProviderVersions: () => {
|
|
145679
|
+
const providerVersions = getCachedProviderVersions(providerLoader);
|
|
145680
|
+
const daemonBuildVersion = getDaemonBuildInfo().version;
|
|
145681
|
+
return {
|
|
145682
|
+
...Object.keys(providerVersions).length > 0 ? { providerVersions } : {},
|
|
145683
|
+
...daemonBuildVersion && daemonBuildVersion !== "unknown" ? { daemonBuildVersion } : {}
|
|
145684
|
+
};
|
|
145685
|
+
}
|
|
145686
|
+
}),
|
|
145687
|
+
onProviderSettingChanged: async (providerType) => {
|
|
145688
|
+
await refreshProviderAvailability(providerType);
|
|
145689
|
+
config2.onStatusChange?.();
|
|
145690
|
+
},
|
|
145691
|
+
onProviderSourceConfigChanged: async () => {
|
|
145692
|
+
await refreshProviderAvailability();
|
|
145693
|
+
config2.onStatusChange?.();
|
|
145694
|
+
},
|
|
145695
|
+
onBeforeSendChat: config2.onBeforeSendChat
|
|
145696
|
+
});
|
|
145697
|
+
agentStreamManager = new DaemonAgentStreamManager(
|
|
145698
|
+
LOG2.forComponent("AgentStream").asLogFn(),
|
|
145699
|
+
providerLoader,
|
|
145700
|
+
sessionRegistry
|
|
145701
|
+
);
|
|
145702
|
+
commandHandler.setAgentStreamManager(agentStreamManager);
|
|
145703
|
+
const router = new DaemonCommandRouter({
|
|
145704
|
+
commandHandler,
|
|
145705
|
+
cliManager,
|
|
145706
|
+
cdpManagers,
|
|
145707
|
+
providerLoader,
|
|
145708
|
+
instanceManager,
|
|
145709
|
+
detectedIdes: detectedIdesRef,
|
|
145710
|
+
sessionRegistry,
|
|
145711
|
+
onCdpManagerCreated: async (ideType, manager) => {
|
|
145712
|
+
await setupIdeInstance(cdpSetupContext, { ideType, manager });
|
|
145713
|
+
await config2.onCdpManagerSetup?.(ideType, manager, ideType);
|
|
145714
|
+
},
|
|
145715
|
+
onIdeConnected: () => poller?.start(),
|
|
145716
|
+
onStatusChange: config2.onStatusChange,
|
|
145717
|
+
onMeshStateChange: config2.onMeshStateChange,
|
|
145718
|
+
onPostChatCommand: config2.onPostChatCommand,
|
|
145719
|
+
sessionHostControl: config2.sessionHostControl,
|
|
145720
|
+
statusInstanceId: config2.statusInstanceId,
|
|
145721
|
+
statusVersion: config2.statusVersion,
|
|
145722
|
+
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
145723
|
+
dispatchMeshCommand: config2.dispatchMeshCommand,
|
|
145724
|
+
updateLocalMeshOwnedSession: config2.updateLocalMeshOwnedSession,
|
|
145725
|
+
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG2.forComponent(`CDP:${ideType}`).asLogFn())
|
|
145726
|
+
});
|
|
145727
|
+
poller = new AgentStreamPoller({
|
|
145728
|
+
agentStreamManager,
|
|
145729
|
+
providerLoader,
|
|
145730
|
+
instanceManager,
|
|
145731
|
+
cdpManagers,
|
|
145732
|
+
sessionRegistry,
|
|
145733
|
+
onStreamsUpdated: config2.onStreamsUpdated
|
|
145734
|
+
});
|
|
145735
|
+
poller.start();
|
|
145736
|
+
instanceManager.startTicking(config2.tickIntervalMs ?? 5e3);
|
|
145737
|
+
const components = {
|
|
145738
|
+
providerLoader,
|
|
145739
|
+
instanceManager,
|
|
145740
|
+
cliManager,
|
|
145741
|
+
commandHandler,
|
|
145742
|
+
agentStreamManager,
|
|
145743
|
+
router,
|
|
145744
|
+
poller,
|
|
145745
|
+
cdpInitializer,
|
|
145746
|
+
cdpManagers,
|
|
145747
|
+
sessionRegistry,
|
|
145748
|
+
detectedIdes: detectedIdesRef,
|
|
145749
|
+
refreshProviderAvailability,
|
|
145750
|
+
dispatchMeshCommand: config2.dispatchMeshCommand,
|
|
145751
|
+
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
145752
|
+
onMeshCoordinatorEventForwarded: config2.onMeshCoordinatorEventForwarded,
|
|
145753
|
+
statusInstanceId: config2.statusInstanceId
|
|
145754
|
+
};
|
|
145755
|
+
components.seqscribeNode = tryOpenDaemonSeqscribeNode({ daemonId: config2.statusInstanceId });
|
|
145756
|
+
setupMeshEventForwarding(components);
|
|
145757
|
+
try {
|
|
145758
|
+
migratePendingEventsJsonlToSqlite();
|
|
145759
|
+
} catch {
|
|
145760
|
+
}
|
|
145761
|
+
components.meshReconcileLoop = setupMeshReconcileLoop(components);
|
|
145762
|
+
components.quotaRefreshLoop = setupQuotaRefreshLoop(components);
|
|
145763
|
+
components.quotaEventRefresh = setupQuotaEventRefresh(components);
|
|
145764
|
+
components.providerStalenessProbe = providerStalenessProbe;
|
|
145765
|
+
setImmediate(() => {
|
|
145766
|
+
const isQuotaProviderEnabled = quotaProviderEnabledFromLoader(components.providerLoader);
|
|
145767
|
+
try {
|
|
145768
|
+
hydrateQuotaCacheFromDisk(process.env, isQuotaProviderEnabled);
|
|
145769
|
+
} catch {
|
|
145770
|
+
}
|
|
145771
|
+
refreshQuotaCacheOnBoot(isQuotaProviderEnabled);
|
|
145772
|
+
});
|
|
145773
|
+
setImmediate(() => void router.resumePendingRefineJobsOnStartup());
|
|
145774
|
+
components.eventLoopMonitor = startEventLoopMonitor();
|
|
145775
|
+
setImmediate(() => router.resumeDeferredRestartsOnStartup());
|
|
145776
|
+
return components;
|
|
145777
|
+
}
|
|
145778
|
+
async function startDaemonDevSupport2(options) {
|
|
145779
|
+
const devServer = new DevServer({
|
|
145780
|
+
providerLoader: options.components.providerLoader,
|
|
145781
|
+
cdpManagers: options.components.cdpManagers,
|
|
145782
|
+
instanceManager: options.components.instanceManager,
|
|
145783
|
+
cliManager: options.components.cliManager,
|
|
145784
|
+
logFn: options.logFn,
|
|
145785
|
+
onProviderSourceConfigChanged: async () => {
|
|
145786
|
+
await options.components.refreshProviderAvailability();
|
|
145787
|
+
}
|
|
145788
|
+
});
|
|
145789
|
+
await devServer.start();
|
|
145790
|
+
options.components.providerLoader.watch();
|
|
145791
|
+
return devServer;
|
|
145792
|
+
}
|
|
145793
|
+
async function shutdownDaemonComponents2(components) {
|
|
145794
|
+
const {
|
|
145795
|
+
poller,
|
|
145796
|
+
cdpInitializer,
|
|
145797
|
+
agentStreamManager,
|
|
145798
|
+
cliManager,
|
|
145799
|
+
instanceManager,
|
|
145800
|
+
cdpManagers,
|
|
145801
|
+
meshReconcileLoop,
|
|
145802
|
+
quotaRefreshLoop,
|
|
145803
|
+
quotaEventRefresh,
|
|
145804
|
+
providerStalenessProbe,
|
|
145805
|
+
eventLoopMonitor,
|
|
145806
|
+
seqscribeNode
|
|
145807
|
+
} = components;
|
|
145808
|
+
poller.stop();
|
|
145809
|
+
cdpInitializer.stop();
|
|
145810
|
+
try {
|
|
145811
|
+
eventLoopMonitor?.stop();
|
|
145812
|
+
} catch {
|
|
145813
|
+
}
|
|
145814
|
+
try {
|
|
145815
|
+
meshReconcileLoop?.stop();
|
|
145816
|
+
} catch {
|
|
145817
|
+
}
|
|
145818
|
+
try {
|
|
145819
|
+
quotaRefreshLoop?.stop();
|
|
145820
|
+
} catch {
|
|
145821
|
+
}
|
|
145822
|
+
try {
|
|
145823
|
+
quotaEventRefresh?.stop();
|
|
145824
|
+
} catch {
|
|
145825
|
+
}
|
|
145826
|
+
try {
|
|
145827
|
+
providerStalenessProbe?.stop();
|
|
145828
|
+
} catch {
|
|
145829
|
+
}
|
|
145830
|
+
try {
|
|
145831
|
+
if (agentStreamManager) {
|
|
145832
|
+
await agentStreamManager.dispose(cdpManagers);
|
|
145833
|
+
}
|
|
145834
|
+
} catch (e) {
|
|
145835
|
+
LOG2.warn("Shutdown", `AgentStream dispose: ${e?.message}`);
|
|
145836
|
+
}
|
|
145837
|
+
try {
|
|
145838
|
+
cliManager.detachAll();
|
|
145839
|
+
} catch {
|
|
145840
|
+
}
|
|
145841
|
+
try {
|
|
145842
|
+
instanceManager.removeByCategory("cli", { dispose: false });
|
|
145843
|
+
} catch {
|
|
145844
|
+
}
|
|
145845
|
+
try {
|
|
145846
|
+
instanceManager.disposeAll();
|
|
145847
|
+
} catch {
|
|
145848
|
+
}
|
|
145849
|
+
for (const m of cdpManagers.values()) {
|
|
145850
|
+
try {
|
|
145851
|
+
m.disconnect();
|
|
145852
|
+
} catch {
|
|
145853
|
+
}
|
|
145854
|
+
}
|
|
145855
|
+
cdpManagers.clear();
|
|
145856
|
+
try {
|
|
145857
|
+
await seqscribeNode?.close();
|
|
145858
|
+
} catch (error48) {
|
|
145859
|
+
LOG2.warn("Shutdown", `Seqscribe close: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
145860
|
+
}
|
|
145861
|
+
try {
|
|
145862
|
+
MeshRuntimeStore.getInstance().vacuum();
|
|
145863
|
+
} catch {
|
|
145864
|
+
}
|
|
145865
|
+
}
|
|
145866
|
+
var import_http2 = require("http");
|
|
145867
|
+
var import_ws3 = require("ws");
|
|
145868
|
+
init_logger();
|
|
145869
|
+
init_ipc_protocol();
|
|
145870
|
+
function buildIpcStatusHttpResponse(method, url2, payload) {
|
|
145871
|
+
if (method && method.toUpperCase() !== "GET") {
|
|
145872
|
+
return { statusCode: 405, body: { ok: false, error: "method not allowed" } };
|
|
145873
|
+
}
|
|
145874
|
+
const path63 = url2 ? url2.split("?")[0] : url2;
|
|
145875
|
+
const KNOWN_ROUTES = ["/", "/status", "/health", "/api/v1/status", "/api/status"];
|
|
145876
|
+
if (path63 && !KNOWN_ROUTES.includes(path63)) {
|
|
145877
|
+
return { statusCode: 404, body: { ok: false, error: "not found" } };
|
|
145878
|
+
}
|
|
145879
|
+
return { statusCode: 200, body: payload };
|
|
145880
|
+
}
|
|
145881
|
+
async function startLocalIpcServer2(opts) {
|
|
145882
|
+
const logCategory = opts.logCategory || "IPC";
|
|
145883
|
+
const clients = /* @__PURE__ */ new Set();
|
|
145884
|
+
let httpServer = null;
|
|
145885
|
+
let wss = null;
|
|
145886
|
+
let listening = false;
|
|
145887
|
+
httpServer = (0, import_http2.createServer)((req, res) => {
|
|
145888
|
+
const payload = {
|
|
145889
|
+
ok: true,
|
|
145890
|
+
pid: process.pid,
|
|
145891
|
+
wsPath: DAEMON_WS_PATH2,
|
|
145892
|
+
port: opts.port,
|
|
145893
|
+
status: opts.buildStatusPayload()
|
|
145894
|
+
};
|
|
145895
|
+
const response = buildIpcStatusHttpResponse(req.method, req.url, payload);
|
|
145896
|
+
const body = JSON.stringify(response.body);
|
|
145897
|
+
res.writeHead(response.statusCode, {
|
|
145898
|
+
"Content-Type": "application/json",
|
|
145899
|
+
"Content-Length": Buffer.byteLength(body),
|
|
145900
|
+
"Connection": "close"
|
|
145901
|
+
});
|
|
145902
|
+
res.end(body);
|
|
145903
|
+
});
|
|
145904
|
+
wss = new import_ws3.WebSocketServer({ noServer: true });
|
|
145905
|
+
wss.on("connection", (ws) => handleConnection(ws));
|
|
145906
|
+
httpServer.on("upgrade", (req, socket, head) => {
|
|
145907
|
+
const wsUrl = new URL(req.url || "/", `http://${req.headers.host || "127.0.0.1"}`);
|
|
145908
|
+
if (wsUrl.pathname !== DAEMON_WS_PATH2) {
|
|
145909
|
+
socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
|
|
145910
|
+
socket.destroy();
|
|
145911
|
+
return;
|
|
145912
|
+
}
|
|
145913
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
145914
|
+
wss.emit("connection", ws, req);
|
|
145915
|
+
});
|
|
145916
|
+
});
|
|
145917
|
+
function handleConnection(ws) {
|
|
145918
|
+
clients.add(ws);
|
|
145919
|
+
sendWelcome(ws);
|
|
145920
|
+
opts.onClientConnected?.(ws);
|
|
145921
|
+
ws.on("message", (raw) => {
|
|
145922
|
+
void handleMessage(ws, raw.toString());
|
|
145923
|
+
});
|
|
145924
|
+
ws.on("close", () => {
|
|
145925
|
+
clients.delete(ws);
|
|
145926
|
+
opts.onClientDisconnected?.(ws);
|
|
145927
|
+
});
|
|
145928
|
+
ws.on("error", () => {
|
|
145929
|
+
clients.delete(ws);
|
|
145930
|
+
opts.onClientDisconnected?.(ws);
|
|
145931
|
+
});
|
|
145932
|
+
}
|
|
145933
|
+
function sendWelcome(ws) {
|
|
145934
|
+
try {
|
|
145935
|
+
ws.send(JSON.stringify({
|
|
145936
|
+
type: "daemon:welcome",
|
|
145937
|
+
payload: opts.buildWelcomePayload()
|
|
145938
|
+
}));
|
|
145939
|
+
} catch (error48) {
|
|
145940
|
+
LOG2.warn(logCategory, `Failed to send welcome: ${error48?.message || error48}`);
|
|
145941
|
+
}
|
|
145942
|
+
}
|
|
145943
|
+
async function handleMessage(ws, raw) {
|
|
145944
|
+
let msg;
|
|
145945
|
+
try {
|
|
145946
|
+
msg = JSON.parse(raw);
|
|
145947
|
+
} catch {
|
|
145948
|
+
return;
|
|
145949
|
+
}
|
|
145950
|
+
if (!msg || typeof msg !== "object") return;
|
|
145951
|
+
if (msg.type === "ext:register") {
|
|
145952
|
+
sendWelcome(ws);
|
|
145953
|
+
return;
|
|
145954
|
+
}
|
|
145955
|
+
if (msg.type !== "ext:command") return;
|
|
145956
|
+
const payload = msg.payload && typeof msg.payload === "object" ? msg.payload : {};
|
|
145957
|
+
const command = typeof payload.command === "string" ? payload.command : "";
|
|
145958
|
+
const args = payload.args && typeof payload.args === "object" ? payload.args : {};
|
|
145959
|
+
const requestId = typeof payload.requestId === "string" ? payload.requestId : typeof payload.messageId === "string" ? payload.messageId : `ipc-${Date.now()}`;
|
|
145960
|
+
if (!command) {
|
|
145961
|
+
ws.send(JSON.stringify({
|
|
145962
|
+
type: "ext:command_result",
|
|
145963
|
+
payload: { requestId, success: false, error: "command required" }
|
|
145964
|
+
}));
|
|
145965
|
+
return;
|
|
145966
|
+
}
|
|
145967
|
+
try {
|
|
145968
|
+
const result = await opts.handleCommand({ command, args, requestId, ws });
|
|
145969
|
+
ws.send(JSON.stringify({
|
|
145970
|
+
type: "ext:command_result",
|
|
145971
|
+
payload: {
|
|
145972
|
+
requestId,
|
|
145973
|
+
success: result.success,
|
|
145974
|
+
result: result.result,
|
|
145975
|
+
error: result.error,
|
|
145976
|
+
...result.extra || {}
|
|
145977
|
+
}
|
|
145978
|
+
}));
|
|
145979
|
+
} catch (error48) {
|
|
145980
|
+
ws.send(JSON.stringify({
|
|
145981
|
+
type: "ext:command_result",
|
|
145982
|
+
payload: {
|
|
145983
|
+
requestId,
|
|
145984
|
+
success: false,
|
|
145985
|
+
error: error48?.message || String(error48)
|
|
145986
|
+
}
|
|
145987
|
+
}));
|
|
145988
|
+
}
|
|
145989
|
+
}
|
|
145990
|
+
await new Promise((resolve31, reject) => {
|
|
145991
|
+
const onError = (error48) => {
|
|
145992
|
+
httpServer?.off("listening", onListening);
|
|
145993
|
+
reject(error48);
|
|
145994
|
+
};
|
|
145995
|
+
const onListening = () => {
|
|
145996
|
+
httpServer?.off("error", onError);
|
|
145997
|
+
listening = true;
|
|
145998
|
+
resolve31();
|
|
145999
|
+
};
|
|
146000
|
+
httpServer.once("error", onError);
|
|
146001
|
+
httpServer.once("listening", onListening);
|
|
146002
|
+
httpServer.listen(opts.port, "127.0.0.1");
|
|
146003
|
+
});
|
|
146004
|
+
LOG2.info(logCategory, `Local IPC listening on ws://127.0.0.1:${opts.port}${DAEMON_WS_PATH2}`);
|
|
146005
|
+
return {
|
|
146006
|
+
isListening: () => listening,
|
|
146007
|
+
broadcast(type2, payload) {
|
|
146008
|
+
const message = JSON.stringify({ type: type2, payload });
|
|
146009
|
+
for (const client of clients) {
|
|
146010
|
+
if (client.readyState !== import_ws3.WebSocket.OPEN) continue;
|
|
146011
|
+
try {
|
|
146012
|
+
client.send(message);
|
|
146013
|
+
} catch {
|
|
146014
|
+
}
|
|
146015
|
+
}
|
|
146016
|
+
},
|
|
146017
|
+
async close() {
|
|
146018
|
+
for (const client of clients) {
|
|
146019
|
+
try {
|
|
146020
|
+
client.close();
|
|
146021
|
+
} catch {
|
|
146022
|
+
}
|
|
146023
|
+
}
|
|
146024
|
+
clients.clear();
|
|
146025
|
+
await new Promise((resolve31) => {
|
|
146026
|
+
if (!httpServer) {
|
|
146027
|
+
resolve31();
|
|
146028
|
+
return;
|
|
146029
|
+
}
|
|
146030
|
+
httpServer.close(() => resolve31());
|
|
146031
|
+
});
|
|
146032
|
+
httpServer = null;
|
|
146033
|
+
wss = null;
|
|
146034
|
+
listening = false;
|
|
146035
|
+
}
|
|
146036
|
+
};
|
|
146037
|
+
}
|
|
146038
|
+
init_fsm_evaluator();
|
|
146039
|
+
init_fsm_loader();
|
|
146040
|
+
var crypto8 = __toESM2(require("crypto"));
|
|
146041
|
+
var import_node_fs10 = require("fs");
|
|
146042
|
+
var import_node_path6 = require("path");
|
|
146043
|
+
init_provider_cli_shared();
|
|
146044
|
+
var import_node_fs11 = require("fs");
|
|
146045
|
+
var import_node_path7 = require("path");
|
|
146046
|
+
init_manifest();
|
|
146047
|
+
var V1_PRIMITIVE_CATALOG = Object.freeze({
|
|
146048
|
+
acp: [
|
|
146049
|
+
"adhdev:acp/session-protocol@1"
|
|
146050
|
+
],
|
|
146051
|
+
tui: [
|
|
146052
|
+
"adhdev:tui/prompt-marker@1",
|
|
146053
|
+
"adhdev:tui/spinner@1",
|
|
146054
|
+
"adhdev:tui/settled-prompt@1",
|
|
146055
|
+
"adhdev:tui/assistant-block@1",
|
|
146056
|
+
"adhdev:tui/tool-block@1",
|
|
146057
|
+
"adhdev:tui/thinking-block@1",
|
|
146058
|
+
"adhdev:tui/user-echo@1",
|
|
146059
|
+
"adhdev:tui/modal@1",
|
|
146060
|
+
"adhdev:tui/modal-as-message@1",
|
|
146061
|
+
"adhdev:tui/footer-chrome@1",
|
|
146062
|
+
"adhdev:tui/welcome-screen@1",
|
|
146063
|
+
"adhdev:tui/visible-region@1",
|
|
146064
|
+
"adhdev:tui/cue-ordering@1",
|
|
146065
|
+
"adhdev:tui/dispatch-order@1",
|
|
146066
|
+
"adhdev:tui/index-finder@1",
|
|
146067
|
+
"adhdev:tui/status-downgrade@1",
|
|
146068
|
+
"adhdev:tui/approval-stitching@1",
|
|
146069
|
+
"adhdev:tui/approval-squash@1",
|
|
146070
|
+
"adhdev:tui/media-input@1",
|
|
146071
|
+
"adhdev:tui/session-id-extraction@1",
|
|
146072
|
+
"adhdev:tui/error-detection@1"
|
|
146073
|
+
],
|
|
146074
|
+
nativeHistory: [
|
|
146075
|
+
"adhdev:native-history/codex-rollout@1",
|
|
146076
|
+
"adhdev:native-history/claude-jsonl@1",
|
|
146077
|
+
"adhdev:native-history/anthropic-cli-transcript@1",
|
|
146078
|
+
"adhdev:native-history/hermes-session@1"
|
|
146079
|
+
],
|
|
146080
|
+
cliCapability: [
|
|
146081
|
+
"adhdev:cli/capability-list@1",
|
|
146082
|
+
"adhdev:cli/control-state@1",
|
|
146083
|
+
"adhdev:cli/capability-action@1",
|
|
146084
|
+
"adhdev:cli/control-toggle@1",
|
|
146085
|
+
"adhdev:cli/picker-open@1",
|
|
146086
|
+
"adhdev:cli/picker-set@1"
|
|
146087
|
+
],
|
|
146088
|
+
common: [
|
|
146089
|
+
"adhdev:common/setting-boolean@1",
|
|
146090
|
+
"adhdev:common/setting-number@1",
|
|
146091
|
+
"adhdev:common/setting-string@1",
|
|
146092
|
+
"adhdev:common/setting-select@1",
|
|
146093
|
+
"adhdev:common/capability-input@1",
|
|
146094
|
+
"adhdev:common/capability-output@1",
|
|
146095
|
+
"adhdev:common/capability-controls@1",
|
|
146096
|
+
"adhdev:common/auth-env-var@1",
|
|
146097
|
+
"adhdev:common/auth-cli-command@1",
|
|
146098
|
+
"adhdev:common/spawn@1",
|
|
146099
|
+
"adhdev:common/timeouts@1",
|
|
146100
|
+
"adhdev:common/resume@1",
|
|
146101
|
+
"adhdev:common/mesh-coordinator@1"
|
|
146102
|
+
],
|
|
146103
|
+
override: [
|
|
146104
|
+
"adhdev:override/cli-parse-session@1",
|
|
146105
|
+
"adhdev:override/cli-detect-status@1",
|
|
146106
|
+
"adhdev:override/cli-parse-approval@1",
|
|
146107
|
+
"adhdev:override/cli-parse-output@1",
|
|
146108
|
+
"adhdev:override/cli-read-native-history@1",
|
|
146109
|
+
"adhdev:override/cli-list-native-history@1",
|
|
146110
|
+
"adhdev:override/cli-capability-handler@1"
|
|
146111
|
+
]
|
|
146112
|
+
});
|
|
146113
|
+
var V1_ALL_PRIMITIVES = Object.freeze(
|
|
146114
|
+
Object.values(V1_PRIMITIVE_CATALOG).flat()
|
|
146115
|
+
);
|
|
146116
|
+
var V1_CONTRACT_VERSION = "1.0.0";
|
|
146117
|
+
var fs65 = __toESM2(require("fs"));
|
|
146118
|
+
var import_chalk2 = __toESM2((init_source(), __toCommonJS(source_exports)));
|
|
146119
|
+
init_dist();
|
|
146120
|
+
var CLAUDE_NO_API_LINE = "Claude has no quota API \u2014 adhdev borrows your statusLine to read it.";
|
|
146121
|
+
var CLAUDE_WRAP_NOT_REPLACE_LINE = "Install wraps (not replaces) your statusline, so nothing is lost.";
|
|
146122
|
+
function windowCue(quota) {
|
|
146123
|
+
if (quota.metadata?.failureKind === "no-data" && (quota.session || quota.weekly)) return "stale";
|
|
146124
|
+
if (quota.metadata?.lastGoodWindows === true) return "refreshing";
|
|
146125
|
+
return void 0;
|
|
146126
|
+
}
|
|
146127
|
+
function formatWindow(label, window, cue = void 0) {
|
|
146128
|
+
if (!window) {
|
|
146129
|
+
return ` ${label.padEnd(8)} ${import_chalk2.default.gray("not reported")}`;
|
|
146130
|
+
}
|
|
146131
|
+
const percent = `${window.usedPercent.toFixed(1)}%`;
|
|
146132
|
+
const bar = renderBar(window.usedPercent);
|
|
146133
|
+
const reset = window.resetsAt === null ? "" : import_chalk2.default.gray(` resets ${formatRelative(window.resetsAt)}`);
|
|
146134
|
+
const marker = cue === "refreshing" ? import_chalk2.default.gray(" (refreshing)") : cue === "stale" ? import_chalk2.default.gray(" (stale)") : "";
|
|
146135
|
+
return ` ${label.padEnd(8)} ${bar} ${percent.padStart(6)} used${reset}${marker}`;
|
|
146136
|
+
}
|
|
146137
|
+
function renderBar(usedPercent) {
|
|
146138
|
+
const width = 20;
|
|
146139
|
+
const filled = Math.round(Math.min(100, Math.max(0, usedPercent)) / 100 * width);
|
|
146140
|
+
const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
|
|
146141
|
+
if (usedPercent >= 90) return import_chalk2.default.red(bar);
|
|
146142
|
+
if (usedPercent >= 70) return import_chalk2.default.yellow(bar);
|
|
146143
|
+
return import_chalk2.default.green(bar);
|
|
146144
|
+
}
|
|
146145
|
+
function formatRelative(atMs) {
|
|
146146
|
+
const deltaMs = atMs - Date.now();
|
|
146147
|
+
if (deltaMs <= 0) {
|
|
146148
|
+
return "now";
|
|
146149
|
+
}
|
|
146150
|
+
const minutes = Math.round(deltaMs / 6e4);
|
|
146151
|
+
if (minutes < 60) return `in ${minutes}m`;
|
|
146152
|
+
const hours = Math.floor(minutes / 60);
|
|
146153
|
+
if (hours < 24) return `in ${hours}h ${minutes % 60}m`;
|
|
146154
|
+
return `in ${Math.floor(hours / 24)}d ${hours % 24}h`;
|
|
146155
|
+
}
|
|
146156
|
+
function truncate(value, max) {
|
|
146157
|
+
return value.length <= max ? value : `${value.slice(0, max - 1)}\u2026`;
|
|
146158
|
+
}
|
|
146159
|
+
function formatAgo(atMs) {
|
|
146160
|
+
const deltaMs = Date.now() - atMs;
|
|
146161
|
+
if (deltaMs <= 0) return "just now";
|
|
146162
|
+
const minutes = Math.round(deltaMs / 6e4);
|
|
146163
|
+
if (minutes < 1) return "just now";
|
|
146164
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
146165
|
+
const hours = Math.floor(minutes / 60);
|
|
146166
|
+
if (hours < 24) return `${hours}h ${minutes % 60}m ago`;
|
|
146167
|
+
return `${Math.floor(hours / 24)}d ${hours % 24}h ago`;
|
|
146168
|
+
}
|
|
146169
|
+
function printQuota2(name, quota) {
|
|
146170
|
+
console.log();
|
|
146171
|
+
const account = formatQuotaAccount(quota);
|
|
146172
|
+
console.log(account ? `${import_chalk2.default.bold(name)} ${import_chalk2.default.gray(account)}` : import_chalk2.default.bold(name));
|
|
146173
|
+
if (quota.status === "ok" || quota.session || quota.weekly) {
|
|
146174
|
+
const cue = windowCue(quota);
|
|
146175
|
+
console.log(formatWindow("5 hour", quota.session, cue));
|
|
146176
|
+
console.log(formatWindow("7 day", quota.weekly, cue));
|
|
146177
|
+
}
|
|
146178
|
+
if (quota.error) {
|
|
146179
|
+
const tone = quota.status === "unavailable" ? import_chalk2.default.gray : import_chalk2.default.yellow;
|
|
146180
|
+
console.log(` ${tone(quota.error)}`);
|
|
146181
|
+
if (quota.provider === "claude-cli" && quota.error.includes("claude:install")) {
|
|
146182
|
+
console.log(` ${import_chalk2.default.gray(CLAUDE_NO_API_LINE)}`);
|
|
146183
|
+
console.log(` ${import_chalk2.default.gray(CLAUDE_WRAP_NOT_REPLACE_LINE)}`);
|
|
146184
|
+
}
|
|
146185
|
+
}
|
|
146186
|
+
console.log();
|
|
146187
|
+
}
|
|
146188
|
+
function printQuotaRefreshOutcome2(entries) {
|
|
146189
|
+
console.log();
|
|
146190
|
+
if (entries.length === 0) {
|
|
146191
|
+
console.log(import_chalk2.default.gray(" Nothing to refresh."));
|
|
146192
|
+
console.log();
|
|
146193
|
+
return;
|
|
146194
|
+
}
|
|
146195
|
+
const refreshed = entries.filter((e) => e.outcome === "refreshed");
|
|
146196
|
+
if (refreshed.length > 0) {
|
|
146197
|
+
console.log(import_chalk2.default.green(`\u2713 Refreshed ${refreshed.map((e) => e.provider).join(", ")}`));
|
|
146198
|
+
}
|
|
146199
|
+
for (const entry of entries) {
|
|
146200
|
+
if (entry.outcome === "refreshed") continue;
|
|
146201
|
+
if (entry.outcome === "cooldown") {
|
|
146202
|
+
console.log(import_chalk2.default.yellow(`\u2022 ${entry.provider}: rate-limited \u2014 not re-probed`));
|
|
146203
|
+
if (typeof entry.retryAtMs === "number" && Number.isFinite(entry.retryAtMs)) {
|
|
146204
|
+
console.log(import_chalk2.default.gray(` Retrying no earlier than ${formatRelative(entry.retryAtMs)}.`));
|
|
146205
|
+
}
|
|
146206
|
+
console.log(import_chalk2.default.gray(" The numbers shown are the last good reading."));
|
|
146207
|
+
console.log(import_chalk2.default.gray(" Re-probing now would extend the provider's own throttle."));
|
|
146208
|
+
continue;
|
|
146209
|
+
}
|
|
146210
|
+
console.log(import_chalk2.default.gray(`\u2022 ${entry.provider}: ${entry.reason || entry.outcome}`));
|
|
146211
|
+
}
|
|
146212
|
+
console.log();
|
|
146213
|
+
}
|
|
146214
|
+
function printClaudeInstallResult2(result) {
|
|
146215
|
+
console.log();
|
|
146216
|
+
console.log(
|
|
146217
|
+
import_chalk2.default.green(
|
|
146218
|
+
result.outcome === "repaired" ? "\u2713 Claude Code quota reporting repaired" : result.outcome === "reinstalled" ? "\u2713 Claude Code quota reporting re-installed" : result.outcome === "wrapped" ? "\u2713 Claude Code quota reporting installed around your statusline" : "\u2713 Claude Code quota reporting installed"
|
|
146219
|
+
)
|
|
146220
|
+
);
|
|
146221
|
+
if (result.outcome === "repaired") {
|
|
146222
|
+
console.log(import_chalk2.default.gray(" Your statusLine pointed at a script that no longer exists:"));
|
|
146223
|
+
console.log(import_chalk2.default.gray(` ${truncate(result.repairedFrom ?? "unknown path", 100)}`));
|
|
146224
|
+
console.log(import_chalk2.default.gray(" It now points at the current wrapper."));
|
|
146225
|
+
}
|
|
146226
|
+
if (result.originalCommand) {
|
|
146227
|
+
console.log(import_chalk2.default.gray(" Your existing statusline is preserved and still runs:"));
|
|
146228
|
+
console.log(import_chalk2.default.gray(` ${truncate(result.originalCommand, 100)}`));
|
|
146229
|
+
console.log(import_chalk2.default.gray(` Backup: ${result.paths.backupFile}`));
|
|
146230
|
+
} else if (result.outcome === "installed") {
|
|
146231
|
+
console.log(import_chalk2.default.gray(" You had no statusline configured; one was not added."));
|
|
146232
|
+
}
|
|
146233
|
+
if (result.volatileWrapperReason) {
|
|
146234
|
+
console.log(
|
|
146235
|
+
import_chalk2.default.yellow(` ! The wrapper was written under ${result.volatileWrapperReason}.`)
|
|
146236
|
+
);
|
|
146237
|
+
console.log(import_chalk2.default.gray(` ${result.paths.wrapperFile}`));
|
|
146238
|
+
console.log(import_chalk2.default.gray(" Claude Code will fail to load it once that path is gone;"));
|
|
146239
|
+
console.log(import_chalk2.default.gray(" re-run `adhdev quota claude:install` from a normal install to fix."));
|
|
146240
|
+
}
|
|
146241
|
+
console.log();
|
|
146242
|
+
console.log(import_chalk2.default.gray(" Open a Claude Code session, then run `adhdev quota claude`."));
|
|
146243
|
+
console.log(import_chalk2.default.gray(" Undo any time with `adhdev quota claude:uninstall`."));
|
|
146244
|
+
console.log();
|
|
146245
|
+
}
|
|
146246
|
+
function printClaudeUninstallResult2(result) {
|
|
146247
|
+
console.log();
|
|
146248
|
+
if (result.outcome === "restored") {
|
|
146249
|
+
console.log(import_chalk2.default.green("\u2713 Your original statusline has been restored"));
|
|
146250
|
+
} else if (result.outcome === "removed") {
|
|
146251
|
+
console.log(import_chalk2.default.green("\u2713 Claude Code quota reporting removed"));
|
|
146252
|
+
console.log(import_chalk2.default.gray(" You had no statusline before install, so none was left behind."));
|
|
146253
|
+
} else {
|
|
146254
|
+
console.log(import_chalk2.default.yellow("\u2022 Claude Code quota reporting was not installed"));
|
|
146255
|
+
console.log(import_chalk2.default.gray(" Your statusLine setting was left untouched."));
|
|
146256
|
+
}
|
|
146257
|
+
console.log();
|
|
146258
|
+
}
|
|
146259
|
+
function printClaudeStatuslineStatus2(status) {
|
|
146260
|
+
console.log();
|
|
146261
|
+
if (status.installed) {
|
|
146262
|
+
console.log(import_chalk2.default.green("\u2713 Installed"));
|
|
146263
|
+
console.log(
|
|
146264
|
+
import_chalk2.default.gray(
|
|
146265
|
+
status.wrappedCommand ? ` Wrapping your statusline: ${truncate(status.wrappedCommand, 100)}` : " You had no statusline before install."
|
|
146266
|
+
)
|
|
146267
|
+
);
|
|
146268
|
+
console.log(import_chalk2.default.gray(` Wrapper: ${status.paths.wrapperFile}`));
|
|
146269
|
+
console.log(import_chalk2.default.gray(` Backup: ${status.paths.backupFile}`));
|
|
146270
|
+
let snapshotMtimeMs = null;
|
|
146271
|
+
try {
|
|
146272
|
+
snapshotMtimeMs = fs65.statSync(status.paths.snapshotFile).mtimeMs;
|
|
146273
|
+
} catch {
|
|
146274
|
+
}
|
|
146275
|
+
console.log(import_chalk2.default.gray(
|
|
146276
|
+
snapshotMtimeMs === null ? " Last snapshot: none yet \u2014 open a Claude Code session to record one" : ` Last snapshot: ${formatAgo(snapshotMtimeMs)} (${status.paths.snapshotFile})`
|
|
146277
|
+
));
|
|
146278
|
+
console.log(import_chalk2.default.gray(" Undo with `adhdev quota claude:uninstall`."));
|
|
146279
|
+
} else if (status.failureKind === "wrapper-missing") {
|
|
146280
|
+
console.log(import_chalk2.default.red("\u2717 Broken \u2014 the configured wrapper no longer exists"));
|
|
146281
|
+
console.log(import_chalk2.default.gray(` statusLine points at: ${truncate(status.danglingWrapperPath ?? "unknown path", 100)}`));
|
|
146282
|
+
console.log(import_chalk2.default.gray(" Claude Code runs that command every prompt and it fails, so"));
|
|
146283
|
+
console.log(import_chalk2.default.gray(" no quota is being captured and your statusline is blank."));
|
|
146284
|
+
if (status.wrappedCommand) {
|
|
146285
|
+
console.log(import_chalk2.default.gray(` Your own statusline is still recorded: ${truncate(status.wrappedCommand, 80)}`));
|
|
146286
|
+
}
|
|
146287
|
+
console.log(import_chalk2.default.gray(" Repair with `adhdev quota claude:install`."));
|
|
146288
|
+
console.log(import_chalk2.default.gray(" Or clear it with `adhdev quota claude:uninstall`."));
|
|
146289
|
+
} else {
|
|
146290
|
+
console.log(import_chalk2.default.yellow("\u2022 Not installed"));
|
|
146291
|
+
if (status.foreignStatusLine) {
|
|
146292
|
+
console.log(import_chalk2.default.gray(" You have your own statusLine configured; install would wrap it."));
|
|
146293
|
+
}
|
|
146294
|
+
console.log(import_chalk2.default.gray(` ${CLAUDE_NO_API_LINE}`));
|
|
146295
|
+
console.log(import_chalk2.default.gray(` ${CLAUDE_WRAP_NOT_REPLACE_LINE}`));
|
|
146296
|
+
console.log(import_chalk2.default.gray(" Set up with `adhdev quota claude:install`."));
|
|
146297
|
+
}
|
|
146298
|
+
console.log();
|
|
146299
|
+
}
|
|
146300
|
+
function printQuotaInstallError2(message) {
|
|
146301
|
+
console.error(import_chalk2.default.red(`
|
|
146302
|
+
\u2717 ${message}
|
|
146303
|
+
`));
|
|
146304
|
+
}
|
|
145915
146305
|
async function appendAssistantJournal(handle, kind, payload) {
|
|
145916
146306
|
if (!handle.topics.some((d) => d.topic === ASSISTANT_JOURNAL_TOPIC)) {
|
|
145917
146307
|
throw new Error(
|
|
@@ -146128,6 +146518,11 @@ Options:
|
|
|
146128
146518
|
|
|
146129
146519
|
Environment:
|
|
146130
146520
|
ADHDEV_SESSION_HOST_NAME Override session host namespace (default: adhdev-standalone)
|
|
146521
|
+
ADHDEV_STANDALONE_PORT Port to listen on when --port is not given (default: 3847).
|
|
146522
|
+
An explicit --port always wins over this.
|
|
146523
|
+
ADHDEV_CONFIG_DIR Override the state/profile directory (default: ~/.adhdev-standalone).
|
|
146524
|
+
Inherited from the environment, not just set explicitly \u2014 see the
|
|
146525
|
+
startup warning if this points at a directory a live daemon owns.
|
|
146131
146526
|
--help, -h Show this help message
|
|
146132
146527
|
|
|
146133
146528
|
Runtime commands:
|
|
@@ -146156,6 +146551,15 @@ function normalizeStandalonePort(raw) {
|
|
|
146156
146551
|
}
|
|
146157
146552
|
return port;
|
|
146158
146553
|
}
|
|
146554
|
+
var STANDALONE_PORT_ENV_VAR = "ADHDEV_STANDALONE_PORT";
|
|
146555
|
+
function resolveStandalonePortEnvOverride(env2 = process.env) {
|
|
146556
|
+
const raw = env2[STANDALONE_PORT_ENV_VAR]?.trim();
|
|
146557
|
+
if (!raw) return void 0;
|
|
146558
|
+
if (!/^\d+$/.test(raw)) return void 0;
|
|
146559
|
+
const port = Number(raw);
|
|
146560
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) return void 0;
|
|
146561
|
+
return port;
|
|
146562
|
+
}
|
|
146159
146563
|
var FLAG_SPECS = [
|
|
146160
146564
|
{ names: ["--port", "-p"], takesValue: true },
|
|
146161
146565
|
{ names: ["--host", "-H"], takesValue: true },
|
|
@@ -147569,7 +147973,7 @@ var StandaloneServer = class {
|
|
|
147569
147973
|
if (!options.host && persistedStandaloneBindHost !== STANDALONE_BIND_HOST_DEFAULT) {
|
|
147570
147974
|
saveStandaloneBindHostPreference(persistedStandaloneBindHost);
|
|
147571
147975
|
}
|
|
147572
|
-
const port = options.port || DEFAULT_PORT;
|
|
147976
|
+
const port = options.port || resolveStandalonePortEnvOverride() || DEFAULT_PORT;
|
|
147573
147977
|
(0, import_daemon_core3.setLogInstancePort)(port);
|
|
147574
147978
|
process.env.ADHDEV_COORDINATOR_MCP_TRANSPORT = "local";
|
|
147575
147979
|
process.env.ADHDEV_COORDINATOR_MCP_PORT = String(port);
|
|
@@ -147694,8 +148098,20 @@ var StandaloneServer = class {
|
|
|
147694
148098
|
if (this.topicRegistry.hasSubscriptions("workspace.git")) void this.topicRegistry.flushNow("workspace.git");
|
|
147695
148099
|
}, STATUS_INTERVAL);
|
|
147696
148100
|
this.running = true;
|
|
147697
|
-
await new Promise((resolve2) => {
|
|
148101
|
+
await new Promise((resolve2, reject) => {
|
|
148102
|
+
const onError = (err) => {
|
|
148103
|
+
this.running = false;
|
|
148104
|
+
if (err.code === "EADDRINUSE") {
|
|
148105
|
+
reject(new Error(
|
|
148106
|
+
`Port ${port} is already in use \u2014 another process (possibly another ADHDev daemon) is listening on ${host}:${port}. Use --port <port> or set ADHDEV_STANDALONE_PORT to pick a different one.`
|
|
148107
|
+
));
|
|
148108
|
+
} else {
|
|
148109
|
+
reject(err);
|
|
148110
|
+
}
|
|
148111
|
+
};
|
|
148112
|
+
this.httpServer.once("error", onError);
|
|
147698
148113
|
this.httpServer.listen(port, host, () => {
|
|
148114
|
+
this.httpServer.off("error", onError);
|
|
147699
148115
|
resolve2();
|
|
147700
148116
|
});
|
|
147701
148117
|
});
|