@repo-prism/dispatch-hub 1.9.0 → 1.10.0
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/dashboard/app.css +1 -1
- package/dist/dashboard/app.js +170 -143
- package/dist/dashboard/app.js.map +68 -34
- package/dist/dashboard/hub.css +674 -30
- package/dist/dashboard/index.html +2 -2
- package/dist/playground.d.ts +17 -5
- package/dist/playground.d.ts.map +1 -1
- package/dist/playground.js +68 -13
- package/dist/playground.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +149 -6
- package/dist/server.js.map +1 -1
- package/dist/trees.d.ts +53 -0
- package/dist/trees.d.ts.map +1 -0
- package/dist/trees.js +152 -0
- package/dist/trees.js.map +1 -0
- package/dist/update.d.ts +37 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +146 -0
- package/dist/update.js.map +1 -0
- package/dist/watch.d.ts.map +1 -1
- package/dist/watch.js +31 -13
- package/dist/watch.js.map +1 -1
- package/package.json +4 -4
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>Prism Dispatch</title>
|
|
7
7
|
<link rel="icon" href="/assets/prism-mark.png" />
|
|
8
|
-
<link rel="stylesheet" href="/assets/hub.css?v=
|
|
8
|
+
<link rel="stylesheet" href="/assets/hub.css?v=mtv2ab9j" />
|
|
9
9
|
</head>
|
|
10
10
|
<body class="prism-theme">
|
|
11
11
|
<div id="root"></div>
|
|
12
|
-
<script type="module" src="/assets/app.js?v=
|
|
12
|
+
<script type="module" src="/assets/app.js?v=mtv2ab9j"></script>
|
|
13
13
|
</body>
|
|
14
14
|
</html>
|
package/dist/playground.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Playground Vite on :
|
|
2
|
+
* Playground Vite on :17331 (next to the Console on :17330), parked with the
|
|
3
|
+
* same down page as the Console. 5173 is Vite’s default and collides with
|
|
4
|
+
* other local apps; override with `PRISM_PLAYGROUND_PORT` when needed.
|
|
3
5
|
*
|
|
4
6
|
* Sleep frees the port (kills whatever is listening) and the hub serves
|
|
5
7
|
* “Prism is down”. Wake starts `apps/playground` again when this repo has one.
|
|
6
8
|
*/
|
|
7
9
|
import { type HubEnv } from "./paths.js";
|
|
8
|
-
export declare const PLAYGROUND_PORT =
|
|
10
|
+
export declare const PLAYGROUND_PORT = 17331;
|
|
9
11
|
export type PlaygroundMode = "vite" | "asleep";
|
|
10
12
|
export type PlaygroundRecord = {
|
|
11
13
|
readonly port: number;
|
|
@@ -19,19 +21,29 @@ export type PlaygroundHandle = {
|
|
|
19
21
|
readonly port?: number;
|
|
20
22
|
};
|
|
21
23
|
export declare function playgroundPort(env?: HubEnv): number;
|
|
22
|
-
/** Tests must not steal the user's
|
|
24
|
+
/** Tests must not steal the user's playground port. */
|
|
23
25
|
export declare function effectivePlaygroundPort(env?: HubEnv): number;
|
|
24
26
|
export declare function playgroundViteEnabled(env?: HubEnv): boolean;
|
|
25
27
|
export declare function playgroundRecordPath(env?: HubEnv): string;
|
|
26
|
-
export declare function playgroundUrl(port: number): string;
|
|
27
|
-
|
|
28
|
+
export declare function playgroundUrl(port: number, env?: HubEnv): string;
|
|
29
|
+
/** Bind/health checks stay on loopback — the daemon listens on 127.0.0.1. */
|
|
30
|
+
export declare function playgroundBindUrl(port: number): string;
|
|
31
|
+
export declare function findPlaygroundApp(workspaceRoot: string, extraRoots?: readonly string[]): Promise<string | undefined>;
|
|
32
|
+
/**
|
|
33
|
+
* Where Vite actually lives: the requested repo, other registered
|
|
34
|
+
* workspaces, `PRISM_PLAYGROUND_ROOT`, then this Prism checkout. Tests stay
|
|
35
|
+
* isolated — they only see the workspace unless they opt in.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolvePlaygroundApp(workspaceRoot: string, extraRoots?: readonly string[], env?: HubEnv): Promise<string | undefined>;
|
|
28
38
|
export declare function readPlaygroundRecord(env?: HubEnv): Promise<PlaygroundRecord | undefined>;
|
|
29
39
|
export declare function writePlaygroundRecord(env: HubEnv, record: PlaygroundRecord): Promise<void>;
|
|
30
40
|
export declare function pidsOnPort(port: number): Promise<number[]>;
|
|
31
41
|
export declare function stopPlaygroundListeners(port: number, extraPid?: number): Promise<void>;
|
|
32
42
|
export declare function spawnPlaygroundVite(input: {
|
|
33
43
|
readonly workspaceRoot: string;
|
|
44
|
+
readonly extraRoots?: readonly string[];
|
|
34
45
|
readonly env?: HubEnv;
|
|
46
|
+
readonly port?: number;
|
|
35
47
|
}): Promise<{
|
|
36
48
|
pid: number;
|
|
37
49
|
} | undefined>;
|
package/dist/playground.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAwB,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAK/D,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAoB,GAAG,MAAM,CAKhE;AAED,uDAAuD;AACvD,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAoB,GAAG,MAAM,CAIzE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAoB,GAAG,OAAO,CASxE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,GAAE,MAAoB,GAAG,MAAM,CAEtE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAoB,GAAG,MAAM,CAE7E;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAWD,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,MAAM,EACrB,UAAU,GAAE,SAAS,MAAM,EAAO,GACjC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW7B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,UAAU,GAAE,SAAS,MAAM,EAAO,EAClC,GAAG,GAAE,MAAoB,GACxB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAa7B;AAED,wBAAsB,oBAAoB,CACxC,GAAG,GAAE,MAAoB,GACxB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAYvC;AAED,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAehE;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAIf;AAgBD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CAsCvC;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAO,KAAa,EAC/B,MAAM,SAAS,GACd,OAAO,CAAC,OAAO,CAAC,CASlB"}
|
package/dist/playground.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Playground Vite on :
|
|
2
|
+
* Playground Vite on :17331 (next to the Console on :17330), parked with the
|
|
3
|
+
* same down page as the Console. 5173 is Vite’s default and collides with
|
|
4
|
+
* other local apps; override with `PRISM_PLAYGROUND_PORT` when needed.
|
|
3
5
|
*
|
|
4
6
|
* Sleep frees the port (kills whatever is listening) and the hub serves
|
|
5
7
|
* “Prism is down”. Wake starts `apps/playground` again when this repo has one.
|
|
@@ -8,10 +10,11 @@ import { execFile, spawn } from "node:child_process";
|
|
|
8
10
|
import { promisify } from "node:util";
|
|
9
11
|
import { access } from "node:fs/promises";
|
|
10
12
|
import { join } from "node:path";
|
|
11
|
-
import {
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { consoleHost, hubHome } from "./paths.js";
|
|
12
15
|
import { readJsonFile, writeJsonFile } from "./json-file.js";
|
|
13
16
|
const execFileAsync = promisify(execFile);
|
|
14
|
-
export const PLAYGROUND_PORT =
|
|
17
|
+
export const PLAYGROUND_PORT = 17331;
|
|
15
18
|
export function playgroundPort(env = process.env) {
|
|
16
19
|
const raw = env.PRISM_PLAYGROUND_PORT?.trim();
|
|
17
20
|
if (raw === "0")
|
|
@@ -19,7 +22,7 @@ export function playgroundPort(env = process.env) {
|
|
|
19
22
|
const parsed = raw ? Number.parseInt(raw, 10) : PLAYGROUND_PORT;
|
|
20
23
|
return Number.isInteger(parsed) && parsed >= 0 ? parsed : PLAYGROUND_PORT;
|
|
21
24
|
}
|
|
22
|
-
/** Tests must not steal the user's
|
|
25
|
+
/** Tests must not steal the user's playground port. */
|
|
23
26
|
export function effectivePlaygroundPort(env = process.env) {
|
|
24
27
|
if (env.PRISM_PLAYGROUND_PORT?.trim())
|
|
25
28
|
return playgroundPort(env);
|
|
@@ -39,19 +42,57 @@ export function playgroundViteEnabled(env = process.env) {
|
|
|
39
42
|
export function playgroundRecordPath(env = process.env) {
|
|
40
43
|
return join(hubHome(env), "playground.json");
|
|
41
44
|
}
|
|
42
|
-
export function playgroundUrl(port) {
|
|
45
|
+
export function playgroundUrl(port, env = process.env) {
|
|
46
|
+
return `http://${consoleHost(env)}:${port}/`;
|
|
47
|
+
}
|
|
48
|
+
/** Bind/health checks stay on loopback — the daemon listens on 127.0.0.1. */
|
|
49
|
+
export function playgroundBindUrl(port) {
|
|
43
50
|
return `http://127.0.0.1:${port}/`;
|
|
44
51
|
}
|
|
45
|
-
|
|
46
|
-
const candidate = join(workspaceRoot, "apps", "playground");
|
|
52
|
+
async function playgroundPackageAt(dir) {
|
|
47
53
|
try {
|
|
48
|
-
await access(join(
|
|
49
|
-
return
|
|
54
|
+
await access(join(dir, "package.json"));
|
|
55
|
+
return dir;
|
|
50
56
|
}
|
|
51
57
|
catch {
|
|
52
58
|
return undefined;
|
|
53
59
|
}
|
|
54
60
|
}
|
|
61
|
+
export async function findPlaygroundApp(workspaceRoot, extraRoots = []) {
|
|
62
|
+
const roots = [workspaceRoot, ...extraRoots].filter((root) => root.trim());
|
|
63
|
+
const seen = new Set();
|
|
64
|
+
for (const root of roots) {
|
|
65
|
+
const candidate = join(root, "apps", "playground");
|
|
66
|
+
if (seen.has(candidate))
|
|
67
|
+
continue;
|
|
68
|
+
seen.add(candidate);
|
|
69
|
+
const found = await playgroundPackageAt(candidate);
|
|
70
|
+
if (found)
|
|
71
|
+
return found;
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Where Vite actually lives: the requested repo, other registered
|
|
77
|
+
* workspaces, `PRISM_PLAYGROUND_ROOT`, then this Prism checkout. Tests stay
|
|
78
|
+
* isolated — they only see the workspace unless they opt in.
|
|
79
|
+
*/
|
|
80
|
+
export async function resolvePlaygroundApp(workspaceRoot, extraRoots = [], env = process.env) {
|
|
81
|
+
const found = await findPlaygroundApp(workspaceRoot, extraRoots);
|
|
82
|
+
if (found)
|
|
83
|
+
return found;
|
|
84
|
+
const override = env.PRISM_PLAYGROUND_ROOT?.trim();
|
|
85
|
+
if (override) {
|
|
86
|
+
const fromOverride = (await playgroundPackageAt(override)) ??
|
|
87
|
+
(await findPlaygroundApp(override));
|
|
88
|
+
if (fromOverride)
|
|
89
|
+
return fromOverride;
|
|
90
|
+
}
|
|
91
|
+
if (env.VITEST === "true" || process.env.VITEST === "true")
|
|
92
|
+
return undefined;
|
|
93
|
+
const hubRepo = fileURLToPath(new URL("../../..", import.meta.url));
|
|
94
|
+
return findPlaygroundApp(hubRepo);
|
|
95
|
+
}
|
|
55
96
|
export async function readPlaygroundRecord(env = process.env) {
|
|
56
97
|
const file = await readJsonFile(playgroundRecordPath(env), null);
|
|
57
98
|
if (!file || typeof file.port !== "number")
|
|
@@ -105,10 +146,23 @@ function stopPid(pid) {
|
|
|
105
146
|
}
|
|
106
147
|
}
|
|
107
148
|
export async function spawnPlaygroundVite(input) {
|
|
108
|
-
const
|
|
149
|
+
const env = input.env ?? process.env;
|
|
150
|
+
const port = input.port ?? playgroundPort(env);
|
|
151
|
+
if (port <= 0)
|
|
152
|
+
return undefined;
|
|
153
|
+
const app = await resolvePlaygroundApp(input.workspaceRoot, input.extraRoots ?? [], env);
|
|
109
154
|
if (!app)
|
|
110
155
|
return undefined;
|
|
111
|
-
const child = spawn("bun", [
|
|
156
|
+
const child = spawn("bun", [
|
|
157
|
+
"run",
|
|
158
|
+
"dev",
|
|
159
|
+
"--",
|
|
160
|
+
"--port",
|
|
161
|
+
String(port),
|
|
162
|
+
"--strictPort",
|
|
163
|
+
"--host",
|
|
164
|
+
"127.0.0.1",
|
|
165
|
+
], {
|
|
112
166
|
cwd: app,
|
|
113
167
|
detached: true,
|
|
114
168
|
stdio: "ignore",
|
|
@@ -116,6 +170,7 @@ export async function spawnPlaygroundVite(input) {
|
|
|
116
170
|
...process.env,
|
|
117
171
|
...input.env,
|
|
118
172
|
PRISM_PLAYGROUND_ROOT: input.workspaceRoot,
|
|
173
|
+
PRISM_PLAYGROUND_PORT: String(port),
|
|
119
174
|
},
|
|
120
175
|
windowsHide: true,
|
|
121
176
|
});
|
|
@@ -128,7 +183,7 @@ export async function playgroundIsLive(port, fetchImpl = fetch) {
|
|
|
128
183
|
if (port <= 0)
|
|
129
184
|
return false;
|
|
130
185
|
try {
|
|
131
|
-
const response = await fetchImpl(
|
|
186
|
+
const response = await fetchImpl(playgroundBindUrl(port), {
|
|
132
187
|
signal: AbortSignal.timeout(800),
|
|
133
188
|
});
|
|
134
189
|
if (!response.ok)
|
|
@@ -144,7 +199,7 @@ export async function playgroundIsDownPage(port, fetchImpl = fetch) {
|
|
|
144
199
|
if (port <= 0)
|
|
145
200
|
return false;
|
|
146
201
|
try {
|
|
147
|
-
const response = await fetchImpl(
|
|
202
|
+
const response = await fetchImpl(playgroundBindUrl(port), {
|
|
148
203
|
signal: AbortSignal.timeout(800),
|
|
149
204
|
});
|
|
150
205
|
if (!response.ok)
|
package/dist/playground.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playground.js","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"playground.js","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAe,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE7D,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAiBrC,MAAM,UAAU,cAAc,CAAC,MAAc,OAAO,CAAC,GAAG;IACtD,MAAM,GAAG,GAAG,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAC;IAC9C,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,CAAC,CAAC;IAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;IAChE,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC;AAC5E,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,uBAAuB,CAAC,MAAc,OAAO,CAAC,GAAG;IAC/D,IAAI,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE;QAAE,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;IAClE,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc,OAAO,CAAC,GAAG;IAC7D,IAAI,GAAG,CAAC,gBAAgB,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAC/C,IACE,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC;QACxD,GAAG,CAAC,gBAAgB,KAAK,GAAG,EAC5B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc,OAAO,CAAC,GAAG;IAC5D,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAc,OAAO,CAAC,GAAG;IACnE,OAAO,UAAU,WAAW,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC;AAC/C,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,oBAAoB,IAAI,GAAG,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,GAAW;IAC5C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;QACxC,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,aAAqB,EACrB,aAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,CAAC,aAAa,EAAE,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,SAAS;QAClC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,aAAqB,EACrB,aAAgC,EAAE,EAClC,MAAc,OAAO,CAAC,GAAG;IAEzB,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACjE,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,QAAQ,GAAG,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,YAAY,GAChB,CAAC,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACrC,CAAC,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtC,IAAI,YAAY;YAAE,OAAO,YAAY,CAAC;IACxC,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IAC7E,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAc,OAAO,CAAC,GAAG;IAEzB,MAAM,IAAI,GAAG,MAAM,YAAY,CAC7B,oBAAoB,CAAC,GAAG,CAAC,EACzB,IAAI,CACL,CAAC;IACF,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC7D,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACrE,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3D,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAW,EACX,MAAwB;IAExB,MAAM,aAAa,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,MAAM,EACN,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,EAC9C,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAC;QACF,OAAO,MAAM;aACV,KAAK,CAAC,KAAK,CAAC;aACZ,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;aACtC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAY,EACZ,QAAiB;IAEjB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrD,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG;QAAE,OAAO;IACtE,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IACD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAKzC;IACC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,GAAG,GAAG,MAAM,oBAAoB,CACpC,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,UAAU,IAAI,EAAE,EACtB,GAAG,CACJ,CAAC;IACF,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CACjB,KAAK,EACL;QACE,KAAK;QACL,KAAK;QACL,IAAI;QACJ,QAAQ;QACR,MAAM,CAAC,IAAI,CAAC;QACZ,cAAc;QACd,QAAQ;QACR,WAAW;KACZ,EACD;QACE,GAAG,EAAE,GAAG;QACR,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,QAAQ;QACf,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,GAAI,KAAK,CAAC,GAAyB;YACnC,qBAAqB,EAAE,KAAK,CAAC,aAAa;YAC1C,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC;SACpC;QACD,WAAW,EAAE,IAAI;KAClB,CACF,CAAC;IACF,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACpD,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,YAA0B,KAAK;IAE/B,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE;YACxD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC;SACjC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,YAA0B,KAAK;IAE/B,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE;YACxD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC;SACjC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAY,EACZ,YAA0B,KAAK,EAC/B,MAAM,GAAG,MAAM;IAEf,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;IACrC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,MAAM,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QACzD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC5B,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAUA,OAAO,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAUA,OAAO,EAwBL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAS9B,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,EAAyB,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAuBhE,OAAO,KAAK,EAEV,SAAS,EAIV,MAAM,YAAY,CAAC;AAiBpB,MAAM,MAAM,YAAY,GAAG,CACzB,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,MAAM,UAAU,GAAG,CACvB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,oEAAoE;IACpE,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxD,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QAClC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;KACjC,KAAK,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;IAC5C,uEAAuE;IACvE,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,aAAa,EAAE,MAAM,KAClB,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC,CAAC;AAsEF,wBAAsB,QAAQ,CAC5B,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,UAAU,GAAG;IAAE,cAAc,EAAE,IAAI,CAAA;CAAE,CAAC,CAi+BhD"}
|
package/dist/server.js
CHANGED
|
@@ -3,7 +3,7 @@ import { access } from "node:fs/promises";
|
|
|
3
3
|
import { createReadStream } from "node:fs";
|
|
4
4
|
import { dirname, extname, join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { createClaudeWorkerPort, createCursorWorkerPort, createDispatchRuntime, DispatchConfigSchema, discoverHostConnectors, vendorCoverage, drainWorkspace, loadConfig, listWorkerModels, requestedWorkerModel, resolveWorkerBackend, getJob, upsertJob, readRunLog, saveConfig, asleepPageHtml, isPrismAsleep, isPrismAsleepSync, } from "@repo-prism/dispatch";
|
|
6
|
+
import { createClaudeWorkerPort, createCursorWorkerPort, createDispatchRuntime, DispatchConfigSchema, discoverHostConnectors, vendorCoverage, drainWorkspace, loadConfig, listWorkerModels, requestedWorkerModel, resolveWorkerBackend, getJob, upsertJob, readRunLog, saveConfig, asleepPageHtml, isPrismAsleep, isPrismAsleepSync, listSkills, writeSkill, deleteSkill, duplicateSkill, } from "@repo-prism/dispatch";
|
|
7
7
|
import { parseHostRequest } from "@repo-prism/host-session/protocol";
|
|
8
8
|
import { originAllowed, tokenFromRequest, tokensMatch, hubCookieHeader, } from "./auth.js";
|
|
9
9
|
import { createIdleTimer, IDLE_MS } from "./idle.js";
|
|
@@ -14,7 +14,9 @@ import { listJobNotes, readJobNote } from "./notes.js";
|
|
|
14
14
|
import { createOsNotifier } from "./notify.js";
|
|
15
15
|
import { readHostTelemetry } from "./host-telemetry.js";
|
|
16
16
|
import { dashboardUrl, hubPort } from "./paths.js";
|
|
17
|
-
import { PLAYGROUND_PORT, effectivePlaygroundPort,
|
|
17
|
+
import { PLAYGROUND_PORT, effectivePlaygroundPort, playgroundIsLive, playgroundUrl, playgroundViteEnabled, resolvePlaygroundApp, spawnPlaygroundVite, stopPlaygroundListeners, waitForPlaygroundLive, writePlaygroundRecord, } from "./playground.js";
|
|
18
|
+
import { collectRepoTrees, runTreeAction } from "./trees.js";
|
|
19
|
+
import { mcpUpdateStatus, applyMcpUpdate } from "./update.js";
|
|
18
20
|
import { HUB_ERROR, publicCaughtError } from "./api-errors.js";
|
|
19
21
|
import { pickLocalFolder } from "./pick-folder.js";
|
|
20
22
|
import { dropMissingWorkspaces, registerWorkspace, unregisterWorkspace, workspaceLabel, } from "./registry.js";
|
|
@@ -148,7 +150,12 @@ export async function startHub(options = {}) {
|
|
|
148
150
|
const wantedPlaygroundPort = effectivePlaygroundPort(env);
|
|
149
151
|
const spawnPlayground = options.spawnPlayground ??
|
|
150
152
|
(async (workspaceRoot) => playgroundViteEnabled(env)
|
|
151
|
-
? spawnPlaygroundVite({
|
|
153
|
+
? spawnPlaygroundVite({
|
|
154
|
+
workspaceRoot,
|
|
155
|
+
extraRoots: workspaces.map((row) => row.path),
|
|
156
|
+
env,
|
|
157
|
+
port: wantedPlaygroundPort || PLAYGROUND_PORT,
|
|
158
|
+
})
|
|
152
159
|
: undefined);
|
|
153
160
|
const stopPlaygroundPort = async () => {
|
|
154
161
|
if (playgroundHttp) {
|
|
@@ -213,7 +220,8 @@ export async function startHub(options = {}) {
|
|
|
213
220
|
await writePlaygroundRecord(env, { port, mode: "vite" });
|
|
214
221
|
return { ok: true, port, url, detail: "Playground is up." };
|
|
215
222
|
}
|
|
216
|
-
const
|
|
223
|
+
const extraRoots = workspaces.map((row) => row.path);
|
|
224
|
+
const app = await resolvePlaygroundApp(workspaceRoot, extraRoots, env);
|
|
217
225
|
if (!app) {
|
|
218
226
|
return {
|
|
219
227
|
ok: false,
|
|
@@ -245,7 +253,12 @@ export async function startHub(options = {}) {
|
|
|
245
253
|
// left `queued`, and re-checks jobs parked behind the concurrency cap.
|
|
246
254
|
const watcher = watchWorkspaces(() => workspaces, onEvent, {
|
|
247
255
|
pollMs: options.pollMs,
|
|
248
|
-
drain:
|
|
256
|
+
// Vitest must not spawn a worker drain: it races GET /api/jobs and can
|
|
257
|
+
// keep `.prism/dispatch` open so afterEach cannot remove the fixture.
|
|
258
|
+
drain: options.drain ??
|
|
259
|
+
(process.env.VITEST === "true"
|
|
260
|
+
? undefined
|
|
261
|
+
: (workspace) => defaultDrain(workspace, env)),
|
|
249
262
|
});
|
|
250
263
|
const idle = createIdleTimer({
|
|
251
264
|
idleMs: options.idleMs ?? IDLE_MS,
|
|
@@ -459,6 +472,12 @@ export async function startHub(options = {}) {
|
|
|
459
472
|
...(body.placement === "worktree" || body.placement === "checkout"
|
|
460
473
|
? { placement: body.placement }
|
|
461
474
|
: {}),
|
|
475
|
+
...(typeof body.branch === "string" && body.branch.trim()
|
|
476
|
+
? { branch: String(body.branch).trim() }
|
|
477
|
+
: {}),
|
|
478
|
+
...(typeof body.worktreePath === "string" && body.worktreePath.trim()
|
|
479
|
+
? { worktreePath: String(body.worktreePath).trim() }
|
|
480
|
+
: {}),
|
|
462
481
|
...(body.workerBackend === "cursor" || body.workerBackend === "claude"
|
|
463
482
|
? { workerBackend: body.workerBackend }
|
|
464
483
|
: {}),
|
|
@@ -512,6 +531,7 @@ export async function startHub(options = {}) {
|
|
|
512
531
|
return;
|
|
513
532
|
}
|
|
514
533
|
if (req.method === "GET" && url.pathname === "/api/jobs") {
|
|
534
|
+
await watcher.refresh({ drain: false });
|
|
515
535
|
json(res, 200, {
|
|
516
536
|
jobs: [...watcher.jobs()],
|
|
517
537
|
asOf: watcher.asOf(),
|
|
@@ -519,6 +539,129 @@ export async function startHub(options = {}) {
|
|
|
519
539
|
});
|
|
520
540
|
return;
|
|
521
541
|
}
|
|
542
|
+
if (req.method === "GET" && url.pathname === "/api/trees") {
|
|
543
|
+
const filter = url.searchParams.get("workspace")?.trim();
|
|
544
|
+
const listed = filter
|
|
545
|
+
? workspaces.filter((entry) => entry.path === filter)
|
|
546
|
+
: workspaces;
|
|
547
|
+
const repos = await Promise.all(listed.map((entry) => collectRepoTrees({
|
|
548
|
+
workspacePath: entry.path,
|
|
549
|
+
label: entry.label,
|
|
550
|
+
jobs: jobs.filter((job) => job.workspacePath === entry.path),
|
|
551
|
+
})));
|
|
552
|
+
json(res, 200, { repos });
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
if (req.method === "POST" && url.pathname === "/api/trees") {
|
|
556
|
+
const body = await readBody(req);
|
|
557
|
+
const workspace = String(body.workspace ?? "").trim() || workspaces[0]?.path || "";
|
|
558
|
+
const treePath = String(body.treePath ?? "").trim();
|
|
559
|
+
const action = String(body.action ?? "").trim();
|
|
560
|
+
if (!workspace ||
|
|
561
|
+
!treePath ||
|
|
562
|
+
(action !== "merge" &&
|
|
563
|
+
action !== "commit" &&
|
|
564
|
+
action !== "push" &&
|
|
565
|
+
action !== "remove")) {
|
|
566
|
+
json(res, 400, { error: HUB_ERROR.actionRequired });
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
try {
|
|
570
|
+
const result = await runTreeAction({
|
|
571
|
+
workspacePath: workspace,
|
|
572
|
+
treePath,
|
|
573
|
+
action,
|
|
574
|
+
...(String(body.branch ?? "").trim()
|
|
575
|
+
? { branch: String(body.branch).trim() }
|
|
576
|
+
: {}),
|
|
577
|
+
...(String(body.jobId ?? "").trim()
|
|
578
|
+
? { jobId: String(body.jobId).trim() }
|
|
579
|
+
: {}),
|
|
580
|
+
...(String(body.title ?? "").trim()
|
|
581
|
+
? { title: String(body.title).trim() }
|
|
582
|
+
: {}),
|
|
583
|
+
});
|
|
584
|
+
json(res, result.ok ? 200 : 400, result);
|
|
585
|
+
}
|
|
586
|
+
catch (cause) {
|
|
587
|
+
json(res, 500, { error: publicCaughtError(cause) });
|
|
588
|
+
}
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
if (req.method === "GET" && url.pathname === "/api/skills") {
|
|
592
|
+
json(res, 200, { skills: await listSkills(env) });
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
if (req.method === "POST" && url.pathname === "/api/skills") {
|
|
596
|
+
const body = await readBody(req);
|
|
597
|
+
const action = String(body.action ?? "save").trim();
|
|
598
|
+
try {
|
|
599
|
+
if (action === "delete") {
|
|
600
|
+
const ok = await deleteSkill(String(body.name ?? ""), env);
|
|
601
|
+
json(res, ok ? 200 : 400, {
|
|
602
|
+
ok,
|
|
603
|
+
detail: ok ? "Deleted." : "Could not delete that skill.",
|
|
604
|
+
});
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
if (action === "duplicate") {
|
|
608
|
+
const copied = await duplicateSkill(String(body.name ?? ""), env);
|
|
609
|
+
if ("error" in copied) {
|
|
610
|
+
json(res, 400, copied);
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
json(res, 200, copied);
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
const saved = await writeSkill({
|
|
617
|
+
name: String(body.name ?? ""),
|
|
618
|
+
description: String(body.description ?? ""),
|
|
619
|
+
body: String(body.body ?? ""),
|
|
620
|
+
status: body.status === "published" ? "published" : "draft",
|
|
621
|
+
}, env);
|
|
622
|
+
if ("error" in saved) {
|
|
623
|
+
json(res, 400, saved);
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
json(res, 200, saved);
|
|
627
|
+
}
|
|
628
|
+
catch (cause) {
|
|
629
|
+
json(res, 500, { error: publicCaughtError(cause) });
|
|
630
|
+
}
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
if (req.method === "GET" && url.pathname === "/api/update") {
|
|
634
|
+
if (process.env.VITEST === "true") {
|
|
635
|
+
json(res, 200, {
|
|
636
|
+
current: version,
|
|
637
|
+
stale: false,
|
|
638
|
+
localCheckout: true,
|
|
639
|
+
hop: "current",
|
|
640
|
+
});
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
json(res, 200, await mcpUpdateStatus(version));
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
if (req.method === "POST" && url.pathname === "/api/update") {
|
|
647
|
+
if (process.env.VITEST === "true") {
|
|
648
|
+
json(res, 200, {
|
|
649
|
+
ok: true,
|
|
650
|
+
current: version,
|
|
651
|
+
cached: false,
|
|
652
|
+
localCheckout: true,
|
|
653
|
+
message: "Already on this build.",
|
|
654
|
+
});
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
try {
|
|
658
|
+
json(res, 200, await applyMcpUpdate(version));
|
|
659
|
+
}
|
|
660
|
+
catch (cause) {
|
|
661
|
+
json(res, 500, { error: publicCaughtError(cause) });
|
|
662
|
+
}
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
522
665
|
// The Repos plane needs to tell "no repositories registered" apart from
|
|
523
666
|
// "registered, but no jobs" — two very different things the old board
|
|
524
667
|
// rendered as one empty sentence (ADR-0048).
|
|
@@ -636,7 +779,7 @@ export async function startHub(options = {}) {
|
|
|
636
779
|
return;
|
|
637
780
|
}
|
|
638
781
|
workspaces = await registerWorkspace(path, env);
|
|
639
|
-
|
|
782
|
+
await watcher.refresh({ drain: false });
|
|
640
783
|
json(res, 200, { workspaces });
|
|
641
784
|
return;
|
|
642
785
|
}
|