@jmfederico/pi-web 1.202610.4 → 1.202610.5
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/cli.js +1 -1
- package/dist/client/assets/classic-CyM97Akm.css +54 -0
- package/dist/client/assets/graphite-DquaqFXU.css +54 -0
- package/dist/client/assets/index-DPS1kTH7.js +4389 -0
- package/dist/client/assets/paper-CB1oLuRr.css +54 -0
- package/dist/client/assets/pi-web-dark-D_KtbM95.css +54 -0
- package/dist/client/assets/pi-web-light-DSNLMIBI.css +54 -0
- package/dist/client/index.html +2 -2
- package/dist/config.js +56 -0
- package/dist/config.js.map +1 -1
- package/dist/pi-packages/captains-log/dist/browser/index.js +13 -17
- package/dist/pi-packages/captains-log/dist/browser/panel.js +7 -11
- package/dist/pi-packages/relays/pi-web-plugin.js +21 -1
- package/dist/pi-packages/relays/relaysPanelElement.js +36 -32
- package/dist/pi-packages/workflows/browser/pi-web-plugin.js +35 -27
- package/dist/pi-packages/workflows/browser/worktreeDialog.js +156 -0
- package/dist/pi-packages/workflows/package.json +1 -0
- package/dist/pi-packages/workflows/prompts/worktree.md +11 -2
- package/dist/pi-packages/workflows/server-plugin.js +579 -0
- package/dist/pi-packages/workflows/vite.config.mjs +17 -0
- package/dist/pi-web-plugins/code-highlight/browser/pi-web-plugin.js +22 -0
- package/dist/pi-web-plugins/code-highlight/package.json +13 -0
- package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +119 -162
- package/dist/pi-web-plugins/git/browser/git-panel.js +61 -46
- package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +25 -3
- package/dist/pi-web-plugins/git/git-backend.js +13 -1
- package/dist/pi-web-plugins/git/server-plugin.js +8 -1
- package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +8 -3
- package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +50 -29
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +11 -11
- package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +21 -1
- package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +35 -19
- package/dist/piWebUpdate.js +32 -9
- package/dist/piWebUpdate.js.map +1 -1
- package/dist/plugin-api.d.ts +174 -45
- package/dist/server/browserMessageProjection.js +1 -1
- package/dist/server/browserMessageProjection.js.map +1 -1
- package/dist/server/configRoutes.js +7 -1
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +3 -2
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/piWebPluginService.js +7 -1
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/plugins/pluginBackendChannelProxyAdmission.js +1 -1
- package/dist/server/plugins/pluginBackendChannelProxyAdmission.js.map +1 -1
- package/dist/server/plugins/pluginBackendChannelProxyRoutes.js +31 -38
- package/dist/server/plugins/pluginBackendChannelProxyRoutes.js.map +1 -1
- package/dist/server/plugins/pluginBackendProxyRoutes.js +38 -45
- package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -1
- package/dist/server/plugins/pluginBackendRegistry.js +58 -34
- package/dist/server/plugins/pluginBackendRegistry.js.map +1 -1
- package/dist/server/plugins/serverPluginCatalogCapability.js +106 -0
- package/dist/server/plugins/serverPluginCatalogCapability.js.map +1 -0
- package/dist/server/plugins/serverPluginRuntime.js +21 -8
- package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
- package/dist/server/sessiond/pluginBackendChannelRoutes.js +24 -14
- package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -1
- package/dist/server/sessiond/pluginBackendRoutes.js +51 -47
- package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -1
- package/dist/server/sessiond/pluginCatalogRoutes.js +37 -0
- package/dist/server/sessiond/pluginCatalogRoutes.js.map +1 -0
- package/dist/server/sessiond/sessionProxyRoutes.js +17 -0
- package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
- package/dist/server/sessiond/sessionServiceDependencies.js +1 -0
- package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
- package/dist/server/sessiond.js +24 -4
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/authRoutes.js +1 -0
- package/dist/server/sessions/authRoutes.js.map +1 -1
- package/dist/server/sessions/authService.js +13 -0
- package/dist/server/sessions/authService.js.map +1 -1
- package/dist/server/sessions/builtinExtensionFactories.js +15 -1
- package/dist/server/sessions/builtinExtensionFactories.js.map +1 -1
- package/dist/server/sessions/companionBackend.js +286 -0
- package/dist/server/sessions/companionBackend.js.map +1 -0
- package/dist/server/sessions/mcpAuthFlowService.js +237 -0
- package/dist/server/sessions/mcpAuthFlowService.js.map +1 -0
- package/dist/server/sessions/mcpAuthRoutes.js +76 -0
- package/dist/server/sessions/mcpAuthRoutes.js.map +1 -0
- package/dist/server/sessions/messageHistoryTarget.js +18 -1
- package/dist/server/sessions/messageHistoryTarget.js.map +1 -1
- package/dist/server/sessions/piSessionEventConnections.js +5 -2
- package/dist/server/sessions/piSessionEventConnections.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +279 -22
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +3 -17
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionNameGenerator.js +4 -4
- package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
- package/dist/server-plugin-api.d.ts +65 -15
- package/dist/server-plugin-api.js +25 -0
- package/dist/server-plugin-api.js.map +1 -1
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/federatedRoutes.js +17 -5
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/pluginApiTypes.d.ts +53 -0
- package/dist/shared/pluginBackendProtocol.js +56 -1
- package/dist/shared/pluginBackendProtocol.js.map +1 -1
- package/dist/shared/pluginCatalogTypes.d.ts +49 -0
- package/dist/shared/pluginCatalogTypes.js +156 -0
- package/dist/shared/pluginCatalogTypes.js.map +1 -0
- package/docs/config.md +68 -2
- package/docs/plugins.md +382 -20
- package/examples/session-bridge-plugin/src/browser/index.ts +1 -1
- package/package.json +7 -12
- package/dist/client/assets/index-BAl5IbYx.js +0 -4429
|
@@ -1,13 +1,27 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { McpAuthFlowService } from "./mcpAuthFlowService.js";
|
|
1
3
|
import { createCodemodeExtension, createMcpExtension, createToolSearchExtension } from "@earendil-works/pi-coding-agent";
|
|
2
4
|
// Pi 1.x guarantees these exports. Create factories lazily and share them across
|
|
3
5
|
// session resource loaders; missing exports must not silently disable builtins.
|
|
4
6
|
let cachedPromise;
|
|
5
7
|
export function getBuiltinExtensionFactories() {
|
|
6
8
|
cachedPromise ??= Promise.resolve().then(() => [
|
|
7
|
-
{ name: "mcp", factory: createMcpExtension(), builtin: true, replaceable: true },
|
|
9
|
+
{ name: "mcp", factory: createMcpExtension({ openUrl: openMcpUrl }), builtin: true, replaceable: true },
|
|
8
10
|
{ name: "codemode", factory: createCodemodeExtension(), builtin: true, replaceable: true },
|
|
9
11
|
{ name: "tool-search", factory: createToolSearchExtension(), builtin: true, replaceable: true },
|
|
10
12
|
]);
|
|
11
13
|
return cachedPromise;
|
|
12
14
|
}
|
|
15
|
+
function openMcpUrl(url) {
|
|
16
|
+
const operation = McpAuthFlowService.current();
|
|
17
|
+
if (operation) {
|
|
18
|
+
operation.openUrl(url);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Preserve Pi's best-effort browser launch outside modal operations. Use no
|
|
22
|
+
// shell: authorization URLs can contain shell metacharacters.
|
|
23
|
+
const [command, args] = process.platform === "darwin" ? ["open", [url]]
|
|
24
|
+
: process.platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", url]] : ["xdg-open", [url]];
|
|
25
|
+
spawn(command, args, { stdio: "ignore", detached: true }).on("error", () => { }).unref();
|
|
26
|
+
}
|
|
13
27
|
//# sourceMappingURL=builtinExtensionFactories.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtinExtensionFactories.js","sourceRoot":"","sources":["../../../src/server/sessions/builtinExtensionFactories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,yBAAyB,EAAwB,MAAM,iCAAiC,CAAC;AAE/I,iFAAiF;AACjF,gFAAgF;AAChF,IAAI,aAAqD,CAAC;AAE1D,MAAM,UAAU,4BAA4B;IAC1C,aAAa,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7C,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"builtinExtensionFactories.js","sourceRoot":"","sources":["../../../src/server/sessions/builtinExtensionFactories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,yBAAyB,EAAwB,MAAM,iCAAiC,CAAC;AAE/I,iFAAiF;AACjF,gFAAgF;AAChF,IAAI,aAAqD,CAAC;AAE1D,MAAM,UAAU,4BAA4B;IAC1C,aAAa,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7C,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;QACvG,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;QAC1F,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,yBAAyB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;KAChG,CAAC,CAAC;IACH,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,EAAE,CAAC;IAC/C,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IACD,4EAA4E;IAC5E,8DAA8D;IAC9D,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;QACrE,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5G,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAA2C,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;AACnI,CAAC"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { cloneBoundedPluginBackendJson, PLUGIN_BACKEND_CHANNEL_DATA_JSON_MAX_BYTES, PLUGIN_BACKEND_CHANNEL_QUEUE_MAX_FRAMES, PLUGIN_BACKEND_CHANNEL_QUEUE_MAX_BYTES, PLUGIN_BACKEND_CHANNEL_DRAIN_TIMEOUT_MS, PLUGIN_BACKEND_CHANNEL_SERVER_TO_BROWSER_QUEUE_MAX_BYTES, serializePluginBackendChannelDataEnvelope, serializePluginBackendChannelReadyEnvelope } from "../../shared/pluginBackendProtocol.js";
|
|
2
|
+
/** One runtime bus owns these facades; detach revokes them without closing the bus. */
|
|
3
|
+
export function bindCompanionBackend(bus, bindingOptions) {
|
|
4
|
+
const lifetime = new AbortController();
|
|
5
|
+
const unsubscribe = bus.on("pi-web:companion-backend:discover", (data) => {
|
|
6
|
+
if (typeof data !== "object" || data === null)
|
|
7
|
+
return;
|
|
8
|
+
const pluginId = Reflect.get(data, "pluginId");
|
|
9
|
+
const accept = Reflect.get(data, "accept");
|
|
10
|
+
if (typeof accept !== "function")
|
|
11
|
+
return;
|
|
12
|
+
Reflect.apply(accept, undefined, [() => {
|
|
13
|
+
lifetime.signal.throwIfAborted();
|
|
14
|
+
// Startup may register the bus before healthy registry authority is ready.
|
|
15
|
+
const options = typeof bindingOptions === "function" ? bindingOptions() : bindingOptions;
|
|
16
|
+
const contribution = options.contributions.find((candidate) => candidate.pluginId === pluginId);
|
|
17
|
+
if (contribution?.apiVersion !== 5)
|
|
18
|
+
throw new Error(`No active v5 companion backend for ${String(pluginId)}`);
|
|
19
|
+
const { moduleRevision, backend } = contribution;
|
|
20
|
+
const canRequest = typeof backend.request === "function";
|
|
21
|
+
const canOpen = typeof backend.openChannel === "function";
|
|
22
|
+
if (!canRequest && !canOpen)
|
|
23
|
+
throw new Error("Companion backend has no operations");
|
|
24
|
+
const identity = { pluginId: contribution.pluginId, moduleRevision };
|
|
25
|
+
return Object.freeze({
|
|
26
|
+
machineId: "local",
|
|
27
|
+
forScope: (scope) => {
|
|
28
|
+
lifetime.signal.throwIfAborted();
|
|
29
|
+
const selected = snapshotScope(scope);
|
|
30
|
+
const request = async (operation, input) => {
|
|
31
|
+
// Snapshot before host lookup can yield to the extension again.
|
|
32
|
+
const detachedInput = cloneBoundedPluginBackendJson(input, "Companion backend input");
|
|
33
|
+
const project = selected.kind === "machine" ? undefined : await options.projects.requireProject(selected.projectId);
|
|
34
|
+
return { ...identity, scope: selected.kind, project, workspaceId: selected.kind === "workspace" ? selected.workspaceId : undefined, operation, input: detachedInput };
|
|
35
|
+
};
|
|
36
|
+
const peer = {
|
|
37
|
+
...(canRequest ? {
|
|
38
|
+
request: async (operation, input, callOptions) => {
|
|
39
|
+
const call = linkedCall(lifetime.signal, callOptions?.signal);
|
|
40
|
+
try {
|
|
41
|
+
return await call.wait(async () => {
|
|
42
|
+
const resolved = await request(operation, input);
|
|
43
|
+
call.signal.throwIfAborted();
|
|
44
|
+
return options.backends.request(resolved, call.signal);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
call.dispose();
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
} : {}),
|
|
52
|
+
...(canOpen ? {
|
|
53
|
+
openChannel: async (operation, input, channelOptions) => {
|
|
54
|
+
const call = linkedCall(lifetime.signal, channelOptions.signal);
|
|
55
|
+
try {
|
|
56
|
+
const resolved = await call.wait(() => request(operation, input));
|
|
57
|
+
call.signal.throwIfAborted();
|
|
58
|
+
return await openChannel(options.backends, resolved, channelOptions, call);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
call.dispose();
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
} : {}),
|
|
66
|
+
};
|
|
67
|
+
if (peer.request !== undefined)
|
|
68
|
+
return Object.freeze({ request: peer.request, ...(peer.openChannel === undefined ? {} : { openChannel: peer.openChannel }) });
|
|
69
|
+
if (peer.openChannel !== undefined)
|
|
70
|
+
return Object.freeze({ openChannel: peer.openChannel });
|
|
71
|
+
throw new Error("Companion backend has no operations");
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}]);
|
|
75
|
+
});
|
|
76
|
+
return () => {
|
|
77
|
+
unsubscribe();
|
|
78
|
+
lifetime.abort(new Error("Companion backend runtime detached"));
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function snapshotScope(scope) {
|
|
82
|
+
if (scope.kind === "machine")
|
|
83
|
+
return Object.freeze({ kind: "machine" });
|
|
84
|
+
if (!["project", "workspace"].includes(scope.kind))
|
|
85
|
+
throw new Error("Invalid companion backend scope");
|
|
86
|
+
requireId(scope.projectId);
|
|
87
|
+
if (scope.kind === "project")
|
|
88
|
+
return Object.freeze({ kind: "project", projectId: scope.projectId });
|
|
89
|
+
requireId(scope.workspaceId);
|
|
90
|
+
return Object.freeze({ kind: "workspace", projectId: scope.projectId, workspaceId: scope.workspaceId });
|
|
91
|
+
}
|
|
92
|
+
function requireId(id) {
|
|
93
|
+
if (typeof id !== "string" || id.trim() === "" || id.length > 512)
|
|
94
|
+
throw new Error("Invalid companion backend scope id");
|
|
95
|
+
}
|
|
96
|
+
function linkedCall(lifetime, caller) {
|
|
97
|
+
const controller = new AbortController();
|
|
98
|
+
const abortLifetime = () => { controller.abort(lifetime.reason); };
|
|
99
|
+
const abortCaller = () => { controller.abort(caller?.reason); };
|
|
100
|
+
if (lifetime.aborted)
|
|
101
|
+
abortLifetime();
|
|
102
|
+
else
|
|
103
|
+
lifetime.addEventListener("abort", abortLifetime, { once: true });
|
|
104
|
+
if (caller?.aborted === true)
|
|
105
|
+
abortCaller();
|
|
106
|
+
else
|
|
107
|
+
caller?.addEventListener("abort", abortCaller, { once: true });
|
|
108
|
+
return {
|
|
109
|
+
signal: controller.signal,
|
|
110
|
+
dispose: () => {
|
|
111
|
+
lifetime.removeEventListener("abort", abortLifetime);
|
|
112
|
+
caller?.removeEventListener("abort", abortCaller);
|
|
113
|
+
},
|
|
114
|
+
wait: async (work) => {
|
|
115
|
+
controller.signal.throwIfAborted();
|
|
116
|
+
let abort = () => { controller.signal.throwIfAborted(); };
|
|
117
|
+
const cancelled = new Promise((_resolve, reject) => {
|
|
118
|
+
abort = () => { reject(controller.signal.reason instanceof Error ? controller.signal.reason : new Error("Companion backend call cancelled")); };
|
|
119
|
+
controller.signal.addEventListener("abort", abort, { once: true });
|
|
120
|
+
});
|
|
121
|
+
try {
|
|
122
|
+
return await Promise.race([work(), cancelled]);
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
controller.signal.removeEventListener("abort", abort);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
async function drainFrames(queued, call) {
|
|
131
|
+
let timer;
|
|
132
|
+
try {
|
|
133
|
+
await call.wait(() => Promise.race([queued, new Promise((_resolve, reject) => {
|
|
134
|
+
timer = setTimeout(() => { reject(new Error("Companion channel receive drain timed out")); }, PLUGIN_BACKEND_CHANNEL_DRAIN_TIMEOUT_MS);
|
|
135
|
+
timer.unref();
|
|
136
|
+
})]));
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
clearTimeout(timer);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async function openChannel(backends, request, options, call) {
|
|
143
|
+
let session;
|
|
144
|
+
let result;
|
|
145
|
+
let closing = false;
|
|
146
|
+
let draining = false;
|
|
147
|
+
let ready = false;
|
|
148
|
+
const openingFrames = [];
|
|
149
|
+
let openingBytes = 0;
|
|
150
|
+
const discardOpeningFrames = () => { openingFrames.length = 0; openingBytes = 0; };
|
|
151
|
+
let queued = Promise.resolve();
|
|
152
|
+
let error;
|
|
153
|
+
let resolveClosed;
|
|
154
|
+
const closed = new Promise((resolve) => { resolveClosed = resolve; });
|
|
155
|
+
const finish = (code, reason) => {
|
|
156
|
+
if (result !== undefined)
|
|
157
|
+
return;
|
|
158
|
+
discardOpeningFrames();
|
|
159
|
+
result = Object.freeze({ code, reason, wasClean: code === 1000 && error === undefined, ...(error === undefined ? {} : { error }) });
|
|
160
|
+
call.signal.removeEventListener("abort", abort);
|
|
161
|
+
call.dispose();
|
|
162
|
+
resolveClosed(result);
|
|
163
|
+
};
|
|
164
|
+
const close = (code, reason) => {
|
|
165
|
+
if (closing || result !== undefined)
|
|
166
|
+
return;
|
|
167
|
+
closing = true;
|
|
168
|
+
draining = code === 1000;
|
|
169
|
+
if (session === undefined) {
|
|
170
|
+
finish(code, reason);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// Match transport close semantics: a clean close boundedly drains accepted frames.
|
|
174
|
+
void (async () => {
|
|
175
|
+
let closeCode = code, closeReason = reason;
|
|
176
|
+
if (draining) {
|
|
177
|
+
try {
|
|
178
|
+
await drainFrames(queued, call);
|
|
179
|
+
}
|
|
180
|
+
catch (failure) {
|
|
181
|
+
draining = false;
|
|
182
|
+
error ??= Object.freeze({ code: "drain-failed", message: String(failure) });
|
|
183
|
+
closeCode = 1011;
|
|
184
|
+
closeReason = "Companion channel receive drain failed";
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
await session.close(closeCode, closeReason);
|
|
188
|
+
finish(closeCode, closeReason);
|
|
189
|
+
})().catch((failure) => {
|
|
190
|
+
error ??= Object.freeze({ code: "close-failed", message: String(failure) });
|
|
191
|
+
finish(1011, "Companion channel cleanup failed");
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
const abort = () => { close(1001, "Companion backend call cancelled"); };
|
|
195
|
+
call.signal.addEventListener("abort", abort, { once: true });
|
|
196
|
+
try {
|
|
197
|
+
await call.wait(async () => {
|
|
198
|
+
session = await backends.openChannel(request, {
|
|
199
|
+
send: (data) => {
|
|
200
|
+
if ((closing && !draining) || result !== undefined)
|
|
201
|
+
throw new Error("Companion channel is closed");
|
|
202
|
+
if (ready) {
|
|
203
|
+
options.onData(data);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
// Match the browser writer: reserve room for ready and bound serialized frames.
|
|
207
|
+
const bytes = Buffer.byteLength(serializePluginBackendChannelDataEnvelope(data), "utf8");
|
|
208
|
+
const readyBytes = Buffer.byteLength(serializePluginBackendChannelReadyEnvelope(), "utf8");
|
|
209
|
+
if (openingFrames.length >= PLUGIN_BACKEND_CHANNEL_QUEUE_MAX_FRAMES - 1
|
|
210
|
+
|| openingBytes + bytes + readyBytes > PLUGIN_BACKEND_CHANNEL_SERVER_TO_BROWSER_QUEUE_MAX_BYTES) {
|
|
211
|
+
throw new Error("Companion channel plugin queue limit was exceeded");
|
|
212
|
+
}
|
|
213
|
+
openingFrames.push(data);
|
|
214
|
+
openingBytes += bytes;
|
|
215
|
+
},
|
|
216
|
+
sendError: (code, message) => { discardOpeningFrames(); error ??= Object.freeze({ code, message }); },
|
|
217
|
+
close: finish,
|
|
218
|
+
}, call.signal);
|
|
219
|
+
if (result !== undefined || call.signal.aborted) {
|
|
220
|
+
await session.close(1001, "Companion channel closed during open");
|
|
221
|
+
throw new Error("Companion channel closed during open");
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
catch (failure) {
|
|
226
|
+
finish(1011, "Companion channel open failed");
|
|
227
|
+
throw failure;
|
|
228
|
+
}
|
|
229
|
+
if (session === undefined)
|
|
230
|
+
throw new Error("Companion channel did not open");
|
|
231
|
+
const opened = session;
|
|
232
|
+
ready = true;
|
|
233
|
+
const isClosed = () => closing || result !== undefined || call.signal.aborted;
|
|
234
|
+
try {
|
|
235
|
+
for (const frame of openingFrames) {
|
|
236
|
+
if (isClosed())
|
|
237
|
+
break;
|
|
238
|
+
options.onData(frame);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (failure) {
|
|
242
|
+
// Once ready, consumer failures close the channel rather than fail its open.
|
|
243
|
+
error ??= Object.freeze({ code: "protocol-error", message: failure instanceof Error ? failure.message : String(failure) });
|
|
244
|
+
close(1000, "Channel protocol error");
|
|
245
|
+
}
|
|
246
|
+
finally {
|
|
247
|
+
discardOpeningFrames();
|
|
248
|
+
}
|
|
249
|
+
let pending = 0;
|
|
250
|
+
let pendingBytes = 0;
|
|
251
|
+
return Object.freeze({
|
|
252
|
+
closed,
|
|
253
|
+
send: (data) => {
|
|
254
|
+
if (closing || result !== undefined || call.signal.aborted)
|
|
255
|
+
throw new Error("Companion channel is closed");
|
|
256
|
+
if (pending >= PLUGIN_BACKEND_CHANNEL_QUEUE_MAX_FRAMES) {
|
|
257
|
+
close(1008, "Companion channel receive queue is full");
|
|
258
|
+
throw new Error("Companion channel receive queue is full");
|
|
259
|
+
}
|
|
260
|
+
let frame;
|
|
261
|
+
try {
|
|
262
|
+
frame = cloneBoundedPluginBackendJson(data, "Companion channel frame", PLUGIN_BACKEND_CHANNEL_DATA_JSON_MAX_BYTES);
|
|
263
|
+
}
|
|
264
|
+
catch (failure) {
|
|
265
|
+
close(1008, "Invalid companion channel frame");
|
|
266
|
+
throw failure;
|
|
267
|
+
}
|
|
268
|
+
const bytes = Buffer.byteLength(JSON.stringify(frame), "utf8");
|
|
269
|
+
if (pendingBytes + bytes > PLUGIN_BACKEND_CHANNEL_QUEUE_MAX_BYTES) {
|
|
270
|
+
close(1008, "Companion channel receive queue is full");
|
|
271
|
+
throw new Error("Companion channel receive queue is full");
|
|
272
|
+
}
|
|
273
|
+
pending += 1;
|
|
274
|
+
pendingBytes += bytes;
|
|
275
|
+
queued = queued.then(async () => {
|
|
276
|
+
if ((!closing || draining) && result === undefined && !call.signal.aborted)
|
|
277
|
+
await opened.receive(frame);
|
|
278
|
+
}).catch((failure) => {
|
|
279
|
+
error ??= Object.freeze({ code: "receive-failed", message: String(failure) });
|
|
280
|
+
close(1011, "Companion channel receive failed");
|
|
281
|
+
}).finally(() => { pending -= 1; pendingBytes -= bytes; });
|
|
282
|
+
},
|
|
283
|
+
close: (reason) => { close(1000, reason ?? "Companion channel closed"); },
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=companionBackend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companionBackend.js","sourceRoot":"","sources":["../../../src/server/sessions/companionBackend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
const execution = new AsyncLocalStorage();
|
|
4
|
+
const MAX_TEXT = 32 * 1024;
|
|
5
|
+
const MAX_PROGRESS = 100;
|
|
6
|
+
/** Operation transport only. Pi owns config, credentials, OAuth and reconnect. */
|
|
7
|
+
export class McpAuthFlowService {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.flows = new Map();
|
|
11
|
+
this.active = new Map();
|
|
12
|
+
this.sessions = new Map();
|
|
13
|
+
this.disposed = false;
|
|
14
|
+
}
|
|
15
|
+
start(options) {
|
|
16
|
+
if (this.disposed)
|
|
17
|
+
throw new Error("MCP authentication service is disposed");
|
|
18
|
+
if (this.sessions.has(options.sessionId))
|
|
19
|
+
throw new Error("MCP authentication is already running for this session");
|
|
20
|
+
// Pi persisted OAuth state is shared across sessions. Do not race two scoped logins against the same credentials.
|
|
21
|
+
if (this.sessions.size > 0)
|
|
22
|
+
throw new Error("Another MCP authentication operation is running on this machine. Finish it before starting another.");
|
|
23
|
+
if (this.flows.size >= 100)
|
|
24
|
+
throw new Error("Too many MCP authentication flows");
|
|
25
|
+
const flow = {
|
|
26
|
+
state: { flowId: randomUUID(), target: "mcp", providerId: "mcp", providerName: "MCP server", status: "running", progress: [], ...(options.mode === undefined ? {} : { mcpMode: options.mode }) },
|
|
27
|
+
identity: options.identity, sessionId: options.sessionId, token: Symbol(), isCurrent: () => options.isCurrent(),
|
|
28
|
+
};
|
|
29
|
+
this.flows.set(flow.state.flowId, flow);
|
|
30
|
+
this.active.set(flow.token, flow);
|
|
31
|
+
this.sessions.set(flow.sessionId, flow);
|
|
32
|
+
flow.timer = setTimeout(() => { this.requestCancel(flow); }, this.options.runningTtlMs ?? 30 * 60_000);
|
|
33
|
+
flow.timer.unref();
|
|
34
|
+
// Keep the real command promise in this scope, not its submission receipt.
|
|
35
|
+
void execution.run({ service: this, token: flow.token }, async () => {
|
|
36
|
+
try {
|
|
37
|
+
await options.run();
|
|
38
|
+
if (flow.commandError !== undefined)
|
|
39
|
+
throw new Error(flow.commandError);
|
|
40
|
+
flow.state.status = "complete";
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
flow.state.status = "error";
|
|
44
|
+
flow.state.error = String(error instanceof Error ? error.message : error).slice(0, MAX_TEXT);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
this.active.delete(flow.token);
|
|
48
|
+
this.sessions.delete(flow.sessionId);
|
|
49
|
+
flow.pending?.settle(undefined);
|
|
50
|
+
clearTimeout(flow.timer);
|
|
51
|
+
if (!this.disposed) {
|
|
52
|
+
flow.timer = setTimeout(() => { this.flows.delete(flow.state.flowId); }, this.options.terminalTtlMs ?? 5 * 60_000);
|
|
53
|
+
flow.timer.unref();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return this.snapshot(flow);
|
|
58
|
+
}
|
|
59
|
+
/** Public /mcp waits for startup; its status UI must never escape into chat. */
|
|
60
|
+
async discover(options) {
|
|
61
|
+
const scope = execution.getStore();
|
|
62
|
+
const own = scope?.service === this ? this.active.get(scope.token) : undefined;
|
|
63
|
+
if (!own && (this.disposed || this.sessions.size > 0))
|
|
64
|
+
throw new Error("Another MCP authentication operation is running on this machine");
|
|
65
|
+
const flow = own ?? {
|
|
66
|
+
state: { flowId: randomUUID(), providerId: "mcp", providerName: "MCP server", status: "running", progress: [] },
|
|
67
|
+
identity: options.identity, sessionId: options.sessionId, token: Symbol(), isCurrent: () => options.isCurrent(),
|
|
68
|
+
};
|
|
69
|
+
if (!own) {
|
|
70
|
+
this.active.set(flow.token, flow);
|
|
71
|
+
this.sessions.set(flow.sessionId, flow);
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
return await execution.run({ service: this, token: flow.token, discovery: true }, async () => {
|
|
75
|
+
const result = await options.run();
|
|
76
|
+
if (flow.commandError !== undefined)
|
|
77
|
+
throw new Error("MCP server discovery failed");
|
|
78
|
+
return result;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
if (!own) {
|
|
83
|
+
this.active.delete(flow.token);
|
|
84
|
+
this.sessions.delete(flow.sessionId);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
assertSessionAvailable(sessionId) {
|
|
89
|
+
const active = this.sessions.get(sessionId);
|
|
90
|
+
const scope = execution.getStore();
|
|
91
|
+
if (active && (scope?.service !== this || scope.token !== active.token))
|
|
92
|
+
throw new Error("MCP authentication operation is running for this session");
|
|
93
|
+
}
|
|
94
|
+
get(flowId) { return this.snapshot(this.requireFlow(flowId)); }
|
|
95
|
+
respond(flowId, requestId, value) {
|
|
96
|
+
const flow = this.requireFlow(flowId);
|
|
97
|
+
const pending = flow.pending;
|
|
98
|
+
if (flow.state.status !== "running" || pending?.id !== requestId)
|
|
99
|
+
throw new Error("MCP authentication request is no longer pending");
|
|
100
|
+
if (typeof value !== "string" || value.length > MAX_TEXT || (pending.values?.includes(value) === false))
|
|
101
|
+
throw new Error("Invalid MCP authentication response");
|
|
102
|
+
pending.settle(value);
|
|
103
|
+
return this.snapshot(flow);
|
|
104
|
+
}
|
|
105
|
+
cancel(flowId) {
|
|
106
|
+
const flow = this.requireFlow(flowId);
|
|
107
|
+
if (flow.state.status === "running")
|
|
108
|
+
this.requestCancel(flow);
|
|
109
|
+
return this.snapshot(flow);
|
|
110
|
+
}
|
|
111
|
+
cancelSession(sessionId) {
|
|
112
|
+
const flow = this.sessions.get(sessionId);
|
|
113
|
+
if (flow)
|
|
114
|
+
this.requestCancel(flow);
|
|
115
|
+
}
|
|
116
|
+
dispose() {
|
|
117
|
+
this.disposed = true;
|
|
118
|
+
for (const flow of this.flows.values()) {
|
|
119
|
+
this.requestCancel(flow);
|
|
120
|
+
clearTimeout(flow.timer);
|
|
121
|
+
}
|
|
122
|
+
this.active.clear();
|
|
123
|
+
this.sessions.clear();
|
|
124
|
+
this.flows.clear();
|
|
125
|
+
}
|
|
126
|
+
/** Invocation-time lookup: stale socket ancestry must use the ordinary bridge. */
|
|
127
|
+
static current(identity) {
|
|
128
|
+
const scope = execution.getStore();
|
|
129
|
+
const flow = scope?.service.active.get(scope.token);
|
|
130
|
+
if (!scope || !flow || (identity !== undefined && identity !== flow.identity) || !flow.isCurrent())
|
|
131
|
+
return undefined;
|
|
132
|
+
return new McpAuthDispatcher(scope.service, flow, scope.discovery === true);
|
|
133
|
+
}
|
|
134
|
+
requireFlow(id) {
|
|
135
|
+
const flow = this.flows.get(id);
|
|
136
|
+
if (!flow)
|
|
137
|
+
throw new Error("MCP authentication flow not found");
|
|
138
|
+
return flow;
|
|
139
|
+
}
|
|
140
|
+
snapshot(flow) { return structuredClone(flow.state); }
|
|
141
|
+
requestCancel(flow) {
|
|
142
|
+
flow.state.cancelRequested = true;
|
|
143
|
+
flow.pending?.settle(undefined);
|
|
144
|
+
}
|
|
145
|
+
wait(flow, title, options, values, placeholder) {
|
|
146
|
+
if (flow.state.cancelRequested === true || options?.signal?.aborted === true)
|
|
147
|
+
return Promise.resolve(undefined);
|
|
148
|
+
if (flow.pending)
|
|
149
|
+
return Promise.reject(new Error("An MCP authentication request is already pending"));
|
|
150
|
+
if (title.length > MAX_TEXT || (placeholder?.length ?? 0) > MAX_TEXT || (values && (values.length > 200 || values.some((value) => value.length > MAX_TEXT))))
|
|
151
|
+
return Promise.reject(new Error("MCP authentication prompt is too large"));
|
|
152
|
+
const id = randomUUID();
|
|
153
|
+
if (values)
|
|
154
|
+
flow.state.select = { requestId: id, message: title, options: values.map((value) => ({ value, label: value })) };
|
|
155
|
+
else
|
|
156
|
+
flow.state.prompt = { requestId: id, message: title, promptType: "text", ...(placeholder === undefined ? {} : { placeholder }) };
|
|
157
|
+
return new Promise((resolve) => {
|
|
158
|
+
let timer;
|
|
159
|
+
const settle = (value) => {
|
|
160
|
+
if (flow.pending?.id !== id)
|
|
161
|
+
return;
|
|
162
|
+
clearTimeout(timer);
|
|
163
|
+
options?.signal?.removeEventListener("abort", abort);
|
|
164
|
+
delete flow.pending;
|
|
165
|
+
delete flow.state.prompt;
|
|
166
|
+
delete flow.state.select;
|
|
167
|
+
resolve(value);
|
|
168
|
+
};
|
|
169
|
+
// Pi aborts the losing input when its browser callback wins. This only
|
|
170
|
+
// dismisses the prompt; it is not cancellation of the auth operation.
|
|
171
|
+
const abort = () => { settle(undefined); };
|
|
172
|
+
flow.pending = { id, settle, ...(values === undefined ? {} : { values }) };
|
|
173
|
+
if (options?.timeout !== undefined && options.timeout > 0) {
|
|
174
|
+
timer = setTimeout(abort, options.timeout);
|
|
175
|
+
timer.unref();
|
|
176
|
+
}
|
|
177
|
+
options?.signal?.addEventListener("abort", abort, { once: true });
|
|
178
|
+
if (options?.signal?.aborted === true)
|
|
179
|
+
abort();
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** Narrow adapter used by the stable session proxy and builtin openUrl hook. */
|
|
184
|
+
class McpAuthDispatcher {
|
|
185
|
+
constructor(service, flow, discovery = false) {
|
|
186
|
+
this.service = service;
|
|
187
|
+
this.flow = flow;
|
|
188
|
+
this.discovery = discovery;
|
|
189
|
+
}
|
|
190
|
+
selectServer(servers) {
|
|
191
|
+
const result = this.select("Choose an MCP server", servers.map((server) => server.name));
|
|
192
|
+
if (this.flow.state.select)
|
|
193
|
+
this.flow.state.select.options = servers.map((server) => ({ value: server.name, label: server.name, ...(server.description === undefined ? {} : { description: server.description }) }));
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
setServer(name) { this.flow.state.providerName = name; }
|
|
197
|
+
isCancelled() { return this.flow.state.cancelRequested === true; }
|
|
198
|
+
notify(message) {
|
|
199
|
+
if (this.discovery)
|
|
200
|
+
return;
|
|
201
|
+
const url = this.flow.state.auth?.url;
|
|
202
|
+
if (url !== undefined && message.includes(url))
|
|
203
|
+
return;
|
|
204
|
+
this.flow.state.progress.push(message.slice(0, MAX_TEXT));
|
|
205
|
+
this.flow.state.progress = this.flow.state.progress.slice(-MAX_PROGRESS);
|
|
206
|
+
}
|
|
207
|
+
openUrl(url) {
|
|
208
|
+
if (this.discovery)
|
|
209
|
+
return;
|
|
210
|
+
if (url.length > MAX_TEXT)
|
|
211
|
+
throw new Error("MCP authorization URL is too large");
|
|
212
|
+
const parsed = new URL(url);
|
|
213
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:")
|
|
214
|
+
throw new Error("Unsupported MCP authorization URL");
|
|
215
|
+
this.flow.state.auth = { url };
|
|
216
|
+
this.flow.state.progress = this.flow.state.progress.filter((message) => !message.includes(url));
|
|
217
|
+
}
|
|
218
|
+
error(message) { this.flow.commandError = message.slice(0, MAX_TEXT); this.notify(message); }
|
|
219
|
+
input(title, placeholder, options) {
|
|
220
|
+
if (this.discovery) {
|
|
221
|
+
this.flow.commandError = "MCP discovery cannot request input";
|
|
222
|
+
return Promise.reject(new Error(this.flow.commandError));
|
|
223
|
+
}
|
|
224
|
+
return this.service.wait(this.flow, title, options, undefined, placeholder);
|
|
225
|
+
}
|
|
226
|
+
select(title, values, options) {
|
|
227
|
+
if (this.discovery) {
|
|
228
|
+
this.flow.commandError = "MCP discovery cannot request input";
|
|
229
|
+
return Promise.reject(new Error(this.flow.commandError));
|
|
230
|
+
}
|
|
231
|
+
return this.service.wait(this.flow, title, options, values);
|
|
232
|
+
}
|
|
233
|
+
async confirm(title, message, options) {
|
|
234
|
+
return await this.select(`${title}\n${message}`, ["Yes", "No"], options) === "Yes";
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=mcpAuthFlowService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpAuthFlowService.js","sourceRoot":"","sources":["../../../src/server/sessions/mcpAuthFlowService.ts"],"names":[],"mappings":"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"}
|