@unbrained/pm-web 2026.7.11 → 2026.7.13
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/CHANGELOG.md +13 -0
- package/README.md +26 -0
- package/dist/app.d.ts +1 -0
- package/dist/app.js +38 -2
- package/dist/app.js.map +1 -1
- package/dist/auth.d.ts +2 -1
- package/dist/auth.js +10 -0
- package/dist/auth.js.map +1 -1
- package/dist/db.js +17 -1
- package/dist/db.js.map +1 -1
- package/dist/ical.js.map +1 -1
- package/dist/index.d.ts +1 -22
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/oidc.d.ts +89 -0
- package/dist/oidc.js +305 -0
- package/dist/oidc.js.map +1 -0
- package/dist/routes/auth.js +3 -15
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/github.js +3 -3
- package/dist/routes/github.js.map +1 -1
- package/dist/routes/oidc.d.ts +4 -0
- package/dist/routes/oidc.js +147 -0
- package/dist/routes/oidc.js.map +1 -0
- package/dist/routes/pm.js +121 -107
- package/dist/routes/pm.js.map +1 -1
- package/dist/routes/projects.js +9 -2
- package/dist/routes/projects.js.map +1 -1
- package/dist/server.js +7 -2
- package/dist/server.js.map +1 -1
- package/dist/services/pm-runner.d.ts +11 -3
- package/dist/services/pm-runner.js +167 -54
- package/dist/services/pm-runner.js.map +1 -1
- package/dist/services/realtime-bus.d.ts +1 -0
- package/dist/services/realtime-bus.js +148 -0
- package/dist/services/realtime-bus.js.map +1 -0
- package/dist/services/sse.d.ts +3 -1
- package/dist/services/sse.js +83 -48
- package/dist/services/sse.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +11 -11
- package/public/cookie-consent.js +54 -39
- package/public/cookie-settings.html +7 -7
- package/public/index.html +2 -0
- package/public/legal-notice.html +10 -12
- package/public/privacy-policy.html +14 -24
- package/public/src/app.js +4 -4
- package/public/src/app.js.map +1 -1
- package/public/src/app.ts +4 -4
- package/public/src/components/toast.js.map +1 -1
- package/public/src/cookie-consent.ts +68 -0
- package/public/src/sw.ts +443 -0
- package/public/src/views/auth.js +22 -0
- package/public/src/views/auth.js.map +1 -1
- package/public/src/views/auth.ts +20 -0
- package/public/src/views/graph.js.map +1 -1
- package/public/styles.css +2 -0
- package/public/sw.js +320 -256
- package/public/terms.html +7 -9
- package/public/tsconfig.json +1 -1
- package/public/tsconfig.scripts.json +18 -0
- package/public/tsconfig.sw.json +18 -0
- package/sql/schema.sql +16 -0
package/dist/server.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { initSchema, assertDbConfigured } from "./db.js";
|
|
2
2
|
import { createApp } from "./app.js";
|
|
3
3
|
import { cleanupStaleClients } from "./services/sse.js";
|
|
4
|
+
import { startRealtimeBus } from "./services/realtime-bus.js";
|
|
5
|
+
import { assertOidcConfiguration } from "./oidc.js";
|
|
4
6
|
const PORT = parseInt(process.env.PORT || "4000", 10);
|
|
5
7
|
const app = createApp();
|
|
6
8
|
// Validate configuration before doing anything that needs the database, so a
|
|
@@ -8,6 +10,7 @@ const app = createApp();
|
|
|
8
10
|
// DNS/connection timeout.
|
|
9
11
|
try {
|
|
10
12
|
assertDbConfigured();
|
|
13
|
+
assertOidcConfiguration();
|
|
11
14
|
}
|
|
12
15
|
catch (err) {
|
|
13
16
|
console.error(err instanceof Error ? err.message : String(err));
|
|
@@ -15,7 +18,8 @@ catch (err) {
|
|
|
15
18
|
}
|
|
16
19
|
// Init DB schema, then start server
|
|
17
20
|
initSchema()
|
|
18
|
-
.then(() => {
|
|
21
|
+
.then(async () => {
|
|
22
|
+
const closeRealtimeBus = await startRealtimeBus();
|
|
19
23
|
// Express 5 invokes the listen callback WITH the error (it is installed
|
|
20
24
|
// as the server's 'error' handler), so ignoring the argument turns
|
|
21
25
|
// EADDRINUSE into a false "running" message and a process that idles
|
|
@@ -31,11 +35,12 @@ initSchema()
|
|
|
31
35
|
console.error(`Server error on :${PORT}:`, err.message);
|
|
32
36
|
process.exit(1);
|
|
33
37
|
});
|
|
38
|
+
server.on("close", () => { void closeRealtimeBus(); });
|
|
34
39
|
// Periodic cleanup of stale SSE clients
|
|
35
40
|
setInterval(cleanupStaleClients, 5 * 60 * 1000);
|
|
36
41
|
})
|
|
37
42
|
.catch((err) => {
|
|
38
|
-
console.error("Failed to initialize
|
|
43
|
+
console.error("Failed to initialize pm-web runtime:", err instanceof Error ? err.message : err);
|
|
39
44
|
process.exit(1);
|
|
40
45
|
});
|
|
41
46
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAEtD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;AAExB,6EAA6E;AAC7E,+EAA+E;AAC/E,0BAA0B;AAC1B,IAAI,CAAC;IACH,kBAAkB,EAAE,CAAC;IACrB,uBAAuB,EAAE,CAAC;AAC5B,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,oCAAoC;AACpC,UAAU,EAAE;KACT,IAAI,CAAC,KAAK,IAAI,EAAE;IACf,MAAM,gBAAgB,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAClD,wEAAwE;IACxE,mEAAmE;IACnE,qEAAqE;IACrE,mCAAmC;IACnC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE;QAC9C,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,CAAC,KAAK,CAAC,mBAAmB,IAAI,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;QAChC,OAAO,CAAC,KAAK,CAAC,oBAAoB,IAAI,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,wCAAwC;IACxC,WAAW,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAClD,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACb,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
export declare class Semaphore {
|
|
2
|
+
private readonly limit;
|
|
3
|
+
private active;
|
|
4
|
+
private readonly waiting;
|
|
5
|
+
constructor(limit: number);
|
|
6
|
+
acquire(): Promise<() => void>;
|
|
7
|
+
}
|
|
1
8
|
export declare function getProjectDir(userId: string, slug: string): string;
|
|
2
|
-
export declare function initProject(userId: string, slug: string, prefix: string): void
|
|
9
|
+
export declare function initProject(userId: string, slug: string, prefix: string): Promise<void>;
|
|
3
10
|
export declare function projectExists(userId: string, slug: string): boolean;
|
|
4
11
|
export interface PmRunOptions {
|
|
5
12
|
args: string[];
|
|
@@ -7,6 +14,7 @@ export interface PmRunOptions {
|
|
|
7
14
|
slug: string;
|
|
8
15
|
input?: string;
|
|
9
16
|
jsonOutput?: boolean;
|
|
17
|
+
timeoutMs?: number;
|
|
10
18
|
}
|
|
11
19
|
export interface PmRunResult {
|
|
12
20
|
stdout: string;
|
|
@@ -20,6 +28,6 @@ export interface EnsureGraphExtensionResult {
|
|
|
20
28
|
active: boolean;
|
|
21
29
|
error?: string;
|
|
22
30
|
}
|
|
23
|
-
export declare function ensureGraphExtension(userId: string, slug: string): EnsureGraphExtensionResult
|
|
24
|
-
export declare function runPm(opts: PmRunOptions): PmRunResult
|
|
31
|
+
export declare function ensureGraphExtension(userId: string, slug: string): Promise<EnsureGraphExtensionResult>;
|
|
32
|
+
export declare function runPm(opts: PmRunOptions): Promise<PmRunResult>;
|
|
25
33
|
export declare function deleteProjectDir(userId: string, slug: string): void;
|
|
@@ -1,7 +1,44 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
const
|
|
4
|
+
const DEFAULT_COMMAND_TIMEOUT_MS = 30_000;
|
|
5
|
+
const MAX_OUTPUT_BYTES = 32 * 1024 * 1024;
|
|
6
|
+
function positiveInteger(value, fallback) {
|
|
7
|
+
const parsed = Number.parseInt(value ?? "", 10);
|
|
8
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
9
|
+
}
|
|
10
|
+
export class Semaphore {
|
|
11
|
+
limit;
|
|
12
|
+
active = 0;
|
|
13
|
+
waiting = [];
|
|
14
|
+
constructor(limit) {
|
|
15
|
+
this.limit = limit;
|
|
16
|
+
}
|
|
17
|
+
async acquire() {
|
|
18
|
+
if (this.active >= this.limit) {
|
|
19
|
+
await new Promise((resolve) => this.waiting.push(resolve));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.active += 1;
|
|
23
|
+
}
|
|
24
|
+
let released = false;
|
|
25
|
+
return () => {
|
|
26
|
+
if (released)
|
|
27
|
+
return;
|
|
28
|
+
released = true;
|
|
29
|
+
const next = this.waiting.shift();
|
|
30
|
+
if (next)
|
|
31
|
+
next();
|
|
32
|
+
else
|
|
33
|
+
this.active -= 1;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const commandSlots = new Semaphore(positiveInteger(process.env.PM_WEB_PM_CONCURRENCY, 8));
|
|
38
|
+
const workspaceTails = new Map();
|
|
39
|
+
function projectsRoot() {
|
|
40
|
+
return process.env.PROJECTS_ROOT || "/app/projects";
|
|
41
|
+
}
|
|
5
42
|
const OLLAMA_BASE_URL = process.env.OLLAMA_BASE_URL ||
|
|
6
43
|
process.env.OLLAMA_HOST ||
|
|
7
44
|
"http://localhost:11434";
|
|
@@ -11,23 +48,123 @@ const OLLAMA_API_KEY = process.env.OLLAMA_API_KEY || "";
|
|
|
11
48
|
const PM_GRAPH_EXTENSION_PATH = process.env.PM_GRAPH_EXTENSION_PATH ||
|
|
12
49
|
path.join(process.cwd(), "extensions", "pm-graph");
|
|
13
50
|
export function getProjectDir(userId, slug) {
|
|
14
|
-
return path.join(
|
|
51
|
+
return path.join(projectsRoot(), userId, slug);
|
|
52
|
+
}
|
|
53
|
+
let cachedPmCommand;
|
|
54
|
+
function pmCliCommand() {
|
|
55
|
+
if (process.env.PM_CLI_BIN)
|
|
56
|
+
return { command: process.env.PM_CLI_BIN, prefixArgs: [] };
|
|
57
|
+
if (cachedPmCommand)
|
|
58
|
+
return cachedPmCommand;
|
|
59
|
+
if (process.platform === "win32") {
|
|
60
|
+
const entry = path.join(process.cwd(), "node_modules", "@unbrained", "pm-cli", "dist", "cli.js");
|
|
61
|
+
cachedPmCommand = fs.existsSync(entry)
|
|
62
|
+
? { command: process.execPath, prefixArgs: [entry] }
|
|
63
|
+
: { command: "pm", prefixArgs: [] };
|
|
64
|
+
return cachedPmCommand;
|
|
65
|
+
}
|
|
66
|
+
const local = path.join(process.cwd(), "node_modules", ".bin", "pm");
|
|
67
|
+
cachedPmCommand = fs.existsSync(local)
|
|
68
|
+
? { command: local, prefixArgs: [] }
|
|
69
|
+
: { command: "pm", prefixArgs: [] };
|
|
70
|
+
return cachedPmCommand;
|
|
71
|
+
}
|
|
72
|
+
async function runProcess(cwd, args, options = {}) {
|
|
73
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
const pmCommand = pmCliCommand();
|
|
76
|
+
let child;
|
|
77
|
+
try {
|
|
78
|
+
child = spawn(pmCommand.command, [...pmCommand.prefixArgs, ...args], {
|
|
79
|
+
cwd,
|
|
80
|
+
env: { ...process.env, HOME: "/tmp", NO_COLOR: "1", ...options.env },
|
|
81
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
82
|
+
windowsHide: true,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
resolve({
|
|
87
|
+
stdout: "",
|
|
88
|
+
stderr: error instanceof Error ? error.message : String(error),
|
|
89
|
+
ok: false,
|
|
90
|
+
});
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const stdout = [];
|
|
94
|
+
const stderr = [];
|
|
95
|
+
let outputBytes = 0;
|
|
96
|
+
let failure = "";
|
|
97
|
+
let settled = false;
|
|
98
|
+
let forceKill;
|
|
99
|
+
const terminate = (reason) => {
|
|
100
|
+
if (failure)
|
|
101
|
+
return;
|
|
102
|
+
failure = reason;
|
|
103
|
+
child.kill("SIGTERM");
|
|
104
|
+
forceKill = setTimeout(() => child.kill("SIGKILL"), 1_000);
|
|
105
|
+
forceKill.unref();
|
|
106
|
+
};
|
|
107
|
+
const collect = (chunks, chunk) => {
|
|
108
|
+
outputBytes += chunk.length;
|
|
109
|
+
if (outputBytes > MAX_OUTPUT_BYTES) {
|
|
110
|
+
terminate(`pm command exceeded the ${MAX_OUTPUT_BYTES}-byte output limit`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
chunks.push(chunk);
|
|
114
|
+
};
|
|
115
|
+
child.stdout.on("data", (chunk) => collect(stdout, chunk));
|
|
116
|
+
child.stderr.on("data", (chunk) => collect(stderr, chunk));
|
|
117
|
+
child.on("error", (error) => {
|
|
118
|
+
failure = error.message;
|
|
119
|
+
});
|
|
120
|
+
const timeout = setTimeout(() => terminate(`pm command timed out after ${timeoutMs}ms`), timeoutMs);
|
|
121
|
+
timeout.unref();
|
|
122
|
+
child.on("close", (code) => {
|
|
123
|
+
if (settled)
|
|
124
|
+
return;
|
|
125
|
+
settled = true;
|
|
126
|
+
clearTimeout(timeout);
|
|
127
|
+
if (forceKill)
|
|
128
|
+
clearTimeout(forceKill);
|
|
129
|
+
const stderrText = Buffer.concat(stderr).toString("utf8");
|
|
130
|
+
resolve({
|
|
131
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
132
|
+
stderr: failure ? `${stderrText}${stderrText ? "\n" : ""}${failure}` : stderrText,
|
|
133
|
+
ok: code === 0 && !failure,
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
child.stdin.on("error", () => undefined);
|
|
137
|
+
child.stdin.end(options.input);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async function runSerialized(workspace, work) {
|
|
141
|
+
const previous = workspaceTails.get(workspace) ?? Promise.resolve();
|
|
142
|
+
let releaseWorkspace;
|
|
143
|
+
const gate = new Promise((resolve) => { releaseWorkspace = resolve; });
|
|
144
|
+
const tail = previous.catch(() => undefined).then(() => gate);
|
|
145
|
+
workspaceTails.set(workspace, tail);
|
|
146
|
+
await previous.catch(() => undefined);
|
|
147
|
+
const releaseSlot = await commandSlots.acquire();
|
|
148
|
+
try {
|
|
149
|
+
return await work();
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
releaseSlot();
|
|
153
|
+
releaseWorkspace();
|
|
154
|
+
void tail.finally(() => {
|
|
155
|
+
if (workspaceTails.get(workspace) === tail)
|
|
156
|
+
workspaceTails.delete(workspace);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
15
159
|
}
|
|
16
|
-
export function initProject(userId, slug, prefix) {
|
|
160
|
+
export async function initProject(userId, slug, prefix) {
|
|
17
161
|
const dir = getProjectDir(userId, slug);
|
|
18
162
|
fs.mkdirSync(dir, { recursive: true });
|
|
19
|
-
const result =
|
|
20
|
-
|
|
21
|
-
encoding: "utf8",
|
|
22
|
-
timeout: 15_000,
|
|
23
|
-
env: { ...process.env, HOME: "/tmp" },
|
|
24
|
-
});
|
|
25
|
-
if (result.error)
|
|
26
|
-
throw result.error;
|
|
27
|
-
if (result.status !== 0)
|
|
163
|
+
const result = await runSerialized(dir, () => runProcess(dir, ["init", prefix], { timeoutMs: 15_000 }));
|
|
164
|
+
if (!result.ok)
|
|
28
165
|
throw new Error(result.stderr || "pm init failed");
|
|
29
166
|
configureLocalOllamaSearch(dir);
|
|
30
|
-
ensureGraphExtension(userId, slug);
|
|
167
|
+
await ensureGraphExtension(userId, slug);
|
|
31
168
|
}
|
|
32
169
|
function configureLocalOllamaSearch(projectDir) {
|
|
33
170
|
const settingsPath = path.join(projectDir, ".agents", "pm", "settings.json");
|
|
@@ -76,14 +213,9 @@ function bundledGraphExtensionManifest() {
|
|
|
76
213
|
function projectGraphExtensionManifest(projectDir) {
|
|
77
214
|
return readJsonFile(path.join(projectDir, ".agents", "pm", "extensions", "pm-graph", "manifest.json"));
|
|
78
215
|
}
|
|
79
|
-
function graphExtensionIsActive(projectDir) {
|
|
80
|
-
const result =
|
|
81
|
-
|
|
82
|
-
encoding: "utf8",
|
|
83
|
-
timeout: 15_000,
|
|
84
|
-
env: { ...process.env, HOME: "/tmp", NO_COLOR: "1" },
|
|
85
|
-
});
|
|
86
|
-
if (result.status !== 0 || !result.stdout)
|
|
216
|
+
async function graphExtensionIsActive(projectDir) {
|
|
217
|
+
const result = await runSerialized(projectDir, () => runProcess(projectDir, ["extension", "explore", "--project", "--json"], { timeoutMs: 15_000 }));
|
|
218
|
+
if (!result.ok || !result.stdout)
|
|
87
219
|
return false;
|
|
88
220
|
try {
|
|
89
221
|
const parsed = JSON.parse(result.stdout);
|
|
@@ -93,20 +225,10 @@ function graphExtensionIsActive(projectDir) {
|
|
|
93
225
|
return false;
|
|
94
226
|
}
|
|
95
227
|
}
|
|
96
|
-
function runExtensionCommand(projectDir, args) {
|
|
97
|
-
|
|
98
|
-
cwd: projectDir,
|
|
99
|
-
encoding: "utf8",
|
|
100
|
-
timeout: 30_000,
|
|
101
|
-
env: { ...process.env, HOME: "/tmp", NO_COLOR: "1" },
|
|
102
|
-
});
|
|
103
|
-
return {
|
|
104
|
-
stdout: result.stdout || "",
|
|
105
|
-
stderr: result.stderr || (result.error ? result.error.message : ""),
|
|
106
|
-
ok: result.status === 0,
|
|
107
|
-
};
|
|
228
|
+
async function runExtensionCommand(projectDir, args) {
|
|
229
|
+
return runSerialized(projectDir, () => runProcess(projectDir, args));
|
|
108
230
|
}
|
|
109
|
-
export function ensureGraphExtension(userId, slug) {
|
|
231
|
+
export async function ensureGraphExtension(userId, slug) {
|
|
110
232
|
const dir = getProjectDir(userId, slug);
|
|
111
233
|
const bundledManifest = bundledGraphExtensionManifest();
|
|
112
234
|
if (!bundledManifest) {
|
|
@@ -120,7 +242,7 @@ export function ensureGraphExtension(userId, slug) {
|
|
|
120
242
|
const projectManifest = projectGraphExtensionManifest(dir);
|
|
121
243
|
const needsInstall = !projectManifest || projectManifest.version !== bundledManifest.version;
|
|
122
244
|
if (needsInstall) {
|
|
123
|
-
const install = runExtensionCommand(dir, ["install", PM_GRAPH_EXTENSION_PATH, "--project"]);
|
|
245
|
+
const install = await runExtensionCommand(dir, ["install", PM_GRAPH_EXTENSION_PATH, "--project"]);
|
|
124
246
|
if (!install.ok) {
|
|
125
247
|
return {
|
|
126
248
|
ok: false,
|
|
@@ -130,8 +252,8 @@ export function ensureGraphExtension(userId, slug) {
|
|
|
130
252
|
};
|
|
131
253
|
}
|
|
132
254
|
}
|
|
133
|
-
if (!graphExtensionIsActive(dir)) {
|
|
134
|
-
const activate = runExtensionCommand(dir, ["extension", "activate", "pm-graph", "--project"]);
|
|
255
|
+
if (!(await graphExtensionIsActive(dir))) {
|
|
256
|
+
const activate = await runExtensionCommand(dir, ["extension", "activate", "pm-graph", "--project"]);
|
|
135
257
|
if (!activate.ok) {
|
|
136
258
|
return {
|
|
137
259
|
ok: false,
|
|
@@ -141,7 +263,7 @@ export function ensureGraphExtension(userId, slug) {
|
|
|
141
263
|
};
|
|
142
264
|
}
|
|
143
265
|
}
|
|
144
|
-
const ping = runExtensionCommand(dir, ["pm-graph", "ping", "--json"]);
|
|
266
|
+
const ping = await runExtensionCommand(dir, ["pm-graph", "ping", "--json"]);
|
|
145
267
|
if (!ping.ok) {
|
|
146
268
|
return {
|
|
147
269
|
ok: false,
|
|
@@ -152,24 +274,15 @@ export function ensureGraphExtension(userId, slug) {
|
|
|
152
274
|
}
|
|
153
275
|
return { ok: true, installed: true, active: true };
|
|
154
276
|
}
|
|
155
|
-
export function runPm(opts) {
|
|
277
|
+
export async function runPm(opts) {
|
|
156
278
|
const dir = getProjectDir(opts.userId, opts.slug);
|
|
157
279
|
const args = opts.jsonOutput ? ["--json", ...opts.args] : opts.args;
|
|
158
|
-
const result =
|
|
159
|
-
cwd: dir,
|
|
160
|
-
encoding: "utf8",
|
|
161
|
-
timeout: 30_000,
|
|
280
|
+
const result = await runSerialized(dir, () => runProcess(dir, args, {
|
|
162
281
|
input: opts.input,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
PM_GRAPH_PROJECT_KEY: `${opts.userId}:${opts.slug}`,
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
const stdout = result.stdout || "";
|
|
171
|
-
const stderr = result.stderr || "";
|
|
172
|
-
const ok = result.status === 0;
|
|
282
|
+
timeoutMs: opts.timeoutMs,
|
|
283
|
+
env: { PM_GRAPH_PROJECT_KEY: `${opts.userId}:${opts.slug}` },
|
|
284
|
+
}));
|
|
285
|
+
const { stdout, stderr, ok } = result;
|
|
173
286
|
let parsed;
|
|
174
287
|
if (opts.jsonOutput && ok && stdout) {
|
|
175
288
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pm-runner.js","sourceRoot":"","sources":["../../src/services/pm-runner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pm-runner.js","sourceRoot":"","sources":["../../src/services/pm-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startRealtimeBus(): Promise<() => Promise<void>>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { pool } from "../db.js";
|
|
3
|
+
import { configureProjectEventPublisher, deliverProjectEvent, } from "./sse.js";
|
|
4
|
+
const CHANNEL = "pm_workspace_events";
|
|
5
|
+
const INSTANCE_ID = randomUUID();
|
|
6
|
+
const PROJECT_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
7
|
+
const EVENT_TYPE = /^[a-z][a-z0-9-]{0,63}$/;
|
|
8
|
+
function safeSharedData(data) {
|
|
9
|
+
if (!data || typeof data !== "object" || Array.isArray(data))
|
|
10
|
+
return {};
|
|
11
|
+
const source = data;
|
|
12
|
+
const safe = {};
|
|
13
|
+
for (const key of ["itemId", "userId", "change", "target", "rel", "reason", "count", "source", "operation"]) {
|
|
14
|
+
const value = source[key];
|
|
15
|
+
if (typeof value === "string" && value.length <= 256)
|
|
16
|
+
safe[key] = value;
|
|
17
|
+
else if (typeof value === "number" && Number.isFinite(value))
|
|
18
|
+
safe[key] = value;
|
|
19
|
+
}
|
|
20
|
+
return safe;
|
|
21
|
+
}
|
|
22
|
+
function parseEnvelope(raw) {
|
|
23
|
+
if (!raw || Buffer.byteLength(raw, "utf8") > 7_500)
|
|
24
|
+
return null;
|
|
25
|
+
try {
|
|
26
|
+
const value = JSON.parse(raw);
|
|
27
|
+
if (!value.projectId || !PROJECT_ID.test(value.projectId) || !value.type || !EVENT_TYPE.test(value.type))
|
|
28
|
+
return null;
|
|
29
|
+
return { projectId: value.projectId, type: value.type, data: safeSharedData(value.data), ...(value.sourceId ? { sourceId: value.sourceId } : {}) };
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function startRealtimeBus() {
|
|
36
|
+
if (process.env.PM_REALTIME_ENABLED === "false")
|
|
37
|
+
return async () => undefined;
|
|
38
|
+
let listener = null;
|
|
39
|
+
let reconnectTimer = null;
|
|
40
|
+
let reconnectDelayMs = 250;
|
|
41
|
+
let stopped = false;
|
|
42
|
+
let connecting = null;
|
|
43
|
+
const handlers = new Map();
|
|
44
|
+
const safeDiagnostic = (error) => {
|
|
45
|
+
if (!(error instanceof Error))
|
|
46
|
+
return { name: typeof error };
|
|
47
|
+
const code = error.code;
|
|
48
|
+
return {
|
|
49
|
+
name: error.name,
|
|
50
|
+
...(code && /^[A-Z0-9_]{1,32}$/i.test(String(code)) ? { code: String(code) } : {}),
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const releaseClient = (client, destroy) => {
|
|
54
|
+
const registered = handlers.get(client);
|
|
55
|
+
if (!registered)
|
|
56
|
+
return;
|
|
57
|
+
client.off("error", registered.error);
|
|
58
|
+
client.off("notification", registered.notification);
|
|
59
|
+
handlers.delete(client);
|
|
60
|
+
client.release(destroy);
|
|
61
|
+
};
|
|
62
|
+
const scheduleReconnect = (error) => {
|
|
63
|
+
if (stopped || reconnectTimer)
|
|
64
|
+
return;
|
|
65
|
+
console.error("Realtime PostgreSQL listener disconnected", safeDiagnostic(error));
|
|
66
|
+
const delay = reconnectDelayMs;
|
|
67
|
+
reconnectDelayMs = Math.min(reconnectDelayMs * 2, 30_000);
|
|
68
|
+
reconnectTimer = setTimeout(() => {
|
|
69
|
+
reconnectTimer = null;
|
|
70
|
+
void connect().catch(scheduleReconnect);
|
|
71
|
+
}, delay);
|
|
72
|
+
reconnectTimer.unref();
|
|
73
|
+
};
|
|
74
|
+
const connectOnce = async () => {
|
|
75
|
+
const client = await pool.connect();
|
|
76
|
+
const notification = (message) => {
|
|
77
|
+
const event = parseEnvelope(message.payload);
|
|
78
|
+
if (!event || event.sourceId === INSTANCE_ID)
|
|
79
|
+
return;
|
|
80
|
+
deliverProjectEvent(event.projectId, { type: event.type, data: event.data });
|
|
81
|
+
};
|
|
82
|
+
const error = (cause) => {
|
|
83
|
+
if (listener !== client)
|
|
84
|
+
return;
|
|
85
|
+
listener = null;
|
|
86
|
+
releaseClient(client, true);
|
|
87
|
+
scheduleReconnect(cause);
|
|
88
|
+
};
|
|
89
|
+
handlers.set(client, { error, notification });
|
|
90
|
+
client.on("error", error);
|
|
91
|
+
client.on("notification", notification);
|
|
92
|
+
listener = client;
|
|
93
|
+
try {
|
|
94
|
+
await client.query(`LISTEN ${CHANNEL}`);
|
|
95
|
+
}
|
|
96
|
+
catch (cause) {
|
|
97
|
+
if (listener === client)
|
|
98
|
+
listener = null;
|
|
99
|
+
releaseClient(client, true);
|
|
100
|
+
throw cause;
|
|
101
|
+
}
|
|
102
|
+
if (stopped) {
|
|
103
|
+
if (listener === client)
|
|
104
|
+
listener = null;
|
|
105
|
+
await client.query(`UNLISTEN ${CHANNEL}`).catch(() => undefined);
|
|
106
|
+
releaseClient(client, false);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
reconnectDelayMs = 250;
|
|
110
|
+
};
|
|
111
|
+
const connect = () => {
|
|
112
|
+
if (connecting)
|
|
113
|
+
return connecting;
|
|
114
|
+
connecting = connectOnce().finally(() => { connecting = null; });
|
|
115
|
+
return connecting;
|
|
116
|
+
};
|
|
117
|
+
await connect();
|
|
118
|
+
configureProjectEventPublisher(async (projectId, event) => {
|
|
119
|
+
if (!PROJECT_ID.test(projectId) || !EVENT_TYPE.test(event.type))
|
|
120
|
+
return;
|
|
121
|
+
const payload = JSON.stringify({
|
|
122
|
+
projectId,
|
|
123
|
+
type: event.type,
|
|
124
|
+
data: safeSharedData(event.data),
|
|
125
|
+
sourceId: INSTANCE_ID,
|
|
126
|
+
});
|
|
127
|
+
if (Buffer.byteLength(payload, "utf8") <= 7_500) {
|
|
128
|
+
await pool.query("SELECT pg_notify($1, $2)", [CHANNEL, payload]);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
console.warn(`Realtime event payload exceeded size limit: ${projectId}/${event.type}`);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
return async () => {
|
|
135
|
+
stopped = true;
|
|
136
|
+
if (reconnectTimer)
|
|
137
|
+
clearTimeout(reconnectTimer);
|
|
138
|
+
reconnectTimer = null;
|
|
139
|
+
configureProjectEventPublisher(null);
|
|
140
|
+
const client = listener;
|
|
141
|
+
listener = null;
|
|
142
|
+
if (client) {
|
|
143
|
+
await client.query(`UNLISTEN ${CHANNEL}`).catch(() => undefined);
|
|
144
|
+
releaseClient(client, false);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=realtime-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime-bus.js","sourceRoot":"","sources":["../../src/services/realtime-bus.ts"],"names":[],"mappings":"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"}
|
package/dist/services/sse.d.ts
CHANGED
|
@@ -14,10 +14,12 @@ export interface PresenceUser {
|
|
|
14
14
|
currentView: string;
|
|
15
15
|
connectedAt: string;
|
|
16
16
|
}
|
|
17
|
+
export declare function configureProjectEventPublisher(publisher: ((projectId: string, event: SSEEvent) => Promise<void>) | null): void;
|
|
17
18
|
export declare function addSSEClient(client: SSEClient): () => void;
|
|
18
19
|
export declare function broadcastProjectEvent(projectId: string, event: SSEEvent): void;
|
|
20
|
+
export declare function deliverProjectEvent(projectId: string, event: SSEEvent): void;
|
|
19
21
|
export declare function broadcastPresence(projectId: string): void;
|
|
20
|
-
export declare function updateClientView(clientId: string, currentView: string):
|
|
22
|
+
export declare function updateClientView(clientId: string, userId: string, projectId: string, currentView: string): boolean;
|
|
21
23
|
export declare function getProjectPresence(projectId: string): PresenceUser[];
|
|
22
24
|
export declare function setupSSEHeaders(res: Response): void;
|
|
23
25
|
export declare function getSSEClientCount(): number;
|