@adhdev/daemon-core 1.0.18-rc.19 → 1.0.18-rc.2
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 +0 -77
- package/dist/cli-adapters/provider-cli-shared.d.ts +0 -33
- package/dist/cli-adapters/pty-transport.d.ts +1 -2
- package/dist/commands/cli-manager.d.ts +0 -9
- package/dist/commands/upgrade-helper.d.ts +0 -1
- package/dist/commands/windows-atomic-upgrade.d.ts +1 -17
- package/dist/config/mesh-json-config.d.ts +0 -62
- package/dist/index.d.ts +2 -4
- package/dist/index.js +4143 -6578
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4138 -6570
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/coordinator-prompt.d.ts +0 -76
- package/dist/mesh/mesh-active-work.d.ts +1 -1
- package/dist/mesh/mesh-ledger.d.ts +1 -28
- package/dist/mesh/mesh-node-identity.d.ts +0 -23
- package/dist/mesh/mesh-refine-gates.d.ts +0 -89
- package/dist/mesh/mesh-remote-event-pull.d.ts +0 -3
- package/dist/mesh/mesh-runtime-store.d.ts +0 -11
- package/dist/mesh/mesh-work-queue.d.ts +1 -24
- package/dist/providers/chat-message-normalization.d.ts +0 -22
- package/dist/providers/cli-provider-instance-types.d.ts +0 -4
- package/dist/providers/cli-provider-instance.d.ts +0 -78
- package/dist/providers/contracts.d.ts +0 -17
- package/dist/providers/provider-schema.d.ts +0 -1
- package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +0 -14
- package/dist/providers/types/interactive-prompt.d.ts +0 -18
- package/dist/repo-mesh-types.d.ts +6 -38
- package/dist/shared-types.d.ts +2 -4
- package/package.json +3 -3
- package/src/boot/daemon-lifecycle.ts +0 -10
- package/src/cli-adapters/cli-state-engine.ts +3 -220
- package/src/cli-adapters/provider-cli-adapter.ts +11 -41
- package/src/cli-adapters/provider-cli-shared.ts +0 -41
- package/src/cli-adapters/pty-transport.d.ts +1 -2
- package/src/cli-adapters/pty-transport.ts +1 -1
- package/src/cli-adapters/session-host-transport.ts +3 -8
- package/src/commands/cli-manager.ts +8 -72
- package/src/commands/high-family/mesh-coordinator-launch.ts +2 -17
- package/src/commands/high-family/mesh-events.ts +2 -13
- package/src/commands/med-family/mesh-crud.ts +0 -155
- package/src/commands/med-family/mesh-queue.ts +1 -74
- package/src/commands/router-refine.ts +4 -71
- package/src/commands/router.ts +0 -8
- package/src/commands/upgrade-helper.ts +82 -106
- package/src/commands/windows-atomic-upgrade.ts +35 -281
- package/src/config/mesh-json-config.ts +0 -111
- package/src/index.ts +1 -21
- package/src/mesh/coordinator-prompt.ts +11 -258
- package/src/mesh/mesh-active-work.ts +1 -11
- package/src/mesh/mesh-completion-synthesis.ts +1 -12
- package/src/mesh/mesh-event-classify.ts +0 -19
- package/src/mesh/mesh-event-forwarding.ts +6 -64
- package/src/mesh/mesh-events-utils.ts +0 -42
- package/src/mesh/mesh-ledger.ts +0 -77
- package/src/mesh/mesh-node-identity.ts +0 -49
- package/src/mesh/mesh-queue-assignment.ts +11 -210
- package/src/mesh/mesh-reconcile-loop.ts +3 -306
- package/src/mesh/mesh-refine-gates.ts +0 -300
- package/src/mesh/mesh-remote-event-pull.ts +47 -68
- package/src/mesh/mesh-runtime-store.ts +0 -21
- package/src/mesh/mesh-work-queue.ts +2 -85
- package/src/providers/chat-message-normalization.ts +0 -53
- package/src/providers/cli-provider-instance-types.ts +0 -53
- package/src/providers/cli-provider-instance.ts +15 -497
- package/src/providers/contracts.ts +1 -25
- package/src/providers/provider-schema.ts +0 -83
- package/src/providers/sdk/v1/builders/cli/detect-status.ts +0 -23
- package/src/providers/sdk/v1/builders/cli/parse-approval.ts +0 -20
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +0 -44
- package/src/providers/types/interactive-prompt.ts +0 -77
- package/src/repo-mesh-types.ts +12 -112
- package/src/session-host/managed-host.ts +0 -34
- package/src/shared-types.ts +1 -9
- package/src/status/reporter.ts +0 -1
- package/src/status/snapshot.ts +0 -2
- package/dist/commands/process-lifecycle.d.ts +0 -43
- package/dist/mesh/mesh-disk-retention.d.ts +0 -105
- package/dist/providers/auto-approve-modes.d.ts +0 -14
- package/src/commands/process-lifecycle.ts +0 -248
- package/src/mesh/mesh-disk-retention.ts +0 -370
- package/src/providers/auto-approve-modes.ts +0 -97
|
@@ -4,18 +4,11 @@ import * as fs from 'fs';
|
|
|
4
4
|
import * as os from 'os';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
import {
|
|
7
|
-
ADHDEV_OWNED_MARKERS,
|
|
8
7
|
createDefaultWindowsAtomicHooks,
|
|
9
8
|
findPortableNode22,
|
|
10
9
|
performWindowsAtomicUpgrade,
|
|
11
10
|
resolveWindowsInstallerLayout,
|
|
12
11
|
} from './windows-atomic-upgrade.js';
|
|
13
|
-
import {
|
|
14
|
-
getProcessCommandLine,
|
|
15
|
-
killProcess,
|
|
16
|
-
stopOwnedProcessesForPrefixes,
|
|
17
|
-
waitForPidExit,
|
|
18
|
-
} from './process-lifecycle.js';
|
|
19
12
|
|
|
20
13
|
const UPGRADE_HELPER_ENV = 'ADHDEV_DAEMON_UPGRADE_HELPER';
|
|
21
14
|
|
|
@@ -144,68 +137,19 @@ function resolveInstallPrefixFromPackageRoot(packageRoot: string, packageName: s
|
|
|
144
137
|
return maybeLibDir;
|
|
145
138
|
}
|
|
146
139
|
|
|
147
|
-
// True when `prefix` is the bin dir of a portable Node 22 the installer manages
|
|
148
|
-
// under ~/.adhdev/tools/node22/<node-vX>/. A `npm i -g adhdev` run while that
|
|
149
|
-
// portable node is the active `node` installs adhdev into node's own default
|
|
150
|
-
// global prefix (= that dir) — a "legacy node22-prefix" install that lives at
|
|
151
|
-
// the FRONT of PATH (Enable-NodePath prepends node22) and shadows the canonical
|
|
152
|
-
// dispatcher shims in ~/.adhdev/npm-global. Because self-upgrade reuses the
|
|
153
|
-
// running prefix, that install then re-installs into the same node22 dir forever
|
|
154
|
-
// and never converts to the dispatcher. Detecting it lets us force convergence.
|
|
155
|
-
function isPortableNode22Prefix(prefix: string | null, homeDir: string): boolean {
|
|
156
|
-
if (!prefix) return false;
|
|
157
|
-
const portableRoot = path.join(homeDir, '.adhdev', 'tools', 'node22');
|
|
158
|
-
const normalizedPrefix = path.resolve(prefix).replace(/[\\/]+$/, '').toLowerCase();
|
|
159
|
-
const normalizedRoot = path.resolve(portableRoot).replace(/[\\/]+$/, '').toLowerCase();
|
|
160
|
-
return normalizedPrefix === normalizedRoot || normalizedPrefix.startsWith(`${normalizedRoot}${path.sep.toLowerCase()}`);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Redirect a legacy node22-prefix install to the canonical dispatcher install
|
|
164
|
-
// root so resolveWindowsInstallerLayout accepts it and the atomic-upgrade
|
|
165
|
-
// publishes the ~/.adhdev/npm-global pointer + shims. Prefer the version the
|
|
166
|
-
// dispatcher pointer already names (so we sit on the real active dispatcher
|
|
167
|
-
// prefix); otherwise synthesize a stable migration sentinel under npm-installs.
|
|
168
|
-
// resolveWindowsInstallerLayout only requires a `npm-installs/version-*` path —
|
|
169
|
-
// performWindowsAtomicUpgrade stages a fresh version- prefix of its own and uses
|
|
170
|
-
// this only as the "old prefix" to stop/clean, so a non-existent path is a no-op.
|
|
171
|
-
function canonicalDispatcherInstallPrefix(homeDir: string): string {
|
|
172
|
-
const installRoot = path.join(homeDir, '.adhdev', 'npm-installs');
|
|
173
|
-
const pointerPath = path.join(homeDir, '.adhdev', 'npm-global', '.adhdev-current');
|
|
174
|
-
try {
|
|
175
|
-
const activeVersion = fs.readFileSync(pointerPath, 'utf8').trim();
|
|
176
|
-
if (activeVersion.startsWith('version-')) return path.join(installRoot, activeVersion);
|
|
177
|
-
} catch {
|
|
178
|
-
// No dispatcher pointer yet (first migration off the legacy layout).
|
|
179
|
-
}
|
|
180
|
-
return path.join(installRoot, 'version-legacy-migrate');
|
|
181
|
-
}
|
|
182
|
-
|
|
183
140
|
export function resolveCurrentGlobalInstallSurface(options: {
|
|
184
141
|
packageName: string;
|
|
185
142
|
currentCliPath?: string;
|
|
186
143
|
nodeExecutable?: string;
|
|
187
144
|
platform?: NodeJS.Platform;
|
|
188
|
-
homeDir?: string;
|
|
189
145
|
}): CurrentGlobalInstallSurface {
|
|
190
146
|
const packageRoot = findCurrentPackageRoot(options.currentCliPath || process.argv[1], options.packageName);
|
|
191
147
|
const npmInvocation = resolveSiblingNpmInvocation(options.nodeExecutable || process.execPath, options.platform);
|
|
192
|
-
const platform = options.platform || process.platform;
|
|
193
|
-
const homeDir = options.homeDir || os.homedir();
|
|
194
|
-
let installPrefix = packageRoot ? resolveInstallPrefixFromPackageRoot(packageRoot, options.packageName) : null;
|
|
195
|
-
// FIX C: on Windows, never let a self-upgrade perpetuate the legacy
|
|
196
|
-
// node22-prefix install. If the running adhdev lives under ~/.adhdev/tools/
|
|
197
|
-
// node22, force the install onto the canonical dispatcher prefix so the update
|
|
198
|
-
// converges to the ~/.adhdev/npm-global pointer + shims. Scoped to win32 AND a
|
|
199
|
-
// tools/node22 prefix so npm-linked dev / standalone / real dispatcher installs
|
|
200
|
-
// are untouched.
|
|
201
|
-
if (platform === 'win32' && isPortableNode22Prefix(installPrefix, homeDir)) {
|
|
202
|
-
installPrefix = canonicalDispatcherInstallPrefix(homeDir);
|
|
203
|
-
}
|
|
204
148
|
return {
|
|
205
149
|
npmExecutable: npmInvocation.executable,
|
|
206
150
|
npmArgsPrefix: npmInvocation.argsPrefix,
|
|
207
151
|
packageRoot,
|
|
208
|
-
installPrefix,
|
|
152
|
+
installPrefix: packageRoot ? resolveInstallPrefixFromPackageRoot(packageRoot, options.packageName) : null,
|
|
209
153
|
execOptions: npmInvocation.execOptions,
|
|
210
154
|
};
|
|
211
155
|
}
|
|
@@ -291,11 +235,77 @@ export function execNpmCommandSync(
|
|
|
291
235
|
);
|
|
292
236
|
}
|
|
293
237
|
|
|
238
|
+
function killPid(pid: number): boolean {
|
|
239
|
+
try {
|
|
240
|
+
if (process.platform === 'win32') {
|
|
241
|
+
execFileSync('taskkill', ['/PID', String(pid), '/T', '/F'], { stdio: 'ignore', windowsHide: true });
|
|
242
|
+
} else {
|
|
243
|
+
process.kill(pid, 'SIGTERM');
|
|
244
|
+
}
|
|
245
|
+
return true;
|
|
246
|
+
} catch {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function getWindowsProcessCommandLine(pid: number): string | null {
|
|
252
|
+
const pidFilter = `ProcessId=${pid}`;
|
|
253
|
+
try {
|
|
254
|
+
const psOut = execFileSync('powershell.exe', [
|
|
255
|
+
'-NoProfile',
|
|
256
|
+
'-NonInteractive',
|
|
257
|
+
'-ExecutionPolicy', 'Bypass',
|
|
258
|
+
'-Command',
|
|
259
|
+
`(Get-CimInstance Win32_Process -Filter "${pidFilter}").CommandLine`,
|
|
260
|
+
], { encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore'], windowsHide: true }).trim();
|
|
261
|
+
if (psOut) return psOut;
|
|
262
|
+
} catch {
|
|
263
|
+
// fall through to wmic fallback
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
const wmicOut = execFileSync('wmic', [
|
|
268
|
+
'process', 'where', pidFilter, 'get', 'CommandLine',
|
|
269
|
+
], { encoding: 'utf8', timeout: 3000, stdio: ['ignore', 'pipe', 'ignore'], windowsHide: true }).trim();
|
|
270
|
+
if (wmicOut) return wmicOut;
|
|
271
|
+
} catch {
|
|
272
|
+
// noop
|
|
273
|
+
}
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function getProcessCommandLine(pid: number): string | null {
|
|
278
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
279
|
+
if (process.platform === 'win32') return getWindowsProcessCommandLine(pid);
|
|
280
|
+
try {
|
|
281
|
+
const text = execFileSync('ps', ['-o', 'command=', '-p', String(pid)], {
|
|
282
|
+
encoding: 'utf8',
|
|
283
|
+
timeout: 3000,
|
|
284
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
285
|
+
}).trim();
|
|
286
|
+
return text || null;
|
|
287
|
+
} catch {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
294
292
|
function isManagedSessionHostPid(pid: number): boolean {
|
|
295
293
|
const commandLine = getProcessCommandLine(pid);
|
|
296
294
|
return !!commandLine && /session-host-daemon/i.test(commandLine);
|
|
297
295
|
}
|
|
298
296
|
|
|
297
|
+
async function waitForPidExit(pid: number, timeoutMs: number): Promise<void> {
|
|
298
|
+
const start = Date.now();
|
|
299
|
+
while (Date.now() - start < timeoutMs) {
|
|
300
|
+
try {
|
|
301
|
+
process.kill(pid, 0);
|
|
302
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
303
|
+
} catch {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
299
309
|
export async function stopSessionHostProcesses(appName: string): Promise<void> {
|
|
300
310
|
const pidFile = path.join(os.homedir(), '.adhdev', `${appName}-session-host.pid`);
|
|
301
311
|
let killedPid: number | null = null;
|
|
@@ -303,7 +313,7 @@ export async function stopSessionHostProcesses(appName: string): Promise<void> {
|
|
|
303
313
|
if (fs.existsSync(pidFile)) {
|
|
304
314
|
const pid = Number.parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
|
|
305
315
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
306
|
-
if (
|
|
316
|
+
if (killPid(pid)) killedPid = pid;
|
|
307
317
|
}
|
|
308
318
|
}
|
|
309
319
|
} catch {
|
|
@@ -420,7 +430,7 @@ export async function stopForeignNativeAddonHolders(
|
|
|
420
430
|
appendUpgradeLog(
|
|
421
431
|
`Foreign native-addon holder found: pid ${holder.pid}${holder.commandLine ? ` — ${holder.commandLine}` : ''}`,
|
|
422
432
|
);
|
|
423
|
-
const killed =
|
|
433
|
+
const killed = killPid(holder.pid);
|
|
424
434
|
if (killed) {
|
|
425
435
|
await waitForPidExit(holder.pid, 15000);
|
|
426
436
|
appendUpgradeLog(`Terminated foreign native-addon holder pid ${holder.pid}`);
|
|
@@ -590,55 +600,21 @@ async function runDaemonUpgradeHelper(payload: DaemonUpgradeHelperPayload): Prom
|
|
|
590
600
|
throw new Error(`portable Node.js 22 npm CLI is missing: ${npmCliPath}`);
|
|
591
601
|
}
|
|
592
602
|
appendUpgradeLog(`Installer-managed pointer layout detected; active prefix will remain untouched: ${windowsInstallerLayout.activePrefix}`);
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
const preStop = await stopOwnedProcessesForPrefixes({
|
|
600
|
-
prefixes: [windowsInstallerLayout.activePrefix, windowsInstallerLayout.stablePrefix],
|
|
601
|
-
excludePids: upgradePids,
|
|
602
|
-
markers: Array.from(ADHDEV_OWNED_MARKERS),
|
|
603
|
-
waitMs: 15_000,
|
|
604
|
-
log: appendUpgradeLog,
|
|
605
|
-
});
|
|
606
|
-
if (preStop.survivors.length > 0) {
|
|
607
|
-
throw new Error(
|
|
608
|
-
`Cannot upgrade: owned processes still running under current prefix: ${preStop.survivors.map((s) => s.pid).join(', ')}`
|
|
609
|
-
);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
try {
|
|
613
|
-
await performWindowsAtomicUpgrade({
|
|
614
|
-
layout: windowsInstallerLayout,
|
|
603
|
+
await performWindowsAtomicUpgrade({
|
|
604
|
+
layout: windowsInstallerLayout,
|
|
605
|
+
packageName: payload.packageName,
|
|
606
|
+
targetVersion: payload.targetVersion,
|
|
607
|
+
portableNode,
|
|
608
|
+
hooks: createDefaultWindowsAtomicHooks({
|
|
615
609
|
packageName: payload.packageName,
|
|
616
610
|
targetVersion: payload.targetVersion,
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
cwd: payload.cwd || process.cwd(),
|
|
625
|
-
env: Object.fromEntries(Object.entries(process.env).filter(([key]) => key !== UPGRADE_HELPER_ENV)),
|
|
626
|
-
log: appendUpgradeLog,
|
|
627
|
-
}),
|
|
628
|
-
});
|
|
629
|
-
} catch (error: any) {
|
|
630
|
-
// performWindowsAtomicUpgrade already rolled the pointer/shims back to the
|
|
631
|
-
// prior version before rethrowing. Without a durable notice that rollback
|
|
632
|
-
// was silent — the daemon simply kept running the old version (the rc.6
|
|
633
|
-
// stuck-upgrade defect). Leave an actionable last-error file naming the
|
|
634
|
-
// target that failed its health/version gate.
|
|
635
|
-
emitUpgradeFailureNotice([
|
|
636
|
-
`adhdev ${payload.packageName}@${payload.targetVersion} upgrade failed and was rolled back: ${error?.message || String(error)}`,
|
|
637
|
-
`Previous version preserved (active prefix: ${windowsInstallerLayout.activePrefix}).`,
|
|
638
|
-
'See daemon-upgrade.log for the full install/health trace. The next daemon start will retry.',
|
|
639
|
-
]);
|
|
640
|
-
throw error;
|
|
641
|
-
}
|
|
611
|
+
npmCliPath,
|
|
612
|
+
restartArgv,
|
|
613
|
+
cwd: payload.cwd || process.cwd(),
|
|
614
|
+
env: Object.fromEntries(Object.entries(process.env).filter(([key]) => key !== UPGRADE_HELPER_ENV)),
|
|
615
|
+
log: appendUpgradeLog,
|
|
616
|
+
}),
|
|
617
|
+
});
|
|
642
618
|
try { fs.unlinkSync(getUpgradeFailureNoticePath()); } catch { /* no previous failure notice */ }
|
|
643
619
|
appendUpgradeLog('Installer-managed Windows atomic upgrade completed');
|
|
644
620
|
return;
|