@blackbelt-technology/pi-agent-dashboard 0.4.6 → 0.5.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/AGENTS.md +339 -190
- package/README.md +50 -7
- package/docs/architecture.md +238 -23
- package/package.json +23 -13
- package/packages/extension/package.json +11 -3
- package/packages/extension/src/__tests__/ask-user-tool.test.ts +1 -1
- package/packages/extension/src/__tests__/build-provider-catalogue.test.ts +176 -0
- package/packages/extension/src/__tests__/command-handler.test.ts +68 -0
- package/packages/extension/src/__tests__/enrich-model-metadata.test.ts +1 -1
- package/packages/extension/src/__tests__/markdown-image-inliner.test.ts +355 -0
- package/packages/extension/src/__tests__/no-tui-multiselect-arm-regression.test.ts +1 -1
- package/packages/extension/src/__tests__/openspec-activity-detector.test.ts +68 -0
- package/packages/extension/src/__tests__/prompt-expander.test.ts +45 -0
- package/packages/extension/src/__tests__/provider-register-reload.test.ts +74 -0
- package/packages/extension/src/__tests__/retry-tracker.test.ts +147 -0
- package/packages/extension/src/__tests__/server-launcher.test.ts +24 -1
- package/packages/extension/src/__tests__/session-sync.test.ts +72 -0
- package/packages/extension/src/__tests__/usage-limit-orderer.test.ts +105 -0
- package/packages/extension/src/ask-user-tool.ts +1 -1
- package/packages/extension/src/bridge-context.ts +1 -1
- package/packages/extension/src/bridge.ts +169 -4
- package/packages/extension/src/command-handler.ts +65 -2
- package/packages/extension/src/flow-event-wiring.ts +1 -1
- package/packages/extension/src/markdown-image-inliner.ts +268 -0
- package/packages/extension/src/multiselect-list.ts +1 -1
- package/packages/extension/src/pi-env.d.ts +16 -9
- package/packages/extension/src/prompt-expander.ts +50 -2
- package/packages/extension/src/provider-register.ts +132 -8
- package/packages/extension/src/retry-tracker.ts +123 -0
- package/packages/extension/src/server-launcher.ts +18 -1
- package/packages/extension/src/session-sync.ts +15 -1
- package/packages/extension/src/usage-limit-orderer.ts +76 -0
- package/packages/server/package.json +6 -6
- package/packages/server/src/__tests__/auto-attach-slug-defense.test.ts +104 -0
- package/packages/server/src/__tests__/bootstrap-install-from-list.test.ts +263 -0
- package/packages/server/src/__tests__/browser-gateway-snapshot-on-connect.test.ts +143 -0
- package/packages/server/src/__tests__/build-auth-status.test.ts +190 -0
- package/packages/server/src/__tests__/changelog-fs.test.ts +171 -0
- package/packages/server/src/__tests__/changelog-parser.test.ts +220 -0
- package/packages/server/src/__tests__/changelog-remote.test.ts +193 -0
- package/packages/server/src/__tests__/cli-parse.test.ts +22 -4
- package/packages/server/src/__tests__/cold-boot-openspec-broadcast.test.ts +161 -0
- package/packages/server/src/__tests__/directory-service-refresh-force.test.ts +1 -1
- package/packages/server/src/__tests__/directory-service-specs-mtime.test.ts +1 -1
- package/packages/server/src/__tests__/directory-service-toctou.test.ts +1 -1
- package/packages/server/src/__tests__/directory-service.test.ts +1 -1
- package/packages/server/src/__tests__/doctor-route.test.ts +132 -0
- package/packages/server/src/__tests__/event-wiring-providers-list.test.ts +154 -0
- package/packages/server/src/__tests__/fixtures/pi-changelog-slice.md +180 -0
- package/packages/server/src/__tests__/fork-empty-session-preflight.test.ts +268 -0
- package/packages/server/src/__tests__/has-openspec-dir.test.ts +64 -0
- package/packages/server/src/__tests__/headless-pid-registry.test.ts +83 -0
- package/packages/server/src/__tests__/health-shape.test.ts +43 -0
- package/packages/server/src/__tests__/idle-timer-respects-terminals.test.ts +115 -0
- package/packages/server/src/__tests__/is-pi-process.test.ts +1 -1
- package/packages/server/src/__tests__/openspec-connect-snapshot.test.ts +92 -0
- package/packages/server/src/__tests__/package-manager-wrapper-resolve.test.ts +4 -4
- package/packages/server/src/__tests__/package-routes.test.ts +1 -1
- package/packages/server/src/__tests__/pending-fork-registry.test.ts +48 -24
- package/packages/server/src/__tests__/pi-changelog-integration.test.ts +165 -0
- package/packages/server/src/__tests__/pi-changelog-routes.test.ts +409 -0
- package/packages/server/src/__tests__/pi-core-checker.test.ts +155 -13
- package/packages/server/src/__tests__/pi-core-updater-managed-path.test.ts +236 -0
- package/packages/server/src/__tests__/pi-core-updater.test.ts +1 -1
- package/packages/server/src/__tests__/pi-dev-version-check.test.ts +184 -0
- package/packages/server/src/__tests__/pi-version-skew.test.ts +4 -4
- package/packages/server/src/__tests__/process-manager-codes.test.ts +80 -0
- package/packages/server/src/__tests__/process-manager-managed-path.test.ts +73 -0
- package/packages/server/src/__tests__/provider-auth-routes.test.ts +12 -4
- package/packages/server/src/__tests__/provider-auth-storage.test.ts +42 -11
- package/packages/server/src/__tests__/provider-catalogue-cache.test.ts +44 -0
- package/packages/server/src/__tests__/recommended-routes.test.ts +1 -1
- package/packages/server/src/__tests__/session-action-handler-spawn-error.test.ts +17 -2
- package/packages/server/src/__tests__/session-action-handler-spawn.test.ts +150 -0
- package/packages/server/src/__tests__/session-discovery-skill-firstmessage.test.ts +95 -0
- package/packages/server/src/__tests__/spawn-correlation-token-integration.test.ts +91 -0
- package/packages/server/src/__tests__/spawn-failure-log.test.ts +118 -0
- package/packages/server/src/__tests__/spawn-preflight.test.ts +91 -0
- package/packages/server/src/__tests__/spawn-register-watchdog.test.ts +250 -0
- package/packages/server/src/__tests__/spawn-token.test.ts +57 -0
- package/packages/server/src/__tests__/subscription-handler.test.ts +98 -6
- package/packages/server/src/__tests__/system-routes-reextract.test.ts +91 -0
- package/packages/server/src/__tests__/system-routes-spawn-failures.test.ts +84 -0
- package/packages/server/src/__tests__/terminal-manager.test.ts +45 -0
- package/packages/server/src/bootstrap-install-from-list.ts +232 -0
- package/packages/server/src/bootstrap-state.ts +18 -0
- package/packages/server/src/browser-gateway.ts +70 -24
- package/packages/server/src/browser-handlers/directory-handler.ts +4 -0
- package/packages/server/src/browser-handlers/handler-context.ts +9 -0
- package/packages/server/src/browser-handlers/session-action-handler.ts +159 -18
- package/packages/server/src/browser-handlers/subscription-handler.ts +50 -3
- package/packages/server/src/changelog-fs.ts +167 -0
- package/packages/server/src/changelog-parser.ts +321 -0
- package/packages/server/src/changelog-remote.ts +134 -0
- package/packages/server/src/cli.ts +23 -2
- package/packages/server/src/directory-service.ts +31 -0
- package/packages/server/src/event-wiring.ts +105 -5
- package/packages/server/src/headless-pid-registry.ts +54 -5
- package/packages/server/src/home-lock.d.ts +124 -0
- package/packages/server/src/home-lock.js +330 -0
- package/packages/server/src/home-lock.js.map +1 -0
- package/packages/server/src/idle-timer.ts +15 -1
- package/packages/server/src/pending-client-correlations.ts +73 -0
- package/packages/server/src/pending-fork-registry.ts +24 -12
- package/packages/server/src/pi-core-checker.ts +77 -17
- package/packages/server/src/pi-core-updater.ts +81 -15
- package/packages/server/src/pi-dev-version-check.ts +145 -0
- package/packages/server/src/pi-gateway.ts +10 -0
- package/packages/server/src/pi-version-skew.ts +12 -4
- package/packages/server/src/process-manager.ts +115 -21
- package/packages/server/src/provider-auth-handlers.ts +9 -0
- package/packages/server/src/provider-auth-storage.ts +83 -51
- package/packages/server/src/provider-catalogue-cache.ts +47 -0
- package/packages/server/src/routes/doctor-routes.ts +140 -0
- package/packages/server/src/routes/pi-changelog-routes.ts +194 -0
- package/packages/server/src/routes/pi-core-routes.ts +1 -1
- package/packages/server/src/routes/provider-auth-routes.ts +14 -1
- package/packages/server/src/routes/provider-routes.ts +4 -4
- package/packages/server/src/routes/system-routes.ts +38 -1
- package/packages/server/src/server.ts +85 -66
- package/packages/server/src/session-api.ts +54 -3
- package/packages/server/src/session-bootstrap.ts +27 -12
- package/packages/server/src/session-discovery.ts +11 -4
- package/packages/server/src/session-file-reader.ts +1 -1
- package/packages/server/src/session-scanner.ts +4 -2
- package/packages/server/src/spawn-failure-log.ts +130 -0
- package/packages/server/src/spawn-preflight.ts +82 -0
- package/packages/server/src/spawn-register-watchdog.ts +291 -0
- package/packages/server/src/spawn-token.ts +20 -0
- package/packages/server/src/terminal-manager.ts +12 -1
- package/packages/shared/package.json +1 -1
- package/packages/shared/src/__tests__/bootstrap/__snapshots__/cube.test.ts.snap +25 -17
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/a-electron.test.ts.snap +5 -4
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/b-npm-global.test.ts.snap +6 -5
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/c-dev-monorepo.test.ts.snap +1 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/e-stale-partial.test.ts.snap +5 -4
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/f-cwd-variants.test.ts.snap +2 -1
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/g-windows-specifics.test.ts.snap +6 -3
- package/packages/shared/src/__tests__/bootstrap/fixtures/dev-monorepo.ts +1 -1
- package/packages/shared/src/__tests__/bootstrap-install-resolve-npm.test.ts +72 -0
- package/packages/shared/src/__tests__/browser-protocol-types.test.ts +47 -1
- package/packages/shared/src/__tests__/changelog-types.test.ts +78 -0
- package/packages/shared/src/__tests__/config.test.ts +48 -0
- package/packages/shared/src/__tests__/dashboard-starter.test.ts +40 -0
- package/packages/shared/src/__tests__/detached-spawn.test.ts +24 -0
- package/packages/shared/src/__tests__/doctor-core.test.ts +134 -0
- package/packages/shared/src/__tests__/doctor-fault-tolerance.test.ts +218 -0
- package/packages/shared/src/__tests__/doctor-format.test.ts +121 -0
- package/packages/shared/src/__tests__/install-managed-node-bootstrap-order.test.ts +68 -0
- package/packages/shared/src/__tests__/install-managed-node.test.ts +192 -0
- package/packages/shared/src/__tests__/installable-list.test.ts +130 -0
- package/packages/shared/src/__tests__/managed-node-path.test.ts +122 -0
- package/packages/shared/src/__tests__/managed-runtime-strategy.test.ts +74 -0
- package/packages/shared/src/__tests__/no-installable-list-in-bridge.test.ts +52 -0
- package/packages/shared/src/__tests__/no-raw-openspec-status-in-skills.test.ts +6 -1
- package/packages/shared/src/__tests__/node-spawn-jiti-contract.test.ts +56 -20
- package/packages/shared/src/__tests__/resolve-jiti.test.ts +140 -9
- package/packages/shared/src/__tests__/skill-block-parser.test.ts +153 -0
- package/packages/shared/src/__tests__/tool-registry-definitions.test.ts +1 -1
- package/packages/shared/src/bootstrap-install.ts +197 -3
- package/packages/shared/src/browser-protocol.ts +155 -1
- package/packages/shared/src/changelog-types.ts +111 -0
- package/packages/shared/src/config.ts +15 -0
- package/packages/shared/src/dashboard-starter.ts +33 -0
- package/packages/shared/src/doctor-core.ts +821 -0
- package/packages/shared/src/index.ts +9 -0
- package/packages/shared/src/installable-list.ts +152 -0
- package/packages/shared/src/launch-source-flag.ts +14 -0
- package/packages/shared/src/launch-source-types.ts +18 -0
- package/packages/shared/src/openspec-activity-detector.ts +25 -7
- package/packages/shared/src/platform/detached-spawn.ts +13 -2
- package/packages/shared/src/platform/managed-node-path.ts +77 -0
- package/packages/shared/src/platform/node-spawn.ts +29 -21
- package/packages/shared/src/protocol.ts +54 -2
- package/packages/shared/src/resolve-jiti.ts +62 -9
- package/packages/shared/src/rest-api.ts +4 -0
- package/packages/shared/src/skill-block-parser.ts +115 -0
- package/packages/shared/src/tool-registry/__tests__/managed-runtime-strategy.test.ts +166 -0
- package/packages/shared/src/tool-registry/definitions.ts +33 -8
- package/packages/shared/src/tool-registry/strategies.ts +42 -0
- package/packages/shared/src/types.ts +64 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synchronous spawn preflight check.
|
|
3
|
+
*
|
|
4
|
+
* Runs before every `spawnPiSession` invocation to catch fast-fail conditions
|
|
5
|
+
* (bad cwd, missing binaries) without racing the spawn itself. All checks run
|
|
6
|
+
* regardless of earlier failures so the caller gets all reasons in one pass.
|
|
7
|
+
*
|
|
8
|
+
* The ToolResolver passed in MUST have `useLoginShell: false` — preflight
|
|
9
|
+
* must never spawn a login shell on the spawn-click hot path. If a resolver
|
|
10
|
+
* with `useLoginShell: true` is passed, the check still runs but a one-time
|
|
11
|
+
* warning is emitted.
|
|
12
|
+
*
|
|
13
|
+
* See change: spawn-failure-diagnostics.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, accessSync, statSync, constants } from "node:fs";
|
|
16
|
+
import { ToolResolver } from "@blackbelt-technology/pi-dashboard-shared/platform/binary-lookup.js";
|
|
17
|
+
|
|
18
|
+
export interface PreflightReason {
|
|
19
|
+
code: string;
|
|
20
|
+
message: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PreflightResult {
|
|
24
|
+
ok: boolean;
|
|
25
|
+
reasons: PreflightReason[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Run all preflight checks for `cwd` and return the accumulated reasons.
|
|
30
|
+
* `ok` is `true` iff `reasons.length === 0`.
|
|
31
|
+
*
|
|
32
|
+
* @param deps.resolver - Must be constructed with `useLoginShell: false`.
|
|
33
|
+
* If omitted, a login-shell-disabled resolver is created automatically.
|
|
34
|
+
* Passing a resolver with `useLoginShell: true` violates the preflight
|
|
35
|
+
* contract; the function still runs but may call into the login shell.
|
|
36
|
+
*/
|
|
37
|
+
export function preflightSpawn(
|
|
38
|
+
cwd: string,
|
|
39
|
+
deps?: { resolver?: ToolResolver },
|
|
40
|
+
): PreflightResult {
|
|
41
|
+
const resolver = deps?.resolver ?? new ToolResolver({ processExecPath: process.execPath, useLoginShell: false });
|
|
42
|
+
|
|
43
|
+
const reasons: PreflightReason[] = [];
|
|
44
|
+
|
|
45
|
+
// 1. cwd exists
|
|
46
|
+
const cwdExists = existsSync(cwd);
|
|
47
|
+
if (!cwdExists) {
|
|
48
|
+
reasons.push({ code: "DIR_MISSING", message: `Directory does not exist: ${cwd}` });
|
|
49
|
+
// No point checking isDirectory / writable if it doesn't exist.
|
|
50
|
+
} else {
|
|
51
|
+
// 2. cwd is a directory
|
|
52
|
+
try {
|
|
53
|
+
const stat = statSync(cwd);
|
|
54
|
+
if (!stat.isDirectory()) {
|
|
55
|
+
reasons.push({ code: "DIR_NOT_DIRECTORY", message: `Path is not a directory: ${cwd}` });
|
|
56
|
+
}
|
|
57
|
+
} catch (err: any) {
|
|
58
|
+
reasons.push({ code: "DIR_NOT_DIRECTORY", message: `Cannot stat path: ${err.message}` });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 3. cwd is writable
|
|
62
|
+
try {
|
|
63
|
+
accessSync(cwd, constants.W_OK);
|
|
64
|
+
} catch {
|
|
65
|
+
reasons.push({ code: "DIR_NOT_WRITABLE", message: `Directory is not writable: ${cwd}` });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 4. pi resolves
|
|
70
|
+
const piCmd = resolver.resolvePi();
|
|
71
|
+
if (piCmd === null) {
|
|
72
|
+
reasons.push({ code: "PI_NOT_FOUND", message: "pi binary not found via managed install or system PATH" });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 5. node resolves
|
|
76
|
+
const nodeCmd = resolver.resolveNode();
|
|
77
|
+
if (nodeCmd === null) {
|
|
78
|
+
reasons.push({ code: "NODE_NOT_FOUND", message: "node binary not found via managed install or system PATH" });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { ok: reasons.length === 0, reasons };
|
|
82
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn-register watchdog.
|
|
3
|
+
*
|
|
4
|
+
* Arms a per-spawn timer after every successful `spawnPiSession`. If the
|
|
5
|
+
* spawned pi session never sends `session_register` within the timeout
|
|
6
|
+
* window, emits `spawn_register_timeout` to the originating WebSocket.
|
|
7
|
+
*
|
|
8
|
+
* Two index maps handle the two spawn families:
|
|
9
|
+
* - `byPid` — headless spawns where the dashboard owns the PID.
|
|
10
|
+
* - `byCwd` — tmux/wt/wsl-tmux spawns where any `session_register` from
|
|
11
|
+
* that directory clears the watch.
|
|
12
|
+
*
|
|
13
|
+
* Late registrations (pi finally registers after the watchdog fired) are
|
|
14
|
+
* detected via `recentlyFired` (60 s TTL) and cause a `spawn_register_recovered`
|
|
15
|
+
* message to auto-clear the timeout banner.
|
|
16
|
+
*
|
|
17
|
+
* See change: spawn-failure-diagnostics.
|
|
18
|
+
*/
|
|
19
|
+
import WebSocket from "ws";
|
|
20
|
+
import { readFileSync } from "node:fs";
|
|
21
|
+
import type { SpawnMechanism } from "@blackbelt-technology/pi-dashboard-shared/platform/spawn-mechanism.js";
|
|
22
|
+
import type {
|
|
23
|
+
SpawnRegisterTimeoutMessage,
|
|
24
|
+
SpawnRegisterRecoveredMessage,
|
|
25
|
+
} from "@blackbelt-technology/pi-dashboard-shared/browser-protocol.js";
|
|
26
|
+
import { clampSpawnRegisterTimeoutMs, loadConfig } from "@blackbelt-technology/pi-dashboard-shared/config.js";
|
|
27
|
+
import { appendSpawnFailure } from "./spawn-failure-log.js";
|
|
28
|
+
|
|
29
|
+
export interface WatchdogArmOptions {
|
|
30
|
+
pid?: number;
|
|
31
|
+
cwd: string;
|
|
32
|
+
mechanism: SpawnMechanism;
|
|
33
|
+
logPath?: string;
|
|
34
|
+
ws: WebSocket;
|
|
35
|
+
/**
|
|
36
|
+
* Server-minted spawn correlation token. When provided, the entry is
|
|
37
|
+
* indexed in `byToken` for strong-identity clearing via `clearByToken`.
|
|
38
|
+
* See change: spawn-correlation-token.
|
|
39
|
+
*/
|
|
40
|
+
spawnToken?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface Entry {
|
|
44
|
+
timer: ReturnType<typeof setTimeout>;
|
|
45
|
+
cwd: string;
|
|
46
|
+
pid?: number;
|
|
47
|
+
mechanism: SpawnMechanism;
|
|
48
|
+
logPath?: string;
|
|
49
|
+
ws: WebSocket;
|
|
50
|
+
timeoutMs: number;
|
|
51
|
+
spawnToken?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface RecentlyFiredEntry {
|
|
55
|
+
firedAt: number;
|
|
56
|
+
pid?: number;
|
|
57
|
+
ws: WebSocket;
|
|
58
|
+
spawnToken?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const RECENTLY_FIRED_TTL_MS = 60_000;
|
|
62
|
+
|
|
63
|
+
export class SpawnRegisterWatchdog {
|
|
64
|
+
/** Default timeout used when arm() callers do not supply one. */
|
|
65
|
+
readonly timeoutMs: number;
|
|
66
|
+
private readonly byPid = new Map<number, Entry>();
|
|
67
|
+
private readonly byCwd = new Map<string, Entry>();
|
|
68
|
+
private readonly byToken = new Map<string, Entry>();
|
|
69
|
+
private readonly recentlyFired = new Map<string, RecentlyFiredEntry>();
|
|
70
|
+
|
|
71
|
+
constructor(timeoutMs: number) {
|
|
72
|
+
this.timeoutMs = clampSpawnRegisterTimeoutMs(timeoutMs);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
arm(opts: WatchdogArmOptions & { timeoutMs?: number }): void {
|
|
76
|
+
// Read-on-arm: caller passes the current config value so a Settings change
|
|
77
|
+
// takes effect on the next spawn without a server restart.
|
|
78
|
+
// See change: spawn-failure-diagnostics (fix W1).
|
|
79
|
+
const effectiveTimeout = clampSpawnRegisterTimeoutMs(opts.timeoutMs ?? this.timeoutMs);
|
|
80
|
+
const { pid, cwd, mechanism, logPath, ws, spawnToken } = opts;
|
|
81
|
+
const entry: Entry = {
|
|
82
|
+
timer: null as unknown as ReturnType<typeof setTimeout>,
|
|
83
|
+
cwd, pid, mechanism, logPath, ws,
|
|
84
|
+
timeoutMs: effectiveTimeout,
|
|
85
|
+
spawnToken,
|
|
86
|
+
};
|
|
87
|
+
entry.timer = setTimeout(() => this._fireEntry(entry), effectiveTimeout);
|
|
88
|
+
// Always index by cwd so a `session_register` clears the watchdog even
|
|
89
|
+
// when the bridge's reported pid differs from the spawner's pid (e.g.
|
|
90
|
+
// Unix headless wraps pi in `sh -c "tail -f /dev/null | pi …"`, so
|
|
91
|
+
// spawnResult.pid is the sh wrapper, not pi). Index by pid additionally
|
|
92
|
+
// for late-recovery lookup. Index by token (when provided) for
|
|
93
|
+
// strong-identity clearing. See change: spawn-correlation-token.
|
|
94
|
+
// Replace any prior entry for the same cwd/pid/token to avoid leaking timers.
|
|
95
|
+
const priorCwd = this.byCwd.get(cwd);
|
|
96
|
+
if (priorCwd) clearTimeout(priorCwd.timer);
|
|
97
|
+
this.byCwd.set(cwd, entry);
|
|
98
|
+
if (pid !== undefined) {
|
|
99
|
+
const priorPid = this.byPid.get(pid);
|
|
100
|
+
if (priorPid && priorPid !== priorCwd) clearTimeout(priorPid.timer);
|
|
101
|
+
this.byPid.set(pid, entry);
|
|
102
|
+
}
|
|
103
|
+
if (spawnToken) {
|
|
104
|
+
const priorTok = this.byToken.get(spawnToken);
|
|
105
|
+
if (priorTok && priorTok !== priorCwd && priorTok !== entry) clearTimeout(priorTok.timer);
|
|
106
|
+
this.byToken.set(spawnToken, entry);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Strong-identity clear: cancel watchdog for this exact spawn invocation.
|
|
112
|
+
* Tier 1 of the three-tier match in `event-wiring.ts`. Removes the entry
|
|
113
|
+
* from all three indices. See change: spawn-correlation-token.
|
|
114
|
+
*/
|
|
115
|
+
clearByToken(spawnToken: string): void {
|
|
116
|
+
const entry = this.byToken.get(spawnToken);
|
|
117
|
+
if (entry) {
|
|
118
|
+
clearTimeout(entry.timer);
|
|
119
|
+
this.byToken.delete(spawnToken);
|
|
120
|
+
const cwdEntry = this.byCwd.get(entry.cwd);
|
|
121
|
+
if (cwdEntry === entry) this.byCwd.delete(entry.cwd);
|
|
122
|
+
if (entry.pid !== undefined) {
|
|
123
|
+
const pidEntry = this.byPid.get(entry.pid);
|
|
124
|
+
if (pidEntry === entry) this.byPid.delete(entry.pid);
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// Check for late recovery: scan recentlyFired for matching token.
|
|
129
|
+
for (const [cwd, fired] of this.recentlyFired) {
|
|
130
|
+
if (fired.spawnToken === spawnToken) {
|
|
131
|
+
this._emitRecovery(cwd, fired);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
clearByPid(pid: number): void {
|
|
138
|
+
const entry = this.byPid.get(pid);
|
|
139
|
+
if (entry) {
|
|
140
|
+
clearTimeout(entry.timer);
|
|
141
|
+
this.byPid.delete(pid);
|
|
142
|
+
// Also clear cwd / token entries if they point at the same arm.
|
|
143
|
+
const cwdEntry = this.byCwd.get(entry.cwd);
|
|
144
|
+
if (cwdEntry === entry) this.byCwd.delete(entry.cwd);
|
|
145
|
+
if (entry.spawnToken) {
|
|
146
|
+
const tokEntry = this.byToken.get(entry.spawnToken);
|
|
147
|
+
if (tokEntry === entry) this.byToken.delete(entry.spawnToken);
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// Check for late recovery.
|
|
152
|
+
this._checkRecoveryByPid(pid);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
clearByCwd(cwd: string): void {
|
|
156
|
+
const entry = this.byCwd.get(cwd);
|
|
157
|
+
if (entry) {
|
|
158
|
+
clearTimeout(entry.timer);
|
|
159
|
+
this.byCwd.delete(cwd);
|
|
160
|
+
// Also clear pid / token entries if they point at the same arm.
|
|
161
|
+
if (entry.pid !== undefined) {
|
|
162
|
+
const pidEntry = this.byPid.get(entry.pid);
|
|
163
|
+
if (pidEntry === entry) this.byPid.delete(entry.pid);
|
|
164
|
+
}
|
|
165
|
+
if (entry.spawnToken) {
|
|
166
|
+
const tokEntry = this.byToken.get(entry.spawnToken);
|
|
167
|
+
if (tokEntry === entry) this.byToken.delete(entry.spawnToken);
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
// Check for late recovery.
|
|
172
|
+
this._checkRecoveryByCwd(cwd);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private _fireEntry(entry: Entry): void {
|
|
176
|
+
const { cwd, pid, logPath, ws, timeoutMs: entryTimeoutMs } = entry;
|
|
177
|
+
// Remove from active maps.
|
|
178
|
+
if (pid !== undefined) {
|
|
179
|
+
const pidEntry = this.byPid.get(pid);
|
|
180
|
+
if (pidEntry === entry) this.byPid.delete(pid);
|
|
181
|
+
}
|
|
182
|
+
const cwdEntry = this.byCwd.get(cwd);
|
|
183
|
+
if (cwdEntry === entry) this.byCwd.delete(cwd);
|
|
184
|
+
|
|
185
|
+
// Record in recentlyFired for late-recovery detection (also drop token entry).
|
|
186
|
+
if (entry.spawnToken) {
|
|
187
|
+
const tokEntry = this.byToken.get(entry.spawnToken);
|
|
188
|
+
if (tokEntry === entry) this.byToken.delete(entry.spawnToken);
|
|
189
|
+
}
|
|
190
|
+
this.recentlyFired.set(cwd, { firedAt: Date.now(), pid, ws, spawnToken: entry.spawnToken });
|
|
191
|
+
|
|
192
|
+
// Read stderr tail if logPath available.
|
|
193
|
+
let stderrTail: string | undefined;
|
|
194
|
+
if (logPath) {
|
|
195
|
+
stderrTail = readLogTail(logPath);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Persist the timeout to the rolling failure log. See change: spawn-failure-diagnostics.
|
|
199
|
+
appendSpawnFailure({
|
|
200
|
+
ts: new Date().toISOString(),
|
|
201
|
+
cwd,
|
|
202
|
+
strategy: entry.mechanism,
|
|
203
|
+
code: "REGISTER_TIMEOUT",
|
|
204
|
+
message: `Pi session spawned but never registered (timeout ${this.timeoutMs}ms)`,
|
|
205
|
+
...(pid !== undefined ? { pid } : {}),
|
|
206
|
+
...(stderrTail ? { stderrTail } : {}),
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
if (ws.readyState !== WebSocket.OPEN) return;
|
|
210
|
+
|
|
211
|
+
const msg: SpawnRegisterTimeoutMessage = {
|
|
212
|
+
type: "spawn_register_timeout",
|
|
213
|
+
cwd,
|
|
214
|
+
timeoutMs: entryTimeoutMs,
|
|
215
|
+
...(pid !== undefined ? { pid } : {}),
|
|
216
|
+
...(stderrTail ? { stderrTail } : {}),
|
|
217
|
+
};
|
|
218
|
+
ws.send(JSON.stringify(msg));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private _checkRecoveryByPid(pid: number): void {
|
|
222
|
+
// recentlyFired is keyed by cwd; scan to find matching pid.
|
|
223
|
+
for (const [cwd, fired] of this.recentlyFired) {
|
|
224
|
+
if (fired.pid === pid) {
|
|
225
|
+
this._emitRecovery(cwd, fired);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private _checkRecoveryByCwd(cwd: string): void {
|
|
232
|
+
const fired = this.recentlyFired.get(cwd);
|
|
233
|
+
if (!fired) return;
|
|
234
|
+
this._emitRecovery(cwd, fired);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private _emitRecovery(cwd: string, fired: RecentlyFiredEntry): void {
|
|
238
|
+
// TTL check.
|
|
239
|
+
if (Date.now() - fired.firedAt > RECENTLY_FIRED_TTL_MS) {
|
|
240
|
+
this.recentlyFired.delete(cwd);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
this.recentlyFired.delete(cwd);
|
|
245
|
+
|
|
246
|
+
if (fired.ws.readyState !== WebSocket.OPEN) return;
|
|
247
|
+
|
|
248
|
+
const msg: SpawnRegisterRecoveredMessage = {
|
|
249
|
+
type: "spawn_register_recovered",
|
|
250
|
+
cwd,
|
|
251
|
+
...(fired.pid !== undefined ? { pid: fired.pid } : {}),
|
|
252
|
+
};
|
|
253
|
+
fired.ws.send(JSON.stringify(msg));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ── Singleton ────────────────────────────────────────────────────────────────
|
|
258
|
+
|
|
259
|
+
let _instance: SpawnRegisterWatchdog | null = null;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Lazy singleton. On first call, reads `spawnRegisterTimeoutMs` from config.
|
|
263
|
+
* Tests can swap the instance via `_setSpawnRegisterWatchdogForTests`.
|
|
264
|
+
*/
|
|
265
|
+
export function getSpawnRegisterWatchdog(): SpawnRegisterWatchdog {
|
|
266
|
+
if (!_instance) {
|
|
267
|
+
const config = loadConfig();
|
|
268
|
+
_instance = new SpawnRegisterWatchdog(config.spawnRegisterTimeoutMs);
|
|
269
|
+
}
|
|
270
|
+
return _instance;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/** Swap the singleton for tests. Pass `null` to reset. */
|
|
274
|
+
export function _setSpawnRegisterWatchdogForTests(w: SpawnRegisterWatchdog | null): void {
|
|
275
|
+
_instance = w;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
279
|
+
|
|
280
|
+
function readLogTail(filePath: string, maxBytes = 4096): string | undefined {
|
|
281
|
+
try {
|
|
282
|
+
const buf = readFileSync(filePath);
|
|
283
|
+
if (!buf.length) return undefined;
|
|
284
|
+
const slice = buf.length <= maxBytes ? buf : buf.slice(buf.length - maxBytes);
|
|
285
|
+
let start = 0;
|
|
286
|
+
while (start < slice.length && (slice[start]! & 0xC0) === 0x80) start++;
|
|
287
|
+
return slice.slice(start).toString("utf-8");
|
|
288
|
+
} catch {
|
|
289
|
+
return undefined;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn correlation token: server-minted UUIDv4 per `spawnPiSession` call.
|
|
3
|
+
*
|
|
4
|
+
* Flow: `mintSpawnToken()` → injected into spawned process env as
|
|
5
|
+
* `PI_DASHBOARD_SPAWN_TOKEN` → bridge reads it → bridge echoes back in
|
|
6
|
+
* `session_register.spawnToken` → server links via `linkByToken`.
|
|
7
|
+
*
|
|
8
|
+
* In-memory only; no persistence. TTL aligned to spawn-register-watchdog.
|
|
9
|
+
*
|
|
10
|
+
* See change: spawn-correlation-token.
|
|
11
|
+
*/
|
|
12
|
+
import { randomUUID } from "node:crypto";
|
|
13
|
+
|
|
14
|
+
/** Mint a fresh UUIDv4 spawn correlation token. */
|
|
15
|
+
export function mintSpawnToken(): string {
|
|
16
|
+
return randomUUID();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Env-var name used for the correlation token in spawned pi processes. */
|
|
20
|
+
export const SPAWN_TOKEN_ENV_VAR = "PI_DASHBOARD_SPAWN_TOKEN";
|
|
@@ -185,7 +185,18 @@ export function createTerminalManager(options?: TerminalManagerOptions): Termina
|
|
|
185
185
|
try {
|
|
186
186
|
const msg: TerminalControlMessage = JSON.parse(str);
|
|
187
187
|
if (msg.type === "resize") {
|
|
188
|
-
|
|
188
|
+
// Defense in depth: reject degenerate resize messages.
|
|
189
|
+
// A PTY at <2 cols/rows is non-functional for every supported
|
|
190
|
+
// shell binding; no legitimate user intent maps there. xterm's
|
|
191
|
+
// FitAddon is supposed to guard against zero, but a transient
|
|
192
|
+
// display:none container measured during a route transition
|
|
193
|
+
// can leak a 1 through. See change:
|
|
194
|
+
// fix-terminal-half-height-dual-mount.
|
|
195
|
+
if (msg.cols < 2 || msg.rows < 2) {
|
|
196
|
+
// ignore — keep previous PTY dimensions
|
|
197
|
+
} else {
|
|
198
|
+
entry.pty.resize(msg.cols, msg.rows);
|
|
199
|
+
}
|
|
189
200
|
} else if (msg.type === "title") {
|
|
190
201
|
// title control message — handled elsewhere
|
|
191
202
|
} else {
|
|
@@ -29,12 +29,12 @@ source: —
|
|
|
29
29
|
path: —
|
|
30
30
|
tried:
|
|
31
31
|
override no override set
|
|
32
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
32
33
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
33
|
-
|
|
34
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
34
35
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
35
|
-
|
|
36
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
36
37
|
npm-global missing: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
37
|
-
npm-global missing: <NPM_ROOT>/@oh-my-pi/pi-coding-agent/dist/cli.js
|
|
38
38
|
managed missing: <HOME>/.pi-dashboard/node_modules/.bin/pi.cmd
|
|
39
39
|
where not found on PATH"
|
|
40
40
|
`;
|
|
@@ -66,8 +66,9 @@ source: managed
|
|
|
66
66
|
path: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
67
67
|
tried:
|
|
68
68
|
override no override set
|
|
69
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
69
70
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
70
|
-
|
|
71
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
71
72
|
managed ok"
|
|
72
73
|
`;
|
|
73
74
|
|
|
@@ -111,12 +112,12 @@ source: —
|
|
|
111
112
|
path: —
|
|
112
113
|
tried:
|
|
113
114
|
override no override set
|
|
115
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
114
116
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
115
|
-
|
|
117
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
116
118
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
117
|
-
|
|
119
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
118
120
|
npm-global missing: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
119
|
-
npm-global missing: <NPM_ROOT>/@oh-my-pi/pi-coding-agent/dist/cli.js
|
|
120
121
|
managed missing: <HOME>/.pi-dashboard/node_modules/.bin/pi.cmd
|
|
121
122
|
where not found on PATH"
|
|
122
123
|
`;
|
|
@@ -150,10 +151,11 @@ source: npm-global
|
|
|
150
151
|
path: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
151
152
|
tried:
|
|
152
153
|
override no override set
|
|
154
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
153
155
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
154
|
-
|
|
156
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
155
157
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
156
|
-
|
|
158
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
157
159
|
npm-global ok
|
|
158
160
|
argv:
|
|
159
161
|
- C:/Program Files/nodejs/node.exe
|
|
@@ -199,6 +201,7 @@ source: bare-import
|
|
|
199
201
|
path: dist/cli.js
|
|
200
202
|
tried:
|
|
201
203
|
override no override set
|
|
204
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
202
205
|
bare-import ok"
|
|
203
206
|
`;
|
|
204
207
|
|
|
@@ -248,8 +251,9 @@ source: managed
|
|
|
248
251
|
path: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
249
252
|
tried:
|
|
250
253
|
override no override set
|
|
254
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
251
255
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
252
|
-
|
|
256
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
253
257
|
managed ok"
|
|
254
258
|
`;
|
|
255
259
|
|
|
@@ -271,12 +275,12 @@ source: —
|
|
|
271
275
|
path: —
|
|
272
276
|
tried:
|
|
273
277
|
override no override set
|
|
278
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
274
279
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
275
|
-
|
|
280
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
276
281
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
277
|
-
|
|
282
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
278
283
|
npm-global missing: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
279
|
-
npm-global missing: <NPM_ROOT>/@oh-my-pi/pi-coding-agent/dist/cli.js
|
|
280
284
|
managed missing: <HOME>/.pi-dashboard/node_modules/.bin/pi.cmd
|
|
281
285
|
where not found on PATH"
|
|
282
286
|
`;
|
|
@@ -288,8 +292,9 @@ source: managed
|
|
|
288
292
|
path: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
289
293
|
tried:
|
|
290
294
|
override no override set
|
|
295
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
291
296
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
292
|
-
|
|
297
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
293
298
|
managed ok"
|
|
294
299
|
`;
|
|
295
300
|
|
|
@@ -320,8 +325,9 @@ source: managed
|
|
|
320
325
|
path: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
321
326
|
tried:
|
|
322
327
|
override no override set
|
|
328
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
323
329
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
324
|
-
|
|
330
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
325
331
|
managed ok
|
|
326
332
|
argv:
|
|
327
333
|
- C:/Program Files/nodejs/node.exe
|
|
@@ -335,10 +341,11 @@ source: npm-global
|
|
|
335
341
|
path: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
336
342
|
tried:
|
|
337
343
|
override no override set
|
|
344
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
338
345
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
339
|
-
|
|
346
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
340
347
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
341
|
-
|
|
348
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
342
349
|
npm-global ok
|
|
343
350
|
argv:
|
|
344
351
|
- C:/Program Files/nodejs/node.exe
|
|
@@ -352,6 +359,7 @@ source: system
|
|
|
352
359
|
path: C:/Program Files/nodejs/node.exe
|
|
353
360
|
tried:
|
|
354
361
|
override no override set
|
|
362
|
+
managed missing: <HOME>/.pi-dashboard/node/node.exe
|
|
355
363
|
managed missing: <HOME>/.pi-dashboard/node_modules/.bin/node.cmd
|
|
356
364
|
where ok
|
|
357
365
|
argv:
|
package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/a-electron.test.ts.snap
CHANGED
|
@@ -29,12 +29,12 @@ source: —
|
|
|
29
29
|
path: —
|
|
30
30
|
tried:
|
|
31
31
|
override no override set
|
|
32
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
32
33
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
33
|
-
|
|
34
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
34
35
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
35
|
-
|
|
36
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
36
37
|
npm-global missing: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
37
|
-
npm-global missing: <NPM_ROOT>/@oh-my-pi/pi-coding-agent/dist/cli.js
|
|
38
38
|
managed missing: <HOME>/.pi-dashboard/node_modules/.bin/pi.cmd
|
|
39
39
|
where not found on PATH"
|
|
40
40
|
`;
|
|
@@ -66,8 +66,9 @@ source: managed
|
|
|
66
66
|
path: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
67
67
|
tried:
|
|
68
68
|
override no override set
|
|
69
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
69
70
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
70
|
-
|
|
71
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
71
72
|
managed ok"
|
|
72
73
|
`;
|
|
73
74
|
|
package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/b-npm-global.test.ts.snap
CHANGED
|
@@ -29,12 +29,12 @@ source: —
|
|
|
29
29
|
path: —
|
|
30
30
|
tried:
|
|
31
31
|
override no override set
|
|
32
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
32
33
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
33
|
-
|
|
34
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
34
35
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
35
|
-
|
|
36
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
36
37
|
npm-global missing: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
37
|
-
npm-global missing: <NPM_ROOT>/@oh-my-pi/pi-coding-agent/dist/cli.js
|
|
38
38
|
managed missing: <HOME>/.pi-dashboard/node_modules/.bin/pi.cmd
|
|
39
39
|
where not found on PATH"
|
|
40
40
|
`;
|
|
@@ -68,10 +68,11 @@ source: npm-global
|
|
|
68
68
|
path: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
69
69
|
tried:
|
|
70
70
|
override no override set
|
|
71
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
71
72
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
72
|
-
|
|
73
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
73
74
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
74
|
-
|
|
75
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
75
76
|
npm-global ok
|
|
76
77
|
argv:
|
|
77
78
|
- C:/Program Files/nodejs/node.exe
|
package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/e-stale-partial.test.ts.snap
CHANGED
|
@@ -27,8 +27,9 @@ source: managed
|
|
|
27
27
|
path: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
28
28
|
tried:
|
|
29
29
|
override no override set
|
|
30
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
30
31
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
31
|
-
|
|
32
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
32
33
|
managed ok"
|
|
33
34
|
`;
|
|
34
35
|
|
|
@@ -50,12 +51,12 @@ source: —
|
|
|
50
51
|
path: —
|
|
51
52
|
tried:
|
|
52
53
|
override no override set
|
|
54
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
53
55
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
54
|
-
|
|
56
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
55
57
|
managed missing: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
56
|
-
|
|
58
|
+
npm-global missing: <NPM_ROOT>/@earendil-works/pi-coding-agent/dist/cli.js
|
|
57
59
|
npm-global missing: <NPM_ROOT>/@mariozechner/pi-coding-agent/dist/cli.js
|
|
58
|
-
npm-global missing: <NPM_ROOT>/@oh-my-pi/pi-coding-agent/dist/cli.js
|
|
59
60
|
managed missing: <HOME>/.pi-dashboard/node_modules/.bin/pi.cmd
|
|
60
61
|
where not found on PATH"
|
|
61
62
|
`;
|
package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/f-cwd-variants.test.ts.snap
CHANGED
|
@@ -7,8 +7,9 @@ source: managed
|
|
|
7
7
|
path: <HOME>/.pi-dashboard/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
|
|
8
8
|
tried:
|
|
9
9
|
override no override set
|
|
10
|
+
bare-import cannot resolve @earendil-works/pi-coding-agent/package.json
|
|
10
11
|
bare-import cannot resolve @mariozechner/pi-coding-agent/package.json
|
|
11
|
-
|
|
12
|
+
managed missing: <HOME>/.pi-dashboard/node_modules/@earendil-works/pi-coding-agent/dist/cli.js
|
|
12
13
|
managed ok"
|
|
13
14
|
`;
|
|
14
15
|
|