@adhdev/daemon-core 1.0.18-rc.2 → 1.0.18-rc.3
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/cli-state-engine.d.ts +77 -0
- package/dist/cli-adapters/pty-transport.d.ts +2 -1
- package/dist/commands/process-lifecycle.d.ts +43 -0
- package/dist/commands/windows-atomic-upgrade.d.ts +12 -1
- package/dist/index.js +470 -147
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +479 -156
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/cli-adapters/cli-state-engine.ts +204 -3
- package/src/cli-adapters/provider-cli-adapter.ts +39 -5
- package/src/cli-adapters/pty-transport.d.ts +2 -1
- package/src/cli-adapters/pty-transport.ts +1 -1
- package/src/cli-adapters/session-host-transport.ts +8 -3
- package/src/commands/process-lifecycle.ts +248 -0
- package/src/commands/upgrade-helper.ts +29 -68
- package/src/commands/windows-atomic-upgrade.ts +96 -4
- package/src/session-host/managed-host.ts +34 -0
package/dist/index.js
CHANGED
|
@@ -442,10 +442,10 @@ function readInjected(value) {
|
|
|
442
442
|
}
|
|
443
443
|
function getDaemonBuildInfo() {
|
|
444
444
|
if (cached) return cached;
|
|
445
|
-
const commit = readInjected(true ? "
|
|
446
|
-
const commitShort = readInjected(true ? "
|
|
447
|
-
const version = readInjected(true ? "1.0.18-rc.
|
|
448
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
445
|
+
const commit = readInjected(true ? "96f3f1365be0d875f5089fc7ce7e4e254ca8e08d" : void 0) ?? "unknown";
|
|
446
|
+
const commitShort = readInjected(true ? "96f3f136" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
447
|
+
const version = readInjected(true ? "1.0.18-rc.3" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
448
|
+
const builtAt = readInjected(true ? "2026-07-21T13:00:17.395Z" : void 0);
|
|
449
449
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
450
450
|
return cached;
|
|
451
451
|
}
|
|
@@ -25779,6 +25779,22 @@ var init_cli_state_engine = __esm({
|
|
|
25779
25779
|
// ── Approval ─────────────────────────────────────
|
|
25780
25780
|
lastApprovalResolvedAt = 0;
|
|
25781
25781
|
lastResolvedModalMessage = "";
|
|
25782
|
+
/**
|
|
25783
|
+
* Normalized approval-context signature captured at resolve time (see
|
|
25784
|
+
* `computeApprovalContentSignature`) — the screen text with blank-line
|
|
25785
|
+
* padding and any manifest-declared chrome (transcriptPty.chromePatterns,
|
|
25786
|
+
* spinner.patterns) stripped out. Used by applyWaitingApproval's
|
|
25787
|
+
* isStaleResolvedRepaint check to tell "the same already-answered modal,
|
|
25788
|
+
* re-parsed from a screen that has not meaningfully changed" apart from
|
|
25789
|
+
* "a genuinely new approval" — content-based, not time-based, because
|
|
25790
|
+
* ordinary TUI chrome (status bar, context meter, blank-line repaint)
|
|
25791
|
+
* keeps producing fresh PTY bytes on an otherwise-unchanged screen and
|
|
25792
|
+
* defeats any output-timestamp discriminator within a few hundred ms.
|
|
25793
|
+
* Cleared whenever a turn starts or the session tears down (see
|
|
25794
|
+
* onTurnStarted / resetActiveTurnState / onPtyExit) so a next-turn
|
|
25795
|
+
* approval is never compared against stale prior-turn state.
|
|
25796
|
+
*/
|
|
25797
|
+
lastApprovalResolvedContentSignature = "";
|
|
25782
25798
|
/**
|
|
25783
25799
|
* Monotonic counter bumped every time the FSM *enters* waiting_approval
|
|
25784
25800
|
* with a freshly captured modal (see `applyWaitingApproval`). It is the
|
|
@@ -25898,11 +25914,17 @@ var init_cli_state_engine = __esm({
|
|
|
25898
25914
|
this.currentTurnTaskId = typeof turnScope.taskId === "string" && turnScope.taskId.trim() ? turnScope.taskId : null;
|
|
25899
25915
|
this.currentTurnStartedAt = Date.now();
|
|
25900
25916
|
this.responseEpoch += 1;
|
|
25917
|
+
this.clearApprovalResolutionMemory();
|
|
25918
|
+
if (this.provider.transcriptAuthority === "provider" && this.currentStatus !== "waiting_approval") {
|
|
25919
|
+
this.setStatus("generating", "turn_started");
|
|
25920
|
+
this.callbacks.onStatusChange();
|
|
25921
|
+
}
|
|
25901
25922
|
}
|
|
25902
25923
|
/** Called when PTY exits */
|
|
25903
25924
|
onPtyExit() {
|
|
25904
25925
|
this.clearAllTimers();
|
|
25905
25926
|
this.setStatus("stopped", "pty_exit");
|
|
25927
|
+
this.clearApprovalResolutionMemory();
|
|
25906
25928
|
}
|
|
25907
25929
|
/** Called when adapter starts up successfully */
|
|
25908
25930
|
onSpawnReady() {
|
|
@@ -25944,6 +25966,7 @@ var init_cli_state_engine = __esm({
|
|
|
25944
25966
|
this.activeModal = null;
|
|
25945
25967
|
this.lastApprovalResolvedAt = Date.now();
|
|
25946
25968
|
this.lastResolvedModalMessage = currentModalMessage;
|
|
25969
|
+
this.lastApprovalResolvedContentSignature = this.computeApprovalContentSignature(snap);
|
|
25947
25970
|
this.lastResolvedEntrySeq = this.approvalEntrySeq;
|
|
25948
25971
|
this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
|
|
25949
25972
|
if (this.approvalExitTimeout) {
|
|
@@ -26066,6 +26089,7 @@ var init_cli_state_engine = __esm({
|
|
|
26066
26089
|
this.pendingScriptStatusSince = 0;
|
|
26067
26090
|
this.approvalResumeDeferSince = 0;
|
|
26068
26091
|
this.approvalResumeDeferEpoch = -1;
|
|
26092
|
+
this.clearApprovalResolutionMemory();
|
|
26069
26093
|
}
|
|
26070
26094
|
clearIdleFinishCandidate(reason) {
|
|
26071
26095
|
if (!this.idleFinishCandidate) return;
|
|
@@ -26224,7 +26248,15 @@ var init_cli_state_engine = __esm({
|
|
|
26224
26248
|
}
|
|
26225
26249
|
if (!status) return;
|
|
26226
26250
|
const prevStatus = this.currentStatus;
|
|
26227
|
-
const ctx = {
|
|
26251
|
+
const ctx = {
|
|
26252
|
+
now,
|
|
26253
|
+
modal,
|
|
26254
|
+
status,
|
|
26255
|
+
parsedMessages,
|
|
26256
|
+
lastParsedAssistant,
|
|
26257
|
+
parsedStatus: parsedStatus || null,
|
|
26258
|
+
prevStatus
|
|
26259
|
+
};
|
|
26228
26260
|
if (!this.applyPendingScriptStatusDebounce(ctx)) return;
|
|
26229
26261
|
const recentInteractiveActivity = this.hasRecentInteractiveActivity(snap, now);
|
|
26230
26262
|
LOG.debug(
|
|
@@ -26260,7 +26292,7 @@ var init_cli_state_engine = __esm({
|
|
|
26260
26292
|
return;
|
|
26261
26293
|
}
|
|
26262
26294
|
if (status === "waiting_approval") {
|
|
26263
|
-
this.applyWaitingApproval(ctx);
|
|
26295
|
+
this.applyWaitingApproval(ctx, snap);
|
|
26264
26296
|
return;
|
|
26265
26297
|
}
|
|
26266
26298
|
if (status === "generating") {
|
|
@@ -26320,7 +26352,7 @@ var init_cli_state_engine = __esm({
|
|
|
26320
26352
|
}, this.timeouts.generatingIdle);
|
|
26321
26353
|
this.callbacks.onStatusChange();
|
|
26322
26354
|
}
|
|
26323
|
-
applyWaitingApproval(ctx) {
|
|
26355
|
+
applyWaitingApproval(ctx, snap) {
|
|
26324
26356
|
const { modal } = ctx;
|
|
26325
26357
|
this.clearIdleFinishCandidate("waiting_approval");
|
|
26326
26358
|
const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
@@ -26367,6 +26399,11 @@ var init_cli_state_engine = __esm({
|
|
|
26367
26399
|
}
|
|
26368
26400
|
return;
|
|
26369
26401
|
}
|
|
26402
|
+
const isStaleResolvedRepaint = !this.activeModal && this.isStaleResolvedApproval(modal, snap);
|
|
26403
|
+
if (isStaleResolvedRepaint) {
|
|
26404
|
+
LOG.debug("CLI", `[${this.provider.type}] ignoring stale re-parsed approval matching the just-resolved modal (approval-context signature unchanged)`);
|
|
26405
|
+
return;
|
|
26406
|
+
}
|
|
26370
26407
|
this.modalLostAt = 0;
|
|
26371
26408
|
this.isWaitingForResponse = true;
|
|
26372
26409
|
this.setStatus("waiting_approval", "script_detect");
|
|
@@ -26652,6 +26689,86 @@ var init_cli_state_engine = __esm({
|
|
|
26652
26689
|
this.recordTrace("idle_finish_cancelled", { trigger: reason });
|
|
26653
26690
|
}
|
|
26654
26691
|
// ─── Helpers ────────────────────────────────────────────────────────────
|
|
26692
|
+
/**
|
|
26693
|
+
* Derive a stable approval-context signature from the current screen,
|
|
26694
|
+
* with blank-line padding and any manifest-declared chrome stripped out.
|
|
26695
|
+
*
|
|
26696
|
+
* Generic by design — no kimi- or provider-specific hardcoding: it reads
|
|
26697
|
+
* whatever `tui.transcriptPty.chromePatterns` and `tui.spinner.patterns`
|
|
26698
|
+
* the ACTIVE provider's own manifest already declares (present on any
|
|
26699
|
+
* declarative-TUI provider; simply absent/empty for scripted providers,
|
|
26700
|
+
* in which case this degrades to blank-line stripping only — never worse
|
|
26701
|
+
* than comparing the raw screen). Those pattern lists exist precisely to
|
|
26702
|
+
* name "known volatile repaint noise" (status bar, context meter, spinner
|
|
26703
|
+
* ticks, banners) — reusing them here means the SAME declared knowledge
|
|
26704
|
+
* that governs transcript-chrome stripping also governs staleness
|
|
26705
|
+
* detection, instead of re-encoding provider knowledge into daemon-core.
|
|
26706
|
+
*
|
|
26707
|
+
* Deliberately NOT a hash of the whole screen/buffer: an ordinary TUI
|
|
26708
|
+
* repaints its footer/status/context-meter chrome continuously even while
|
|
26709
|
+
* genuinely idle, so a raw whole-screen or whole-buffer fingerprint (or a
|
|
26710
|
+
* mere "did any bytes arrive" timestamp) changes on every repaint tick
|
|
26711
|
+
* regardless of whether anything approval-relevant actually happened.
|
|
26712
|
+
* Stripping the declared chrome first yields a signature that only
|
|
26713
|
+
* changes when the surrounding conversation/tool-output content itself
|
|
26714
|
+
* changes — exactly the discriminator applyWaitingApproval's
|
|
26715
|
+
* isStaleResolvedRepaint check needs.
|
|
26716
|
+
*/
|
|
26717
|
+
computeApprovalContentSignature(snap) {
|
|
26718
|
+
const screenText = snap.screenText || snap.accumulatedBuffer || "";
|
|
26719
|
+
if (!screenText) return "";
|
|
26720
|
+
const tui = this.provider.tui;
|
|
26721
|
+
const patternSpecs = [
|
|
26722
|
+
...Array.isArray(tui?.transcriptPty?.chromePatterns) ? tui.transcriptPty.chromePatterns : [],
|
|
26723
|
+
...Array.isArray(tui?.spinner?.patterns) ? tui.spinner.patterns : []
|
|
26724
|
+
];
|
|
26725
|
+
const chromeRegexes = [];
|
|
26726
|
+
for (const spec of patternSpecs) {
|
|
26727
|
+
if (spec && typeof spec.regex === "string") {
|
|
26728
|
+
try {
|
|
26729
|
+
chromeRegexes.push(new RegExp(spec.regex, typeof spec.flags === "string" ? spec.flags : ""));
|
|
26730
|
+
} catch {
|
|
26731
|
+
}
|
|
26732
|
+
}
|
|
26733
|
+
}
|
|
26734
|
+
const kept = [];
|
|
26735
|
+
for (const rawLine of screenText.split("\n")) {
|
|
26736
|
+
const line = rawLine.trim();
|
|
26737
|
+
if (!line) continue;
|
|
26738
|
+
if (chromeRegexes.some((re) => re.test(line))) continue;
|
|
26739
|
+
kept.push(line);
|
|
26740
|
+
}
|
|
26741
|
+
return kept.join("\n");
|
|
26742
|
+
}
|
|
26743
|
+
/**
|
|
26744
|
+
* True when `modal` is a stale re-parse of an already-resolved approval:
|
|
26745
|
+
* same message text, and the chrome-stripped approval-context signature
|
|
26746
|
+
* of `snap` is unchanged from the signature captured at resolve time.
|
|
26747
|
+
*
|
|
26748
|
+
* Public and reused verbatim by BOTH the settled-eval capture path
|
|
26749
|
+
* (applyWaitingApproval, below) and any OUTSIDE re-parse the adapter
|
|
26750
|
+
* performs independently of the settle loop — e.g. provider-cli-adapter's
|
|
26751
|
+
* getStatus()/getDebugState() startup-gate modal detection, which reads
|
|
26752
|
+
* `recentOutputBuffer` directly while `startupParseGate` is open and can
|
|
26753
|
+
* re-surface the same already-resolved modal before the gate closes.
|
|
26754
|
+
* Centralizing the discriminator here means there is exactly ONE
|
|
26755
|
+
* definition of "stale" for the whole session — no divergent duplicate
|
|
26756
|
+
* heuristic re-implemented per call site.
|
|
26757
|
+
*/
|
|
26758
|
+
isStaleResolvedApproval(modal, snap) {
|
|
26759
|
+
if (!modal) return false;
|
|
26760
|
+
const normalizedMessage = typeof modal.message === "string" ? modal.message.trim() : "";
|
|
26761
|
+
if (!normalizedMessage) return false;
|
|
26762
|
+
return this.lastApprovalResolvedAt > 0 && normalizedMessage === this.lastResolvedModalMessage && this.computeApprovalContentSignature(snap) === this.lastApprovalResolvedContentSignature;
|
|
26763
|
+
}
|
|
26764
|
+
/** Clear all resolve-time approval bookkeeping (message, timestamp, content
|
|
26765
|
+
* signature) — called at turn/session boundaries so a next-turn or
|
|
26766
|
+
* next-session approval is never compared against stale prior state. */
|
|
26767
|
+
clearApprovalResolutionMemory() {
|
|
26768
|
+
this.lastApprovalResolvedAt = 0;
|
|
26769
|
+
this.lastResolvedModalMessage = "";
|
|
26770
|
+
this.lastApprovalResolvedContentSignature = "";
|
|
26771
|
+
}
|
|
26655
26772
|
/**
|
|
26656
26773
|
* Schedule one more settled evaluation while pinned to `waiting_approval`
|
|
26657
26774
|
* with no actionable modal. The settled FSM normally only re-runs on new
|
|
@@ -27477,8 +27594,8 @@ ${lastSnapshot}`;
|
|
|
27477
27594
|
}
|
|
27478
27595
|
}
|
|
27479
27596
|
});
|
|
27480
|
-
this.ptyProcess.onExit(({ exitCode }) => {
|
|
27481
|
-
LOG.info("CLI", `[${this.cliType}] Exit code ${exitCode}`);
|
|
27597
|
+
this.ptyProcess.onExit(({ exitCode, signal }) => {
|
|
27598
|
+
LOG.info("CLI", `[${this.cliType}] Exit code ${exitCode === null || exitCode === void 0 ? "unknown" : exitCode}${signal ? ` (signal ${signal})` : ""}`);
|
|
27482
27599
|
this.flushPendingOutputParse();
|
|
27483
27600
|
this.ptyProcess = null;
|
|
27484
27601
|
this.engine.onPtyExit();
|
|
@@ -27784,7 +27901,10 @@ ${lastSnapshot}`;
|
|
|
27784
27901
|
// ─── Public API (CliAdapter) ───────────────────
|
|
27785
27902
|
getStatus(options = {}) {
|
|
27786
27903
|
const allowParse = options.allowParse !== false;
|
|
27787
|
-
|
|
27904
|
+
let startupModal = allowParse && this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
|
|
27905
|
+
if (startupModal && this.engine.isStaleResolvedApproval(startupModal, { screenText: this.terminalScreen.getText(), accumulatedBuffer: this.accumulatedBuffer })) {
|
|
27906
|
+
startupModal = null;
|
|
27907
|
+
}
|
|
27788
27908
|
const startupDetectedStatus = allowParse && this.startupParseGate && !startupModal ? this.runDetectStatus(this.recentOutputBuffer || this.terminalScreen.getText()) : null;
|
|
27789
27909
|
if (allowParse && this.engine.currentStatus === "generating" && !this.engine.currentTurnScope && !this.engine.activeModal) {
|
|
27790
27910
|
const now = Date.now();
|
|
@@ -27818,7 +27938,7 @@ ${lastSnapshot}`;
|
|
|
27818
27938
|
if (liveDetect === "waiting_approval") {
|
|
27819
27939
|
const liveModal = this.runParseApproval(this.terminalScreen.getText()) || this.runParseApproval(this.recentOutputBuffer);
|
|
27820
27940
|
const buttonsOk = liveModal && Array.isArray(liveModal.buttons) && liveModal.buttons.some((b) => typeof b === "string" && b.trim());
|
|
27821
|
-
if (liveModal && buttonsOk) {
|
|
27941
|
+
if (liveModal && buttonsOk && !this.engine.isStaleResolvedApproval(liveModal, { screenText: this.terminalScreen.getText(), accumulatedBuffer: this.accumulatedBuffer })) {
|
|
27822
27942
|
effectiveModal = liveModal;
|
|
27823
27943
|
if (!this.engine.activeModal) this.engine.activeModal = liveModal;
|
|
27824
27944
|
}
|
|
@@ -28944,7 +29064,10 @@ ${lastSnapshot}`;
|
|
|
28944
29064
|
}
|
|
28945
29065
|
getDebugState() {
|
|
28946
29066
|
const screenText = sanitizeTerminalText(this.terminalScreen.getText());
|
|
28947
|
-
|
|
29067
|
+
let startupModal = this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
|
|
29068
|
+
if (startupModal && this.engine.isStaleResolvedApproval(startupModal, { screenText: this.terminalScreen.getText(), accumulatedBuffer: this.accumulatedBuffer })) {
|
|
29069
|
+
startupModal = null;
|
|
29070
|
+
}
|
|
28948
29071
|
const startupDetectedStatus = this.startupParseGate && !startupModal ? this.runDetectStatus(this.recentOutputBuffer || screenText) : null;
|
|
28949
29072
|
const effectiveReady = this.ready || !!startupModal || startupDetectedStatus === "waiting_approval";
|
|
28950
29073
|
const parsedDebugState = this.getParsedDebugState();
|
|
@@ -42712,20 +42835,202 @@ var notificationHandlers = {
|
|
|
42712
42835
|
init_config();
|
|
42713
42836
|
|
|
42714
42837
|
// src/commands/upgrade-helper.ts
|
|
42715
|
-
var import_child_process6 = require("child_process");
|
|
42716
42838
|
var import_child_process7 = require("child_process");
|
|
42839
|
+
var import_child_process8 = require("child_process");
|
|
42717
42840
|
var fs15 = __toESM(require("fs"));
|
|
42718
42841
|
var os13 = __toESM(require("os"));
|
|
42719
42842
|
var path21 = __toESM(require("path"));
|
|
42720
42843
|
|
|
42721
42844
|
// src/commands/windows-atomic-upgrade.ts
|
|
42722
|
-
var
|
|
42845
|
+
var import_child_process6 = require("child_process");
|
|
42723
42846
|
var fs14 = __toESM(require("fs"));
|
|
42724
42847
|
var http2 = __toESM(require("http"));
|
|
42725
42848
|
var path20 = __toESM(require("path"));
|
|
42849
|
+
|
|
42850
|
+
// src/commands/process-lifecycle.ts
|
|
42851
|
+
var import_child_process5 = require("child_process");
|
|
42852
|
+
function defaultExecFileSync() {
|
|
42853
|
+
return import_child_process5.execFileSync;
|
|
42854
|
+
}
|
|
42855
|
+
function getWindowsProcessCommandLine(pid, exec7) {
|
|
42856
|
+
const pidFilter = `ProcessId=${pid}`;
|
|
42857
|
+
try {
|
|
42858
|
+
const psOut = exec7("powershell.exe", [
|
|
42859
|
+
"-NoProfile",
|
|
42860
|
+
"-NonInteractive",
|
|
42861
|
+
"-ExecutionPolicy",
|
|
42862
|
+
"Bypass",
|
|
42863
|
+
"-Command",
|
|
42864
|
+
`(Get-CimInstance Win32_Process -Filter "${pidFilter}").CommandLine`
|
|
42865
|
+
], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"], windowsHide: true });
|
|
42866
|
+
const text = String(psOut).trim();
|
|
42867
|
+
if (text) return text;
|
|
42868
|
+
} catch {
|
|
42869
|
+
}
|
|
42870
|
+
try {
|
|
42871
|
+
const wmicOut = exec7("wmic", [
|
|
42872
|
+
"process",
|
|
42873
|
+
"where",
|
|
42874
|
+
pidFilter,
|
|
42875
|
+
"get",
|
|
42876
|
+
"CommandLine"
|
|
42877
|
+
], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"], windowsHide: true });
|
|
42878
|
+
const text = String(wmicOut).trim();
|
|
42879
|
+
if (text) return text;
|
|
42880
|
+
} catch {
|
|
42881
|
+
}
|
|
42882
|
+
return null;
|
|
42883
|
+
}
|
|
42884
|
+
function getProcessCommandLine(pid, options = {}) {
|
|
42885
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
42886
|
+
const exec7 = options.execFileSync ?? defaultExecFileSync();
|
|
42887
|
+
const platform10 = options.platform ?? process.platform;
|
|
42888
|
+
if (platform10 === "win32") {
|
|
42889
|
+
return getWindowsProcessCommandLine(pid, exec7);
|
|
42890
|
+
}
|
|
42891
|
+
try {
|
|
42892
|
+
const text = String(exec7("ps", ["-o", "command=", "-p", String(pid)], {
|
|
42893
|
+
encoding: "utf8",
|
|
42894
|
+
timeout: 3e3,
|
|
42895
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
42896
|
+
})).trim();
|
|
42897
|
+
return text || null;
|
|
42898
|
+
} catch {
|
|
42899
|
+
return null;
|
|
42900
|
+
}
|
|
42901
|
+
}
|
|
42902
|
+
function parseNodeScriptPath(commandLine) {
|
|
42903
|
+
if (!commandLine) return null;
|
|
42904
|
+
let rest = commandLine.trim();
|
|
42905
|
+
if (rest.startsWith('"')) {
|
|
42906
|
+
const end = rest.indexOf('"', 1);
|
|
42907
|
+
if (end === -1) return null;
|
|
42908
|
+
rest = rest.slice(end + 1).trim();
|
|
42909
|
+
} else {
|
|
42910
|
+
const idx2 = rest.search(/\s/);
|
|
42911
|
+
if (idx2 === -1) return null;
|
|
42912
|
+
rest = rest.slice(idx2 + 1).trim();
|
|
42913
|
+
}
|
|
42914
|
+
if (!rest) return null;
|
|
42915
|
+
if (rest.startsWith('"')) {
|
|
42916
|
+
const end = rest.indexOf('"', 1);
|
|
42917
|
+
return end === -1 ? rest.slice(1) : rest.slice(1, end);
|
|
42918
|
+
}
|
|
42919
|
+
const idx = rest.search(/\s/);
|
|
42920
|
+
return idx === -1 ? rest : rest.slice(0, idx);
|
|
42921
|
+
}
|
|
42922
|
+
function normalizeWindowsPath(value) {
|
|
42923
|
+
return value.toLowerCase().replace(/\//g, "\\").replace(/\\+$/, "");
|
|
42924
|
+
}
|
|
42925
|
+
function killProcess(pid, options = {}) {
|
|
42926
|
+
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
42927
|
+
const exec7 = options.execFileSync ?? defaultExecFileSync();
|
|
42928
|
+
const platform10 = options.platform ?? process.platform;
|
|
42929
|
+
try {
|
|
42930
|
+
if (platform10 === "win32") {
|
|
42931
|
+
exec7("taskkill", ["/PID", String(pid), "/T", "/F"], {
|
|
42932
|
+
stdio: "ignore",
|
|
42933
|
+
windowsHide: true
|
|
42934
|
+
});
|
|
42935
|
+
} else {
|
|
42936
|
+
process.kill(pid, "SIGTERM");
|
|
42937
|
+
}
|
|
42938
|
+
return true;
|
|
42939
|
+
} catch {
|
|
42940
|
+
return false;
|
|
42941
|
+
}
|
|
42942
|
+
}
|
|
42943
|
+
async function waitForPidExit(pid, timeoutMs) {
|
|
42944
|
+
const start = Date.now();
|
|
42945
|
+
while (Date.now() - start < timeoutMs) {
|
|
42946
|
+
try {
|
|
42947
|
+
process.kill(pid, 0);
|
|
42948
|
+
await new Promise((resolve27) => setTimeout(resolve27, 250));
|
|
42949
|
+
} catch {
|
|
42950
|
+
return true;
|
|
42951
|
+
}
|
|
42952
|
+
}
|
|
42953
|
+
return false;
|
|
42954
|
+
}
|
|
42955
|
+
function listOwnedNodeProcesses(options) {
|
|
42956
|
+
const platform10 = options.platform ?? process.platform;
|
|
42957
|
+
if (platform10 !== "win32") return [];
|
|
42958
|
+
const exec7 = options.execFileSync ?? defaultExecFileSync();
|
|
42959
|
+
const prefixes = options.prefixes.map((p) => normalizeWindowsPath(p));
|
|
42960
|
+
const exclude = new Set((options.excludePids ?? []).filter((n) => Number.isFinite(n) && n > 0));
|
|
42961
|
+
const markers = (options.markers ?? []).map((m) => m.toLowerCase().replace(/\//g, "\\"));
|
|
42962
|
+
let pids = [];
|
|
42963
|
+
try {
|
|
42964
|
+
const out = String(exec7("powershell.exe", [
|
|
42965
|
+
"-NoProfile",
|
|
42966
|
+
"-NonInteractive",
|
|
42967
|
+
"-ExecutionPolicy",
|
|
42968
|
+
"Bypass",
|
|
42969
|
+
"-Command",
|
|
42970
|
+
"Get-Process node -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Id | ConvertTo-Json -Compress"
|
|
42971
|
+
], { encoding: "utf8", timeout: 8e3, stdio: ["ignore", "pipe", "ignore"], windowsHide: true })).trim();
|
|
42972
|
+
if (out) {
|
|
42973
|
+
const parsed = JSON.parse(out);
|
|
42974
|
+
pids = Array.isArray(parsed) ? parsed : [parsed];
|
|
42975
|
+
}
|
|
42976
|
+
} catch {
|
|
42977
|
+
return [];
|
|
42978
|
+
}
|
|
42979
|
+
const results = [];
|
|
42980
|
+
for (const pid of pids) {
|
|
42981
|
+
if (!Number.isFinite(pid) || pid <= 0 || exclude.has(pid)) continue;
|
|
42982
|
+
const commandLine = getProcessCommandLine(pid, { platform: platform10, execFileSync: exec7 });
|
|
42983
|
+
if (!commandLine) continue;
|
|
42984
|
+
const lower = commandLine.toLowerCase();
|
|
42985
|
+
const underPrefix = prefixes.some((prefix) => lower.includes(prefix));
|
|
42986
|
+
if (!underPrefix) continue;
|
|
42987
|
+
if (markers.length > 0 && !markers.some((marker) => lower.includes(marker))) continue;
|
|
42988
|
+
results.push({ pid, commandLine });
|
|
42989
|
+
}
|
|
42990
|
+
return results;
|
|
42991
|
+
}
|
|
42992
|
+
async function stopOwnedProcesses(options) {
|
|
42993
|
+
const waitMs = options.waitMs ?? 15e3;
|
|
42994
|
+
const killed = /* @__PURE__ */ new Set();
|
|
42995
|
+
for (const p of options.processes) {
|
|
42996
|
+
if (killProcess(p.pid, options)) killed.add(p.pid);
|
|
42997
|
+
}
|
|
42998
|
+
const survivors = [];
|
|
42999
|
+
for (const p of options.processes) {
|
|
43000
|
+
if (!killed.has(p.pid)) {
|
|
43001
|
+
survivors.push(p);
|
|
43002
|
+
continue;
|
|
43003
|
+
}
|
|
43004
|
+
const exited = await waitForPidExit(p.pid, waitMs);
|
|
43005
|
+
if (!exited) survivors.push(p);
|
|
43006
|
+
}
|
|
43007
|
+
return { stopped: options.processes.length - survivors.length, survivors };
|
|
43008
|
+
}
|
|
43009
|
+
async function stopOwnedProcessesForPrefixes(options) {
|
|
43010
|
+
const processes = listOwnedNodeProcesses(options);
|
|
43011
|
+
if (processes.length === 0) return { stopped: 0, survivors: [] };
|
|
43012
|
+
options.log?.(`Stopping ${processes.length} owned process(es) under prefixes: ${options.prefixes.join(", ")}`);
|
|
43013
|
+
const result = await stopOwnedProcesses({
|
|
43014
|
+
processes,
|
|
43015
|
+
waitMs: options.waitMs,
|
|
43016
|
+
platform: options.platform,
|
|
43017
|
+
execFileSync: options.execFileSync
|
|
43018
|
+
});
|
|
43019
|
+
if (result.survivors.length > 0) {
|
|
43020
|
+
options.log?.(`Could not stop ${result.survivors.length} owned process(es): ${result.survivors.map((s2) => s2.pid).join(", ")}`);
|
|
43021
|
+
}
|
|
43022
|
+
return result;
|
|
43023
|
+
}
|
|
43024
|
+
|
|
43025
|
+
// src/commands/windows-atomic-upgrade.ts
|
|
42726
43026
|
var POINTER_NAME = ".adhdev-current";
|
|
42727
43027
|
var STABLE_FILES = [POINTER_NAME, "adhdev.cmd", "adhdev.ps1", "adhdev"];
|
|
42728
43028
|
var DEFAULT_HEALTH_PORT = 19222;
|
|
43029
|
+
var ADHDEV_OWNED_MARKERS = [
|
|
43030
|
+
"session-host-daemon",
|
|
43031
|
+
"node_modules/adhdev",
|
|
43032
|
+
"node_modules/@adhdev/daemon-standalone"
|
|
43033
|
+
];
|
|
42729
43034
|
function normalizeForCompare(value) {
|
|
42730
43035
|
return path20.resolve(value).replace(/[\\/]+$/, "").toLowerCase();
|
|
42731
43036
|
}
|
|
@@ -42748,7 +43053,7 @@ function resolveWindowsInstallerLayout(options) {
|
|
|
42748
43053
|
}
|
|
42749
43054
|
function nodeMajor(nodeExecutable) {
|
|
42750
43055
|
try {
|
|
42751
|
-
const version = String((0,
|
|
43056
|
+
const version = String((0, import_child_process6.execFileSync)(nodeExecutable, ["-p", "process.versions.node"], {
|
|
42752
43057
|
encoding: "utf8",
|
|
42753
43058
|
timeout: 5e3,
|
|
42754
43059
|
windowsHide: true,
|
|
@@ -42810,7 +43115,7 @@ exit $LASTEXITCODE\r
|
|
|
42810
43115
|
}
|
|
42811
43116
|
}
|
|
42812
43117
|
function validateStagedCli(portableNode, cliEntry, targetVersion) {
|
|
42813
|
-
const output = String((0,
|
|
43118
|
+
const output = String((0, import_child_process6.execFileSync)(portableNode, [cliEntry, "--version"], {
|
|
42814
43119
|
encoding: "utf8",
|
|
42815
43120
|
timeout: 15e3,
|
|
42816
43121
|
windowsHide: true,
|
|
@@ -42839,7 +43144,7 @@ function atomicWrite(destination, content, encoding) {
|
|
|
42839
43144
|
`} finally { if ([IO.File]::Exists($temporary)) { [IO.File]::Delete($temporary) } }`
|
|
42840
43145
|
].join("\n");
|
|
42841
43146
|
const encoded = Buffer.from(script, "utf16le").toString("base64");
|
|
42842
|
-
const result = (0,
|
|
43147
|
+
const result = (0, import_child_process6.spawnSync)("powershell.exe", [
|
|
42843
43148
|
"-NoLogo",
|
|
42844
43149
|
"-NoProfile",
|
|
42845
43150
|
"-NonInteractive",
|
|
@@ -42924,6 +43229,19 @@ async function performWindowsAtomicUpgrade(options) {
|
|
|
42924
43229
|
pinStagedShims(stagedPrefix, portableNode, stagedCliEntry);
|
|
42925
43230
|
validateStagedCli(portableNode, stagedCliEntry, targetVersion);
|
|
42926
43231
|
hooks.log(`Validated staged CLI and portable Node 22 shims in ${stagedPrefix}`);
|
|
43232
|
+
const excludedPids = new Set([process.pid, ...options.excludePids ?? []].filter((n) => Number.isFinite(n) && n > 0));
|
|
43233
|
+
const preStop = await stopOwnedProcessesForPrefixes({
|
|
43234
|
+
prefixes: [layout.activePrefix, layout.stablePrefix],
|
|
43235
|
+
excludePids: Array.from(excludedPids),
|
|
43236
|
+
markers: Array.from(ADHDEV_OWNED_MARKERS),
|
|
43237
|
+
waitMs: 15e3,
|
|
43238
|
+
log: hooks.log
|
|
43239
|
+
});
|
|
43240
|
+
if (preStop.survivors.length > 0) {
|
|
43241
|
+
throw new Error(
|
|
43242
|
+
`Cannot activate ${versionName}: ${preStop.survivors.length} owned process(es) still running under the current prefix`
|
|
43243
|
+
);
|
|
43244
|
+
}
|
|
42927
43245
|
activated = true;
|
|
42928
43246
|
publishStableShimsAndPointer(layout, versionName);
|
|
42929
43247
|
hooks.log(`Atomically activated ${versionName}`);
|
|
@@ -42933,7 +43251,7 @@ async function performWindowsAtomicUpgrade(options) {
|
|
|
42933
43251
|
throw new Error("replacement daemon did not pass the health/version gate");
|
|
42934
43252
|
}
|
|
42935
43253
|
hooks.log(`Replacement daemon pid ${daemonPid} passed health for ${targetVersion}`);
|
|
42936
|
-
hooks.cleanup(layout, stagedPrefix);
|
|
43254
|
+
await hooks.cleanup(layout, stagedPrefix);
|
|
42937
43255
|
return { stagedPrefix, stagedCliEntry, daemonPid };
|
|
42938
43256
|
} catch (error) {
|
|
42939
43257
|
if (restarted?.pid) hooks.stopProcess(restarted.pid);
|
|
@@ -42951,7 +43269,7 @@ async function performWindowsAtomicUpgrade(options) {
|
|
|
42951
43269
|
hooks.log("Failed to restart the previous daemon during rollback");
|
|
42952
43270
|
}
|
|
42953
43271
|
try {
|
|
42954
|
-
hooks.cleanup(layout, layout.activePrefix);
|
|
43272
|
+
await hooks.cleanup(layout, layout.activePrefix);
|
|
42955
43273
|
} catch {
|
|
42956
43274
|
}
|
|
42957
43275
|
throw error;
|
|
@@ -42963,7 +43281,7 @@ function createDefaultWindowsAtomicHooks(options) {
|
|
|
42963
43281
|
const env = { ...options.env, ADHDEV_BOOTSTRAP: "1" };
|
|
42964
43282
|
const pathKey = Object.keys(env).find((key2) => key2.toLowerCase() === "path") || "Path";
|
|
42965
43283
|
env[pathKey] = `${path20.dirname(portableNode)};${env[pathKey] || ""}`;
|
|
42966
|
-
(0,
|
|
43284
|
+
(0, import_child_process6.execFileSync)(portableNode, [
|
|
42967
43285
|
options.npmCliPath,
|
|
42968
43286
|
"install",
|
|
42969
43287
|
"-g",
|
|
@@ -42983,7 +43301,7 @@ function createDefaultWindowsAtomicHooks(options) {
|
|
|
42983
43301
|
restart: (portableNode, stagedCliEntry) => {
|
|
42984
43302
|
const restartArgv = options.restartArgv.map((arg, index) => index === 0 ? stagedCliEntry : arg);
|
|
42985
43303
|
if (restartArgv.length === 0) throw new Error("replacement daemon restart arguments are missing");
|
|
42986
|
-
const child = (0,
|
|
43304
|
+
const child = (0, import_child_process6.spawn)(portableNode, restartArgv, {
|
|
42987
43305
|
detached: true,
|
|
42988
43306
|
stdio: "ignore",
|
|
42989
43307
|
windowsHide: true,
|
|
@@ -42995,7 +43313,7 @@ function createDefaultWindowsAtomicHooks(options) {
|
|
|
42995
43313
|
},
|
|
42996
43314
|
restartOld: (portableNode) => {
|
|
42997
43315
|
if (options.restartArgv.length === 0) return;
|
|
42998
|
-
const child = (0,
|
|
43316
|
+
const child = (0, import_child_process6.spawn)(portableNode, options.restartArgv, {
|
|
42999
43317
|
detached: true,
|
|
43000
43318
|
stdio: "ignore",
|
|
43001
43319
|
windowsHide: true,
|
|
@@ -43033,15 +43351,23 @@ function createDefaultWindowsAtomicHooks(options) {
|
|
|
43033
43351
|
},
|
|
43034
43352
|
stopProcess: (pid) => {
|
|
43035
43353
|
try {
|
|
43036
|
-
(0,
|
|
43354
|
+
(0, import_child_process6.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
|
|
43037
43355
|
} catch {
|
|
43038
43356
|
}
|
|
43039
43357
|
},
|
|
43040
|
-
cleanup: (layout, activePrefix) =>
|
|
43358
|
+
cleanup: async (layout, activePrefix) => cleanupInactivePrefixesWithGuard({
|
|
43359
|
+
layout,
|
|
43360
|
+
activePrefix,
|
|
43361
|
+
excludePids: [process.pid],
|
|
43362
|
+
markers: Array.from(ADHDEV_OWNED_MARKERS),
|
|
43363
|
+
waitMs: 15e3,
|
|
43364
|
+
log: options.log
|
|
43365
|
+
}),
|
|
43041
43366
|
log: options.log
|
|
43042
43367
|
};
|
|
43043
43368
|
}
|
|
43044
|
-
function
|
|
43369
|
+
async function cleanupInactivePrefixesWithGuard(options) {
|
|
43370
|
+
const { layout, activePrefix, log } = options;
|
|
43045
43371
|
let candidates = [];
|
|
43046
43372
|
try {
|
|
43047
43373
|
candidates = fs14.readdirSync(layout.installRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.startsWith("version-")).map((entry) => path20.join(layout.installRoot, entry.name)).filter((entry) => normalizeForCompare(entry) !== normalizeForCompare(activePrefix)).sort().slice(0, 8);
|
|
@@ -43049,19 +43375,41 @@ function boundedCleanupInactivePrefixes(layout, activePrefix, log) {
|
|
|
43049
43375
|
return;
|
|
43050
43376
|
}
|
|
43051
43377
|
if (candidates.length === 0) return;
|
|
43052
|
-
const
|
|
43053
|
-
|
|
43054
|
-
|
|
43055
|
-
|
|
43056
|
-
|
|
43057
|
-
|
|
43058
|
-
|
|
43059
|
-
|
|
43060
|
-
|
|
43061
|
-
|
|
43062
|
-
|
|
43063
|
-
|
|
43064
|
-
|
|
43378
|
+
for (const candidate of candidates) {
|
|
43379
|
+
const stopResult = await stopOwnedProcessesForPrefixes({
|
|
43380
|
+
prefixes: [candidate],
|
|
43381
|
+
excludePids: options.excludePids,
|
|
43382
|
+
markers: options.markers,
|
|
43383
|
+
waitMs: options.waitMs ?? 15e3,
|
|
43384
|
+
log
|
|
43385
|
+
});
|
|
43386
|
+
if (stopResult.survivors.length > 0) {
|
|
43387
|
+
log?.(`Skipping cleanup of ${candidate}: ${stopResult.survivors.length} owned process(es) could not be stopped`);
|
|
43388
|
+
continue;
|
|
43389
|
+
}
|
|
43390
|
+
removeInactivePrefix(candidate, log);
|
|
43391
|
+
}
|
|
43392
|
+
}
|
|
43393
|
+
function removeInactivePrefix(target, log) {
|
|
43394
|
+
try {
|
|
43395
|
+
const escaped = quotePowerShellLiteral(target);
|
|
43396
|
+
const script = `if (Test-Path -LiteralPath ${escaped}) { Remove-Item -LiteralPath ${escaped} -Recurse -Force }`;
|
|
43397
|
+
const encoded = Buffer.from(script, "utf16le").toString("base64");
|
|
43398
|
+
const result = (0, import_child_process6.spawnSync)("powershell.exe", [
|
|
43399
|
+
"-NoLogo",
|
|
43400
|
+
"-NoProfile",
|
|
43401
|
+
"-NonInteractive",
|
|
43402
|
+
"-ExecutionPolicy",
|
|
43403
|
+
"Bypass",
|
|
43404
|
+
"-EncodedCommand",
|
|
43405
|
+
encoded
|
|
43406
|
+
], { timeout: 5e3, windowsHide: true, stdio: "ignore" });
|
|
43407
|
+
if (result.error || result.status !== 0) {
|
|
43408
|
+
log?.(`Failed to remove inactive prefix ${target}: ${result.error?.message || `exit ${result.status}`}`);
|
|
43409
|
+
}
|
|
43410
|
+
} catch (error) {
|
|
43411
|
+
log?.(`Failed to remove inactive prefix ${target}: ${error?.message || String(error)}`);
|
|
43412
|
+
}
|
|
43065
43413
|
}
|
|
43066
43414
|
|
|
43067
43415
|
// src/commands/upgrade-helper.ts
|
|
@@ -43190,7 +43538,7 @@ function getNpmExecOptions(platform10 = process.platform) {
|
|
|
43190
43538
|
}
|
|
43191
43539
|
function execNpmCommandSync(args, options = {}, surface) {
|
|
43192
43540
|
const execOptions = surface?.execOptions || getNpmExecOptions();
|
|
43193
|
-
return (0,
|
|
43541
|
+
return (0, import_child_process7.execFileSync)(
|
|
43194
43542
|
surface?.npmExecutable || "npm",
|
|
43195
43543
|
[...surface?.npmArgsPrefix || [], ...args],
|
|
43196
43544
|
{
|
|
@@ -43200,74 +43548,10 @@ function execNpmCommandSync(args, options = {}, surface) {
|
|
|
43200
43548
|
}
|
|
43201
43549
|
);
|
|
43202
43550
|
}
|
|
43203
|
-
function killPid(pid) {
|
|
43204
|
-
try {
|
|
43205
|
-
if (process.platform === "win32") {
|
|
43206
|
-
(0, import_child_process6.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
|
|
43207
|
-
} else {
|
|
43208
|
-
process.kill(pid, "SIGTERM");
|
|
43209
|
-
}
|
|
43210
|
-
return true;
|
|
43211
|
-
} catch {
|
|
43212
|
-
return false;
|
|
43213
|
-
}
|
|
43214
|
-
}
|
|
43215
|
-
function getWindowsProcessCommandLine(pid) {
|
|
43216
|
-
const pidFilter = `ProcessId=${pid}`;
|
|
43217
|
-
try {
|
|
43218
|
-
const psOut = (0, import_child_process6.execFileSync)("powershell.exe", [
|
|
43219
|
-
"-NoProfile",
|
|
43220
|
-
"-NonInteractive",
|
|
43221
|
-
"-ExecutionPolicy",
|
|
43222
|
-
"Bypass",
|
|
43223
|
-
"-Command",
|
|
43224
|
-
`(Get-CimInstance Win32_Process -Filter "${pidFilter}").CommandLine`
|
|
43225
|
-
], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"], windowsHide: true }).trim();
|
|
43226
|
-
if (psOut) return psOut;
|
|
43227
|
-
} catch {
|
|
43228
|
-
}
|
|
43229
|
-
try {
|
|
43230
|
-
const wmicOut = (0, import_child_process6.execFileSync)("wmic", [
|
|
43231
|
-
"process",
|
|
43232
|
-
"where",
|
|
43233
|
-
pidFilter,
|
|
43234
|
-
"get",
|
|
43235
|
-
"CommandLine"
|
|
43236
|
-
], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"], windowsHide: true }).trim();
|
|
43237
|
-
if (wmicOut) return wmicOut;
|
|
43238
|
-
} catch {
|
|
43239
|
-
}
|
|
43240
|
-
return null;
|
|
43241
|
-
}
|
|
43242
|
-
function getProcessCommandLine(pid) {
|
|
43243
|
-
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
43244
|
-
if (process.platform === "win32") return getWindowsProcessCommandLine(pid);
|
|
43245
|
-
try {
|
|
43246
|
-
const text = (0, import_child_process6.execFileSync)("ps", ["-o", "command=", "-p", String(pid)], {
|
|
43247
|
-
encoding: "utf8",
|
|
43248
|
-
timeout: 3e3,
|
|
43249
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
43250
|
-
}).trim();
|
|
43251
|
-
return text || null;
|
|
43252
|
-
} catch {
|
|
43253
|
-
return null;
|
|
43254
|
-
}
|
|
43255
|
-
}
|
|
43256
43551
|
function isManagedSessionHostPid(pid) {
|
|
43257
43552
|
const commandLine = getProcessCommandLine(pid);
|
|
43258
43553
|
return !!commandLine && /session-host-daemon/i.test(commandLine);
|
|
43259
43554
|
}
|
|
43260
|
-
async function waitForPidExit(pid, timeoutMs) {
|
|
43261
|
-
const start = Date.now();
|
|
43262
|
-
while (Date.now() - start < timeoutMs) {
|
|
43263
|
-
try {
|
|
43264
|
-
process.kill(pid, 0);
|
|
43265
|
-
await new Promise((resolve27) => setTimeout(resolve27, 250));
|
|
43266
|
-
} catch {
|
|
43267
|
-
return;
|
|
43268
|
-
}
|
|
43269
|
-
}
|
|
43270
|
-
}
|
|
43271
43555
|
async function stopSessionHostProcesses(appName) {
|
|
43272
43556
|
const pidFile = path21.join(os13.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
43273
43557
|
let killedPid = null;
|
|
@@ -43275,7 +43559,7 @@ async function stopSessionHostProcesses(appName) {
|
|
|
43275
43559
|
if (fs15.existsSync(pidFile)) {
|
|
43276
43560
|
const pid = Number.parseInt(fs15.readFileSync(pidFile, "utf8").trim(), 10);
|
|
43277
43561
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
43278
|
-
if (
|
|
43562
|
+
if (killProcess(pid)) killedPid = pid;
|
|
43279
43563
|
}
|
|
43280
43564
|
}
|
|
43281
43565
|
} catch {
|
|
@@ -43311,7 +43595,7 @@ function listForeignNativeAddonHolders(packageRoot) {
|
|
|
43311
43595
|
].join("\n");
|
|
43312
43596
|
let out = "";
|
|
43313
43597
|
try {
|
|
43314
|
-
out = String((0,
|
|
43598
|
+
out = String((0, import_child_process7.execFileSync)("powershell.exe", [
|
|
43315
43599
|
"-NoProfile",
|
|
43316
43600
|
"-NonInteractive",
|
|
43317
43601
|
"-ExecutionPolicy",
|
|
@@ -43343,7 +43627,7 @@ async function stopForeignNativeAddonHolders(packageRoot, options = {}) {
|
|
|
43343
43627
|
appendUpgradeLog(
|
|
43344
43628
|
`Foreign native-addon holder found: pid ${holder.pid}${holder.commandLine ? ` \u2014 ${holder.commandLine}` : ""}`
|
|
43345
43629
|
);
|
|
43346
|
-
const killed =
|
|
43630
|
+
const killed = killProcess(holder.pid);
|
|
43347
43631
|
if (killed) {
|
|
43348
43632
|
await waitForPidExit(holder.pid, 15e3);
|
|
43349
43633
|
appendUpgradeLog(`Terminated foreign native-addon holder pid ${holder.pid}`);
|
|
@@ -43435,7 +43719,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
43435
43719
|
}
|
|
43436
43720
|
function spawnDetachedDaemonUpgradeHelper(payload) {
|
|
43437
43721
|
const env = { ...process.env, [UPGRADE_HELPER_ENV]: JSON.stringify(payload) };
|
|
43438
|
-
const child = (0,
|
|
43722
|
+
const child = (0, import_child_process8.spawn)(process.execPath, process.argv.slice(1), {
|
|
43439
43723
|
detached: true,
|
|
43440
43724
|
stdio: "ignore",
|
|
43441
43725
|
windowsHide: true,
|
|
@@ -43476,11 +43760,25 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
43476
43760
|
throw new Error(`portable Node.js 22 npm CLI is missing: ${npmCliPath}`);
|
|
43477
43761
|
}
|
|
43478
43762
|
appendUpgradeLog(`Installer-managed pointer layout detected; active prefix will remain untouched: ${windowsInstallerLayout.activePrefix}`);
|
|
43763
|
+
const upgradePids = [process.pid, payload.parentPid].filter((n) => Number.isFinite(n) && n > 0);
|
|
43764
|
+
const preStop = await stopOwnedProcessesForPrefixes({
|
|
43765
|
+
prefixes: [windowsInstallerLayout.activePrefix, windowsInstallerLayout.stablePrefix],
|
|
43766
|
+
excludePids: upgradePids,
|
|
43767
|
+
markers: Array.from(ADHDEV_OWNED_MARKERS),
|
|
43768
|
+
waitMs: 15e3,
|
|
43769
|
+
log: appendUpgradeLog
|
|
43770
|
+
});
|
|
43771
|
+
if (preStop.survivors.length > 0) {
|
|
43772
|
+
throw new Error(
|
|
43773
|
+
`Cannot upgrade: owned processes still running under current prefix: ${preStop.survivors.map((s2) => s2.pid).join(", ")}`
|
|
43774
|
+
);
|
|
43775
|
+
}
|
|
43479
43776
|
await performWindowsAtomicUpgrade({
|
|
43480
43777
|
layout: windowsInstallerLayout,
|
|
43481
43778
|
packageName: payload.packageName,
|
|
43482
43779
|
targetVersion: payload.targetVersion,
|
|
43483
43780
|
portableNode,
|
|
43781
|
+
excludePids: upgradePids,
|
|
43484
43782
|
hooks: createDefaultWindowsAtomicHooks({
|
|
43485
43783
|
packageName: payload.packageName,
|
|
43486
43784
|
targetVersion: payload.targetVersion,
|
|
@@ -43506,7 +43804,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
43506
43804
|
let installOutput = "";
|
|
43507
43805
|
for (let attempt = 1; attempt <= maxInstallAttempts; attempt++) {
|
|
43508
43806
|
try {
|
|
43509
|
-
installOutput = String((0,
|
|
43807
|
+
installOutput = String((0, import_child_process7.execFileSync)(
|
|
43510
43808
|
installCommand.command,
|
|
43511
43809
|
installCommand.args,
|
|
43512
43810
|
{
|
|
@@ -43559,7 +43857,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
43559
43857
|
const env = { ...process.env };
|
|
43560
43858
|
delete env[UPGRADE_HELPER_ENV];
|
|
43561
43859
|
appendUpgradeLog(`Restarting daemon with args: ${restartArgv.join(" ")}`);
|
|
43562
|
-
const child = (0,
|
|
43860
|
+
const child = (0, import_child_process8.spawn)(process.execPath, restartArgv, {
|
|
43563
43861
|
detached: true,
|
|
43564
43862
|
stdio: "ignore",
|
|
43565
43863
|
windowsHide: true,
|
|
@@ -44141,7 +44439,7 @@ var os22 = __toESM(require("os"));
|
|
|
44141
44439
|
var path30 = __toESM(require("path"));
|
|
44142
44440
|
var crypto6 = __toESM(require("crypto"));
|
|
44143
44441
|
var import_fs16 = require("fs");
|
|
44144
|
-
var
|
|
44442
|
+
var import_child_process10 = require("child_process");
|
|
44145
44443
|
var import_chalk = __toESM(require("chalk"));
|
|
44146
44444
|
init_provider_cli_adapter();
|
|
44147
44445
|
init_cli_detector();
|
|
@@ -51241,7 +51539,7 @@ ${buttons.join("\n")}`;
|
|
|
51241
51539
|
// src/providers/acp-provider-instance.ts
|
|
51242
51540
|
var path29 = __toESM(require("path"));
|
|
51243
51541
|
var import_stream = require("stream");
|
|
51244
|
-
var
|
|
51542
|
+
var import_child_process9 = require("child_process");
|
|
51245
51543
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
51246
51544
|
init_contracts2();
|
|
51247
51545
|
init_provider_input_support();
|
|
@@ -51765,7 +52063,7 @@ var AcpProviderInstance = class {
|
|
|
51765
52063
|
this.errorMessage = null;
|
|
51766
52064
|
this.errorReason = null;
|
|
51767
52065
|
this.stderrBuffer = [];
|
|
51768
|
-
this.process = (0,
|
|
52066
|
+
this.process = (0, import_child_process9.spawn)(command, args, {
|
|
51769
52067
|
cwd: this.workingDir,
|
|
51770
52068
|
env,
|
|
51771
52069
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -52515,7 +52813,7 @@ function commandExists(command) {
|
|
|
52515
52813
|
return (0, import_fs16.existsSync)(expandExecutable(trimmed));
|
|
52516
52814
|
}
|
|
52517
52815
|
try {
|
|
52518
|
-
(0,
|
|
52816
|
+
(0, import_child_process10.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
52519
52817
|
stdio: "ignore",
|
|
52520
52818
|
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
52521
52819
|
});
|
|
@@ -53995,7 +54293,7 @@ var cliAgentHandlers = {
|
|
|
53995
54293
|
};
|
|
53996
54294
|
|
|
53997
54295
|
// src/launch.ts
|
|
53998
|
-
var
|
|
54296
|
+
var import_child_process11 = require("child_process");
|
|
53999
54297
|
var net = __toESM(require("net"));
|
|
54000
54298
|
var os27 = __toESM(require("os"));
|
|
54001
54299
|
var path38 = __toESM(require("path"));
|
|
@@ -57917,7 +58215,7 @@ function findMacAppProcessPids(psOutput, appPaths) {
|
|
|
57917
58215
|
// src/launch.ts
|
|
57918
58216
|
async function execQuiet(command, options = {}) {
|
|
57919
58217
|
return new Promise((resolve27) => {
|
|
57920
|
-
(0,
|
|
58218
|
+
(0, import_child_process11.exec)(command, options, (error, stdout) => {
|
|
57921
58219
|
if (error) return resolve27("");
|
|
57922
58220
|
resolve27(stdout.toString());
|
|
57923
58221
|
});
|
|
@@ -58317,10 +58615,10 @@ async function launchMacOS(ide, port, workspace, newWindow) {
|
|
|
58317
58615
|
const canUseAppLauncher = !!appName;
|
|
58318
58616
|
const useAppLauncher = preferredMethod === "app" ? canUseAppLauncher : preferredMethod === "cli" ? false : !canUseCli && canUseAppLauncher;
|
|
58319
58617
|
if (!useAppLauncher && ide.cliCommand) {
|
|
58320
|
-
(0,
|
|
58618
|
+
(0, import_child_process11.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore", windowsHide: true }).unref();
|
|
58321
58619
|
} else if (appName) {
|
|
58322
58620
|
const openArgs = ["-a", appName, "--args", ...args];
|
|
58323
|
-
(0,
|
|
58621
|
+
(0, import_child_process11.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
|
|
58324
58622
|
} else {
|
|
58325
58623
|
throw new Error(`No app identifier or CLI for ${ide.displayName}`);
|
|
58326
58624
|
}
|
|
@@ -58346,7 +58644,7 @@ async function launchLinux(ide, port, workspace, newWindow) {
|
|
|
58346
58644
|
const args = ["--remote-debugging-port=" + port];
|
|
58347
58645
|
if (newWindow) args.push("--new-window");
|
|
58348
58646
|
if (workspace) args.push(workspace);
|
|
58349
|
-
(0,
|
|
58647
|
+
(0, import_child_process11.spawn)(cli, args, { detached: true, stdio: "ignore", windowsHide: true }).unref();
|
|
58350
58648
|
}
|
|
58351
58649
|
function getAvailableIdeIds() {
|
|
58352
58650
|
return getProviderLoader().getAvailableIdeTypes();
|
|
@@ -58426,15 +58724,15 @@ var ideHandlers = {
|
|
|
58426
58724
|
stop_ide: async (ctx, args) => {
|
|
58427
58725
|
const ideType = args?.ideType;
|
|
58428
58726
|
if (!ideType) throw new Error("ideType required");
|
|
58429
|
-
const
|
|
58430
|
-
await ctx.stopIde(ideType,
|
|
58727
|
+
const killProcess2 = args?.killProcess !== false;
|
|
58728
|
+
await ctx.stopIde(ideType, killProcess2);
|
|
58431
58729
|
try {
|
|
58432
58730
|
const results = await detectIDEs(ctx.deps.providerLoader);
|
|
58433
58731
|
ctx.deps.detectedIdes.value = results;
|
|
58434
58732
|
ctx.deps.providerLoader.setIdeDetectionResults(results, true);
|
|
58435
58733
|
} catch {
|
|
58436
58734
|
}
|
|
58437
|
-
return { success: true, ideType, stopped: true, processKilled:
|
|
58735
|
+
return { success: true, ideType, stopped: true, processKilled: killProcess2 };
|
|
58438
58736
|
},
|
|
58439
58737
|
// ─── IDE restart ───
|
|
58440
58738
|
restart_ide: async (ctx, args) => {
|
|
@@ -61715,18 +62013,18 @@ function resolveRefineryAutoPublishSubmoduleMainCommits(mesh, workspace) {
|
|
|
61715
62013
|
return { enabled: false };
|
|
61716
62014
|
}
|
|
61717
62015
|
async function computeGitPatchId(cwd, fromRef, toRef, excludePaths = []) {
|
|
61718
|
-
const { execFileSync:
|
|
62016
|
+
const { execFileSync: execFileSync12 } = await import("child_process");
|
|
61719
62017
|
const diffArgs = ["diff", "--patch", "--full-index", fromRef, toRef];
|
|
61720
62018
|
if (excludePaths.length > 0) {
|
|
61721
62019
|
diffArgs.push("--", ".", ...excludePaths.map((path46) => `:(exclude)${path46}`));
|
|
61722
62020
|
}
|
|
61723
|
-
const diff =
|
|
62021
|
+
const diff = execFileSync12(GIT2, diffArgs, {
|
|
61724
62022
|
cwd,
|
|
61725
62023
|
encoding: "utf8",
|
|
61726
62024
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
61727
62025
|
});
|
|
61728
62026
|
if (!diff.trim()) return "";
|
|
61729
|
-
const patchId =
|
|
62027
|
+
const patchId = execFileSync12(GIT2, ["patch-id", "--stable"], {
|
|
61730
62028
|
cwd,
|
|
61731
62029
|
input: diff,
|
|
61732
62030
|
encoding: "utf8",
|
|
@@ -61737,8 +62035,8 @@ async function computeGitPatchId(cwd, fromRef, toRef, excludePaths = []) {
|
|
|
61737
62035
|
async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead) {
|
|
61738
62036
|
const startedAt = Date.now();
|
|
61739
62037
|
try {
|
|
61740
|
-
const { execFileSync:
|
|
61741
|
-
const git = (args) =>
|
|
62038
|
+
const { execFileSync: execFileSync12 } = await import("child_process");
|
|
62039
|
+
const git = (args) => execFileSync12(GIT2, args, {
|
|
61742
62040
|
cwd: repoRoot,
|
|
61743
62041
|
encoding: "utf8",
|
|
61744
62042
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -61973,8 +62271,8 @@ function execGitOk(cwd, args) {
|
|
|
61973
62271
|
async function checkWorktreeChangesPatchEquivalentInRef(repoRoot, ref, worktreeHead) {
|
|
61974
62272
|
const startedAt = Date.now();
|
|
61975
62273
|
try {
|
|
61976
|
-
const { execFileSync:
|
|
61977
|
-
const git = (gitArgs) =>
|
|
62274
|
+
const { execFileSync: execFileSync12 } = await import("child_process");
|
|
62275
|
+
const git = (gitArgs) => execFileSync12(GIT2, gitArgs, {
|
|
61978
62276
|
cwd: repoRoot,
|
|
61979
62277
|
encoding: "utf8",
|
|
61980
62278
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -62037,8 +62335,8 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
62037
62335
|
async function runMeshRefineEffectiveDiffGate(repoRoot, baseHead, branchHead) {
|
|
62038
62336
|
const startedAt = Date.now();
|
|
62039
62337
|
try {
|
|
62040
|
-
const { execFileSync:
|
|
62041
|
-
const git = (args, opts) =>
|
|
62338
|
+
const { execFileSync: execFileSync12 } = await import("child_process");
|
|
62339
|
+
const git = (args, opts) => execFileSync12(GIT2, args, {
|
|
62042
62340
|
cwd: opts?.cwd || repoRoot,
|
|
62043
62341
|
encoding: "utf8",
|
|
62044
62342
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -66147,7 +66445,7 @@ var DaemonCommandRouter = class {
|
|
|
66147
66445
|
/**
|
|
66148
66446
|
* IDE stop: CDP disconnect + InstanceManager cleanup + optionally kill OS process
|
|
66149
66447
|
*/
|
|
66150
|
-
async stopIde(ideType,
|
|
66448
|
+
async stopIde(ideType, killProcess2 = false) {
|
|
66151
66449
|
const cdpKeysToRemove = [];
|
|
66152
66450
|
for (const key2 of this.deps.cdpManagers.keys()) {
|
|
66153
66451
|
if (key2 === ideType || key2.startsWith(`${ideType}_`)) {
|
|
@@ -66185,7 +66483,7 @@ var DaemonCommandRouter = class {
|
|
|
66185
66483
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
66186
66484
|
}
|
|
66187
66485
|
}
|
|
66188
|
-
if (
|
|
66486
|
+
if (killProcess2) {
|
|
66189
66487
|
const running = await isIdeRunning(ideType);
|
|
66190
66488
|
if (running) {
|
|
66191
66489
|
LOG.info("StopIDE", `Killing IDE process: ${ideType}`);
|
|
@@ -66200,7 +66498,7 @@ var DaemonCommandRouter = class {
|
|
|
66200
66498
|
}
|
|
66201
66499
|
}
|
|
66202
66500
|
this.deps.onStatusChange?.();
|
|
66203
|
-
LOG.info("StopIDE", `IDE stopped: ${ideType} (processKill=${
|
|
66501
|
+
LOG.info("StopIDE", `IDE stopped: ${ideType} (processKill=${killProcess2})`);
|
|
66204
66502
|
}
|
|
66205
66503
|
};
|
|
66206
66504
|
|
|
@@ -67910,7 +68208,7 @@ var fs38 = __toESM(require("fs"));
|
|
|
67910
68208
|
var path40 = __toESM(require("path"));
|
|
67911
68209
|
var os29 = __toESM(require("os"));
|
|
67912
68210
|
var import_os5 = require("os");
|
|
67913
|
-
var
|
|
68211
|
+
var import_child_process12 = require("child_process");
|
|
67914
68212
|
var ARCHIVE_PATH = path40.join(os29.homedir(), ".adhdev", "version-history.json");
|
|
67915
68213
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
67916
68214
|
var VersionArchive = class {
|
|
@@ -67966,7 +68264,7 @@ var VersionArchive = class {
|
|
|
67966
68264
|
};
|
|
67967
68265
|
async function runCommand(cmd, timeout = 1e4) {
|
|
67968
68266
|
return new Promise((resolve27) => {
|
|
67969
|
-
(0,
|
|
68267
|
+
(0, import_child_process12.exec)(cmd, {
|
|
67970
68268
|
encoding: "utf-8",
|
|
67971
68269
|
timeout
|
|
67972
68270
|
}, (error, stdout) => {
|
|
@@ -73135,8 +73433,10 @@ var SessionHostRuntimeTransport = class {
|
|
|
73135
73433
|
return;
|
|
73136
73434
|
}
|
|
73137
73435
|
if (event.type === "session_exit") {
|
|
73436
|
+
const exitCode = typeof event.exitCode === "number" ? event.exitCode : null;
|
|
73437
|
+
const signal = typeof event.signal === "number" ? event.signal : null;
|
|
73138
73438
|
for (const callback of this.exitCallbacks) {
|
|
73139
|
-
callback({ exitCode
|
|
73439
|
+
callback({ exitCode, signal });
|
|
73140
73440
|
}
|
|
73141
73441
|
void this.closeClient(false);
|
|
73142
73442
|
}
|
|
@@ -73523,11 +73823,12 @@ async function listHostedCliRuntimes(endpoint) {
|
|
|
73523
73823
|
}
|
|
73524
73824
|
|
|
73525
73825
|
// src/session-host/managed-host.ts
|
|
73526
|
-
var
|
|
73826
|
+
var import_child_process13 = require("child_process");
|
|
73527
73827
|
var fs43 = __toESM(require("fs"));
|
|
73528
73828
|
var os31 = __toESM(require("os"));
|
|
73529
73829
|
var path45 = __toESM(require("path"));
|
|
73530
73830
|
var import_session_host_core13 = require("@adhdev/session-host-core");
|
|
73831
|
+
init_logger();
|
|
73531
73832
|
init_runtime_defaults();
|
|
73532
73833
|
function createManagedSessionHost(options) {
|
|
73533
73834
|
const appName = options.appName;
|
|
@@ -73551,6 +73852,14 @@ function createManagedSessionHost(options) {
|
|
|
73551
73852
|
}
|
|
73552
73853
|
return require.resolve("@adhdev/session-host-daemon");
|
|
73553
73854
|
}
|
|
73855
|
+
function pathsEquivalent(left, right) {
|
|
73856
|
+
return path45.resolve(left).toLowerCase() === path45.resolve(right).toLowerCase();
|
|
73857
|
+
}
|
|
73858
|
+
function getRunningSessionHostScriptPath(pid) {
|
|
73859
|
+
const commandLine = getProcessCommandLine(pid);
|
|
73860
|
+
if (!commandLine || !/session-host-daemon/i.test(commandLine)) return null;
|
|
73861
|
+
return parseNodeScriptPath(commandLine);
|
|
73862
|
+
}
|
|
73554
73863
|
function getPidFile() {
|
|
73555
73864
|
return path45.join(os31.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
73556
73865
|
}
|
|
@@ -73564,12 +73873,12 @@ function createManagedSessionHost(options) {
|
|
|
73564
73873
|
return null;
|
|
73565
73874
|
}
|
|
73566
73875
|
}
|
|
73567
|
-
function
|
|
73876
|
+
function killPid(pid) {
|
|
73568
73877
|
try {
|
|
73569
73878
|
if (process.platform === "win32") {
|
|
73570
73879
|
const spawnOpts = { stdio: "ignore" };
|
|
73571
73880
|
if (options.killWindowsHide) spawnOpts.windowsHide = true;
|
|
73572
|
-
(0,
|
|
73881
|
+
(0, import_child_process13.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], spawnOpts);
|
|
73573
73882
|
} else {
|
|
73574
73883
|
process.kill(pid, "SIGTERM");
|
|
73575
73884
|
}
|
|
@@ -73588,7 +73897,7 @@ function createManagedSessionHost(options) {
|
|
|
73588
73897
|
logFd = fs43.openSync(path45.join(logDir, "session-host.log"), "a");
|
|
73589
73898
|
stdio = ["ignore", logFd, logFd];
|
|
73590
73899
|
}
|
|
73591
|
-
const child = (0,
|
|
73900
|
+
const child = (0, import_child_process13.spawn)(process.execPath, [entry], {
|
|
73592
73901
|
detached: true,
|
|
73593
73902
|
stdio,
|
|
73594
73903
|
windowsHide: true,
|
|
@@ -73609,7 +73918,7 @@ function createManagedSessionHost(options) {
|
|
|
73609
73918
|
if (fs43.existsSync(pidFile)) {
|
|
73610
73919
|
const pid = Number.parseInt(fs43.readFileSync(pidFile, "utf8").trim(), 10);
|
|
73611
73920
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedPid(pid)) {
|
|
73612
|
-
stopped =
|
|
73921
|
+
stopped = killPid(pid) || stopped;
|
|
73613
73922
|
}
|
|
73614
73923
|
}
|
|
73615
73924
|
} catch {
|
|
@@ -73626,6 +73935,20 @@ function createManagedSessionHost(options) {
|
|
|
73626
73935
|
}
|
|
73627
73936
|
async function ensureReady() {
|
|
73628
73937
|
options.beforeEnsureReady?.();
|
|
73938
|
+
if (process.platform === "win32") {
|
|
73939
|
+
const existingPid = getPid();
|
|
73940
|
+
if (existingPid !== null) {
|
|
73941
|
+
const runningPath = getRunningSessionHostScriptPath(existingPid);
|
|
73942
|
+
const currentEntry = resolveEntry();
|
|
73943
|
+
if (runningPath && !pathsEquivalent(runningPath, currentEntry)) {
|
|
73944
|
+
LOG.warn(
|
|
73945
|
+
"SessionHost",
|
|
73946
|
+
`Detected stale host pid ${existingPid} running from ${runningPath}; restarting from ${currentEntry}`
|
|
73947
|
+
);
|
|
73948
|
+
stopManagedSessionHostProcess();
|
|
73949
|
+
}
|
|
73950
|
+
}
|
|
73951
|
+
}
|
|
73629
73952
|
try {
|
|
73630
73953
|
return await ensureSessionHostReady({
|
|
73631
73954
|
appName,
|
|
@@ -73654,7 +73977,7 @@ function createManagedSessionHost(options) {
|
|
|
73654
73977
|
getPid,
|
|
73655
73978
|
buildEnv,
|
|
73656
73979
|
resolveEntry,
|
|
73657
|
-
killPid
|
|
73980
|
+
killPid,
|
|
73658
73981
|
spawnHost,
|
|
73659
73982
|
stopManagedSessionHostProcess,
|
|
73660
73983
|
ensureReady,
|
|
@@ -73676,7 +73999,7 @@ function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
|
73676
73999
|
}
|
|
73677
74000
|
|
|
73678
74001
|
// src/installer.ts
|
|
73679
|
-
var
|
|
74002
|
+
var import_child_process14 = require("child_process");
|
|
73680
74003
|
var import_util3 = require("util");
|
|
73681
74004
|
var EXTENSION_CATALOG = [
|
|
73682
74005
|
// AI Agent extensions
|
|
@@ -73764,7 +74087,7 @@ var EXTENSION_CATALOG = [
|
|
|
73764
74087
|
apiKeyName: "OpenAI/Anthropic API key"
|
|
73765
74088
|
}
|
|
73766
74089
|
];
|
|
73767
|
-
var execAsync4 = (0, import_util3.promisify)(
|
|
74090
|
+
var execAsync4 = (0, import_util3.promisify)(import_child_process14.exec);
|
|
73768
74091
|
async function isExtensionInstalled(ide, marketplaceId) {
|
|
73769
74092
|
if (!ide.cliCommand) return false;
|
|
73770
74093
|
try {
|
|
@@ -73808,7 +74131,7 @@ async function installExtension(ide, extension) {
|
|
|
73808
74131
|
fs44.writeFileSync(vsixPath, buffer);
|
|
73809
74132
|
return new Promise((resolve27) => {
|
|
73810
74133
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
73811
|
-
(0,
|
|
74134
|
+
(0, import_child_process14.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
73812
74135
|
resolve27({
|
|
73813
74136
|
extensionId: extension.id,
|
|
73814
74137
|
marketplaceId: extension.marketplaceId,
|
|
@@ -73824,7 +74147,7 @@ async function installExtension(ide, extension) {
|
|
|
73824
74147
|
}
|
|
73825
74148
|
return new Promise((resolve27) => {
|
|
73826
74149
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
73827
|
-
(0,
|
|
74150
|
+
(0, import_child_process14.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
73828
74151
|
if (error) {
|
|
73829
74152
|
resolve27({
|
|
73830
74153
|
extensionId: extension.id,
|
|
@@ -73861,7 +74184,7 @@ function launchIDE(ide, workspacePath) {
|
|
|
73861
74184
|
if (!ide.cliCommand) return false;
|
|
73862
74185
|
try {
|
|
73863
74186
|
const args = workspacePath ? `"${workspacePath}"` : "";
|
|
73864
|
-
(0,
|
|
74187
|
+
(0, import_child_process14.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
|
|
73865
74188
|
return true;
|
|
73866
74189
|
} catch {
|
|
73867
74190
|
return false;
|