wicked-crew 0.7.26 → 0.7.28
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/api/routes.d.ts +8 -0
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +9 -2
- package/dist/api/routes.js.map +1 -1
- package/dist/api/server.d.ts +13 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +14 -0
- package/dist/api/server.js.map +1 -1
- package/dist/cli/index.js +46 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +22 -18
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/deliver.d.ts +26 -10
- package/dist/core/deliver.d.ts.map +1 -1
- package/dist/core/deliver.js +27 -11
- package/dist/core/deliver.js.map +1 -1
- package/dist/core/deliverable-floor.d.ts.map +1 -1
- package/dist/core/deliverable-floor.js +5 -4
- package/dist/core/deliverable-floor.js.map +1 -1
- package/dist/interactive/bridge-pool.d.ts +130 -2
- package/dist/interactive/bridge-pool.d.ts.map +1 -1
- package/dist/interactive/bridge-pool.js +281 -8
- package/dist/interactive/bridge-pool.js.map +1 -1
- package/dist/interactive/bus-location.d.ts +65 -0
- package/dist/interactive/bus-location.d.ts.map +1 -0
- package/dist/interactive/bus-location.js +75 -0
- package/dist/interactive/bus-location.js.map +1 -0
- package/dist/interactive/chat-events.d.ts.map +1 -1
- package/dist/interactive/chat-events.js +29 -23
- package/dist/interactive/chat-events.js.map +1 -1
- package/dist/interactive/demo-events.d.ts +16 -1
- package/dist/interactive/demo-events.d.ts.map +1 -1
- package/dist/interactive/demo-events.js +262 -43
- package/dist/interactive/demo-events.js.map +1 -1
- package/dist/interactive/doc-grounding.d.ts +202 -0
- package/dist/interactive/doc-grounding.d.ts.map +1 -0
- package/dist/interactive/doc-grounding.js +647 -0
- package/dist/interactive/doc-grounding.js.map +1 -0
- package/dist/interactive/draft-events.d.ts +54 -1
- package/dist/interactive/draft-events.d.ts.map +1 -1
- package/dist/interactive/draft-events.js +234 -117
- package/dist/interactive/draft-events.js.map +1 -1
- package/dist/interactive/edit-events.d.ts.map +1 -1
- package/dist/interactive/edit-events.js +27 -21
- package/dist/interactive/edit-events.js.map +1 -1
- package/dist/interactive/proxy-routes.d.ts +78 -0
- package/dist/interactive/proxy-routes.d.ts.map +1 -1
- package/dist/interactive/proxy-routes.js +355 -14
- package/dist/interactive/proxy-routes.js.map +1 -1
- package/dist/interactive/repo-snapshot.d.ts +31 -0
- package/dist/interactive/repo-snapshot.d.ts.map +1 -1
- package/dist/interactive/repo-snapshot.js +56 -1
- package/dist/interactive/repo-snapshot.js.map +1 -1
- package/dist/qe/conformance.d.ts +10 -1
- package/dist/qe/conformance.d.ts.map +1 -1
- package/dist/qe/conformance.js +57 -4
- package/dist/qe/conformance.js.map +1 -1
- package/dist/skills/plugin-source.d.ts +149 -32
- package/dist/skills/plugin-source.d.ts.map +1 -1
- package/dist/skills/plugin-source.js +303 -108
- package/dist/skills/plugin-source.js.map +1 -1
- package/dist/skills/root-fence.d.ts +2 -2
- package/dist/skills/root-fence.js +4 -4
- package/dist/skills/root-fence.js.map +1 -1
- package/dist/skills/runtime.d.ts +19 -2
- package/dist/skills/runtime.d.ts.map +1 -1
- package/dist/skills/runtime.js +82 -8
- package/dist/skills/runtime.js.map +1 -1
- package/dist/skills/store.d.ts +2 -2
- package/dist/skills/store.d.ts.map +1 -1
- package/dist/skills/store.js +30 -9
- package/dist/skills/store.js.map +1 -1
- package/dist/studio/assets/index-CdmCMh2f.js +539 -0
- package/dist/studio/index.html +1 -1
- package/dist/studio/testid-inventory.json +125 -5
- package/endpoint-manifest.json +16 -1
- package/package.json +3 -3
- package/dist/studio/assets/index-FcZg3WDR.js +0 -539
|
@@ -24,10 +24,42 @@
|
|
|
24
24
|
* `POST /api/studio-origin`, interactive ≥ 0.8.0) so the bridge's `GET /` redirects a direct
|
|
25
25
|
* visitor into studio instead of its API-only fallback page. Fire-and-forget, once per pooled
|
|
26
26
|
* bridge: recording can never fail — or slow down — a proxied request.
|
|
27
|
+
*
|
|
28
|
+
* THE SPAWN ENV (acceptance findings F-042 + F-043). The bridge validates and registers a doc's
|
|
29
|
+
* project against `WICKED_CREW_API` — defaulting to `http://127.0.0.1:7701` when unset — and emits
|
|
30
|
+
* onto the wicked-bus at `WICKED_BUS_DATA_DIR` — defaulting to `~/.something-wicked/wicked-bus`.
|
|
31
|
+
* A bridge spawned with the daemon's bare env therefore talked to whatever daemon owned :7701 (a
|
|
32
|
+
* daemon on any other port could not create a single project-bound document) and shared ONE bus
|
|
33
|
+
* with every other daemon on the host (two daemons' durable cursors racing for one `doc.created`).
|
|
34
|
+
* So the spawn now exports BOTH: `WICKED_CREW_API` = this daemon's own bound origin, and
|
|
35
|
+
* `WICKED_BUS_DATA_DIR` = the directory of the bus this daemon's interactive seams read. The pair
|
|
36
|
+
* is written beside the lockfile (`.wi-serve.crew.json`) so an ADOPTED bridge can be checked: one
|
|
37
|
+
* this daemon (or a sibling) started with a DIFFERENT pair is recycled — restarted with the right
|
|
38
|
+
* env — and one nobody recorded (an operator-run `wicked-interactive serve`, a pre-upgrade bridge)
|
|
39
|
+
* is adopted with a warning that names the fix. A bridge is only useful to the daemon whose bus it
|
|
40
|
+
* emits to; sharing one across daemons is exactly the isolation break F-043 recorded.
|
|
41
|
+
*
|
|
42
|
+
* RECYCLING FAILS CLOSED (codex r4 on crew#506). Stopping a mismatched bridge is only "done" when
|
|
43
|
+
* its pid is DEMONSTRABLY gone: a refused signal (EPERM — a bridge running as another user) or a
|
|
44
|
+
* pid that survives SIGTERM, the grace and SIGKILL refuses the start, naming the pid and the daemon
|
|
45
|
+
* that owned it, and leaves the sidecar untouched — a replacement is never started beside a bridge
|
|
46
|
+
* that may still be running. The replacement itself must prove it is OURS before it is recorded as
|
|
47
|
+
* crew's: the lockfile pid has to be the child this daemon spawned or one of its descendants
|
|
48
|
+
* (`npx` → shell → node), it must differ from the pid just recycled, and a bridge whose lineage
|
|
49
|
+
* cannot be read is used but never written into the sidecar. A sidecar entry is a claim of
|
|
50
|
+
* ownership that licenses a later kill, so it is only ever written for a pid this daemon spawned.
|
|
27
51
|
*/
|
|
28
52
|
import { type ChildProcess } from 'node:child_process';
|
|
29
53
|
import type { AddressInfo } from 'node:net';
|
|
30
54
|
export declare const LOCK_NAME = ".wi-serve.json";
|
|
55
|
+
/** Crew's sidecar beside the bridge's lockfile: which pid crew started, and with which env (F-042/F-043). */
|
|
56
|
+
export declare const CREW_SIDECAR_NAME = ".wi-serve.crew.json";
|
|
57
|
+
/** How long a recycled bridge gets to exit on SIGTERM before SIGKILL. */
|
|
58
|
+
export declare const RECYCLE_GRACE_MS = 3000;
|
|
59
|
+
/** How long after SIGKILL the pid gets to leave the process table before the recycle is refused. */
|
|
60
|
+
export declare const RECYCLE_HARD_MS = 1000;
|
|
61
|
+
/** Parent hops walked when proving a lockfile pid descends from the child this daemon spawned. */
|
|
62
|
+
export declare const LINEAGE_MAX_HOPS = 16;
|
|
31
63
|
/**
|
|
32
64
|
* The wicked-interactive range crew will start, as an npm spec.
|
|
33
65
|
*
|
|
@@ -69,9 +101,38 @@ export declare class BridgeUnavailableError extends Error {
|
|
|
69
101
|
readonly hint: string;
|
|
70
102
|
constructor(message: string, hint: string);
|
|
71
103
|
}
|
|
104
|
+
/** The two variables crew hands the bridge it spawns (F-042/F-043). Absent = not set — the bridge
|
|
105
|
+
* falls back to its own defaults, which is exactly the pre-fix behavior this exists to end. */
|
|
106
|
+
export interface BridgeEnv {
|
|
107
|
+
/** The daemon's own origin — where the bridge validates/registers project bindings. */
|
|
108
|
+
WICKED_CREW_API?: string;
|
|
109
|
+
/** The directory holding the `bus.db` this daemon's interactive seams read. */
|
|
110
|
+
WICKED_BUS_DATA_DIR?: string;
|
|
111
|
+
}
|
|
112
|
+
/** What crew writes beside the lockfile after IT starts a bridge. */
|
|
113
|
+
export interface CrewSidecar {
|
|
114
|
+
/** The bridge's pid (the lockfile's). */
|
|
115
|
+
pid: number;
|
|
116
|
+
env: BridgeEnv;
|
|
117
|
+
startedBy: 'wicked-crew';
|
|
118
|
+
startedAt: string;
|
|
119
|
+
/** The DAEMON that spawned it. A bridge whose owner is still alive is that daemon's to stop —
|
|
120
|
+
* never this one's (codex on crew#506). */
|
|
121
|
+
ownerPid?: number;
|
|
122
|
+
}
|
|
72
123
|
/** Injectable IO — the integration suite substitutes a fake bridge for the real `npx` spawn. */
|
|
73
124
|
export interface BridgePoolIo {
|
|
74
|
-
spawn
|
|
125
|
+
/** The spawn; the second argument is the FULL child env (the daemon's, plus {@link BridgeEnv}). */
|
|
126
|
+
spawn?: (root: string, env: NodeJS.ProcessEnv) => ChildProcess;
|
|
127
|
+
/** Signal delivery for a recycle (tests inject a refusal). Default `process.kill`. */
|
|
128
|
+
kill?: (pid: number, signal: NodeJS.Signals) => void;
|
|
129
|
+
/** Liveness probe while waiting for a recycled bridge to leave. Default {@link pidAlive}. */
|
|
130
|
+
alive?: (pid: number) => boolean;
|
|
131
|
+
/** Parent-pid lookup for the spawn-lineage proof (tests inject). Default {@link parentPidOf}. */
|
|
132
|
+
parentOf?: (pid: number) => number | null;
|
|
133
|
+
/** Recycle timing overrides (tests); defaults {@link RECYCLE_GRACE_MS} / {@link RECYCLE_HARD_MS}. */
|
|
134
|
+
recycleGraceMs?: number;
|
|
135
|
+
recycleHardMs?: number;
|
|
75
136
|
startTimeoutMs?: number;
|
|
76
137
|
healthTimeoutMs?: number;
|
|
77
138
|
log?: (msg: string) => void;
|
|
@@ -80,10 +141,26 @@ export interface BridgePoolIo {
|
|
|
80
141
|
/**
|
|
81
142
|
* The daemon's own origin (`http://<bound host>:<bound port>`), resolved LAZILY — the pool is
|
|
82
143
|
* built before `listen`, but only consulted while serving a request, i.e. after the address is
|
|
83
|
-
* bound. Null (or absent) means "nothing to record" and the pool never POSTs (#298).
|
|
144
|
+
* bound. Null (or absent) means "nothing to record" and the pool never POSTs (#298). It is also
|
|
145
|
+
* the `WICKED_CREW_API` the spawned bridge gets (F-042) — the bridge must talk to THIS daemon.
|
|
84
146
|
*/
|
|
85
147
|
studioOrigin?: () => string | null;
|
|
148
|
+
/**
|
|
149
|
+
* The directory of the bus db this daemon's interactive seams read — exported to the spawned
|
|
150
|
+
* bridge as `WICKED_BUS_DATA_DIR` so both meet on one bus (F-043), and recorded in the sidecar so
|
|
151
|
+
* an adopted bridge can be checked against it. Null/absent = not exported (the bridge keeps
|
|
152
|
+
* wicked-bus's own default): the CLI passes null only when `--bus-db` names a file wicked-bus
|
|
153
|
+
* cannot be pointed at through a data dir, or wicked-bus is not importable at all.
|
|
154
|
+
*/
|
|
155
|
+
busDataDir?: string | null;
|
|
86
156
|
}
|
|
157
|
+
/** The {@link BridgeEnv} this pool hands a bridge it starts, from its io. Only DEFINED values ride. */
|
|
158
|
+
export declare function bridgeEnvFor(io: Pick<BridgePoolIo, 'studioOrigin' | 'busDataDir'>): BridgeEnv;
|
|
159
|
+
export { busDataDirOf } from './bus-location.js';
|
|
160
|
+
/** `true` when two bridge envs agree on every variable either one sets. */
|
|
161
|
+
export declare function bridgeEnvMatches(a: BridgeEnv, b: BridgeEnv): boolean;
|
|
162
|
+
/** `<root>/.wi-serve.crew.json`, or null when absent/unparseable/incomplete. */
|
|
163
|
+
export declare function readCrewSidecar(root: string): CrewSidecar | null;
|
|
87
164
|
/**
|
|
88
165
|
* The daemon's own http origin from its bound server address, or null before `listen`. Wildcard
|
|
89
166
|
* binds (`0.0.0.0` / `::`) are not dialable from a browser, so they normalize to loopback — the
|
|
@@ -94,6 +171,20 @@ export declare function boundOrigin(addr: AddressInfo | string | null): string |
|
|
|
94
171
|
export declare function readLock(root: string): LiveBridge | null;
|
|
95
172
|
/** Signal 0 probes existence without delivering: EPERM means alive-but-not-ours. */
|
|
96
173
|
export declare function pidAlive(pid: number): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* The parent pid of `pid`, or null when it cannot be read (no such process, no `ps` / PowerShell,
|
|
176
|
+
* an unparseable answer). POSIX asks `ps`; Windows asks CIM. Only consulted once per bridge start.
|
|
177
|
+
*/
|
|
178
|
+
export declare function parentPidOf(pid: number): number | null;
|
|
179
|
+
/** What the lineage proof concluded about a lockfile pid relative to the child this daemon spawned. */
|
|
180
|
+
export type SpawnLineage = 'ours' | 'foreign' | 'unknown';
|
|
181
|
+
/**
|
|
182
|
+
* Is `pid` the child this daemon spawned (`childPid`) or one of its descendants (`npx` → shell →
|
|
183
|
+
* node)? Walks parents until it meets `childPid` (ours), reaches the root of the process tree or a
|
|
184
|
+
* cycle (foreign — somebody else's bridge took the lockfile), or cannot read a hop / runs out of
|
|
185
|
+
* hops (unknown — used but never recorded as crew's). Pure: the lookup is injected.
|
|
186
|
+
*/
|
|
187
|
+
export declare function spawnLineage(pid: number, childPid: number, parentOf: (pid: number) => number | null): SpawnLineage;
|
|
97
188
|
export declare class InteractiveBridgePool {
|
|
98
189
|
private readonly io;
|
|
99
190
|
/** Last bridge known good per root — the fast path that keeps the proxy off `fetch` per request. */
|
|
@@ -108,6 +199,29 @@ export declare class InteractiveBridgePool {
|
|
|
108
199
|
/** Live bridges, for tests and future operator introspection. */
|
|
109
200
|
keys(): string[];
|
|
110
201
|
private resolveOrStart;
|
|
202
|
+
/**
|
|
203
|
+
* A live bridge was found through the lockfile. Is it one THIS daemon can use (F-042/F-043)?
|
|
204
|
+
* - crew's sidecar names this pid and its env matches ours → adopt silently;
|
|
205
|
+
* - the sidecar names this pid with a DIFFERENT env: if the daemon that spawned it (`ownerPid`)
|
|
206
|
+
* is STILL ALIVE, the bridge is that daemon's — two daemons sharing one docs root — and this
|
|
207
|
+
* one must not kill it mid-create (codex on crew#506): refuse with a `BridgeUnavailableError`
|
|
208
|
+
* naming the owner and the fix (give this daemon its own interactive root). Only a bridge
|
|
209
|
+
* whose owner is gone (a previous daemon that exited, or this very process after a
|
|
210
|
+
* reconfiguration) is recycled — SIGTERM, grace, SIGKILL — and restarted with the right env;
|
|
211
|
+
* - no sidecar (or another pid) → nobody recorded how it was started (an operator's terminal
|
|
212
|
+
* `wicked-interactive serve`, a pre-upgrade bridge): adopt it, but say what it may be missing
|
|
213
|
+
* and how to fix it. Killing a process crew did not start is not crew's call.
|
|
214
|
+
*/
|
|
215
|
+
private adoptOrRecycle;
|
|
216
|
+
/**
|
|
217
|
+
* SIGTERM, wait up to {@link RECYCLE_GRACE_MS} for exit, SIGKILL whatever ignored it — and then
|
|
218
|
+
* PROVE the pid is gone. Fails closed (codex r4 on crew#506): a refused signal (EPERM) or a pid
|
|
219
|
+
* still in the process table after the hard wait throws a `BridgeUnavailableError` naming the pid
|
|
220
|
+
* and its owner, so no replacement is started beside a bridge that may still be running and the
|
|
221
|
+
* sidecar that records it is never touched. ESRCH is not a failure — the bridge left before we
|
|
222
|
+
* signalled — but even then the pid has to be observed gone.
|
|
223
|
+
*/
|
|
224
|
+
private terminate;
|
|
111
225
|
/**
|
|
112
226
|
* POST the daemon's own origin to the bridge's `/api/studio-origin` (#298), so the bridge's
|
|
113
227
|
* `GET /` redirects a direct visitor into studio instead of the API-only fallback page.
|
|
@@ -118,6 +232,20 @@ export declare class InteractiveBridgePool {
|
|
|
118
232
|
private recordStudioOrigin;
|
|
119
233
|
/** The lockfile points at a bridge that is alive, answering, and serving THIS root. */
|
|
120
234
|
private healthy;
|
|
235
|
+
/**
|
|
236
|
+
* Spawn a bridge for `root` and wait for it to answer. `replacing` is the pid just recycled
|
|
237
|
+
* (see {@link adoptOrRecycle}). Before the new bridge is used — and before ANY sidecar is
|
|
238
|
+
* written — it has to prove it is ours: not the recycled pid (that bridge was not stopped), and
|
|
239
|
+
* the child this daemon spawned or one of its descendants (`npx` → shell → node, checked through
|
|
240
|
+
* {@link spawnLineage}). A bridge somebody else started under our lockfile while we were
|
|
241
|
+
* starting is refused (and our own spawn abandoned); one whose lineage cannot be read is used
|
|
242
|
+
* but NOT recorded — a sidecar is a claim of ownership, and only a pid this daemon spawned earns it.
|
|
243
|
+
*/
|
|
121
244
|
private start;
|
|
245
|
+
/** Record which pid crew started and with which env, so a later adopt can tell ours from a
|
|
246
|
+
* sibling daemon's (see {@link adoptOrRecycle}). Only ever called for a pid whose lineage from
|
|
247
|
+
* this daemon's own spawn is PROVEN (see {@link start}). Best-effort: an unwritable sidecar only
|
|
248
|
+
* costs the adopt-time check, never the start. */
|
|
249
|
+
private writeSidecar;
|
|
122
250
|
}
|
|
123
251
|
//# sourceMappingURL=bridge-pool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-pool.d.ts","sourceRoot":"","sources":["../../src/interactive/bridge-pool.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"bridge-pool.d.ts","sourceRoot":"","sources":["../../src/interactive/bridge-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,11 +24,43 @@
|
|
|
24
24
|
* `POST /api/studio-origin`, interactive ≥ 0.8.0) so the bridge's `GET /` redirects a direct
|
|
25
25
|
* visitor into studio instead of its API-only fallback page. Fire-and-forget, once per pooled
|
|
26
26
|
* bridge: recording can never fail — or slow down — a proxied request.
|
|
27
|
+
*
|
|
28
|
+
* THE SPAWN ENV (acceptance findings F-042 + F-043). The bridge validates and registers a doc's
|
|
29
|
+
* project against `WICKED_CREW_API` — defaulting to `http://127.0.0.1:7701` when unset — and emits
|
|
30
|
+
* onto the wicked-bus at `WICKED_BUS_DATA_DIR` — defaulting to `~/.something-wicked/wicked-bus`.
|
|
31
|
+
* A bridge spawned with the daemon's bare env therefore talked to whatever daemon owned :7701 (a
|
|
32
|
+
* daemon on any other port could not create a single project-bound document) and shared ONE bus
|
|
33
|
+
* with every other daemon on the host (two daemons' durable cursors racing for one `doc.created`).
|
|
34
|
+
* So the spawn now exports BOTH: `WICKED_CREW_API` = this daemon's own bound origin, and
|
|
35
|
+
* `WICKED_BUS_DATA_DIR` = the directory of the bus this daemon's interactive seams read. The pair
|
|
36
|
+
* is written beside the lockfile (`.wi-serve.crew.json`) so an ADOPTED bridge can be checked: one
|
|
37
|
+
* this daemon (or a sibling) started with a DIFFERENT pair is recycled — restarted with the right
|
|
38
|
+
* env — and one nobody recorded (an operator-run `wicked-interactive serve`, a pre-upgrade bridge)
|
|
39
|
+
* is adopted with a warning that names the fix. A bridge is only useful to the daemon whose bus it
|
|
40
|
+
* emits to; sharing one across daemons is exactly the isolation break F-043 recorded.
|
|
41
|
+
*
|
|
42
|
+
* RECYCLING FAILS CLOSED (codex r4 on crew#506). Stopping a mismatched bridge is only "done" when
|
|
43
|
+
* its pid is DEMONSTRABLY gone: a refused signal (EPERM — a bridge running as another user) or a
|
|
44
|
+
* pid that survives SIGTERM, the grace and SIGKILL refuses the start, naming the pid and the daemon
|
|
45
|
+
* that owned it, and leaves the sidecar untouched — a replacement is never started beside a bridge
|
|
46
|
+
* that may still be running. The replacement itself must prove it is OURS before it is recorded as
|
|
47
|
+
* crew's: the lockfile pid has to be the child this daemon spawned or one of its descendants
|
|
48
|
+
* (`npx` → shell → node), it must differ from the pid just recycled, and a bridge whose lineage
|
|
49
|
+
* cannot be read is used but never written into the sidecar. A sidecar entry is a claim of
|
|
50
|
+
* ownership that licenses a later kill, so it is only ever written for a pid this daemon spawned.
|
|
27
51
|
*/
|
|
28
|
-
import { spawn as nodeSpawn } from 'node:child_process';
|
|
29
|
-
import { mkdirSync, readFileSync } from 'node:fs';
|
|
52
|
+
import { spawn as nodeSpawn, spawnSync } from 'node:child_process';
|
|
53
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
30
54
|
import { join, resolve } from 'node:path';
|
|
31
55
|
export const LOCK_NAME = '.wi-serve.json';
|
|
56
|
+
/** Crew's sidecar beside the bridge's lockfile: which pid crew started, and with which env (F-042/F-043). */
|
|
57
|
+
export const CREW_SIDECAR_NAME = '.wi-serve.crew.json';
|
|
58
|
+
/** How long a recycled bridge gets to exit on SIGTERM before SIGKILL. */
|
|
59
|
+
export const RECYCLE_GRACE_MS = 3000;
|
|
60
|
+
/** How long after SIGKILL the pid gets to leave the process table before the recycle is refused. */
|
|
61
|
+
export const RECYCLE_HARD_MS = 1000;
|
|
62
|
+
/** Parent hops walked when proving a lockfile pid descends from the child this daemon spawned. */
|
|
63
|
+
export const LINEAGE_MAX_HOPS = 16;
|
|
32
64
|
/**
|
|
33
65
|
* The wicked-interactive range crew will start, as an npm spec.
|
|
34
66
|
*
|
|
@@ -72,6 +104,46 @@ export class BridgeUnavailableError extends Error {
|
|
|
72
104
|
function serveCommand(root) {
|
|
73
105
|
return `npx ${INTERACTIVE_SPEC} serve --root ${root}`;
|
|
74
106
|
}
|
|
107
|
+
/** The {@link BridgeEnv} this pool hands a bridge it starts, from its io. Only DEFINED values ride. */
|
|
108
|
+
export function bridgeEnvFor(io) {
|
|
109
|
+
const origin = io.studioOrigin?.() ?? null;
|
|
110
|
+
const busDir = io.busDataDir ?? null;
|
|
111
|
+
return {
|
|
112
|
+
...(origin !== null ? { WICKED_CREW_API: origin } : {}),
|
|
113
|
+
...(busDir !== null ? { WICKED_BUS_DATA_DIR: busDir } : {}),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export { busDataDirOf } from './bus-location.js';
|
|
117
|
+
/** `true` when two bridge envs agree on every variable either one sets. */
|
|
118
|
+
export function bridgeEnvMatches(a, b) {
|
|
119
|
+
return a.WICKED_CREW_API === b.WICKED_CREW_API && a.WICKED_BUS_DATA_DIR === b.WICKED_BUS_DATA_DIR;
|
|
120
|
+
}
|
|
121
|
+
/** `<root>/.wi-serve.crew.json`, or null when absent/unparseable/incomplete. */
|
|
122
|
+
export function readCrewSidecar(root) {
|
|
123
|
+
try {
|
|
124
|
+
const raw = JSON.parse(readFileSync(join(root, CREW_SIDECAR_NAME), 'utf8'));
|
|
125
|
+
if (typeof raw.pid !== 'number' || typeof raw.env !== 'object' || raw.env === null)
|
|
126
|
+
return null;
|
|
127
|
+
const env = {
|
|
128
|
+
...(typeof raw.env.WICKED_CREW_API === 'string' ? { WICKED_CREW_API: raw.env.WICKED_CREW_API } : {}),
|
|
129
|
+
...(typeof raw.env.WICKED_BUS_DATA_DIR === 'string' ? { WICKED_BUS_DATA_DIR: raw.env.WICKED_BUS_DATA_DIR } : {}),
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
pid: raw.pid,
|
|
133
|
+
env,
|
|
134
|
+
startedBy: 'wicked-crew',
|
|
135
|
+
startedAt: typeof raw.startedAt === 'string' ? raw.startedAt : '',
|
|
136
|
+
...(typeof raw.ownerPid === 'number' ? { ownerPid: raw.ownerPid } : {}),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function describeEnv(env) {
|
|
144
|
+
const parts = Object.entries(env).map(([k, v]) => `${k}=${v}`);
|
|
145
|
+
return parts.length > 0 ? parts.join(' ') : '(no env)';
|
|
146
|
+
}
|
|
75
147
|
/**
|
|
76
148
|
* The daemon's own http origin from its bound server address, or null before `listen`. Wildcard
|
|
77
149
|
* binds (`0.0.0.0` / `::`) are not dialable from a browser, so they normalize to loopback — the
|
|
@@ -111,6 +183,50 @@ export function pidAlive(pid) {
|
|
|
111
183
|
return err.code === 'EPERM';
|
|
112
184
|
}
|
|
113
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* The parent pid of `pid`, or null when it cannot be read (no such process, no `ps` / PowerShell,
|
|
188
|
+
* an unparseable answer). POSIX asks `ps`; Windows asks CIM. Only consulted once per bridge start.
|
|
189
|
+
*/
|
|
190
|
+
export function parentPidOf(pid) {
|
|
191
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
192
|
+
return null;
|
|
193
|
+
try {
|
|
194
|
+
const res = process.platform === 'win32'
|
|
195
|
+
? spawnSync('powershell', ['-NoProfile', '-NonInteractive', '-Command', `(Get-CimInstance Win32_Process -Filter "ProcessId=${pid}").ParentProcessId`], { encoding: 'utf8', timeout: 5000, windowsHide: true })
|
|
196
|
+
: spawnSync('ps', ['-o', 'ppid=', '-p', String(pid)], { encoding: 'utf8', timeout: 5000 });
|
|
197
|
+
if (res.error || res.status !== 0)
|
|
198
|
+
return null;
|
|
199
|
+
const ppid = Number.parseInt(String(res.stdout).trim(), 10);
|
|
200
|
+
return Number.isInteger(ppid) && ppid >= 0 ? ppid : null;
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Is `pid` the child this daemon spawned (`childPid`) or one of its descendants (`npx` → shell →
|
|
208
|
+
* node)? Walks parents until it meets `childPid` (ours), reaches the root of the process tree or a
|
|
209
|
+
* cycle (foreign — somebody else's bridge took the lockfile), or cannot read a hop / runs out of
|
|
210
|
+
* hops (unknown — used but never recorded as crew's). Pure: the lookup is injected.
|
|
211
|
+
*/
|
|
212
|
+
export function spawnLineage(pid, childPid, parentOf) {
|
|
213
|
+
if (pid === childPid)
|
|
214
|
+
return 'ours';
|
|
215
|
+
const seen = new Set([pid]);
|
|
216
|
+
let cursor = pid;
|
|
217
|
+
for (let hop = 0; hop < LINEAGE_MAX_HOPS; hop++) {
|
|
218
|
+
const parent = parentOf(cursor);
|
|
219
|
+
if (parent === null)
|
|
220
|
+
return 'unknown';
|
|
221
|
+
if (parent === childPid)
|
|
222
|
+
return 'ours';
|
|
223
|
+
if (parent <= 1 || seen.has(parent))
|
|
224
|
+
return 'foreign';
|
|
225
|
+
seen.add(parent);
|
|
226
|
+
cursor = parent;
|
|
227
|
+
}
|
|
228
|
+
return 'unknown';
|
|
229
|
+
}
|
|
114
230
|
/** `GET /api/health` → the root that bridge is serving, or null (timeout, refusal, non-200). */
|
|
115
231
|
async function bridgeIdentity(bridge, timeoutMs) {
|
|
116
232
|
try {
|
|
@@ -163,12 +279,107 @@ export class InteractiveBridgePool {
|
|
|
163
279
|
// Adopt-or-start; either way the bridge just answered `/api/health` for this root, which is
|
|
164
280
|
// exactly the moment #298 wants the studio origin recorded — fire-and-forget, so recording
|
|
165
281
|
// can never delay (let alone fail) the proxied request that triggered the resolution.
|
|
166
|
-
const
|
|
282
|
+
const adopted = await this.healthy(root);
|
|
283
|
+
const bridge = adopted !== null ? await this.adoptOrRecycle(root, adopted) : await this.start(root);
|
|
167
284
|
const entry = { bridge, originRecorded: false };
|
|
168
285
|
this.live.set(root, entry);
|
|
169
286
|
this.recordStudioOrigin(entry);
|
|
170
287
|
return bridge;
|
|
171
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* A live bridge was found through the lockfile. Is it one THIS daemon can use (F-042/F-043)?
|
|
291
|
+
* - crew's sidecar names this pid and its env matches ours → adopt silently;
|
|
292
|
+
* - the sidecar names this pid with a DIFFERENT env: if the daemon that spawned it (`ownerPid`)
|
|
293
|
+
* is STILL ALIVE, the bridge is that daemon's — two daemons sharing one docs root — and this
|
|
294
|
+
* one must not kill it mid-create (codex on crew#506): refuse with a `BridgeUnavailableError`
|
|
295
|
+
* naming the owner and the fix (give this daemon its own interactive root). Only a bridge
|
|
296
|
+
* whose owner is gone (a previous daemon that exited, or this very process after a
|
|
297
|
+
* reconfiguration) is recycled — SIGTERM, grace, SIGKILL — and restarted with the right env;
|
|
298
|
+
* - no sidecar (or another pid) → nobody recorded how it was started (an operator's terminal
|
|
299
|
+
* `wicked-interactive serve`, a pre-upgrade bridge): adopt it, but say what it may be missing
|
|
300
|
+
* and how to fix it. Killing a process crew did not start is not crew's call.
|
|
301
|
+
*/
|
|
302
|
+
async adoptOrRecycle(root, live) {
|
|
303
|
+
const expected = bridgeEnvFor(this.io);
|
|
304
|
+
const sidecar = readCrewSidecar(root);
|
|
305
|
+
if (sidecar !== null && sidecar.pid === live.pid) {
|
|
306
|
+
if (bridgeEnvMatches(sidecar.env, expected))
|
|
307
|
+
return live;
|
|
308
|
+
const owner = sidecar.ownerPid;
|
|
309
|
+
const ownerOrigin = sidecar.env.WICKED_CREW_API ?? '(unknown origin)';
|
|
310
|
+
if (owner === undefined || !Number.isInteger(owner) || owner <= 0) {
|
|
311
|
+
// No PROVEN owner (a pre-upgrade sidecar): not this daemon's to kill, and not adoptable
|
|
312
|
+
// either — its events go elsewhere. Refuse and name the fix (codex on crew#506).
|
|
313
|
+
this.io.log?.(`interactive bridge pid ${live.pid} for ${root} was recorded without an owning daemon and with ` +
|
|
314
|
+
`${describeEnv(sidecar.env)}; this daemon needs ${describeEnv(expected)} — NOT recycling a bridge of unproven ownership`);
|
|
315
|
+
throw new BridgeUnavailableError(`the interactive bridge for ${root} (pid ${live.pid}) was started for a different bus or crew API ` +
|
|
316
|
+
`(${ownerOrigin}) by a daemon this one cannot identify`, `stop it yourself (kill ${live.pid}) if no other crew daemon is using it, or give this daemon its own ` +
|
|
317
|
+
`interactive root (WICKED_INTERACTIVE_ROOT, or the project's interactiveRoot setting); the next request starts a bridge for this one`);
|
|
318
|
+
}
|
|
319
|
+
if (owner !== process.pid && pidAlive(owner)) {
|
|
320
|
+
this.io.log?.(`interactive bridge pid ${live.pid} for ${root} belongs to another live crew daemon (pid ${owner}, ` +
|
|
321
|
+
`${ownerOrigin}) with ${describeEnv(sidecar.env)}; this daemon needs ${describeEnv(expected)} — NOT ` +
|
|
322
|
+
`recycling a bridge another daemon owns`);
|
|
323
|
+
throw new BridgeUnavailableError(`the interactive bridge for ${root} is owned by another running crew daemon (pid ${owner}, ${ownerOrigin}) ` +
|
|
324
|
+
`on a different bus or crew API — two daemons cannot share one interactive docs root`, `give this daemon its own interactive root (WICKED_INTERACTIVE_ROOT, or the project's interactiveRoot ` +
|
|
325
|
+
`setting) or stop the other daemon (pid ${owner}); the next request starts a bridge for this one`);
|
|
326
|
+
}
|
|
327
|
+
this.io.log?.(`interactive bridge pid ${live.pid} for ${root} was started by crew${owner !== undefined ? ` (daemon pid ${owner}, gone)` : ''} ` +
|
|
328
|
+
`with ${describeEnv(sidecar.env)}, but this daemon needs ${describeEnv(expected)} — recycling it so its events reach this daemon`);
|
|
329
|
+
await this.terminate(root, live.pid, owner);
|
|
330
|
+
return this.start(root, live.pid);
|
|
331
|
+
}
|
|
332
|
+
if (Object.keys(expected).length > 0) {
|
|
333
|
+
this.io.log?.(`adopting interactive bridge pid ${live.pid} for ${root}, which this daemon did not start: it may not ` +
|
|
334
|
+
`share this daemon's bus or crew API (expected ${describeEnv(expected)}). If documents created ` +
|
|
335
|
+
`through this project stay on their placeholder, stop it (kill ${live.pid}) — the next request ` +
|
|
336
|
+
`restarts it with this daemon's env.`);
|
|
337
|
+
}
|
|
338
|
+
return live;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* SIGTERM, wait up to {@link RECYCLE_GRACE_MS} for exit, SIGKILL whatever ignored it — and then
|
|
342
|
+
* PROVE the pid is gone. Fails closed (codex r4 on crew#506): a refused signal (EPERM) or a pid
|
|
343
|
+
* still in the process table after the hard wait throws a `BridgeUnavailableError` naming the pid
|
|
344
|
+
* and its owner, so no replacement is started beside a bridge that may still be running and the
|
|
345
|
+
* sidecar that records it is never touched. ESRCH is not a failure — the bridge left before we
|
|
346
|
+
* signalled — but even then the pid has to be observed gone.
|
|
347
|
+
*/
|
|
348
|
+
async terminate(root, pid, owner) {
|
|
349
|
+
const kill = this.io.kill ?? ((p, sig) => void process.kill(p, sig));
|
|
350
|
+
const alive = this.io.alive ?? pidAlive;
|
|
351
|
+
const graceMs = this.io.recycleGraceMs ?? RECYCLE_GRACE_MS;
|
|
352
|
+
const hardMs = this.io.recycleHardMs ?? RECYCLE_HARD_MS;
|
|
353
|
+
const who = `interactive bridge pid ${pid} for ${root} (started by crew daemon pid ${owner ?? '?'}, since gone)`;
|
|
354
|
+
const refuse = (why) => {
|
|
355
|
+
this.io.log?.(`could not stop the ${who}: ${why} — NOT starting a replacement beside it`);
|
|
356
|
+
throw new BridgeUnavailableError(`could not stop the ${who}: ${why}; a replacement is not started beside a bridge that may still be running`, `stop it yourself (kill ${pid}) if no other crew daemon is using it, or give this daemon its own interactive ` +
|
|
357
|
+
`root (WICKED_INTERACTIVE_ROOT, or the project's interactiveRoot setting); the next request starts a bridge for this one`);
|
|
358
|
+
};
|
|
359
|
+
const signal = (sig) => {
|
|
360
|
+
try {
|
|
361
|
+
kill(pid, sig);
|
|
362
|
+
}
|
|
363
|
+
catch (err) {
|
|
364
|
+
const code = err.code;
|
|
365
|
+
if (code === 'ESRCH')
|
|
366
|
+
return; // already gone — verified below, never assumed
|
|
367
|
+
refuse(`${sig} was refused (${code ?? err.message})`);
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
signal('SIGTERM');
|
|
371
|
+
const grace = Date.now() + graceMs;
|
|
372
|
+
while (alive(pid) && Date.now() < grace)
|
|
373
|
+
await sleep(50);
|
|
374
|
+
if (alive(pid)) {
|
|
375
|
+
signal('SIGKILL');
|
|
376
|
+
const hard = Date.now() + hardMs;
|
|
377
|
+
while (alive(pid) && Date.now() < hard)
|
|
378
|
+
await sleep(25);
|
|
379
|
+
}
|
|
380
|
+
if (alive(pid))
|
|
381
|
+
refuse(`still running ${graceMs + hardMs} ms after SIGTERM and SIGKILL`);
|
|
382
|
+
}
|
|
172
383
|
/**
|
|
173
384
|
* POST the daemon's own origin to the bridge's `/api/studio-origin` (#298), so the bridge's
|
|
174
385
|
* `GET /` redirects a direct visitor into studio instead of the API-only fallback page.
|
|
@@ -225,7 +436,16 @@ export class InteractiveBridgePool {
|
|
|
225
436
|
}
|
|
226
437
|
return null;
|
|
227
438
|
}
|
|
228
|
-
|
|
439
|
+
/**
|
|
440
|
+
* Spawn a bridge for `root` and wait for it to answer. `replacing` is the pid just recycled
|
|
441
|
+
* (see {@link adoptOrRecycle}). Before the new bridge is used — and before ANY sidecar is
|
|
442
|
+
* written — it has to prove it is ours: not the recycled pid (that bridge was not stopped), and
|
|
443
|
+
* the child this daemon spawned or one of its descendants (`npx` → shell → node, checked through
|
|
444
|
+
* {@link spawnLineage}). A bridge somebody else started under our lockfile while we were
|
|
445
|
+
* starting is refused (and our own spawn abandoned); one whose lineage cannot be read is used
|
|
446
|
+
* but NOT recorded — a sidecar is a claim of ownership, and only a pid this daemon spawned earns it.
|
|
447
|
+
*/
|
|
448
|
+
async start(root, replacing) {
|
|
229
449
|
try {
|
|
230
450
|
// `npx` runs with cwd=root; a missing directory fails the spawn with an opaque error.
|
|
231
451
|
mkdirSync(root, { recursive: true });
|
|
@@ -234,35 +454,88 @@ export class InteractiveBridgePool {
|
|
|
234
454
|
throw new BridgeUnavailableError(`interactive root ${root} is not usable: ${err.message}`, `create the docs root and retry: mkdir -p ${root} && ${serveCommand(root)}`);
|
|
235
455
|
}
|
|
236
456
|
let spawnFailure = null;
|
|
237
|
-
|
|
457
|
+
// F-042/F-043: the bridge gets THIS daemon's crew API and bus location on top of the daemon's
|
|
458
|
+
// own env. The daemon's bound origin wins over an inherited WICKED_CREW_API — the bridge
|
|
459
|
+
// validates project bindings against whatever it is told, and only this daemon has them.
|
|
460
|
+
const bridgeEnv = bridgeEnvFor(this.io);
|
|
461
|
+
const env = { ...process.env, ...bridgeEnv };
|
|
462
|
+
const child = (this.io.spawn ?? defaultSpawn)(root, env);
|
|
463
|
+
const childPid = child.pid; // undefined when the spawn failed synchronously — its 'error' follows
|
|
238
464
|
// Detached + unref: the bridge is a SHARED instance keyed by root, so it must outlive the
|
|
239
465
|
// daemon that happened to start it (and be adoptable by the next one via the lockfile).
|
|
240
466
|
child.on('error', (err) => {
|
|
241
467
|
spawnFailure = err.message;
|
|
242
468
|
});
|
|
243
469
|
child.unref?.();
|
|
470
|
+
const abandon = () => {
|
|
471
|
+
// Our own spawn, and only ever ours: whatever it was about to become is not wanted now.
|
|
472
|
+
try {
|
|
473
|
+
child.kill('SIGTERM');
|
|
474
|
+
}
|
|
475
|
+
catch {
|
|
476
|
+
/* never started, or already gone */
|
|
477
|
+
}
|
|
478
|
+
};
|
|
244
479
|
const deadline = Date.now() + (this.io.startTimeoutMs ?? START_TIMEOUT_MS);
|
|
245
480
|
while (Date.now() < deadline) {
|
|
246
481
|
if (spawnFailure !== null) {
|
|
247
482
|
throw new BridgeUnavailableError(`could not spawn the interactive bridge in ${root}: ${spawnFailure}`, `install Node 22+ so \`npx\` is on PATH, then run: ${serveCommand(root)}`);
|
|
248
483
|
}
|
|
249
484
|
const healthy = await this.healthy(root);
|
|
250
|
-
if (healthy)
|
|
485
|
+
if (healthy) {
|
|
486
|
+
if (replacing !== undefined && healthy.pid === replacing) {
|
|
487
|
+
abandon();
|
|
488
|
+
this.io.log?.(`recycled interactive bridge pid ${replacing} for ${root} is still answering /api/health — it was not stopped`);
|
|
489
|
+
throw new BridgeUnavailableError(`the recycled interactive bridge pid ${replacing} for ${root} is still answering; it was not stopped, so no replacement is started beside it`, `stop it yourself (kill ${replacing}) if no other crew daemon is using it, or give this daemon its own interactive ` +
|
|
490
|
+
`root (WICKED_INTERACTIVE_ROOT, or the project's interactiveRoot setting); the next request starts a bridge for this one`);
|
|
491
|
+
}
|
|
492
|
+
const lineage = childPid === undefined ? 'unknown' : spawnLineage(healthy.pid, childPid, this.io.parentOf ?? parentPidOf);
|
|
493
|
+
if (lineage === 'foreign') {
|
|
494
|
+
abandon();
|
|
495
|
+
this.io.log?.(`interactive bridge pid ${healthy.pid} took ${root}'s lockfile while this daemon was starting one (spawned pid ${childPid}); ` +
|
|
496
|
+
`it is not ours — NOT recording it as crew's, and not using it`);
|
|
497
|
+
throw new BridgeUnavailableError(`a bridge this daemon did not start (pid ${healthy.pid}) took the lockfile in ${root} while this daemon was starting one`, `if that bridge is yours, use it as-is: it is on its own bus and crew API; otherwise stop it (kill ${healthy.pid}) — ` +
|
|
498
|
+
`the next request starts a bridge for this daemon`);
|
|
499
|
+
}
|
|
500
|
+
if (lineage === 'ours') {
|
|
501
|
+
this.writeSidecar(root, healthy.pid, bridgeEnv);
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
this.io.log?.(`cannot tell whether interactive bridge pid ${healthy.pid} for ${root} descends from the child this daemon spawned ` +
|
|
505
|
+
`(pid ${childPid ?? '?'}); using it, but NOT recording it as crew's — a later daemon will adopt it with a warning rather than recycle it`);
|
|
506
|
+
}
|
|
251
507
|
return healthy;
|
|
508
|
+
}
|
|
252
509
|
await sleep(150);
|
|
253
510
|
}
|
|
511
|
+
abandon();
|
|
254
512
|
this.io.log?.(`interactive bridge for ${root} did not come up within the start budget`);
|
|
255
513
|
throw new BridgeUnavailableError(`the interactive bridge for ${root} did not become healthy in time`, `run \`${serveCommand(root)}\` in a terminal to see the failure (or check ${join(root, '.wi-serve.log')})`);
|
|
256
514
|
}
|
|
515
|
+
/** Record which pid crew started and with which env, so a later adopt can tell ours from a
|
|
516
|
+
* sibling daemon's (see {@link adoptOrRecycle}). Only ever called for a pid whose lineage from
|
|
517
|
+
* this daemon's own spawn is PROVEN (see {@link start}). Best-effort: an unwritable sidecar only
|
|
518
|
+
* costs the adopt-time check, never the start. */
|
|
519
|
+
writeSidecar(root, pid, env) {
|
|
520
|
+
const sidecar = { pid, env, startedBy: 'wicked-crew', startedAt: new Date().toISOString(), ownerPid: process.pid };
|
|
521
|
+
try {
|
|
522
|
+
writeFileSync(join(root, CREW_SIDECAR_NAME), JSON.stringify(sidecar, null, 2), 'utf8');
|
|
523
|
+
}
|
|
524
|
+
catch (err) {
|
|
525
|
+
this.io.debug?.(`could not write ${CREW_SIDECAR_NAME} in ${root}: ${err.message}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
257
528
|
}
|
|
258
|
-
/** `npx wicked-interactive serve` in `<root>`, detached, output to the bridge's own log
|
|
259
|
-
|
|
529
|
+
/** `npx wicked-interactive serve` in `<root>`, detached, output to the bridge's own log, with the
|
|
530
|
+
* env the pool computed (the daemon's own plus {@link BridgeEnv}). */
|
|
531
|
+
function defaultSpawn(root, env) {
|
|
260
532
|
// `--yes` is load-bearing: without it npx PROMPTS when the package is not installed, and a
|
|
261
533
|
// daemon has no tty to answer with — the request would hang instead of failing to a 503.
|
|
262
534
|
return nodeSpawn('npx', ['--yes', INTERACTIVE_SPEC, 'serve', '--root', root], {
|
|
263
535
|
cwd: root,
|
|
264
536
|
detached: true,
|
|
265
537
|
stdio: 'ignore',
|
|
538
|
+
env,
|
|
266
539
|
});
|
|
267
540
|
}
|
|
268
541
|
//# sourceMappingURL=bridge-pool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-pool.js","sourceRoot":"","sources":["../../src/interactive/bridge-pool.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bridge-pool.js","sourceRoot":"","sources":["../../src/interactive/bridge-pool.ts"],"names":[],"mappings":"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"}
|