@chainingintention/pi-web-cn 1.202610.4 → 2.202610.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/README.md +2 -2
- package/dist/cli.js +31 -7
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/PiWebApp-BXSziMEg.js +4921 -0
- package/dist/client/assets/classic-CyM97Akm.css +54 -0
- package/dist/client/assets/external-B9K8duyP.js +2 -0
- package/dist/client/assets/graphite-DquaqFXU.css +54 -0
- package/dist/client/assets/index-cdtUOfOW.js +2 -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/assets/vendor-editor-core-BfnHL1Dg.js +10 -0
- package/dist/client/assets/{vendor-editor-languages-DOCw3vc9.js → vendor-editor-languages-bNquDJP0.js} +1 -1
- package/dist/client/index.html +3 -47
- package/dist/config.js +11 -2
- package/dist/config.js.map +1 -1
- package/dist/nativeServices/installedServiceDefinitions.js +10 -7
- package/dist/nativeServices/installedServiceDefinitions.js.map +1 -1
- package/dist/pi-packages/captains-log/dist/browser/index.js +43 -47
- package/dist/pi-packages/captains-log/dist/browser/panel.js +6 -10
- package/dist/pi-packages/captains-log/dist/companion.js +1 -1
- package/dist/pi-packages/captains-log/package.json +4 -4
- package/dist/pi-packages/relays/extensions/index.js +61 -0
- package/dist/pi-packages/relays/package.json +10 -1
- package/dist/pi-packages/relays/pi-web-plugin.js +52 -2
- package/dist/pi-packages/relays/prompts/relay-worktree.md +6 -16
- package/dist/pi-packages/relays/prompts/relay.md +6 -33
- package/dist/pi-packages/relays/relayDispatch.js +67 -0
- package/dist/pi-packages/relays/relayIdentity.js +37 -0
- package/dist/pi-packages/relays/relaysPanelElement.js +75 -37
- package/dist/pi-packages/relays/skills/relay/SKILL.md +24 -68
- package/dist/pi-packages/relays/skills/relay-runner/SKILL.md +40 -219
- package/dist/pi-packages/workflows/browser/pi-web-plugin.js +42 -0
- package/dist/pi-packages/workflows/browser/worktreeDialog.js +170 -0
- package/dist/pi-packages/workflows/package.json +23 -0
- package/dist/pi-packages/workflows/prompts/worktree.md +21 -0
- package/dist/pi-packages/workflows/server-plugin.js +586 -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 +115 -105
- package/dist/pi-web-plugins/git/browser/git-panel.js +60 -46
- package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +23 -3
- package/dist/pi-web-plugins/git/git-backend.js +20 -1
- package/dist/pi-web-plugins/git/server-plugin.js +20 -3
- package/dist/pi-web-plugins/git/workspace-discovery-notify.cjs +14 -0
- package/dist/pi-web-plugins/git/workspaceDiscoveryHooks.js +186 -0
- package/dist/pi-web-plugins/info/infoInternals.js +3 -3
- package/dist/pi-web-plugins/info/pi-web-plugin.js +1 -1
- package/dist/pi-web-plugins/mermaid/browser/mermaid-engine.js +1087 -422
- package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +8 -3
- package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +39 -33
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +13 -13
- package/dist/pi-web-plugins/updates/updatesLogic.js +4 -5
- package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +21 -1
- package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +39 -22
- package/dist/pi-web-plugins/zh-cn/bundled.json +44 -1
- package/dist/pi-web-plugins/zh-cn/cli.json +60 -1
- package/dist/pi-web-plugins/zh-cn/client.json +7 -1
- package/dist/pi-web-plugins/zh-cn/components.json +252 -2
- package/dist/pi-web-plugins/zh-cn/config-errors.json +17 -1
- package/dist/pi-web-plugins/zh-cn/files.json +10 -1
- package/dist/pi-web-plugins/zh-cn/main.json +1 -1
- package/dist/pi-web-plugins/zh-cn/provider-auth.json +2 -1
- package/dist/pi-web-plugins/zh-cn/server.json +83 -1
- package/dist/piAi.js +4 -0
- package/dist/piAi.js.map +1 -0
- package/dist/piRuntime.js +150 -0
- package/dist/piRuntime.js.map +1 -0
- package/dist/piSdk.js +5 -0
- package/dist/piSdk.js.map +1 -0
- package/dist/piWebUpdate.js +508 -0
- package/dist/piWebUpdate.js.map +1 -0
- package/dist/piWebVersionReport.js +43 -1
- package/dist/piWebVersionReport.js.map +1 -1
- package/dist/plugin-api.d.ts +393 -51
- package/dist/server/activity/workspaceActivityService.js +8 -1
- package/dist/server/activity/workspaceActivityService.js.map +1 -1
- package/dist/server/app.js +19 -4
- package/dist/server/app.js.map +1 -1
- package/dist/server/browserMessageProjection.js +39 -20
- package/dist/server/browserMessageProjection.js.map +1 -1
- package/dist/server/configRoutes.js +8 -0
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/index.js +10 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/knownAutoInstallPiPackages.js +6 -0
- package/dist/server/knownAutoInstallPiPackages.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +37 -2
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/navigationPreferenceRoutes.js +59 -0
- package/dist/server/navigationPreferenceRoutes.js.map +1 -0
- package/dist/server/piPackageService.js +1 -1
- package/dist/server/piPackageService.js.map +1 -1
- package/dist/server/piWebPluginCatalog.js +1 -1
- package/dist/server/piWebPluginCatalog.js.map +1 -1
- package/dist/server/piWebPluginService.js +7 -1
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebStatus.js +17 -56
- package/dist/server/piWebStatus.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 +40 -42
- package/dist/server/plugins/pluginBackendChannelProxyRoutes.js.map +1 -1
- package/dist/server/plugins/pluginBackendProxyRoutes.js +40 -44
- package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -1
- package/dist/server/plugins/pluginBackendRegistry.js +66 -35
- package/dist/server/plugins/pluginBackendRegistry.js.map +1 -1
- package/dist/server/plugins/projectPluginSettings.js +95 -0
- package/dist/server/plugins/projectPluginSettings.js.map +1 -0
- package/dist/server/plugins/serverPluginCatalogCapability.js +106 -0
- package/dist/server/plugins/serverPluginCatalogCapability.js.map +1 -0
- package/dist/server/plugins/serverPluginRuntime.js +47 -11
- package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
- package/dist/server/projectTrustRoutes.js +1 -1
- package/dist/server/projectTrustRoutes.js.map +1 -1
- package/dist/server/projects/projectLifecycleService.js +17 -7
- package/dist/server/projects/projectLifecycleService.js.map +1 -1
- package/dist/server/realtime/sessionEventHub.js +22 -9
- package/dist/server/realtime/sessionEventHub.js.map +1 -1
- package/dist/server/sessiond/agentHttpDispatcher.js +1 -1
- package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -1
- package/dist/server/sessiond/autoInstallPiPackages.js +3 -3
- package/dist/server/sessiond/pluginBackendChannelRoutes.js +27 -14
- package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -1
- package/dist/server/sessiond/pluginBackendRoutes.js +56 -49
- package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -1
- package/dist/server/sessiond/pluginCatalogRoutes.js +41 -0
- package/dist/server/sessiond/pluginCatalogRoutes.js.map +1 -0
- package/dist/server/sessiond/sessionProxyRoutes.js +46 -1
- 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/workspaceCatalogRoutes.js +6 -2
- package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -1
- package/dist/server/sessiond/workspaceNotificationRoutes.js +55 -0
- package/dist/server/sessiond/workspaceNotificationRoutes.js.map +1 -0
- package/dist/server/sessiond.js +58 -8
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/askUserDomain.js +232 -0
- package/dist/server/sessions/askUserDomain.js.map +1 -0
- package/dist/server/sessions/askUserTool.js +18 -18
- package/dist/server/sessions/askUserTool.js.map +1 -1
- package/dist/server/sessions/attachmentService.js +1 -1
- package/dist/server/sessions/attachmentService.js.map +1 -1
- package/dist/server/sessions/authRoutes.js +12 -0
- package/dist/server/sessions/authRoutes.js.map +1 -1
- package/dist/server/sessions/authService.js +11 -1
- package/dist/server/sessions/authService.js.map +1 -1
- package/dist/server/sessions/builtinExtensionFactories.js +36 -0
- package/dist/server/sessions/builtinExtensionFactories.js.map +1 -0
- package/dist/server/sessions/companionBackend.js +286 -0
- package/dist/server/sessions/companionBackend.js.map +1 -0
- package/dist/server/sessions/dockerEnvironmentFacts.js +16 -1
- package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -1
- package/dist/server/sessions/extensionSessionDispatch.js +76 -0
- package/dist/server/sessions/extensionSessionDispatch.js.map +1 -0
- package/dist/server/sessions/globalProviderPolicy.js +88 -19
- package/dist/server/sessions/globalProviderPolicy.js.map +1 -1
- package/dist/server/sessions/managementAgentTools.js +2 -2
- package/dist/server/sessions/managementAgentTools.js.map +1 -1
- package/dist/server/sessions/mcpAuthFlowService.js +289 -0
- package/dist/server/sessions/mcpAuthFlowService.js.map +1 -0
- package/dist/server/sessions/mcpAuthRoutes.js +104 -0
- package/dist/server/sessions/mcpAuthRoutes.js.map +1 -0
- package/dist/server/sessions/mcpOAuthCredentialAdapter.js +92 -0
- package/dist/server/sessions/mcpOAuthCredentialAdapter.js.map +1 -0
- package/dist/server/sessions/messageHistoryTarget.js +79 -0
- package/dist/server/sessions/messageHistoryTarget.js.map +1 -0
- package/dist/server/sessions/piSessionEventConnections.js +5 -2
- package/dist/server/sessions/piSessionEventConnections.js.map +1 -1
- package/dist/server/sessions/piSessionManagerGateway.js +32 -27
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +1296 -341
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/plainTextTheme.js +1 -1
- package/dist/server/sessions/plainTextTheme.js.map +1 -1
- package/dist/server/sessions/projectAuthService.js +1 -1
- package/dist/server/sessions/projectAuthService.js.map +1 -1
- package/dist/server/sessions/projectSettingsScope.js +1 -1
- package/dist/server/sessions/projectSettingsScope.js.map +1 -1
- package/dist/server/sessions/projectTrust.js +1 -1
- package/dist/server/sessions/projectTrust.js.map +1 -1
- package/dist/server/sessions/queuedMessageMutation.js +170 -0
- package/dist/server/sessions/queuedMessageMutation.js.map +1 -0
- package/dist/server/sessions/relaySkill.js +57 -7
- package/dist/server/sessions/relaySkill.js.map +1 -1
- package/dist/server/sessions/sessionArchiveMapping.js +6 -0
- package/dist/server/sessions/sessionArchiveMapping.js.map +1 -1
- package/dist/server/sessions/sessionArchiveStore.js +5 -1
- package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
- package/dist/server/sessions/sessionArchiveTree.js +2 -2
- package/dist/server/sessions/sessionArchiveTree.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +11 -24
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionImageDimensions.js +31 -0
- package/dist/server/sessions/sessionImageDimensions.js.map +1 -0
- package/dist/server/sessions/sessionMediaIndex.js +191 -0
- package/dist/server/sessions/sessionMediaIndex.js.map +1 -0
- package/dist/server/sessions/sessionMetadata.js +51 -0
- package/dist/server/sessions/sessionMetadata.js.map +1 -0
- package/dist/server/sessions/sessionModelScope.js +2 -2
- package/dist/server/sessions/sessionModelScope.js.map +1 -1
- package/dist/server/sessions/sessionNameGenerator.js +13 -33
- package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
- package/dist/server/sessions/sessionReadAccess.js +41 -0
- package/dist/server/sessions/sessionReadAccess.js.map +1 -0
- package/dist/server/sessions/sessionRoutes.js +61 -6
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/sessionSummaryScanner.js +62 -5
- package/dist/server/sessions/sessionSummaryScanner.js.map +1 -1
- package/dist/server/sessions/sessionUiEvents.js +17 -4
- package/dist/server/sessions/sessionUiEvents.js.map +1 -1
- package/dist/server/sessions/spawnSessionTool.js +11 -3
- package/dist/server/sessions/spawnSessionTool.js.map +1 -1
- package/dist/server/sessions/spawnSubsessionTool.js +35 -19
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
- package/dist/server/sessions/subsessionCompletionDelivery.js +15 -0
- package/dist/server/sessions/subsessionCompletionDelivery.js.map +1 -0
- package/dist/server/sessions/subsessionCompletionInbox.js +134 -0
- package/dist/server/sessions/subsessionCompletionInbox.js.map +1 -0
- package/dist/server/sessions/subsessionProvenance.js +27 -0
- package/dist/server/sessions/subsessionProvenance.js.map +1 -0
- package/dist/server/sessions/transcriptMarkdown.js +48 -0
- package/dist/server/sessions/transcriptMarkdown.js.map +1 -0
- package/dist/server/sessions/transcriptMessages.js +3 -0
- package/dist/server/sessions/transcriptMessages.js.map +1 -1
- package/dist/server/startupLogger.js +13 -0
- package/dist/server/startupLogger.js.map +1 -0
- package/dist/server/startupUrls.js +27 -0
- package/dist/server/startupUrls.js.map +1 -0
- package/dist/server/status/machineStatusService.js +15 -9
- package/dist/server/status/machineStatusService.js.map +1 -1
- package/dist/server/storage/navigationPreferenceStore.js +138 -0
- package/dist/server/storage/navigationPreferenceStore.js.map +1 -0
- package/dist/server/webSocketBridge.js +9 -0
- package/dist/server/webSocketBridge.js.map +1 -1
- package/dist/server/workbench/skillSync.js +1 -1
- package/dist/server/workbench/skillSync.js.map +1 -1
- package/dist/server/workbench/workbenchTools.js +2 -2
- package/dist/server/workbench/workbenchTools.js.map +1 -1
- package/dist/server/workspaces/filePreviewService.js +5 -2
- package/dist/server/workspaces/filePreviewService.js.map +1 -1
- package/dist/server/workspaces/projectPiWebConfig.js +87 -6
- package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
- package/dist/server/workspaces/workspaceChangeNotifier.js +12 -0
- package/dist/server/workspaces/workspaceChangeNotifier.js.map +1 -0
- package/dist/server/workspaces/workspaceNotificationCommand.js +64 -0
- package/dist/server/workspaces/workspaceNotificationCommand.js.map +1 -0
- package/dist/server/workspaces/workspaceProviderRegistry.js +53 -0
- package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -1
- package/dist/server-plugin-api.d.ts +83 -15
- package/dist/server-plugin-api.js +25 -0
- package/dist/server-plugin-api.js.map +1 -1
- package/dist/sessiond/sessionDaemonClient.js +27 -3
- package/dist/sessiond/sessionDaemonClient.js.map +1 -1
- package/dist/shared/apiTypes.js +3 -2
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +3 -0
- package/dist/shared/capabilities.js.map +1 -1
- package/dist/shared/federatedRoutes.js +25 -5
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/machineStatus.js +11 -2
- package/dist/shared/machineStatus.js.map +1 -1
- package/dist/shared/navigationPreferences.js +6 -0
- package/dist/shared/navigationPreferences.js.map +1 -0
- package/dist/shared/piWebConfigParsing.js +54 -0
- package/dist/shared/piWebConfigParsing.js.map +1 -1
- package/dist/shared/pluginApiTypes.d.ts +55 -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/dist/shared/sessionMedia.js +12 -0
- package/dist/shared/sessionMedia.js.map +1 -0
- package/dist/shared/streamingBehavior.js +8 -0
- package/dist/shared/streamingBehavior.js.map +1 -0
- package/dist/shared/themePreference.js +24 -0
- package/dist/shared/themePreference.js.map +1 -0
- package/dist/workspaceNotificationCli.js +95 -0
- package/dist/workspaceNotificationCli.js.map +1 -0
- package/docs/README.md +31 -0
- package/docs/config.md +77 -4
- package/docs/plugins.md +60 -11
- package/examples/session-bridge-plugin/package.json +2 -2
- package/examples/session-bridge-plugin/src/browser/index.ts +1 -1
- package/examples/session-bridge-plugin/src/companion.ts +1 -1
- package/extensions/pi-web.ts +3 -1
- package/package.json +46 -34
- package/skills/README.md +10 -9
- package/skills/relay/SKILL.md +24 -68
- package/skills/relay-runner/SKILL.md +40 -219
- package/dist/client/assets/PiWebApp-CN3g7SqA.js +0 -4362
- package/dist/client/assets/external-DUGCSDhZ.js +0 -2
- package/dist/client/assets/index-JduZlbIF.js +0 -2
- package/dist/client/assets/vendor-editor-core-YWog6mAR.js +0 -10
- package/dist/server/sessions/pendingAskStore.js +0 -275
- package/dist/server/sessions/pendingAskStore.js.map +0 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from "node:path";
|
|
2
|
+
import { loadProjectPiWebConfig, snapshotPluginSettings } from "../workspaces/projectPiWebConfig.js";
|
|
3
|
+
/**
|
|
4
|
+
* Daemon-lifetime project overrides, including absent files and scope errors.
|
|
5
|
+
* Only a new instance observes edits; each invocation supplies its own global base.
|
|
6
|
+
*/
|
|
7
|
+
export class ProjectPluginSettingsSnapshots {
|
|
8
|
+
constructor(projects, { timeoutMs = 5_000, loadConfig = loadProjectPiWebConfig } = {}) {
|
|
9
|
+
this.projects = projects;
|
|
10
|
+
this.scopes = new Map();
|
|
11
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0)
|
|
12
|
+
throw new Error("Project config timeoutMs must be a positive integer");
|
|
13
|
+
this.timeoutMs = timeoutMs;
|
|
14
|
+
this.loadConfig = loadConfig;
|
|
15
|
+
}
|
|
16
|
+
/** Optional startup preload. Bad or timed-out scopes are retained without rejecting startup. */
|
|
17
|
+
async initialize(projects) {
|
|
18
|
+
await Promise.all(projects.map(async ({ id }) => {
|
|
19
|
+
const registered = await this.requireProject(id);
|
|
20
|
+
await this.scopeSnapshot(registered);
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
async resolve(pluginId, globalSettings, project, signal) {
|
|
24
|
+
signal.throwIfAborted();
|
|
25
|
+
// Capture before yielding: callers cannot change the base during project I/O.
|
|
26
|
+
const base = snapshotPluginSettings(globalSettings, `Global settings for server plugin ${pluginId}`);
|
|
27
|
+
try {
|
|
28
|
+
const registered = await this.requireProject(project.id);
|
|
29
|
+
signal.throwIfAborted();
|
|
30
|
+
const snapshot = await this.scopeSnapshot(registered);
|
|
31
|
+
signal.throwIfAborted();
|
|
32
|
+
if ("error" in snapshot)
|
|
33
|
+
throw snapshot.error;
|
|
34
|
+
const overrides = Object.hasOwn(snapshot.settings, pluginId) ? snapshot.settings[pluginId] : undefined;
|
|
35
|
+
return snapshotPluginSettings({ ...base, ...overrides }, `Project settings for server plugin ${pluginId}`);
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
signal.throwIfAborted();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async requireProject(id) {
|
|
42
|
+
if (id === "")
|
|
43
|
+
throw new Error("PI WEB plugin settings require a registered project id");
|
|
44
|
+
const project = await this.projects.requireProject(id);
|
|
45
|
+
if (project.id !== id)
|
|
46
|
+
throw new Error("PI WEB plugin settings resolved a mismatched project id");
|
|
47
|
+
if (!isAbsolute(project.path))
|
|
48
|
+
throw new Error("PI WEB plugin settings require an absolute registered project path");
|
|
49
|
+
// Never read a caller-supplied path, even for an already cached id.
|
|
50
|
+
return { id, path: resolve(project.path) };
|
|
51
|
+
}
|
|
52
|
+
scopeSnapshot(project) {
|
|
53
|
+
const key = JSON.stringify([project.id, project.path]);
|
|
54
|
+
let snapshot = this.scopes.get(key);
|
|
55
|
+
if (snapshot === undefined) {
|
|
56
|
+
snapshot = this.loadScope(project);
|
|
57
|
+
this.scopes.set(key, snapshot);
|
|
58
|
+
}
|
|
59
|
+
return snapshot;
|
|
60
|
+
}
|
|
61
|
+
async loadScope(project) {
|
|
62
|
+
// This deadline belongs to the shared snapshot, not to any one caller.
|
|
63
|
+
const controller = new AbortController();
|
|
64
|
+
let timeout;
|
|
65
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
66
|
+
timeout = setTimeout(() => {
|
|
67
|
+
const error = new Error(`Project config read timed out after ${String(this.timeoutMs)}ms`);
|
|
68
|
+
reject(error);
|
|
69
|
+
controller.abort(error);
|
|
70
|
+
}, this.timeoutMs);
|
|
71
|
+
timeout.unref();
|
|
72
|
+
});
|
|
73
|
+
try {
|
|
74
|
+
// Race as well as abort: stat/open and an uncooperative reader may not
|
|
75
|
+
// settle on cancellation. A late result must never replace this snapshot.
|
|
76
|
+
const loaded = await Promise.race([
|
|
77
|
+
Promise.resolve().then(() => this.loadConfig(project.path, controller.signal)),
|
|
78
|
+
deadline,
|
|
79
|
+
]);
|
|
80
|
+
const settings = Object.freeze(Object.fromEntries(Object.entries(loaded.config.plugins ?? {})
|
|
81
|
+
.flatMap(([pluginId, config]) => config.settings === undefined ? [] : [[pluginId, config.settings]])));
|
|
82
|
+
return Object.freeze({ settings });
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// Fulfilled error snapshots avoid unhandled preload rejections and fail only
|
|
86
|
+
// consumers of this project. They must not fall back to global settings.
|
|
87
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
88
|
+
return Object.freeze({ error: new Error(`PI WEB plugin settings for project ${project.id} (${project.path}) could not be loaded: ${message}`, { cause: error }) });
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
clearTimeout(timeout);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=projectPluginSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectPluginSettings.js","sourceRoot":"","sources":["../../../src/server/plugins/projectPluginSettings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from "node:path";
|
|
2
|
+
import { PI_WEB_HOST_CATALOG_CAPABILITY, } from "../../shared/pluginCatalogTypes.js";
|
|
3
|
+
/** Register after provider topology settles, alongside the workspace authority factory. */
|
|
4
|
+
export function createServerPluginCatalogCapabilityFactory(options) {
|
|
5
|
+
return Object.freeze({
|
|
6
|
+
capability: PI_WEB_HOST_CATALOG_CAPABILITY,
|
|
7
|
+
create(context) {
|
|
8
|
+
const disposal = new AbortController();
|
|
9
|
+
const lifetime = AbortSignal.any([context.lifetimeSignal, disposal.signal]);
|
|
10
|
+
function signalFor(read) {
|
|
11
|
+
return read?.signal === undefined ? lifetime : AbortSignal.any([lifetime, read.signal]);
|
|
12
|
+
}
|
|
13
|
+
function assertActive(signal) {
|
|
14
|
+
if (lifetime.aborted)
|
|
15
|
+
throw new Error(`PI WEB host catalog for server plugin ${context.pluginId} is no longer active`, { cause: lifetime.reason });
|
|
16
|
+
signal.throwIfAborted();
|
|
17
|
+
}
|
|
18
|
+
async function read(requested, operation) {
|
|
19
|
+
const signal = signalFor(requested);
|
|
20
|
+
assertActive(signal);
|
|
21
|
+
try {
|
|
22
|
+
const result = await operation(signal);
|
|
23
|
+
assertActive(signal);
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
assertActive(signal);
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function project(projectId, signal) {
|
|
32
|
+
assertActive(signal);
|
|
33
|
+
const result = await options.projects.requireProject(projectId);
|
|
34
|
+
assertActive(signal);
|
|
35
|
+
if (result.id !== projectId)
|
|
36
|
+
throw new Error("Catalog project authority returned a mismatched project");
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
async function workspaces(projectId, signal) {
|
|
40
|
+
const selected = await project(projectId, signal);
|
|
41
|
+
const resolution = await options.workspaces.resolve(selected, signal);
|
|
42
|
+
assertActive(signal);
|
|
43
|
+
if (resolution.projectId !== projectId)
|
|
44
|
+
throw new Error("Catalog workspace authority returned a mismatched project");
|
|
45
|
+
return resolution.workspaces.map((workspace) => {
|
|
46
|
+
if (workspace.projectId !== projectId)
|
|
47
|
+
throw new Error("Catalog workspace is outside selected project");
|
|
48
|
+
return {
|
|
49
|
+
id: workspace.id, projectId, path: absolutePath(workspace.path), label: workspace.label, isMain: workspace.isMain,
|
|
50
|
+
...(workspace.provider === undefined ? {} : { provider: workspace.provider }),
|
|
51
|
+
...(workspace.removal === undefined ? {} : { removal: workspace.removal }),
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function workspace(selection, signal) {
|
|
56
|
+
const result = (await workspaces(selection.projectId, signal)).find(({ id }) => id === selection.workspaceId);
|
|
57
|
+
if (result === undefined)
|
|
58
|
+
throw new Error("Catalog selected workspace is stale or unavailable");
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
async function sessions(selection, signal) {
|
|
62
|
+
const selected = await workspace(selection, signal);
|
|
63
|
+
const rows = await options.sessions.listCatalogSessions(selected.path, signal);
|
|
64
|
+
assertActive(signal);
|
|
65
|
+
// A reader must not supply records from a different workspace, even for get-by-id.
|
|
66
|
+
if (rows.some((row) => absolutePath(row.cwd) !== selected.path))
|
|
67
|
+
throw new Error("Catalog session is outside selected workspace");
|
|
68
|
+
return rows;
|
|
69
|
+
}
|
|
70
|
+
const value = PI_WEB_HOST_CATALOG_CAPABILITY.parse({
|
|
71
|
+
version: 1,
|
|
72
|
+
projects: {
|
|
73
|
+
list: (requested) => read(requested, async (signal) => {
|
|
74
|
+
const rows = await options.projects.list();
|
|
75
|
+
assertActive(signal);
|
|
76
|
+
return rows.map(projectSnapshot);
|
|
77
|
+
}),
|
|
78
|
+
get: (id, requested) => read(requested, async (signal) => projectSnapshot(await project(id, signal))),
|
|
79
|
+
},
|
|
80
|
+
workspaces: {
|
|
81
|
+
list: (id, requested) => read(requested, (signal) => workspaces(id, signal)),
|
|
82
|
+
get: (selection, requested) => read(requested, (signal) => workspace(selection, signal)),
|
|
83
|
+
},
|
|
84
|
+
sessions: {
|
|
85
|
+
list: (selection, requested) => read(requested, (signal) => sessions(selection, signal)),
|
|
86
|
+
get: (selection, requested) => read(requested, async (signal) => {
|
|
87
|
+
const result = (await sessions({ projectId: selection.projectId, workspaceId: selection.workspaceId }, signal)).find(({ id }) => id === selection.sessionId);
|
|
88
|
+
if (result === undefined)
|
|
89
|
+
throw new Error("Catalog selected session is stale or unavailable");
|
|
90
|
+
return result;
|
|
91
|
+
}),
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
return Object.freeze({ value, dispose: () => { disposal.abort(); } });
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function absolutePath(path) {
|
|
99
|
+
if (!isAbsolute(path))
|
|
100
|
+
throw new Error("Catalog authority returned a non-absolute path");
|
|
101
|
+
return resolve(path);
|
|
102
|
+
}
|
|
103
|
+
function projectSnapshot(project) {
|
|
104
|
+
return { id: project.id, name: project.name, path: absolutePath(project.path) };
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=serverPluginCatalogCapability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverPluginCatalogCapability.js","sourceRoot":"","sources":["../../../src/server/plugins/serverPluginCatalogCapability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EACL,8BAA8B,GAO/B,MAAM,oCAAoC,CAAC;AAc5C,2FAA2F;AAC3F,MAAM,UAAU,0CAA0C,CACxD,OAAmD;IAEnD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,UAAU,EAAE,8BAA8B;QAC1C,MAAM,CAAC,OAA0C;YAC/C,MAAM,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5E,SAAS,SAAS,CAAC,IAA+B;gBAChD,OAAO,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAC1F,CAAC;YACD,SAAS,YAAY,CAAC,MAAmB;gBACvC,IAAI,QAAQ,CAAC,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,OAAO,CAAC,QAAQ,sBAAsB,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBACnJ,MAAM,CAAC,cAAc,EAAE,CAAC;YAC1B,CAAC;YACD,KAAK,UAAU,IAAI,CAAI,SAA+C,EAAE,SAA8C;gBACpH,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;gBACpC,YAAY,CAAC,MAAM,CAAC,CAAC;gBACrB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;oBACvC,YAAY,CAAC,MAAM,CAAC,CAAC;oBACrB,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,YAAY,CAAC,MAAM,CAAC,CAAC;oBACrB,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YACD,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,MAAmB;gBAC3D,YAAY,CAAC,MAAM,CAAC,CAAC;gBACrB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;gBAChE,YAAY,CAAC,MAAM,CAAC,CAAC;gBACrB,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;gBACxG,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,KAAK,UAAU,UAAU,CAAC,SAAiB,EAAE,MAAmB;gBAC9D,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBAClD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBACtE,YAAY,CAAC,MAAM,CAAC,CAAC;gBACrB,IAAI,UAAU,CAAC,SAAS,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;gBACrH,OAAO,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;oBAC7C,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS;wBAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;oBACxG,OAAO;wBACL,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM;wBACjH,GAAG,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC;wBAC7E,GAAG,CAAC,SAAS,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC;qBAC3E,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YACD,KAAK,UAAU,SAAS,CAAC,SAAmC,EAAE,MAAmB;gBAC/E,MAAM,MAAM,GAAG,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,WAAW,CAAC,CAAC;gBAC9G,IAAI,MAAM,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;gBAChG,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,KAAK,UAAU,QAAQ,CAAC,SAAmC,EAAE,MAAmB;gBAC9E,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBACpD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/E,YAAY,CAAC,MAAM,CAAC,CAAC;gBACrB,mFAAmF;gBACnF,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;gBAClI,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,GAAG,8BAA8B,CAAC,KAAK,CAAC;gBACjD,OAAO,EAAE,CAAC;gBACV,QAAQ,EAAE;oBACR,IAAI,EAAE,CAAC,SAAoC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;wBAC/E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;wBAC3C,YAAY,CAAC,MAAM,CAAC,CAAC;wBACrB,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;oBACnC,CAAC,CAAC;oBACF,GAAG,EAAE,CAAC,EAAU,EAAE,SAAoC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;iBACzI;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,CAAC,EAAU,EAAE,SAAoC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;oBAC/G,GAAG,EAAE,CAAC,SAAmC,EAAE,SAAoC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;iBAC9I;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,CAAC,SAAmC,EAAE,SAAoC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;oBAC7I,GAAG,EAAE,CAAC,SAAiC,EAAE,SAAoC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;wBACjH,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,SAAS,CAAC,CAAC;wBAC7J,IAAI,MAAM,KAAK,SAAS;4BAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;wBAC9F,OAAO,MAAM,CAAC;oBAChB,CAAC,CAAC;iBACH;aACF,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACzF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC;AACD,SAAS,eAAe,CAAC,OAAmD;IAC1E,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;AAClF,CAAC"}
|
|
@@ -22,13 +22,15 @@ export async function createServerPluginRuntime(options) {
|
|
|
22
22
|
return await ServerPluginRuntime.activate(snapshot, options);
|
|
23
23
|
}
|
|
24
24
|
export class ServerPluginRuntime {
|
|
25
|
-
constructor(dataDir, safeStart, diagnostics, logger, importer, execFile, lifecycleTimeoutMs, noticeSink, hostCapabilities, hostCapabilityFactories, lateHostCapabilities, enforceRequiredTerminal, translator) {
|
|
25
|
+
constructor(dataDir, safeStart, diagnostics, logger, importer, execFile, projectSettingsResolver, workspaceNotificationsFactory, lifecycleTimeoutMs, noticeSink, hostCapabilities, hostCapabilityFactories, lateHostCapabilities, enforceRequiredTerminal, translator) {
|
|
26
26
|
this.dataDir = dataDir;
|
|
27
27
|
this.safeStart = safeStart;
|
|
28
28
|
this.diagnostics = diagnostics;
|
|
29
29
|
this.logger = logger;
|
|
30
30
|
this.importer = importer;
|
|
31
31
|
this.execFile = execFile;
|
|
32
|
+
this.projectSettingsResolver = projectSettingsResolver;
|
|
33
|
+
this.workspaceNotificationsFactory = workspaceNotificationsFactory;
|
|
32
34
|
this.lifecycleTimeoutMs = lifecycleTimeoutMs;
|
|
33
35
|
this.noticeSink = noticeSink;
|
|
34
36
|
this.enforceRequiredTerminal = enforceRequiredTerminal;
|
|
@@ -51,7 +53,7 @@ export class ServerPluginRuntime {
|
|
|
51
53
|
this.registerHostCapability(capability);
|
|
52
54
|
}
|
|
53
55
|
static async activate(snapshot, options) {
|
|
54
|
-
const runtime = new ServerPluginRuntime(resolve(options.dataDir), options.safeStart, Object.freeze(snapshot.diagnostics.map((diagnostic) => Object.freeze({ ...diagnostic }))), options.logger, options.importer ?? importServerPluginModule, options.execFile ?? createServerPluginExecFile(), positiveInteger(options.lifecycleTimeoutMs, DEFAULT_LIFECYCLE_TIMEOUT_MS, "lifecycleTimeoutMs"), options.noticeSink, snapshotHostCapabilities(options.hostCapabilities), snapshotHostCapabilityFactories(options.hostCapabilityFactories), snapshotLateHostCapabilities(options.lateHostCapabilities), options.enforceRequiredTerminal !== false && options.safeStart !== "none", options.translator);
|
|
56
|
+
const runtime = new ServerPluginRuntime(resolve(options.dataDir), options.safeStart, Object.freeze(snapshot.diagnostics.map((diagnostic) => Object.freeze({ ...diagnostic }))), options.logger, options.importer ?? importServerPluginModule, options.execFile ?? createServerPluginExecFile(), options.projectSettingsResolver, options.workspaceNotificationsFactory, positiveInteger(options.lifecycleTimeoutMs, DEFAULT_LIFECYCLE_TIMEOUT_MS, "lifecycleTimeoutMs"), options.noticeSink, snapshotHostCapabilities(options.hostCapabilities), snapshotHostCapabilityFactories(options.hostCapabilityFactories), snapshotLateHostCapabilities(options.lateHostCapabilities), options.enforceRequiredTerminal !== false && options.safeStart !== "none", options.translator);
|
|
55
57
|
try {
|
|
56
58
|
await runtime.start(snapshot.plugins);
|
|
57
59
|
return runtime;
|
|
@@ -224,14 +226,21 @@ export class ServerPluginRuntime {
|
|
|
224
226
|
const dataDirectory = resolve(this.dataDir, "plugin-data", entry.id);
|
|
225
227
|
await mkdir(dataDirectory, { recursive: true });
|
|
226
228
|
const scopedLogger = createScopedLogger(entry.id, this.logger);
|
|
229
|
+
if (loadedPlugin.apiVersion === 3) {
|
|
230
|
+
this.logger.warn({ pluginId: entry.id, apiVersion: 3 }, "Server plugin API v3 is deprecated; migrate to API v5");
|
|
231
|
+
}
|
|
227
232
|
noticeReporter = createScopedNoticeReporter(entry.id, this.noticeSink);
|
|
233
|
+
const resolveProjectSettings = this.projectSettingsResolver?.bind(undefined, entry.id, settings);
|
|
234
|
+
const workspaceNotifications = this.workspaceNotificationsFactory?.(entry.id);
|
|
228
235
|
const activationValue = await runBounded(entry.id, phase, this.lifecycleTimeoutMs, (signal) => loadedPlugin.activate(Object.freeze({
|
|
229
|
-
apiVersion:
|
|
236
|
+
apiVersion: loadedPlugin.apiVersion,
|
|
230
237
|
pluginId: entry.id,
|
|
231
238
|
packageRoot: entry.packageRoot,
|
|
232
239
|
dataDirectory,
|
|
233
240
|
logger: scopedLogger,
|
|
234
241
|
settings,
|
|
242
|
+
...(resolveProjectSettings === undefined ? {} : { resolveProjectSettings }),
|
|
243
|
+
...(workspaceNotifications === undefined ? {} : { workspaceNotifications }),
|
|
235
244
|
...(noticeReporter === undefined ? {} : { notices: noticeReporter.reporter }),
|
|
236
245
|
execFile: this.execFile,
|
|
237
246
|
signal,
|
|
@@ -240,7 +249,7 @@ export class ServerPluginRuntime {
|
|
|
240
249
|
})));
|
|
241
250
|
rollbackDispose = activationDisposeForRollback(activationValue);
|
|
242
251
|
phase = "validate";
|
|
243
|
-
const loadedActivation = parseActivation(activationValue, entry.id);
|
|
252
|
+
const loadedActivation = parseActivation(activationValue, entry.id, loadedPlugin.apiVersion);
|
|
244
253
|
if (this.enforceRequiredTerminal && entry.id === REQUIRED_TERMINAL_PLUGIN_ID) {
|
|
245
254
|
requireTerminalActivation(loadedActivation);
|
|
246
255
|
}
|
|
@@ -475,6 +484,7 @@ export class ServerPluginRuntime {
|
|
|
475
484
|
source: staged.entry.source,
|
|
476
485
|
scope: staged.entry.scope,
|
|
477
486
|
moduleRevision: requireServerModule(staged.entry).revision,
|
|
487
|
+
apiVersion: staged.plugin.apiVersion,
|
|
478
488
|
backend: staged.activation.peer,
|
|
479
489
|
requires: this.resolvedCapabilityRequirements(staged),
|
|
480
490
|
});
|
|
@@ -681,7 +691,7 @@ function parsePluginExport(imported) {
|
|
|
681
691
|
const apiVersion = plugin["apiVersion"];
|
|
682
692
|
const name = plugin["name"];
|
|
683
693
|
const activateValue = plugin["activate"];
|
|
684
|
-
if (apiVersion !== 3) {
|
|
694
|
+
if (apiVersion !== 3 && apiVersion !== 5) {
|
|
685
695
|
throw new IncompatibleServerPluginError(`Unsupported server plugin API version: ${formatUnknown(apiVersion)}`);
|
|
686
696
|
}
|
|
687
697
|
if (typeof name !== "string" || name === "") {
|
|
@@ -692,6 +702,7 @@ function parsePluginExport(imported) {
|
|
|
692
702
|
}
|
|
693
703
|
const requires = snapshotCapabilityRequirements(plugin["requires"], `Server plugin ${name} requirements`);
|
|
694
704
|
return Object.freeze({
|
|
705
|
+
apiVersion,
|
|
695
706
|
name,
|
|
696
707
|
...(requires.length === 0 ? {} : { requires }),
|
|
697
708
|
activate(context) {
|
|
@@ -710,7 +721,7 @@ function activationDisposeForRollback(value) {
|
|
|
710
721
|
await Reflect.apply(dispose, value, [signal]);
|
|
711
722
|
};
|
|
712
723
|
}
|
|
713
|
-
function parseActivation(value, pluginId) {
|
|
724
|
+
function parseActivation(value, pluginId, apiVersion) {
|
|
714
725
|
if (!isRecord(value))
|
|
715
726
|
throw new IncompatibleServerPluginError("Server plugin activation must be an object");
|
|
716
727
|
if (value["workspaceProviders"] !== undefined) {
|
|
@@ -727,7 +738,7 @@ function parseActivation(value, pluginId) {
|
|
|
727
738
|
const provides = snapshotCapabilityProvisions(value["provides"], pluginId, `Server plugin ${pluginId} provisions`);
|
|
728
739
|
const candidate = {
|
|
729
740
|
workspaceProvider: workspaceProviderValue === undefined ? undefined : snapshotWorkspaceProvider(workspaceProviderValue),
|
|
730
|
-
peer: peerValue === undefined ? undefined : snapshotPluginPeer(peerValue),
|
|
741
|
+
peer: peerValue === undefined ? undefined : snapshotPluginPeer(peerValue, apiVersion),
|
|
731
742
|
provides,
|
|
732
743
|
start: value["start"],
|
|
733
744
|
dispose: value["dispose"],
|
|
@@ -1041,7 +1052,7 @@ function combinedDisposalError(pluginError, hostCleanupError) {
|
|
|
1041
1052
|
return pluginError;
|
|
1042
1053
|
return new AggregateError([pluginError, hostCleanupError], `${errorMessage(pluginError)}; host capability cleanup failed: ${errorMessage(hostCleanupError)}`);
|
|
1043
1054
|
}
|
|
1044
|
-
function snapshotPluginPeer(value) {
|
|
1055
|
+
function snapshotPluginPeer(value, apiVersion) {
|
|
1045
1056
|
if (!isPluginPeer(value)) {
|
|
1046
1057
|
throw new IncompatibleServerPluginError("Server plugin peer must include a request or channel handler");
|
|
1047
1058
|
}
|
|
@@ -1049,10 +1060,10 @@ function snapshotPluginPeer(value) {
|
|
|
1049
1060
|
const openChannel = value.openChannel?.bind(value);
|
|
1050
1061
|
const snapshotRequest = request === undefined
|
|
1051
1062
|
? undefined
|
|
1052
|
-
: (context) => request(context);
|
|
1063
|
+
: (context) => request(peerContextForVersion(context, apiVersion));
|
|
1053
1064
|
const snapshotOpenChannel = openChannel === undefined
|
|
1054
1065
|
? undefined
|
|
1055
|
-
: async (context) => (snapshotPluginPeerChannel(await openChannel(context)));
|
|
1066
|
+
: async (context) => (snapshotPluginPeerChannel(await openChannel(peerContextForVersion(context, apiVersion))));
|
|
1056
1067
|
if (snapshotRequest !== undefined && snapshotOpenChannel !== undefined) {
|
|
1057
1068
|
return Object.freeze({ request: snapshotRequest, openChannel: snapshotOpenChannel });
|
|
1058
1069
|
}
|
|
@@ -1062,6 +1073,14 @@ function snapshotPluginPeer(value) {
|
|
|
1062
1073
|
return Object.freeze({ openChannel: snapshotOpenChannel });
|
|
1063
1074
|
throw new IncompatibleServerPluginError("Server plugin peer must include a request or channel handler");
|
|
1064
1075
|
}
|
|
1076
|
+
function peerContextForVersion(context, apiVersion) {
|
|
1077
|
+
if (apiVersion === 5)
|
|
1078
|
+
return context;
|
|
1079
|
+
if (context.scope.kind !== "workspace")
|
|
1080
|
+
throw new Error("Server plugin API v3 requires workspace scope");
|
|
1081
|
+
const { scope, ...invocation } = context;
|
|
1082
|
+
return Object.freeze({ ...invocation, project: scope.project, workspace: scope.workspace });
|
|
1083
|
+
}
|
|
1065
1084
|
function isPluginPeer(value) {
|
|
1066
1085
|
if (!isRecord(value))
|
|
1067
1086
|
return false;
|
|
@@ -1101,17 +1120,20 @@ function snapshotWorkspaceProvider(value) {
|
|
|
1101
1120
|
probe: value["probe"],
|
|
1102
1121
|
list: value["list"],
|
|
1103
1122
|
prepareRemove: value["prepareRemove"],
|
|
1123
|
+
integration: value["integration"],
|
|
1104
1124
|
};
|
|
1105
1125
|
if (!isWorkspaceProvider(candidate))
|
|
1106
1126
|
throw new IncompatibleServerPluginError("Server plugin workspaceProvider is invalid");
|
|
1107
1127
|
const probe = candidate.probe.bind(value);
|
|
1108
1128
|
const list = candidate.list.bind(value);
|
|
1109
1129
|
const prepareRemove = candidate.prepareRemove?.bind(value);
|
|
1130
|
+
const integration = snapshotWorkspaceProviderIntegration(candidate.integration);
|
|
1110
1131
|
return Object.freeze({
|
|
1111
1132
|
...(candidate.fallback === undefined ? {} : { fallback: candidate.fallback }),
|
|
1112
1133
|
probe: (project, signal) => probe(project, signal),
|
|
1113
1134
|
list: (project, signal) => list(project, signal),
|
|
1114
1135
|
...(prepareRemove === undefined ? {} : { prepareRemove: (context) => prepareRemove(context) }),
|
|
1136
|
+
...(integration === undefined ? {} : { integration }),
|
|
1115
1137
|
});
|
|
1116
1138
|
}
|
|
1117
1139
|
function isWorkspaceProvider(value) {
|
|
@@ -1124,7 +1146,21 @@ function isWorkspaceProvider(value) {
|
|
|
1124
1146
|
return (fallback === undefined || typeof fallback === "boolean")
|
|
1125
1147
|
&& typeof probe === "function"
|
|
1126
1148
|
&& typeof list === "function"
|
|
1127
|
-
&& (prepareRemove === undefined || typeof prepareRemove === "function")
|
|
1149
|
+
&& (prepareRemove === undefined || typeof prepareRemove === "function")
|
|
1150
|
+
&& (value["integration"] === undefined || isWorkspaceProviderIntegration(value["integration"]));
|
|
1151
|
+
}
|
|
1152
|
+
function isWorkspaceProviderIntegration(value) {
|
|
1153
|
+
return isRecord(value) && typeof value["reconcile"] === "function" && typeof value["acceptNotification"] === "function";
|
|
1154
|
+
}
|
|
1155
|
+
function snapshotWorkspaceProviderIntegration(value) {
|
|
1156
|
+
if (value === undefined)
|
|
1157
|
+
return undefined;
|
|
1158
|
+
const reconcile = value.reconcile.bind(value);
|
|
1159
|
+
const acceptNotification = value.acceptNotification.bind(value);
|
|
1160
|
+
return Object.freeze({
|
|
1161
|
+
reconcile: (project, signal) => reconcile(project, signal),
|
|
1162
|
+
acceptNotification: (project, signal) => acceptNotification(project, signal),
|
|
1163
|
+
});
|
|
1128
1164
|
}
|
|
1129
1165
|
function parseHealth(value) {
|
|
1130
1166
|
if (!isRecord(value))
|