@quolu/lattice 0.79.2 → 0.79.4
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/LICENSE +1 -1
- package/README.ja.md +1 -1
- package/README.md +9 -3
- package/bin/lattice-bridge.mjs +31 -24
- package/bin/lattice-dashboard-supervisor.mjs +18 -0
- package/bin/lattice-dashboard.mjs +32 -10
- package/docs/bridge-setup.md +29 -0
- package/package.json +2 -2
- package/sensor/dist/bin/lattice-sensor.js +6 -26
- package/sensor/dist/bin/node-version-check.d.ts +10 -1
- package/sensor/dist/bin/node-version-check.d.ts.map +1 -1
- package/sensor/dist/bin/node-version-check.js +43 -1
- package/sensor/dist/bin/node-version-check.js.map +1 -1
- package/sensor/dist/extraction/parse-pool.d.ts +8 -1
- package/sensor/dist/extraction/parse-pool.d.ts.map +1 -1
- package/sensor/dist/extraction/parse-pool.js +83 -12
- package/sensor/dist/extraction/parse-pool.js.map +1 -1
- package/sensor/dist/extraction/parse-worker.js +2 -0
- package/sensor/dist/extraction/parse-worker.js.map +1 -1
- package/sensor/dist/mcp/daemon-paths.d.ts +4 -0
- package/sensor/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon-paths.js +12 -0
- package/sensor/dist/mcp/daemon-paths.js.map +1 -1
- package/sensor/dist/mcp/index.d.ts.map +1 -1
- package/sensor/dist/mcp/index.js +52 -28
- package/sensor/dist/mcp/index.js.map +1 -1
- package/sensor/package.json +1 -1
- package/src/bridge-cli.mjs +6 -2
- package/src/bridge-config.mjs +8 -0
- package/src/bridge-daemon.mjs +30 -2
- package/src/dashboard-delivery.mjs +14 -2
- package/src/dashboard-lifecycle-ipc.mjs +5 -0
- package/src/dashboard-lifecycle-journal.mjs +235 -0
- package/src/dashboard-process-control.mjs +74 -0
- package/src/dashboard-supervisor.mjs +180 -0
- package/src/dashboard-windows-process-control.ps1 +40 -0
- package/src/factory-diagnostics.mjs +22 -9
- package/src/node-version-guard.mjs +3 -42
- package/src/todo-dashboard-registry.mjs +24 -3
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
1
|
import { randomBytes } from 'node:crypto';
|
|
3
2
|
import { homedir } from 'node:os';
|
|
4
3
|
import {
|
|
@@ -9,6 +8,10 @@ import path from 'node:path';
|
|
|
9
8
|
import packageJson from '../package.json' with { type: 'json' };
|
|
10
9
|
import { isAuditPendingPhaseStatus } from './todo-audit-pending.mjs';
|
|
11
10
|
import { observeStartIdentityEpochMs } from './runtime-os-observation.mjs';
|
|
11
|
+
import { spawnSupervisedDashboard } from './dashboard-supervisor.mjs';
|
|
12
|
+
import { reconcileLifecycleRuns, readDashboardLifecycleStatus,
|
|
13
|
+
recordDashboardEnsureDecision } from './dashboard-lifecycle-journal.mjs';
|
|
14
|
+
import { observeDashboardProcess } from './dashboard-process-control.mjs';
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* The version of the code in THIS process. A daemon loads its modules once at
|
|
@@ -49,6 +52,10 @@ function paths(env) {
|
|
|
49
52
|
};
|
|
50
53
|
}
|
|
51
54
|
|
|
55
|
+
export async function readTodoDashboardLifecycleStatus({ env = process.env } = {}) {
|
|
56
|
+
return readDashboardLifecycleStatus(runtimeDir(env));
|
|
57
|
+
}
|
|
58
|
+
|
|
52
59
|
function validEntry(entry) {
|
|
53
60
|
return entry !== null && typeof entry === 'object' && !Array.isArray(entry)
|
|
54
61
|
&& Object.keys(entry).sort().join(',') === 'display_name,last_seen_at,project_id,repo_root,session_id'
|
|
@@ -523,7 +530,7 @@ export async function forgetTodoDashboardDaemonRecord({ env = process.env } = {}
|
|
|
523
530
|
await rm(daemonRecordRef(paths(env), process.pid), { force: true });
|
|
524
531
|
}
|
|
525
532
|
|
|
526
|
-
export async function ensureTodoDashboardDaemon({ env = process.env, spawnDaemon =
|
|
533
|
+
export async function ensureTodoDashboardDaemon({ env = process.env, spawnDaemon = spawnSupervisedDashboard,
|
|
527
534
|
signalProcess = process.kill, isProcessAlive = processIsAlive, startupTimeoutMs = 120_000,
|
|
528
535
|
legacyStopTimeoutMs = 3_000, replacementIsProcessAlive = processIsAlive,
|
|
529
536
|
attestationTimeoutMs = 2_000, strayStopTimeoutMs = 3_000,
|
|
@@ -535,15 +542,18 @@ export async function ensureTodoDashboardDaemon({ env = process.env, spawnDaemon
|
|
|
535
542
|
const reap = (keepPid) => reapStrayDaemons(refs, keepPid,
|
|
536
543
|
{ signalProcess, isProcessAlive, timeoutMs: strayStopTimeoutMs });
|
|
537
544
|
return withLock(refs.startupLock, async () => {
|
|
545
|
+
await reconcileLifecycleRuns(refs.root, observeDashboardProcess);
|
|
538
546
|
const existing = await readJson(refs.descriptor, null);
|
|
539
547
|
const existingAttestation = await daemonAttestation(existing, { timeoutMs: attestationTimeoutMs });
|
|
540
548
|
if (existingAttestation === 'current') {
|
|
549
|
+
await recordDashboardEnsureDecision(refs.root, 'reuse_current', existing.pid);
|
|
541
550
|
await reap(existing.pid);
|
|
542
551
|
return existing;
|
|
543
552
|
}
|
|
544
553
|
if (validDaemonDescriptor(existing) && existingAttestation === null
|
|
545
554
|
&& await isProcessAlive(existing.pid)
|
|
546
555
|
&& !await descriptorPidWasReused(existing, { observeProcessStartEpochMs })) {
|
|
556
|
+
await recordDashboardEnsureDecision(refs.root, 'alive_unresponsive', existing.pid);
|
|
547
557
|
throw dashboardError('DASHBOARD_DAEMON_UNRESPONSIVE', 'dashboard daemon is alive but temporarily unresponsive');
|
|
548
558
|
}
|
|
549
559
|
let legacy = existingAttestation === 'legacy' ? existing : null;
|
|
@@ -558,6 +568,7 @@ export async function ensureTodoDashboardDaemon({ env = process.env, spawnDaemon
|
|
|
558
568
|
// 引き取った相手は生きて応答しているので、descriptorの不変条件を満たす。
|
|
559
569
|
await atomicJson(refs.descriptor, adopted.record);
|
|
560
570
|
if (adopted.attestation === 'current') {
|
|
571
|
+
await recordDashboardEnsureDecision(refs.root, 'adopt_current', adopted.record.pid);
|
|
561
572
|
await reap(adopted.record.pid);
|
|
562
573
|
return adopted.record;
|
|
563
574
|
}
|
|
@@ -569,9 +580,14 @@ export async function ensureTodoDashboardDaemon({ env = process.env, spawnDaemon
|
|
|
569
580
|
&& Number(portText) <= 65_535 ? Number(portText) : DEFAULT_PORT;
|
|
570
581
|
const port = legacy === null ? configuredPort : 0;
|
|
571
582
|
if (legacy === null) await rm(refs.descriptor, { force: true });
|
|
572
|
-
const
|
|
583
|
+
const startupDecision = legacy !== null ? 'replace_legacy'
|
|
584
|
+
: validDaemonDescriptor(existing) && await isProcessAlive(existing.pid) ? 'pid_reused'
|
|
585
|
+
: 'start_missing';
|
|
586
|
+
await recordDashboardEnsureDecision(refs.root, startupDecision, legacy?.pid ?? null);
|
|
587
|
+
const child = await spawnDaemon(process.execPath, [path.resolve(import.meta.dirname, '../bin/lattice-dashboard.mjs')], {
|
|
573
588
|
detached: true,
|
|
574
589
|
stdio: 'ignore',
|
|
590
|
+
version: TODO_DASHBOARD_CODE_VERSION,
|
|
575
591
|
env: { ...env, LATTICE_DASHBOARD_RUNTIME_DIR: refs.root, LATTICE_DASHBOARD_PORT: String(port) },
|
|
576
592
|
});
|
|
577
593
|
child.unref();
|
|
@@ -584,6 +600,10 @@ export async function ensureTodoDashboardDaemon({ env = process.env, spawnDaemon
|
|
|
584
600
|
const deadline = Date.now() + startupTimeoutMs;
|
|
585
601
|
while (Date.now() < deadline) {
|
|
586
602
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
603
|
+
if (child.observationError) {
|
|
604
|
+
child.kill?.('SIGTERM');
|
|
605
|
+
throw child.observationError;
|
|
606
|
+
}
|
|
587
607
|
const descriptor = typeof child.pid === 'number'
|
|
588
608
|
? await readJson(daemonRecordRef(refs, child.pid), null) : null;
|
|
589
609
|
const healthy = await daemonHealthy(descriptor);
|
|
@@ -601,6 +621,7 @@ export async function ensureTodoDashboardDaemon({ env = process.env, spawnDaemon
|
|
|
601
621
|
}
|
|
602
622
|
}
|
|
603
623
|
await atomicJson(refs.descriptor, descriptor);
|
|
624
|
+
await recordDashboardEnsureDecision(refs.root, startupDecision, descriptor.pid);
|
|
604
625
|
await reap(descriptor.pid);
|
|
605
626
|
return descriptor;
|
|
606
627
|
}
|