@adhdev/daemon-core 1.0.23-rc.1 → 1.0.24-rc.1
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/cli-adapters/provider-cli-shared.d.ts +2 -0
- package/dist/commands/upgrade-helper.d.ts +8 -0
- package/dist/commands/windows-atomic-upgrade.d.ts +8 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +229 -79
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +185 -37
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +24 -0
- package/package.json +3 -3
- package/src/cli-adapters/provider-cli-shared.ts +109 -6
- package/src/commands/upgrade-helper.d.ts +3 -0
- package/src/commands/upgrade-helper.ts +35 -8
- package/src/commands/windows-atomic-upgrade.ts +26 -4
- package/src/index.ts +2 -1
- package/src/providers/cli-provider-instance.ts +86 -14
- package/src/session-host/managed-host.ts +47 -1
package/dist/index.mjs
CHANGED
|
@@ -786,10 +786,10 @@ function readInjected(value) {
|
|
|
786
786
|
}
|
|
787
787
|
function getDaemonBuildInfo() {
|
|
788
788
|
if (cached) return cached;
|
|
789
|
-
const commit = readInjected(true ? "
|
|
790
|
-
const commitShort = readInjected(true ? "
|
|
791
|
-
const version = readInjected(true ? "1.0.
|
|
792
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
789
|
+
const commit = readInjected(true ? "159c481abed0a48a043711e3c9c8a3a12b900336" : void 0) ?? "unknown";
|
|
790
|
+
const commitShort = readInjected(true ? "159c481a" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
791
|
+
const version = readInjected(true ? "1.0.24-rc.1" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
792
|
+
const builtAt = readInjected(true ? "2026-07-24T11:39:26.052Z" : void 0);
|
|
793
793
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
794
794
|
return cached;
|
|
795
795
|
}
|
|
@@ -13070,6 +13070,7 @@ var init_spawn_env = __esm({
|
|
|
13070
13070
|
// src/cli-adapters/provider-cli-shared.ts
|
|
13071
13071
|
import * as os6 from "os";
|
|
13072
13072
|
import * as path11 from "path";
|
|
13073
|
+
import { execSync } from "child_process";
|
|
13073
13074
|
function isPurePtyTranscriptProvider(provider) {
|
|
13074
13075
|
if (!provider) return false;
|
|
13075
13076
|
if (provider.transcriptAuthority === "provider") return false;
|
|
@@ -13225,6 +13226,73 @@ function buildCliScreenSnapshot(text) {
|
|
|
13225
13226
|
linesBelowPrompt: promptLineIndex >= 0 ? lines.slice(promptLineIndex + 1) : []
|
|
13226
13227
|
};
|
|
13227
13228
|
}
|
|
13229
|
+
function windowsExecutableExtensions() {
|
|
13230
|
+
const raw = process.env.PATHEXT;
|
|
13231
|
+
const fromEnv = raw ? raw.split(";").map((e) => e.trim().toLowerCase()).filter(Boolean) : [".exe", ".cmd", ".bat"];
|
|
13232
|
+
const merged = [...fromEnv];
|
|
13233
|
+
if (!merged.includes(".ps1")) merged.push(".ps1");
|
|
13234
|
+
if (!merged.includes("")) merged.push("");
|
|
13235
|
+
return Array.from(new Set(merged));
|
|
13236
|
+
}
|
|
13237
|
+
function npmGlobalPrefix() {
|
|
13238
|
+
if (cachedNpmPrefix !== void 0) return cachedNpmPrefix ?? void 0;
|
|
13239
|
+
try {
|
|
13240
|
+
const prefix = execSync("npm config get prefix", {
|
|
13241
|
+
encoding: "utf-8",
|
|
13242
|
+
timeout: 2e3,
|
|
13243
|
+
windowsHide: true,
|
|
13244
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
13245
|
+
}).trim();
|
|
13246
|
+
cachedNpmPrefix = prefix && prefix !== "undefined" ? prefix : null;
|
|
13247
|
+
} catch {
|
|
13248
|
+
cachedNpmPrefix = null;
|
|
13249
|
+
}
|
|
13250
|
+
return cachedNpmPrefix ?? void 0;
|
|
13251
|
+
}
|
|
13252
|
+
function windowsExtraBinDirs() {
|
|
13253
|
+
const dirs = [];
|
|
13254
|
+
const fs44 = __require("fs");
|
|
13255
|
+
const push = (dir) => {
|
|
13256
|
+
if (!dir) return;
|
|
13257
|
+
try {
|
|
13258
|
+
if (fs44.existsSync(dir)) dirs.push(dir);
|
|
13259
|
+
} catch {
|
|
13260
|
+
}
|
|
13261
|
+
};
|
|
13262
|
+
if (process.env.APPDATA) push(path11.join(process.env.APPDATA, "npm"));
|
|
13263
|
+
if (process.env.LOCALAPPDATA) push(path11.join(process.env.LOCALAPPDATA, "npm"));
|
|
13264
|
+
if (process.env.USERPROFILE) push(path11.join(process.env.USERPROFILE, "scoop", "shims"));
|
|
13265
|
+
push(npmGlobalPrefix());
|
|
13266
|
+
try {
|
|
13267
|
+
push(path11.dirname(process.execPath));
|
|
13268
|
+
} catch {
|
|
13269
|
+
}
|
|
13270
|
+
return dirs;
|
|
13271
|
+
}
|
|
13272
|
+
function unixExtraBinDirs() {
|
|
13273
|
+
const dirs = [];
|
|
13274
|
+
const fs44 = __require("fs");
|
|
13275
|
+
const home = os6.homedir();
|
|
13276
|
+
const push = (dir) => {
|
|
13277
|
+
if (!dir) return;
|
|
13278
|
+
try {
|
|
13279
|
+
if (fs44.existsSync(dir)) dirs.push(dir);
|
|
13280
|
+
} catch {
|
|
13281
|
+
}
|
|
13282
|
+
};
|
|
13283
|
+
push(path11.join(home, ".local", "bin"));
|
|
13284
|
+
push(path11.join(home, ".claude", "local", "bin"));
|
|
13285
|
+
push(path11.join(home, ".npm-global", "bin"));
|
|
13286
|
+
push("/usr/local/bin");
|
|
13287
|
+
push("/opt/homebrew/bin");
|
|
13288
|
+
const prefix = npmGlobalPrefix();
|
|
13289
|
+
if (prefix) push(path11.join(prefix, "bin"));
|
|
13290
|
+
try {
|
|
13291
|
+
push(path11.dirname(process.execPath));
|
|
13292
|
+
} catch {
|
|
13293
|
+
}
|
|
13294
|
+
return dirs;
|
|
13295
|
+
}
|
|
13228
13296
|
function findBinary(name) {
|
|
13229
13297
|
const trimmed = String(name || "").trim();
|
|
13230
13298
|
if (!trimmed) return trimmed;
|
|
@@ -13236,21 +13304,12 @@ function findBinary(name) {
|
|
|
13236
13304
|
const paths = (process.env.PATH || "").split(path11.delimiter);
|
|
13237
13305
|
const extraDirs = [];
|
|
13238
13306
|
if (isWin) {
|
|
13239
|
-
|
|
13240
|
-
try {
|
|
13241
|
-
extraDirs.push(path11.dirname(process.execPath));
|
|
13242
|
-
} catch {
|
|
13243
|
-
}
|
|
13307
|
+
extraDirs.push(...windowsExtraBinDirs());
|
|
13244
13308
|
} else {
|
|
13245
|
-
extraDirs.push(
|
|
13246
|
-
extraDirs.push("/usr/local/bin", "/opt/homebrew/bin");
|
|
13247
|
-
try {
|
|
13248
|
-
extraDirs.push(path11.dirname(process.execPath));
|
|
13249
|
-
} catch {
|
|
13250
|
-
}
|
|
13309
|
+
extraDirs.push(...unixExtraBinDirs());
|
|
13251
13310
|
}
|
|
13252
13311
|
const searchDirs = [...paths, ...extraDirs];
|
|
13253
|
-
const exes = isWin ?
|
|
13312
|
+
const exes = isWin ? windowsExecutableExtensions() : [""];
|
|
13254
13313
|
for (const p of searchDirs) {
|
|
13255
13314
|
if (!p) continue;
|
|
13256
13315
|
for (const ext of exes) {
|
|
@@ -13375,7 +13434,7 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
13375
13434
|
}
|
|
13376
13435
|
};
|
|
13377
13436
|
}
|
|
13378
|
-
var TerminalTranscriptAccumulator, MESH_SEND_KEY_ENCODING, MESH_DESTRUCTIVE_KEYS, MESH_SEND_KEYS_MAX_ITEMS, MESH_SEND_KEYS_MAX_TEXT_BYTES, buildCliSpawnEnv;
|
|
13437
|
+
var TerminalTranscriptAccumulator, MESH_SEND_KEY_ENCODING, MESH_DESTRUCTIVE_KEYS, MESH_SEND_KEYS_MAX_ITEMS, MESH_SEND_KEYS_MAX_TEXT_BYTES, buildCliSpawnEnv, cachedNpmPrefix;
|
|
13379
13438
|
var init_provider_cli_shared = __esm({
|
|
13380
13439
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
13381
13440
|
"use strict";
|
|
@@ -13551,6 +13610,7 @@ var init_provider_cli_shared = __esm({
|
|
|
13551
13610
|
MESH_SEND_KEYS_MAX_ITEMS = 64;
|
|
13552
13611
|
MESH_SEND_KEYS_MAX_TEXT_BYTES = 4096;
|
|
13553
13612
|
buildCliSpawnEnv = sanitizeSpawnEnv;
|
|
13613
|
+
cachedNpmPrefix = void 0;
|
|
13554
13614
|
}
|
|
13555
13615
|
});
|
|
13556
13616
|
|
|
@@ -43873,10 +43933,16 @@ var ADHDEV_OWNED_MARKERS = [
|
|
|
43873
43933
|
function normalizeForCompare(value) {
|
|
43874
43934
|
return path20.resolve(value).replace(/[\\/]+$/, "").toLowerCase();
|
|
43875
43935
|
}
|
|
43936
|
+
var DEFAULT_INSTANCE_DIR = ".adhdev";
|
|
43937
|
+
function normalizeInstanceDir(instanceDir) {
|
|
43938
|
+
const trimmed = instanceDir?.trim();
|
|
43939
|
+
return trimmed ? trimmed : DEFAULT_INSTANCE_DIR;
|
|
43940
|
+
}
|
|
43876
43941
|
function resolveWindowsInstallerLayout(options) {
|
|
43877
43942
|
if ((options.platform || process.platform) !== "win32" || !options.installPrefix) return null;
|
|
43878
|
-
const
|
|
43879
|
-
const
|
|
43943
|
+
const instanceDir = normalizeInstanceDir(options.instanceDir);
|
|
43944
|
+
const installRoot = path20.join(options.homeDir, instanceDir, "npm-installs");
|
|
43945
|
+
const stablePrefix = path20.join(options.homeDir, instanceDir, "npm-global");
|
|
43880
43946
|
const pointerPath = path20.join(stablePrefix, POINTER_NAME);
|
|
43881
43947
|
const activeVersionName = path20.basename(options.installPrefix);
|
|
43882
43948
|
if (!activeVersionName.startsWith("version-")) return null;
|
|
@@ -43904,9 +43970,9 @@ function nodeMajor(nodeExecutable) {
|
|
|
43904
43970
|
return null;
|
|
43905
43971
|
}
|
|
43906
43972
|
}
|
|
43907
|
-
function findPortableNode22(homeDir, currentNode = process.execPath) {
|
|
43973
|
+
function findPortableNode22(homeDir, currentNode = process.execPath, instanceDir = DEFAULT_INSTANCE_DIR) {
|
|
43908
43974
|
const candidates = [currentNode];
|
|
43909
|
-
const portableRoot = path20.join(homeDir,
|
|
43975
|
+
const portableRoot = path20.join(homeDir, normalizeInstanceDir(instanceDir), "tools", "node22");
|
|
43910
43976
|
try {
|
|
43911
43977
|
const dirs = fs14.readdirSync(portableRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path20.join(portableRoot, entry.name, "node.exe"));
|
|
43912
43978
|
candidates.push(...dirs);
|
|
@@ -44290,7 +44356,12 @@ function removeInactivePrefix(target, log) {
|
|
|
44290
44356
|
}
|
|
44291
44357
|
|
|
44292
44358
|
// src/commands/upgrade-helper.ts
|
|
44359
|
+
init_config();
|
|
44293
44360
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
44361
|
+
function resolveInstanceDir(configDir = getConfigDir()) {
|
|
44362
|
+
const base = path21.basename(configDir).trim();
|
|
44363
|
+
return base || ".adhdev";
|
|
44364
|
+
}
|
|
44294
44365
|
function getUpgradeLogPath(home = os14.homedir()) {
|
|
44295
44366
|
const dir = path21.join(home, ".adhdev");
|
|
44296
44367
|
fs15.mkdirSync(dir, { recursive: true });
|
|
@@ -44372,16 +44443,16 @@ function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
|
44372
44443
|
}
|
|
44373
44444
|
return maybeLibDir;
|
|
44374
44445
|
}
|
|
44375
|
-
function isPortableNode22Prefix(prefix, homeDir) {
|
|
44446
|
+
function isPortableNode22Prefix(prefix, homeDir, instanceDir = ".adhdev") {
|
|
44376
44447
|
if (!prefix) return false;
|
|
44377
|
-
const portableRoot = path21.join(homeDir,
|
|
44448
|
+
const portableRoot = path21.join(homeDir, instanceDir, "tools", "node22");
|
|
44378
44449
|
const normalizedPrefix = path21.resolve(prefix).replace(/[\\/]+$/, "").toLowerCase();
|
|
44379
44450
|
const normalizedRoot = path21.resolve(portableRoot).replace(/[\\/]+$/, "").toLowerCase();
|
|
44380
44451
|
return normalizedPrefix === normalizedRoot || normalizedPrefix.startsWith(`${normalizedRoot}${path21.sep.toLowerCase()}`);
|
|
44381
44452
|
}
|
|
44382
|
-
function canonicalDispatcherInstallPrefix(homeDir) {
|
|
44383
|
-
const installRoot = path21.join(homeDir,
|
|
44384
|
-
const pointerPath = path21.join(homeDir,
|
|
44453
|
+
function canonicalDispatcherInstallPrefix(homeDir, instanceDir = ".adhdev") {
|
|
44454
|
+
const installRoot = path21.join(homeDir, instanceDir, "npm-installs");
|
|
44455
|
+
const pointerPath = path21.join(homeDir, instanceDir, "npm-global", ".adhdev-current");
|
|
44385
44456
|
try {
|
|
44386
44457
|
const activeVersion = fs15.readFileSync(pointerPath, "utf8").trim();
|
|
44387
44458
|
if (activeVersion.startsWith("version-")) return path21.join(installRoot, activeVersion);
|
|
@@ -44394,9 +44465,10 @@ function resolveCurrentGlobalInstallSurface(options) {
|
|
|
44394
44465
|
const npmInvocation = resolveSiblingNpmInvocation(options.nodeExecutable || process.execPath, options.platform);
|
|
44395
44466
|
const platform10 = options.platform || process.platform;
|
|
44396
44467
|
const homeDir = options.homeDir || os14.homedir();
|
|
44468
|
+
const instanceDir = options.instanceDir || resolveInstanceDir();
|
|
44397
44469
|
let installPrefix = packageRoot ? resolveInstallPrefixFromPackageRoot(packageRoot, options.packageName) : null;
|
|
44398
|
-
if (platform10 === "win32" && isPortableNode22Prefix(installPrefix, homeDir)) {
|
|
44399
|
-
installPrefix = canonicalDispatcherInstallPrefix(homeDir);
|
|
44470
|
+
if (platform10 === "win32" && isPortableNode22Prefix(installPrefix, homeDir, instanceDir)) {
|
|
44471
|
+
installPrefix = canonicalDispatcherInstallPrefix(homeDir, instanceDir);
|
|
44400
44472
|
}
|
|
44401
44473
|
return {
|
|
44402
44474
|
npmExecutable: npmInvocation.executable,
|
|
@@ -44646,12 +44718,14 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
44646
44718
|
}
|
|
44647
44719
|
await stopSessionHostProcesses(sessionHostAppName);
|
|
44648
44720
|
removeDaemonPidFile();
|
|
44721
|
+
const instanceDir = resolveInstanceDir();
|
|
44649
44722
|
const windowsInstallerLayout = resolveWindowsInstallerLayout({
|
|
44650
44723
|
homeDir: os14.homedir(),
|
|
44651
|
-
installPrefix: installCommand.surface.installPrefix
|
|
44724
|
+
installPrefix: installCommand.surface.installPrefix,
|
|
44725
|
+
instanceDir
|
|
44652
44726
|
});
|
|
44653
44727
|
if (windowsInstallerLayout) {
|
|
44654
|
-
const portableNode = findPortableNode22(os14.homedir());
|
|
44728
|
+
const portableNode = findPortableNode22(os14.homedir(), process.execPath, instanceDir);
|
|
44655
44729
|
if (!portableNode) {
|
|
44656
44730
|
throw new Error("installer-managed Windows update requires the portable Node.js 22 runtime");
|
|
44657
44731
|
}
|
|
@@ -49032,6 +49106,7 @@ init_logger();
|
|
|
49032
49106
|
init_debug_trace();
|
|
49033
49107
|
init_debug_config();
|
|
49034
49108
|
init_mesh_event_trace();
|
|
49109
|
+
init_mesh_events_utils();
|
|
49035
49110
|
init_control_effects();
|
|
49036
49111
|
init_approval_utils();
|
|
49037
49112
|
init_provider_patch_state();
|
|
@@ -50515,6 +50590,17 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
50515
50590
|
// this to refuse a SECOND completion for a turn whose completion already fired —
|
|
50516
50591
|
// so a worker that finished cleanly and is simply being auto-cleaned never emits a
|
|
50517
50592
|
// duplicate. taskId '' covers an ad-hoc (no-task) turn. null = none emitted yet.
|
|
50593
|
+
//
|
|
50594
|
+
// COMPLETION-WEAK-REARM (fix1): the latch now carries the EVIDENCE STRENGTH of the
|
|
50595
|
+
// recorded emit. `weak` mirrors isWeakCompletionEvidence() over the exact event that
|
|
50596
|
+
// was pushed (evidenceLevel ∈ {weak,insufficient}, reviewRecommended, or a
|
|
50597
|
+
// missing_final_assistant diagnostic — the CANON-C decoupled-immediate emit and the
|
|
50598
|
+
// startup-grace fast-collapse synth are the two weak producers). `emittedAtEpoch`
|
|
50599
|
+
// snapshots busyEpoch at emit time so the transcript re-emit paths can require a real
|
|
50600
|
+
// generating→idle transition (busyEpoch advanced past this) before re-arming — a
|
|
50601
|
+
// static idle screen can never re-fire the same weak frame. A weak latch is a
|
|
50602
|
+
// ONE-SHOT re-arm: the genuine re-emit overwrites this with weak=false, so a
|
|
50603
|
+
// subsequent idle tick hits the non-weak latch and stops (never a third emit).
|
|
50518
50604
|
lastEmittedCompletion = null;
|
|
50519
50605
|
async enforceFreshSessionLaunchIfNeeded() {
|
|
50520
50606
|
const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
|
|
@@ -51270,7 +51356,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51270
51356
|
flushMeshCompletionBeforeCleanup() {
|
|
51271
51357
|
if (!this.isMeshWorkerSession()) return false;
|
|
51272
51358
|
const taskId = this.completingTurnTaskId();
|
|
51273
|
-
if (this.
|
|
51359
|
+
if (this.shouldSuppressCompletionReEmit(taskId)) {
|
|
51274
51360
|
return false;
|
|
51275
51361
|
}
|
|
51276
51362
|
if (!this.injectedTaskHasStartedGenerating()) return false;
|
|
@@ -51334,7 +51420,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51334
51420
|
if (observedStatus !== "idle") return false;
|
|
51335
51421
|
if (this.hasAdapterPendingResponse()) return false;
|
|
51336
51422
|
const taskId = this.completingTurnTaskId();
|
|
51337
|
-
if (this.
|
|
51423
|
+
if (this.shouldSuppressCompletionReEmit(taskId)) {
|
|
51338
51424
|
return false;
|
|
51339
51425
|
}
|
|
51340
51426
|
if (!this.injectedTaskHasStartedGenerating()) return false;
|
|
@@ -51399,7 +51485,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51399
51485
|
if (observedStatus !== "idle") return false;
|
|
51400
51486
|
if (this.hasAdapterPendingResponse()) return false;
|
|
51401
51487
|
const taskId = this.completingTurnTaskId();
|
|
51402
|
-
if (this.
|
|
51488
|
+
if (this.shouldSuppressCompletionReEmit(taskId)) {
|
|
51403
51489
|
return false;
|
|
51404
51490
|
}
|
|
51405
51491
|
if (!this.injectedTaskHasStartedGenerating()) return false;
|
|
@@ -51832,8 +51918,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51832
51918
|
if (summary) {
|
|
51833
51919
|
this.lastCompletionSummary = { content: summary, receivedAt: opts.timestamp };
|
|
51834
51920
|
}
|
|
51835
|
-
|
|
51836
|
-
this.pushEvent({
|
|
51921
|
+
const completionEvent = {
|
|
51837
51922
|
event: "agent:generating_completed",
|
|
51838
51923
|
chatTitle: opts.chatTitle,
|
|
51839
51924
|
duration: opts.duration,
|
|
@@ -51845,11 +51930,49 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51845
51930
|
finalSummary: opts.finalSummary,
|
|
51846
51931
|
...opts.evidenceLevel !== void 0 ? { evidenceLevel: opts.evidenceLevel } : {},
|
|
51847
51932
|
...opts.completionDiagnostic !== void 0 ? { completionDiagnostic: opts.completionDiagnostic } : {}
|
|
51848
|
-
}
|
|
51933
|
+
};
|
|
51934
|
+
this.lastEmittedCompletion = {
|
|
51935
|
+
taskId: typeof opts.taskId === "string" ? opts.taskId : "",
|
|
51936
|
+
at: Date.now(),
|
|
51937
|
+
evidenceLevel: opts.evidenceLevel,
|
|
51938
|
+
weak: isWeakCompletionEvidence(completionEvent),
|
|
51939
|
+
emittedAtEpoch: this.busyEpoch
|
|
51940
|
+
};
|
|
51941
|
+
this.pushEvent(completionEvent);
|
|
51849
51942
|
if (this.settings?.silentNextIdlePush === true) {
|
|
51850
51943
|
this.updateSettings({ silentNextIdlePush: void 0, silentNextIdlePushArmedAt: void 0 });
|
|
51851
51944
|
}
|
|
51852
51945
|
}
|
|
51946
|
+
/**
|
|
51947
|
+
* COMPLETION-WEAK-REARM (fix1): the double-emit guard shared by the three transcript
|
|
51948
|
+
* re-emit paths (flushMeshCompletionBeforeCleanup, tryReconcilePurePtyCompletionForStall,
|
|
51949
|
+
* tryReconcileNativeSourceCompletionForStall). Returns true when a re-emit for `taskId`
|
|
51950
|
+
* must be SUPPRESSED because this turn's completion already fired with strong evidence.
|
|
51951
|
+
*
|
|
51952
|
+
* The defect this replaces: the old guard short-circuited on ANY prior emit for the
|
|
51953
|
+
* taskId, regardless of its evidence. After a WEAK completion (CANON-C decoupled-immediate
|
|
51954
|
+
* missing_final_assistant, or a startup-grace fast-collapse synth), the same session
|
|
51955
|
+
* reaching a GENUINE idle later (final assistant present) was silently swallowed — the
|
|
51956
|
+
* worker never emitted the genuine completion and the coordinator held on the acked-death
|
|
51957
|
+
* deadline (8 min).
|
|
51958
|
+
*
|
|
51959
|
+
* New behavior:
|
|
51960
|
+
* • no latch / taskId mismatch → NOT suppressed (the caller's own evidence gate runs).
|
|
51961
|
+
* • prior emit was GENUINE (not weak) → SUPPRESSED (single-shot; a clean completion is
|
|
51962
|
+
* never re-emitted).
|
|
51963
|
+
* • prior emit was WEAK → re-arm ONE-SHOT, but only across a real generating→idle
|
|
51964
|
+
* transition: require busyEpoch to have advanced past the weak emit's epoch, so a
|
|
51965
|
+
* static idle screen cannot re-fire the same weak frame. The genuine re-emit passes
|
|
51966
|
+
* evidenceLevel:'transcript' (non-weak), overwriting the latch → any subsequent idle
|
|
51967
|
+
* tick hits the now-genuine latch and is suppressed. Never a third emit.
|
|
51968
|
+
*/
|
|
51969
|
+
shouldSuppressCompletionReEmit(taskId) {
|
|
51970
|
+
const latch = this.lastEmittedCompletion;
|
|
51971
|
+
if (!latch || latch.taskId !== (taskId ?? "")) return false;
|
|
51972
|
+
if (!latch.weak) return true;
|
|
51973
|
+
if (this.busyEpoch <= latch.emittedAtEpoch) return true;
|
|
51974
|
+
return false;
|
|
51975
|
+
}
|
|
51853
51976
|
/**
|
|
51854
51977
|
* AUTOAPPROVE-FLAP-INBOX-MISSING sticky-approval overlay. Returns the adapterStatus a
|
|
51855
51978
|
* flap-prone claude-cli approval SHOULD present this frame — either the raw status
|
|
@@ -75931,8 +76054,31 @@ function createManagedSessionHost(options) {
|
|
|
75931
76054
|
return false;
|
|
75932
76055
|
}
|
|
75933
76056
|
}
|
|
76057
|
+
function resolveSessionHostNode() {
|
|
76058
|
+
if (process.platform !== "win32") {
|
|
76059
|
+
return process.execPath;
|
|
76060
|
+
}
|
|
76061
|
+
let portableNode = null;
|
|
76062
|
+
try {
|
|
76063
|
+
portableNode = findPortableNode22(os32.homedir(), process.execPath, resolveInstanceDir());
|
|
76064
|
+
} catch (error) {
|
|
76065
|
+
LOG.warn(
|
|
76066
|
+
"SessionHost",
|
|
76067
|
+
`Failed to resolve portable Node 22 for the session-host spawn: ${error instanceof Error ? error.message : String(error)}`
|
|
76068
|
+
);
|
|
76069
|
+
}
|
|
76070
|
+
if (portableNode) {
|
|
76071
|
+
return portableNode;
|
|
76072
|
+
}
|
|
76073
|
+
LOG.warn(
|
|
76074
|
+
"SessionHost",
|
|
76075
|
+
`Portable Node 22 not found; spawning the session-host with ${process.execPath}. node-pty may fail to load its conpty.node prebuild under a non-22 Node on win32.`
|
|
76076
|
+
);
|
|
76077
|
+
return process.execPath;
|
|
76078
|
+
}
|
|
75934
76079
|
function spawnHost() {
|
|
75935
76080
|
const entry = resolveEntry();
|
|
76081
|
+
const nodeExecutable = resolveSessionHostNode();
|
|
75936
76082
|
let stdio = "ignore";
|
|
75937
76083
|
let logFd = null;
|
|
75938
76084
|
if (options.spawnStdio === "logfile") {
|
|
@@ -75941,7 +76087,7 @@ function createManagedSessionHost(options) {
|
|
|
75941
76087
|
logFd = fs43.openSync(path45.join(logDir, "session-host.log"), "a");
|
|
75942
76088
|
stdio = ["ignore", logFd, logFd];
|
|
75943
76089
|
}
|
|
75944
|
-
const child = spawn5(
|
|
76090
|
+
const child = spawn5(nodeExecutable, [entry], {
|
|
75945
76091
|
detached: true,
|
|
75946
76092
|
stdio,
|
|
75947
76093
|
windowsHide: true,
|
|
@@ -77087,6 +77233,7 @@ export {
|
|
|
77087
77233
|
getActiveMeshMissionSummaries,
|
|
77088
77234
|
getActiveSessionDeliveries,
|
|
77089
77235
|
getAvailableIdeIds,
|
|
77236
|
+
getConfigDir,
|
|
77090
77237
|
getCoordinatorForSession,
|
|
77091
77238
|
getCurrentDaemonLogPath,
|
|
77092
77239
|
getDaemonBuildInfo,
|
|
@@ -77263,6 +77410,7 @@ export {
|
|
|
77263
77410
|
resolveDeliveryDecision,
|
|
77264
77411
|
resolveEffectiveMeshNodeHealth,
|
|
77265
77412
|
resolveGitRepository,
|
|
77413
|
+
resolveInstanceDir,
|
|
77266
77414
|
resolveMagiSessionCleanupMode,
|
|
77267
77415
|
resolveMaxParallelTasks,
|
|
77268
77416
|
resolveMeshHostStatus,
|