@xopcai/xopc 0.0.395 → 0.0.397

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.
Files changed (192) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/src/plugin.js +1 -1
  3. package/dist/extensions/telegram/xopc.extension.json +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BRtkz-ZU.js → agent-avatar-dicebear-CIEGrioy.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-Dqg2NOn-.js → agent-defaults-settings-panel-CzKNVkRn.js} +1 -1
  6. package/dist/gateway/static/root/assets/agent-plugin-dialog-mpA9rwYd.js +1 -0
  7. package/dist/gateway/static/root/assets/{agents-0zgLsfVA.js → agents-7VMa7Rzo.js} +3 -3
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-BZS8FvoL.js → app-management-settings-panel-DIJ0ii-n.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-RxXMAxiB.js → appearance-settings-BGnyHS-p.js} +1 -1
  10. package/dist/gateway/static/root/assets/apps-page-CvqDUvof.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-DEnHq3OR.js → archive-plugin-CR8FcRAa.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-BwkugzB8.js → automations-page-BLInZo7N.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-workspace-K8aDhoYt.js → automations-workspace-DvTSHLt3.js} +1 -1
  14. package/dist/gateway/static/root/assets/{binary-plugins-NWeXhh1k.js → binary-plugins-DW9pu205.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-D_bKN3BN.js → block-editor-ClgTc5v8.js} +1 -1
  16. package/dist/gateway/static/root/assets/{browser-automation-inputs-vtPkXfJ8.js → browser-automation-inputs-Bn7kDuUB.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-automations-page-DBPbwOG8.js → browser-automations-page-CJGBhDnv.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-settings-page-VBZDYoXD.js → browser-settings-page-tsi5W-cJ.js} +1 -1
  19. package/dist/gateway/static/root/assets/capabilities-page-CfbGk8q_.js +2 -0
  20. package/dist/gateway/static/root/assets/{capabilities-settings-panel-C_OMsW_8.js → capabilities-settings-panel-BkO7QEyA.js} +1 -1
  21. package/dist/gateway/static/root/assets/{capability-header-actions-CMJXWq8a.js → capability-header-actions-9ZG71-BO.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channels-C_TVCc1N.js → channels-D0CwJktG.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-9YRAokOl.js → chat-terminal-dock-x1W2_hwc.js} +1 -1
  24. package/dist/gateway/static/root/assets/{computer-settings-page-BPYAZ4ks.js → computer-settings-page-D_b_bFVz.js} +1 -1
  25. package/dist/gateway/static/root/assets/{connector-service-page-B81cEAEX.js → connector-service-page-Kf8kaNm_.js} +1 -1
  26. package/dist/gateway/static/root/assets/{connectors-page-C0NvAP2V.js → connectors-page-DlpfL2Rc.js} +1 -1
  27. package/dist/gateway/static/root/assets/{date-picker-BvKP4P3n.js → date-picker-d5kiPUG0.js} +1 -1
  28. package/dist/gateway/static/root/assets/{dependency-picker-TvrNaf8y.js → dependency-picker-BcH76tQC.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-De-_QNSD.js → desktop-pet-B-925tPX.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-CRSRTIwT.js → desktop-pet-settings-3XJ4qR65.js} +1 -1
  31. package/dist/gateway/static/root/assets/device-pairing-wizard-12m5Z9-8.js +1 -0
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-DOPXwYNR.js → directory-picker-path-field-B-qZCjGR.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-DzXvpUwj.js → extension-debug-page-BlQu1u6X.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-C0S1zNeP.js → extension-page-CXxM1M62.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-C3Z7bFjy.js → extension-settings-page-AF5nvsPP.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-settings-Btc2wTQe.js → gateway-settings-ABXvW_yL.js} +1 -1
  37. package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-BFYBbh1P.js → highlighted-body-KQOG7T2V-Czdbbi0H.js} +1 -1
  38. package/dist/gateway/static/root/assets/{home-page-C5sLR47Q.js → home-page-LXGxGwVl.js} +1 -1
  39. package/dist/gateway/static/root/assets/{image-generation-api-Vqcyqnzb.js → image-generation-api-DPFPJ2ps.js} +1 -1
  40. package/dist/gateway/static/root/assets/{imports-page-BJGHrzhX.js → imports-page-Bwyotfbt.js} +1 -1
  41. package/dist/gateway/static/root/assets/index-BKHxJaGD.css +1 -0
  42. package/dist/gateway/static/root/assets/{index-BNRLzxpH.js → index-Dsp_gNdl.js} +116 -116
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BQkQoPmm.js → keyboard-shortcuts-settings-C20gl-l7.js} +1 -1
  44. package/dist/gateway/static/root/assets/{local-app-workbench-page-DbxLz9Ms.js → local-app-workbench-page-o0M_OSjC.js} +1 -1
  45. package/dist/gateway/static/root/assets/{local-apps-page-CaatwSrK.js → local-apps-page-DoWJCmOq.js} +1 -1
  46. package/dist/gateway/static/root/assets/{logs-page-3Wo4Lmts.js → logs-page-BFTL93RX.js} +1 -1
  47. package/dist/gateway/static/root/assets/{management-settings-BHlbM8IM.js → management-settings-C52cuMg1.js} +1 -1
  48. package/dist/gateway/static/root/assets/{media-plugins-Cq1uLrd8.js → media-plugins-DLrTRF0a.js} +1 -1
  49. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-CPYJsRUJ.js +1 -0
  50. package/dist/gateway/static/root/assets/{note-detail-panel-MjKND8HC.js → note-detail-panel-CNN41byS.js} +3 -3
  51. package/dist/gateway/static/root/assets/{notes-page-Cv040hVD.js → notes-page-BsfBp_8z.js} +1 -1
  52. package/dist/gateway/static/root/assets/{page-context-capture-button-Cp71nTq2.js → page-context-capture-button-YTVWZ02-.js} +1 -1
  53. package/dist/gateway/static/root/assets/{personal-page-CyEUWV2n.js → personal-page-N4KoCZYG.js} +1 -1
  54. package/dist/gateway/static/root/assets/plugin-details-page-DcrrzQI-.js +1 -0
  55. package/dist/gateway/static/root/assets/{preview-open-alternatives-gzCecXc4.js → preview-open-alternatives-DzA__S54.js} +1 -1
  56. package/dist/gateway/static/root/assets/{product-open-page-CWFT7VuQ.js → product-open-page-DvlMKj0T.js} +1 -1
  57. package/dist/gateway/static/root/assets/{product-preview-content-Dh111Kca.js → product-preview-content-qdFyo4NG.js} +1 -1
  58. package/dist/gateway/static/root/assets/{project-detail-page-CyhyZiTi.js → project-detail-page-y67s_fA8.js} +1 -1
  59. package/dist/gateway/static/root/assets/{projects-page-QUdyJino.js → projects-page-D5iYgi0O.js} +1 -1
  60. package/dist/gateway/static/root/assets/{remote-access-hub-Cd8P0Dxs.js → remote-access-hub-DeFF7Re-.js} +1 -1
  61. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-bTjVfYm5.js → runtime-tools-settings-panel-BCHLh-KQ.js} +1 -1
  62. package/dist/gateway/static/root/assets/{schema-form-BGOzfVyj.js → schema-form-CJvaVHkx.js} +1 -1
  63. package/dist/gateway/static/root/assets/{sessions-page-BGMemJF6.js → sessions-page-DZ93_D5M.js} +1 -1
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-F1WX7vxq.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-form-section-Bqm1IKvR.js → settings-form-section-B3eODxNv.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-page-CniJVL-o.js → settings-page-Dg86uCnr.js} +1 -1
  67. package/dist/gateway/static/root/assets/{setup-status-panel-JPs4-QRw.js → setup-status-panel-ruFzAArp.js} +1 -1
  68. package/dist/gateway/static/root/assets/{share-preview-page-BnDGFgBR.js → share-preview-page-DCy1f25V.js} +1 -1
  69. package/dist/gateway/static/root/assets/{shares-settings-Cgp5BuLt.js → shares-settings-DeIVZvpJ.js} +1 -1
  70. package/dist/gateway/static/root/assets/{skill-api-CFdrz6tl.js → skill-api-RisyPAMA.js} +1 -1
  71. package/dist/gateway/static/root/assets/{skill-reload-api-Cy5jVfms.js → skill-reload-api-Dwkm1Fof.js} +1 -1
  72. package/dist/gateway/static/root/assets/{skills-page-CxaA3P5E.js → skills-page-UiTLsrFc.js} +1 -1
  73. package/dist/gateway/static/root/assets/{style-C_MAnir7.js → style-CwMX73G7.js} +1 -1
  74. package/dist/gateway/static/root/assets/{system-settings-panel-BjnIlilP.js → system-settings-panel-Cma37Pfm.js} +1 -1
  75. package/dist/gateway/static/root/assets/{task-detail-page-Bg79rPnF.js → task-detail-page-BKOF_kxS.js} +1 -1
  76. package/dist/gateway/static/root/assets/{tracing-settings-page-BCI0tUbe.js → tracing-settings-page-DC-kLysq.js} +1 -1
  77. package/dist/gateway/static/root/assets/{tunnel-api-0knnta9z.js → tunnel-api-BgdhbR1L.js} +1 -1
  78. package/dist/gateway/static/root/assets/{usage-page-D5aT1eie.js → usage-page-BSlFg3Xj.js} +1 -1
  79. package/dist/gateway/static/root/assets/{use-autosave-Ds_mbAfe.js → use-autosave-iKvZ1pvC.js} +1 -1
  80. package/dist/gateway/static/root/assets/{user-model-page-D7L0-pDt.js → user-model-page-D4GB8QsM.js} +1 -1
  81. package/dist/gateway/static/root/assets/{voice-api-key-field-CPoGdarN.js → voice-api-key-field-CESbtuwM.js} +1 -1
  82. package/dist/gateway/static/root/assets/{work-discovery-overlay-CWNguy2Z.js → work-discovery-overlay-dtPpmYyh.js} +1 -1
  83. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BcDMFfkT.js → workflow-run-setup-panel-DmFn3E_B.js} +1 -1
  84. package/dist/gateway/static/root/assets/{workflows-page-BwZB-s4N.js → workflows-page-DEtaRuxH.js} +1 -1
  85. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-DlKr98VO.js → xopc-cloud-account-card-DTZnabfg.js} +1 -1
  86. package/dist/gateway/static/root/index.html +2 -2
  87. package/dist/package.js +1 -1
  88. package/dist/src/agent/embedded/codemode-extension.d.ts +1 -0
  89. package/dist/src/agent/embedded/codemode-extension.js +6 -1
  90. package/dist/src/agent/embedded/run-for-session.js +1 -1
  91. package/dist/src/agent/embedded/run-turn.js +34 -2
  92. package/dist/src/agent/embedded/session-runner.js +1 -1
  93. package/dist/src/agent/mcp/config.d.ts +2 -0
  94. package/dist/src/agent/mcp/config.js +2 -2
  95. package/dist/src/agent/mcp/connection-setup.js +13 -1
  96. package/dist/src/agent/mcp/effective-server.d.ts +3 -0
  97. package/dist/src/agent/mcp/effective-server.js +27 -0
  98. package/dist/src/agent/mcp/native-mcp.d.ts +1 -1
  99. package/dist/src/agent/mcp/native-mcp.js +13 -4
  100. package/dist/src/agent/mcp/tool-catalog.js +2 -1
  101. package/dist/src/agent/skills/index.d.ts +1 -0
  102. package/dist/src/agent/skills/index.js +6 -2
  103. package/dist/src/agent/skills/skill-manager.d.ts +1 -0
  104. package/dist/src/agent/skills/skill-manager.js +6 -1
  105. package/dist/src/agent/skills/skill-sources.d.ts +1 -0
  106. package/dist/src/agent/skills/skill-sources.js +4 -3
  107. package/dist/src/agent/skills/types.d.ts +1 -0
  108. package/dist/src/agent/workspace-runtime/registry.js +6 -2
  109. package/dist/src/browser/native-messaging-host.js +1 -1
  110. package/dist/src/browser/providers/browser-ext-install.js +2 -2
  111. package/dist/src/channels/index.js +1 -1
  112. package/dist/src/channels/manager.js +1 -1
  113. package/dist/src/cli/commands/channels.js +1 -1
  114. package/dist/src/cli/commands/connectors.js +1 -1
  115. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  116. package/dist/src/cli/commands/extension-agent-plugin.js +92 -7
  117. package/dist/src/cli/commands/extension-marketplace.js +2 -2
  118. package/dist/src/cli/commands/extension.js +1 -1
  119. package/dist/src/cli/commands/mcp.js +6 -4
  120. package/dist/src/cli/commands/models.js +1 -1
  121. package/dist/src/cli/commands/onboard/model.js +1 -1
  122. package/dist/src/cli/commands/onboard.js +1 -1
  123. package/dist/src/extensions/agent-plugins/auth.d.ts +7 -1
  124. package/dist/src/extensions/agent-plugins/auth.js +53 -12
  125. package/dist/src/extensions/agent-plugins/branding.d.ts +6 -0
  126. package/dist/src/extensions/agent-plugins/branding.js +44 -0
  127. package/dist/src/extensions/agent-plugins/cli-authorization.d.ts +22 -0
  128. package/dist/src/extensions/agent-plugins/cli-authorization.js +198 -0
  129. package/dist/src/extensions/agent-plugins/connection-reuse.d.ts +10 -0
  130. package/dist/src/extensions/agent-plugins/connection-reuse.js +23 -0
  131. package/dist/src/extensions/agent-plugins/credentials.js +24 -1
  132. package/dist/src/extensions/agent-plugins/formats.d.ts +27 -0
  133. package/dist/src/extensions/agent-plugins/formats.js +208 -0
  134. package/dist/src/extensions/agent-plugins/inventory.d.ts +142 -2
  135. package/dist/src/extensions/agent-plugins/inventory.js +39 -5
  136. package/dist/src/extensions/agent-plugins/mcp-adapter.d.ts +2 -1
  137. package/dist/src/extensions/agent-plugins/mcp-adapter.js +42 -8
  138. package/dist/src/extensions/agent-plugins/mcp-format.d.ts +2 -0
  139. package/dist/src/extensions/agent-plugins/mcp-format.js +82 -0
  140. package/dist/src/extensions/agent-plugins/resources.d.ts +14 -0
  141. package/dist/src/extensions/agent-plugins/resources.js +112 -0
  142. package/dist/src/extensions/agent-plugins/setup-contract.d.ts +54 -0
  143. package/dist/src/extensions/agent-plugins/setup-contract.js +58 -0
  144. package/dist/src/extensions/agent-plugins/setup.d.ts +119 -0
  145. package/dist/src/extensions/agent-plugins/setup.js +491 -0
  146. package/dist/src/extensions/agent-plugins/source-catalog.d.ts +21 -0
  147. package/dist/src/extensions/agent-plugins/source-catalog.js +175 -0
  148. package/dist/src/extensions/agent-plugins/sources.d.ts +1 -1
  149. package/dist/src/extensions/agent-plugins/sources.js +12 -3
  150. package/dist/src/extensions/agent-plugins/store.d.ts +33 -2
  151. package/dist/src/extensions/agent-plugins/store.js +175 -25
  152. package/dist/src/extensions/agent-plugins/user-config.d.ts +5 -0
  153. package/dist/src/extensions/agent-plugins/user-config.js +49 -0
  154. package/dist/src/extensions/agent-plugins/validation.d.ts +26 -1
  155. package/dist/src/extensions/agent-plugins/validation.js +142 -27
  156. package/dist/src/extensions/sdk/index.js +1 -1
  157. package/dist/src/gateway/hono/app.js +1 -1
  158. package/dist/src/gateway/hono/routes/agent-plugins.js +120 -9
  159. package/dist/src/gateway/hono/routes/browser-install.js +1 -1
  160. package/dist/src/gateway/hono/routes/composer-history.js +22 -4
  161. package/dist/src/gateway/hono/routes/mcp.js +6 -4
  162. package/dist/src/gateway/hono/routes/provider-setup.js +7 -0
  163. package/dist/src/gateway/service.js +11 -9
  164. package/dist/src/gateway/session-context-summary.js +1 -1
  165. package/dist/src/gateway/xopc-cloud-capability-setup.d.ts +4 -0
  166. package/dist/src/gateway/xopc-cloud-capability-setup.js +90 -26
  167. package/dist/src/home-intelligence/host.js +2 -2
  168. package/dist/src/providers/setup/engine.js +12 -10
  169. package/dist/src/providers/setup/voice.js +24 -6
  170. package/dist/src/storage/sqlite/composer-input-history-repository.d.ts +4 -3
  171. package/dist/src/storage/sqlite/composer-input-history-repository.js +10 -8
  172. package/dist/src/storage/sqlite/device-pairing-approval.js +1 -1
  173. package/dist/src/storage/sqlite/migrations/257_session_composer_history.sql +11 -0
  174. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  175. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  176. package/dist/src/storage/sqlite/schema.js +1 -1
  177. package/dist/src/tui/backends/embedded-backend.d.ts +2 -2
  178. package/dist/src/tui/backends/embedded-backend.js +4 -4
  179. package/dist/src/tui/backends/gateway-realtime-backend.d.ts +2 -2
  180. package/dist/src/tui/backends/gateway-realtime-backend.js +7 -4
  181. package/dist/src/tui/composer-history.d.ts +14 -0
  182. package/dist/src/tui/composer-history.js +85 -0
  183. package/dist/src/tui/tui-backend.d.ts +4 -3
  184. package/dist/src/tui/tui.js +19 -46
  185. package/package.json +12 -4
  186. package/dist/gateway/static/root/assets/agent-plugin-dialog-CKK95Jmr.js +0 -1
  187. package/dist/gateway/static/root/assets/apps-page-mGU9WLjP.js +0 -1
  188. package/dist/gateway/static/root/assets/capabilities-page-CQsGp9Sx.js +0 -2
  189. package/dist/gateway/static/root/assets/device-pairing-wizard-DnyJ8Bja.js +0 -1
  190. package/dist/gateway/static/root/assets/index-zIgp-ZTu.css +0 -1
  191. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-XhlIBp5t.js +0 -1
  192. package/dist/gateway/static/root/assets/settings-advanced-gate-BiySFw1N.js +0 -1
@@ -0,0 +1,208 @@
1
+ import { basename, join } from "node:path";
2
+ import { existsSync, readdirSync, statSync } from "node:fs";
3
+ //#region src/extensions/agent-plugins/formats.ts
4
+ const PLUGIN_MANIFEST_PATHS = [
5
+ "plugin.json",
6
+ ".codex-plugin/plugin.json",
7
+ ".claude-plugin/plugin.json"
8
+ ];
9
+ /** Interpret each dialect before applying the common package and execution checks. */
10
+ function readPluginLayout(root, read, safe, importManifest) {
11
+ const has = (path) => existsSync(join(root, path));
12
+ const json = (path) => {
13
+ const value = JSON.parse(read(join(root, path)));
14
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Expected an object: ${path}`);
15
+ return value;
16
+ };
17
+ const path = PLUGIN_MANIFEST_PATHS.find(has);
18
+ if (!path && !importManifest) throw new Error("No supported plugin manifest found");
19
+ const dialect = path === "plugin.json" ? "portable" : path?.startsWith(".codex") ? "codex" : "claude";
20
+ const raw = path ? json(path) : importManifest;
21
+ const compatibility = [];
22
+ if (dialect !== "portable" && has(".codex-plugin/plugin.json") && has(".claude-plugin/plugin.json")) compatibility.push({
23
+ component: "manifest:claude",
24
+ support: "unsupported",
25
+ message: "Codex dialect selected; the separate Claude manifest is not applied."
26
+ });
27
+ const object = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
28
+ const overlay = dialect === "portable" ? object(object(raw.extensions)["com.openai"] ?? (has(".codex-plugin/plugin.json") ? json(".codex-plugin/plugin.json") : {})) : raw;
29
+ const manifest = dialect === "portable" ? raw : {
30
+ $schema: "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
31
+ ...Object.fromEntries([
32
+ "name",
33
+ "version",
34
+ "description",
35
+ "homepage",
36
+ "repository",
37
+ "license",
38
+ "keywords",
39
+ "extensions"
40
+ ].filter((key) => raw[key] !== void 0).map((key) => [key, raw[key]])),
41
+ ...raw.author ? { author: typeof raw.author === "string" ? { name: raw.author } : raw.author } : {}
42
+ };
43
+ const paths = (value, component) => {
44
+ if (value === void 0) return [];
45
+ const values = typeof value === "string" ? [value] : Array.isArray(value) ? value : [];
46
+ if (!values.length || values.some((v) => typeof v !== "string" || !v.startsWith("./"))) {
47
+ compatibility.push({
48
+ component,
49
+ support: "invalid",
50
+ message: "Expected package-relative paths beginning with ./"
51
+ });
52
+ return [];
53
+ }
54
+ return values.map((v) => safe(join(root, v)));
55
+ };
56
+ const guarded = (component, fn, fallback) => {
57
+ try {
58
+ return fn();
59
+ } catch (error) {
60
+ compatibility.push({
61
+ component,
62
+ support: "invalid",
63
+ message: error instanceof Error ? error.message : String(error)
64
+ });
65
+ return fallback;
66
+ }
67
+ };
68
+ const defaults = has("skills") ? guarded("skills", () => [safe(join(root, "skills"))], []) : [];
69
+ const declared = paths(overlay.skills, "skills");
70
+ const skillRoots = [...new Set(dialect === "portable" ? defaults : dialect === "claude" ? [...defaults, ...declared] : overlay.skills === void 0 ? defaults : declared)];
71
+ const mcpConfigs = [];
72
+ if (dialect === "portable" && has("mcp.json")) {
73
+ const config = guarded("mcp", () => json("mcp.json"), void 0);
74
+ if (config) mcpConfigs.push(config);
75
+ }
76
+ const legacyDefault = has(".mcp.json");
77
+ if (dialect !== "portable" && legacyDefault && (dialect === "claude" || overlay.mcpServers === void 0)) {
78
+ const config = guarded("mcp", () => json(".mcp.json"), void 0);
79
+ if (config) mcpConfigs.push(config);
80
+ }
81
+ if (dialect !== "portable" || !has("mcp.json")) {
82
+ if (overlay.mcpServers !== void 0) for (const item of Array.isArray(overlay.mcpServers) ? overlay.mcpServers : [overlay.mcpServers]) if (typeof item === "string") for (const file of paths(item, "mcp")) {
83
+ const config = guarded("mcp", () => JSON.parse(read(file)), void 0);
84
+ if (config) mcpConfigs.push(config);
85
+ }
86
+ else if (item && typeof item === "object") mcpConfigs.push({ mcpServers: item });
87
+ else compatibility.push({
88
+ component: "mcp",
89
+ support: "invalid",
90
+ message: "Expected an MCP configuration object or package path."
91
+ });
92
+ }
93
+ for (const [key, conventional] of Object.entries({
94
+ apps: ".app.json",
95
+ hooks: "hooks/hooks.json",
96
+ agents: "agents",
97
+ commands: "commands",
98
+ lspServers: ".lsp.json",
99
+ outputStyles: "output-styles",
100
+ settings: "settings.json",
101
+ workflows: "workflows",
102
+ monitors: "monitors",
103
+ channels: "channels",
104
+ themes: "themes"
105
+ })) if (overlay[key] !== void 0 || has(conventional)) compatibility.push({
106
+ component: key,
107
+ support: key === "apps" ? "needs_adapter" : "unsupported",
108
+ message: key === "apps" ? "Platform application tools require a host capability adapter; accounts are not inherited." : `${key} is not executed by this compatibility version.`
109
+ });
110
+ const userConfig = Object.create(null);
111
+ for (const [key, value] of Object.entries(object(overlay.userConfig))) {
112
+ const field = object(value);
113
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) || ![
114
+ "string",
115
+ "number",
116
+ "boolean"
117
+ ].includes(String(field.type))) {
118
+ compatibility.push({
119
+ component: `config:${key}`,
120
+ support: "unsupported",
121
+ message: "Unsupported configuration field."
122
+ });
123
+ continue;
124
+ }
125
+ userConfig[key] = {
126
+ type: field.type,
127
+ title: String(field.title ?? key),
128
+ required: field.required === true,
129
+ sensitive: field.sensitive === true,
130
+ ...[
131
+ "string",
132
+ "number",
133
+ "boolean"
134
+ ].includes(typeof field.default) ? { default: field.default } : {}
135
+ };
136
+ }
137
+ const tasks = [object(overlay.interface).defaultPrompt].flat().filter((v) => typeof v === "string");
138
+ if (overlay.onboardingSkill !== void 0) compatibility.push({
139
+ component: "onboardingSkill",
140
+ support: "unsupported",
141
+ message: "Automatic onboarding skill execution is not supported; use the host setup flow."
142
+ });
143
+ const known = new Set([
144
+ "$schema",
145
+ "name",
146
+ "version",
147
+ "description",
148
+ "author",
149
+ "homepage",
150
+ "repository",
151
+ "license",
152
+ "keywords",
153
+ "extensions",
154
+ "displayName",
155
+ "skills",
156
+ "mcpServers",
157
+ "interface",
158
+ "userConfig",
159
+ "onboardingSkill",
160
+ "apps",
161
+ "hooks",
162
+ "agents",
163
+ "commands",
164
+ "lspServers",
165
+ "outputStyles",
166
+ "settings",
167
+ "workflows",
168
+ "monitors",
169
+ "channels",
170
+ "themes"
171
+ ]);
172
+ for (const key of Object.keys(overlay)) if (!known.has(key)) compatibility.push({
173
+ component: key,
174
+ support: "unsupported",
175
+ message: "Unrecognized platform declaration."
176
+ });
177
+ return {
178
+ descriptorVersion: 1,
179
+ adapterVersion: "xopc-plugin-v1",
180
+ dialect,
181
+ manifest,
182
+ skillRoots,
183
+ mcpConfigs,
184
+ compatibility,
185
+ userConfig,
186
+ tasks
187
+ };
188
+ }
189
+ function collectPluginSkillFiles(root, safe) {
190
+ const result = [];
191
+ const visit = (path, depth) => {
192
+ const target = safe(path);
193
+ if (depth > 16) throw new Error("Skill directory nesting exceeds limits");
194
+ if (statSync(target).isFile()) {
195
+ if (basename(target) === "SKILL.md") result.push(target);
196
+ return;
197
+ }
198
+ if (existsSync(join(target, "SKILL.md"))) {
199
+ result.push(safe(join(target, "SKILL.md")));
200
+ return;
201
+ }
202
+ for (const name of readdirSync(target).sort()) visit(join(target, name), depth + 1);
203
+ };
204
+ visit(root, 0);
205
+ return result;
206
+ }
207
+ //#endregion
208
+ export { PLUGIN_MANIFEST_PATHS, collectPluginSkillFiles, readPluginLayout };
@@ -1,15 +1,79 @@
1
- import { type InstalledAgentPlugin } from './store.js';
2
- export declare function agentPluginInventoryRow(plugin: InstalledAgentPlugin): {
1
+ import { AgentPluginStore, type InstalledAgentPlugin } from './store.js';
2
+ export declare function agentPluginInventoryRow(plugin: InstalledAgentPlugin, store?: AgentPluginStore): {
3
3
  components: {
4
4
  skills: {
5
5
  name: string;
6
6
  }[];
7
7
  mcp: {
8
+ connectionAuth?: {
9
+ mode: "none" | "oauth" | "api-key";
10
+ headerName?: string;
11
+ prefix?: string;
12
+ };
8
13
  name: string;
9
14
  id: string;
10
15
  type: "stdio" | "streamable-http";
11
16
  }[];
12
17
  };
18
+ installationSource: string;
19
+ resolvedCommit: string;
20
+ dialect: import("./formats.js").PluginDialect;
21
+ verification: string;
22
+ compatibility: import("./formats.js").CompatibilityItem[];
23
+ workspacePaths: string[];
24
+ setup: {
25
+ authorizations: {
26
+ id: string;
27
+ title: string;
28
+ servers: string[];
29
+ methods: ({
30
+ type: "oauth";
31
+ server: string;
32
+ id: string;
33
+ title: string;
34
+ instructions: string[];
35
+ helpUrl?: string;
36
+ } | {
37
+ type: "form";
38
+ fields: string[];
39
+ id: string;
40
+ title: string;
41
+ instructions: string[];
42
+ helpUrl?: string;
43
+ } | {
44
+ type: "cli";
45
+ fields: string[];
46
+ login: {
47
+ command: string;
48
+ args: string[];
49
+ env: Record<string, string>;
50
+ cwd?: string;
51
+ };
52
+ check: {
53
+ command: string;
54
+ args: string[];
55
+ env: Record<string, string>;
56
+ cwd?: string;
57
+ };
58
+ timeoutSeconds: number;
59
+ id: string;
60
+ title: string;
61
+ instructions: string[];
62
+ helpUrl?: string;
63
+ })[];
64
+ description?: string;
65
+ }[];
66
+ userConfig: {
67
+ [k: string]: {
68
+ default: string | number | boolean;
69
+ type: "string" | "number" | "boolean";
70
+ title: string;
71
+ required: boolean;
72
+ sensitive: boolean;
73
+ };
74
+ };
75
+ tasks: string[];
76
+ };
13
77
  diagnostics: import("./validation.js").PluginDiagnostic[];
14
78
  provenance?: {
15
79
  kind: "store";
@@ -30,8 +94,14 @@ export declare function agentPluginInventoryRow(plugin: InstalledAgentPlugin): {
30
94
  version: string;
31
95
  description: string;
32
96
  source: string;
97
+ branding: {
98
+ iconUrl: string;
99
+ iconSha256: string;
100
+ };
33
101
  active: boolean;
34
102
  activationEligible: boolean;
103
+ installationState: string;
104
+ authorizationStatus: string;
35
105
  readiness: "ready" | "blocked" | "degraded" | "setup_required";
36
106
  hasUi: boolean;
37
107
  hasConfigSchema: boolean;
@@ -43,11 +113,75 @@ export declare function listAgentPluginInventory(): {
43
113
  name: string;
44
114
  }[];
45
115
  mcp: {
116
+ connectionAuth?: {
117
+ mode: "none" | "oauth" | "api-key";
118
+ headerName?: string;
119
+ prefix?: string;
120
+ };
46
121
  name: string;
47
122
  id: string;
48
123
  type: "stdio" | "streamable-http";
49
124
  }[];
50
125
  };
126
+ installationSource: string;
127
+ resolvedCommit: string;
128
+ dialect: import("./formats.js").PluginDialect;
129
+ verification: string;
130
+ compatibility: import("./formats.js").CompatibilityItem[];
131
+ workspacePaths: string[];
132
+ setup: {
133
+ authorizations: {
134
+ id: string;
135
+ title: string;
136
+ servers: string[];
137
+ methods: ({
138
+ type: "oauth";
139
+ server: string;
140
+ id: string;
141
+ title: string;
142
+ instructions: string[];
143
+ helpUrl?: string;
144
+ } | {
145
+ type: "form";
146
+ fields: string[];
147
+ id: string;
148
+ title: string;
149
+ instructions: string[];
150
+ helpUrl?: string;
151
+ } | {
152
+ type: "cli";
153
+ fields: string[];
154
+ login: {
155
+ command: string;
156
+ args: string[];
157
+ env: Record<string, string>;
158
+ cwd?: string;
159
+ };
160
+ check: {
161
+ command: string;
162
+ args: string[];
163
+ env: Record<string, string>;
164
+ cwd?: string;
165
+ };
166
+ timeoutSeconds: number;
167
+ id: string;
168
+ title: string;
169
+ instructions: string[];
170
+ helpUrl?: string;
171
+ })[];
172
+ description?: string;
173
+ }[];
174
+ userConfig: {
175
+ [k: string]: {
176
+ default: string | number | boolean;
177
+ type: "string" | "number" | "boolean";
178
+ title: string;
179
+ required: boolean;
180
+ sensitive: boolean;
181
+ };
182
+ };
183
+ tasks: string[];
184
+ };
51
185
  diagnostics: import("./validation.js").PluginDiagnostic[];
52
186
  provenance?: {
53
187
  kind: "store";
@@ -68,8 +202,14 @@ export declare function listAgentPluginInventory(): {
68
202
  version: string;
69
203
  description: string;
70
204
  source: string;
205
+ branding: {
206
+ iconUrl: string;
207
+ iconSha256: string;
208
+ };
71
209
  active: boolean;
72
210
  activationEligible: boolean;
211
+ installationState: string;
212
+ authorizationStatus: string;
73
213
  readiness: "ready" | "blocked" | "degraded" | "setup_required";
74
214
  hasUi: boolean;
75
215
  hasConfigSchema: boolean;
@@ -1,17 +1,35 @@
1
+ import { pluginAuthorizations } from "./setup-contract.js";
1
2
  import { pluginServerId } from "./validation.js";
2
3
  import { AgentPluginStore } from "./store.js";
4
+ import { pluginBranding } from "./branding.js";
5
+ import { join } from "node:path";
6
+ import { existsSync, readFileSync } from "node:fs";
3
7
  //#region src/extensions/agent-plugins/inventory.ts
4
- function agentPluginInventoryRow(plugin) {
8
+ function agentPluginInventoryRow(plugin, store = new AgentPluginStore()) {
9
+ const setupPath = join(store.stateDir, "plugin-setup", `${plugin.id}.json`);
10
+ let saved;
11
+ try {
12
+ saved = existsSync(setupPath) ? JSON.parse(readFileSync(setupPath, "utf8")) : void 0;
13
+ } catch {}
14
+ const job = saved?.packageRevision === plugin.receipt.revision ? saved : void 0;
15
+ let authorizations = [];
16
+ try {
17
+ authorizations = pluginAuthorizations(plugin.manifest);
18
+ } catch {}
19
+ const needsAuthorization = !!job && ((job.missingConfig?.length ?? 0) > 0 || job.connections?.some((value) => value.state !== "connected") || job.authorizations?.some((value) => value.state !== "connected"));
5
20
  return {
6
21
  id: `plugin:${plugin.id}`,
7
22
  pluginId: plugin.id,
8
23
  format: plugin.format,
9
24
  name: plugin.manifest.name,
10
- version: plugin.manifest.version,
25
+ version: plugin.manifest.version ?? plugin.receipt.provenance?.version,
11
26
  description: plugin.manifest.description,
12
27
  source: "agent-plugin",
13
- active: plugin.receipt.enabled && plugin.readiness !== "blocked",
28
+ branding: pluginBranding(plugin.rootDir, plugin.manifest),
29
+ active: plugin.receipt.enabled && plugin.readiness !== "blocked" && plugin.readiness !== "setup_required",
14
30
  activationEligible: plugin.receipt.enabled,
31
+ installationState: job?.installed || job?.state === "completed" ? "installed" : job ? "preparing" : "installed",
32
+ authorizationStatus: needsAuthorization ? "required" : job?.connections?.length || authorizations.length ? "connected" : "not_required",
15
33
  readiness: plugin.readiness,
16
34
  hasUi: false,
17
35
  hasConfigSchema: false,
@@ -22,14 +40,30 @@ function agentPluginInventoryRow(plugin) {
22
40
  mcp: Object.entries(plugin.servers).map(([name, server]) => ({
23
41
  name,
24
42
  id: pluginServerId(plugin.id, name),
25
- type: server.type
43
+ type: server.type,
44
+ ...server.type !== "stdio" ? { connectionAuth: server.connectionAuth } : {}
26
45
  }))
27
46
  },
47
+ installationSource: plugin.receipt.source,
48
+ resolvedCommit: plugin.receipt.resolvedCommit,
49
+ dialect: plugin.layout?.dialect ?? "portable",
50
+ verification: "unverified",
51
+ compatibility: plugin.layout?.compatibility ?? [],
52
+ workspacePaths: plugin.receipt.workspacePaths ?? null,
53
+ setup: {
54
+ authorizations,
55
+ userConfig: Object.fromEntries(Object.entries(plugin.layout?.userConfig ?? {}).map(([key, field]) => [key, {
56
+ ...field,
57
+ default: field.sensitive ? void 0 : field.default
58
+ }])),
59
+ tasks: plugin.layout?.tasks ?? []
60
+ },
28
61
  diagnostics: plugin.diagnostics
29
62
  };
30
63
  }
31
64
  function listAgentPluginInventory() {
32
- return new AgentPluginStore().list().map(agentPluginInventoryRow);
65
+ const store = new AgentPluginStore();
66
+ return store.list().map((plugin) => agentPluginInventoryRow(plugin, store));
33
67
  }
34
68
  //#endregion
35
69
  export { agentPluginInventoryRow, listAgentPluginInventory };
@@ -1,3 +1,4 @@
1
1
  import { AgentPluginStore, type InstalledAgentPlugin } from './store.js';
2
2
  import { type PluginDiagnostic } from './validation.js';
3
- export declare function materializePluginServers(plugin: InstalledAgentPlugin, store?: AgentPluginStore, diagnostics?: PluginDiagnostic[]): Record<string, Record<string, unknown>>;
3
+ export declare function pluginOAuthCredentialId(pluginId: string, revision: string, serverName: string): string;
4
+ export declare function materializePluginServers(plugin: InstalledAgentPlugin, store?: AgentPluginStore, diagnostics?: PluginDiagnostic[], setup?: boolean): Record<string, Record<string, unknown>>;
@@ -1,13 +1,37 @@
1
1
  import { containedPath, expandPluginVariables, pluginServerId, resolvePluginCwd } from "./validation.js";
2
2
  import { AgentPluginStore } from "./store.js";
3
3
  import { applyPluginAuthBinding, readPluginAuthBinding } from "./auth.js";
4
- import { resolve } from "node:path";
4
+ import { expandUserConfig, readPluginUserConfig } from "./user-config.js";
5
+ import { homedir } from "node:os";
6
+ import { join, resolve } from "node:path";
7
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
8
+ import { createHash } from "node:crypto";
5
9
  //#region src/extensions/agent-plugins/mcp-adapter.ts
6
- function materializePluginServers(plugin, store = new AgentPluginStore(), diagnostics = []) {
10
+ function pluginOAuthCredentialId(pluginId, revision, serverName) {
11
+ return `mcp_draft_${createHash("sha256").update(JSON.stringify([
12
+ "plugin",
13
+ pluginId,
14
+ revision,
15
+ serverName
16
+ ])).digest("hex").slice(0, 32)}`;
17
+ }
18
+ function materializePluginServers(plugin, store = new AgentPluginStore(), diagnostics = [], setup = false) {
7
19
  const root = plugin.rootDir;
8
20
  const data = store.dataDir(plugin.id);
21
+ mkdirSync(data, {
22
+ recursive: true,
23
+ mode: 448
24
+ });
25
+ const values = {
26
+ ...Object.fromEntries(Object.entries(plugin.layout?.userConfig ?? {}).filter(([, field]) => field.default !== void 0).map(([key, field]) => [key, field.default])),
27
+ ...readPluginUserConfig(store, plugin.id, plugin.receipt.revision)
28
+ };
29
+ const expand = (value) => expandUserConfig(expandPluginVariables(value.replace(/\$\{PLUGIN_ACCOUNTS\}/g, join(data, "accounts", plugin.receipt.revision)).replace(/\$\{PLUGIN_RESOURCES\}/g, join(data, "resources", plugin.receipt.revision)), root, data), values);
9
30
  const servers = Object.create(null);
31
+ const setupPath = join(store.stateDir, "plugin-setup", `${plugin.id}.json`);
32
+ const job = !setup && existsSync(setupPath) ? JSON.parse(readFileSync(setupPath, "utf8")) : void 0;
10
33
  for (const [name, server] of Object.entries(plugin.servers)) try {
34
+ if (job?.packageRevision === plugin.receipt.revision && (job.state !== "completed" && !job.installed || job.connections.find((c) => c.name === name)?.state !== "connected")) continue;
11
35
  const origin = {
12
36
  id: plugin.id,
13
37
  serverName: name,
@@ -17,20 +41,30 @@ function materializePluginServers(plugin, store = new AgentPluginStore(), diagno
17
41
  };
18
42
  const raw = server.type !== "stdio" ? {
19
43
  ...server,
44
+ ...plugin.receipt.credentialScope === "revision" ? { xopcOAuthCredentialId: pluginOAuthCredentialId(plugin.id, plugin.receipt.revision, name) } : {},
45
+ ...server.headers ? { headers: Object.fromEntries(Object.entries(server.headers).map(([key, value]) => [key, expand(value)])) } : {},
20
46
  xopcPlugin: origin
21
47
  } : {
22
48
  type: "stdio",
23
49
  xopcPlugin: origin,
24
- command: server.command.startsWith("./") ? containedPath(root, resolve(root, server.command)) : server.command,
25
- args: server.args?.map((value) => expandPluginVariables(value, root, data)),
50
+ command: server.command.startsWith("./") ? containedPath(root, resolve(root, server.command)) : server.command.startsWith("${PLUGIN_RESOURCES}/") ? containedPath(data, join(data, "resources", plugin.receipt.revision, server.command.slice(20))) : server.command,
51
+ args: server.args?.map((value) => {
52
+ const expanded = expand(value);
53
+ if (typeof expanded !== "string") throw new Error("Sensitive arguments are not supported; use environment variables");
54
+ return expanded;
55
+ }),
26
56
  env: {
27
- ...Object.fromEntries(Object.entries(server.env ?? {}).map(([key, value]) => [key, expandPluginVariables(value, root, data)])),
57
+ ...Object.fromEntries(Object.entries(server.env ?? {}).map(([key, value]) => [key, expand(value)])),
58
+ PLUGIN_HOST_HOME: homedir(),
28
59
  PLUGIN_ROOT: root,
29
- PLUGIN_DATA: data
60
+ PLUGIN_DATA: data,
61
+ PLUGIN_RESOURCES: join(data, "resources", plugin.receipt.revision),
62
+ CLAUDE_PLUGIN_ROOT: root,
63
+ CLAUDE_PLUGIN_DATA: data
30
64
  },
31
65
  cwd: resolvePluginCwd(server.cwd, root, data)
32
66
  };
33
- servers[pluginServerId(plugin.id, name)] = applyPluginAuthBinding(raw, readPluginAuthBinding(store, plugin.id, name, server));
67
+ servers[pluginServerId(plugin.id, name)] = applyPluginAuthBinding(raw, readPluginAuthBinding(store, plugin.id, name, server, plugin.receipt.revision));
34
68
  } catch (error) {
35
69
  diagnostics.push({
36
70
  component: `mcp:${name}`,
@@ -40,4 +74,4 @@ function materializePluginServers(plugin, store = new AgentPluginStore(), diagno
40
74
  return servers;
41
75
  }
42
76
  //#endregion
43
- export { materializePluginServers };
77
+ export { materializePluginServers, pluginOAuthCredentialId };
@@ -0,0 +1,2 @@
1
+ /** Only map authentication settings that native pi can represent without semantic loss. */
2
+ export declare function normalizePluginMcpServer(input: unknown, legacy: boolean, warn: (message: string) => void): unknown;
@@ -0,0 +1,82 @@
1
+ import { z } from "zod";
2
+ //#region src/extensions/agent-plugins/mcp-format.ts
3
+ const oauthClient = z.discriminatedUnion("mode", [z.strictObject({
4
+ mode: z.literal("provided"),
5
+ clientId: z.string().min(1),
6
+ tokenEndpointAuthMethod: z.literal("none").optional()
7
+ }), z.strictObject({ mode: z.enum(["dcr", "cimd"]) })]);
8
+ const scope = z.string().trim().min(1);
9
+ const authSchema = z.discriminatedUnion("type", [
10
+ z.strictObject({
11
+ type: z.enum(["oauth", "mixed"]),
12
+ client: oauthClient.optional(),
13
+ baseScopes: z.array(scope).optional(),
14
+ defaultScopes: z.array(scope).optional()
15
+ }),
16
+ z.strictObject({ type: z.literal("none") }),
17
+ z.strictObject({
18
+ type: z.literal("api_key"),
19
+ headerScheme: z.enum([
20
+ "bearer",
21
+ "basic",
22
+ "custom_header"
23
+ ]),
24
+ headerName: z.string().optional()
25
+ })
26
+ ]);
27
+ /** Only map authentication settings that native pi can represent without semantic loss. */
28
+ function normalizePluginMcpServer(input, legacy, warn) {
29
+ const value = { ...z.record(z.string(), z.unknown()).parse(input) };
30
+ const extensions = value.extensions;
31
+ if (extensions !== void 0) {
32
+ const ext = z.record(z.string(), z.unknown()).parse(extensions);
33
+ for (const key of Object.keys(ext)) if (key !== "com.openai") warn(`Unrecognized MCP extension: ${key}`);
34
+ const openai = ext["com.openai"] === void 0 ? {} : z.record(z.string(), z.unknown()).parse(ext["com.openai"]);
35
+ for (const key of Object.keys(openai)) if (key !== "auth") warn(`Unrecognized OpenAI MCP declaration: ${key}`);
36
+ if (openai.auth !== void 0) {
37
+ const auth = authSchema.parse(openai.auth);
38
+ if (auth.type === "oauth" || auth.type === "mixed") {
39
+ if (auth.baseScopes?.length && auth.defaultScopes === void 0) throw new Error("OAuth base scopes with discovered defaults require an adapter");
40
+ value.oauth = {
41
+ ...auth.client?.mode === "provided" ? { clientId: auth.client.clientId } : auth.client ? { clientRegistration: auth.client.mode } : {},
42
+ ...auth.defaultScopes !== void 0 ? { scope: [...new Set([...auth.baseScopes ?? [], ...auth.defaultScopes])].join(" ") } : {}
43
+ };
44
+ value.connectionAuth = { mode: "oauth" };
45
+ } else if (auth.type === "api_key") {
46
+ if (auth.headerScheme === "custom_header" && !auth.headerName || auth.headerScheme !== "custom_header" && auth.headerName) throw new Error("Invalid API key header declaration");
47
+ value.connectionAuth = {
48
+ mode: "api-key",
49
+ headerName: auth.headerName ?? "Authorization",
50
+ prefix: auth.headerScheme === "bearer" ? "Bearer " : auth.headerScheme === "basic" ? "Basic " : ""
51
+ };
52
+ } else value.connectionAuth = { mode: "none" };
53
+ }
54
+ delete value.extensions;
55
+ }
56
+ if (legacy) {
57
+ const allowed = new Set([
58
+ "type",
59
+ "command",
60
+ "args",
61
+ "env",
62
+ "cwd",
63
+ "url",
64
+ "headers",
65
+ "oauth_resource",
66
+ "oauth",
67
+ "connectionAuth"
68
+ ]);
69
+ for (const key of Object.keys(value)) if (!allowed.has(key)) {
70
+ warn(`Unsupported MCP field: ${key}`);
71
+ delete value[key];
72
+ }
73
+ if (value.oauth_resource !== void 0 && value.oauth_resource !== value.url) throw new Error("A distinct OAuth resource requires an adapter");
74
+ delete value.oauth_resource;
75
+ value.type = value.type === "http" ? "streamable-http" : value.type ?? (value.command ? "stdio" : "streamable-http");
76
+ if (typeof value.command === "string") value.command = value.command.replace(/^\$\{(?:CLAUDE_)?PLUGIN_ROOT\}\//, "./");
77
+ if (typeof value.cwd === "string") value.cwd = value.cwd.replace(/^\$\{CLAUDE_PLUGIN_(ROOT|DATA)\}/, "${PLUGIN_$1}");
78
+ }
79
+ return value;
80
+ }
81
+ //#endregion
82
+ export { normalizePluginMcpServer };
@@ -0,0 +1,14 @@
1
+ import type { AgentPluginStore, InstalledAgentPlugin } from './store.js';
2
+ export declare function pluginResources(plugin: Pick<InstalledAgentPlugin, 'manifest'>): {
3
+ url: string;
4
+ sha256: string;
5
+ maxBytes: number;
6
+ executable: boolean;
7
+ id: string;
8
+ platform?: "darwin" | "linux" | "win32";
9
+ arch?: "arm64" | "x64";
10
+ }[];
11
+ /** Download pinned files; execute them only later through an explicitly reviewed MCP process. */
12
+ export declare function preparePluginResources(store: AgentPluginStore, plugin: InstalledAgentPlugin, signal: AbortSignal): Promise<void>;
13
+ /** Derive ownership from retained revisions, including rollback and staged packages. */
14
+ export declare function prunePluginResourceCache(store: AgentPluginStore): void;