@bastani/atomic 0.9.25-alpha.3 → 0.9.25-alpha.4

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 (178) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/builtin/intercom/package.json +1 -1
  3. package/dist/builtin/mcp/CHANGELOG.md +30 -0
  4. package/dist/builtin/mcp/OAUTH.md +59 -269
  5. package/dist/builtin/mcp/README.md +58 -345
  6. package/dist/builtin/mcp/index.bundle.mjs +4 -28073
  7. package/dist/builtin/mcp/native-client-licenses/LICENSES/modelcontextprotocol-typescript-sdk.txt +21 -0
  8. package/dist/builtin/mcp/native-client-licenses/NOTICE +30 -0
  9. package/dist/builtin/mcp/package.json +4 -25
  10. package/dist/builtin/subagents/package.json +1 -1
  11. package/dist/builtin/web-access/package.json +1 -1
  12. package/dist/builtin/workflows/package.json +1 -1
  13. package/dist/cli/args.d.ts.map +1 -1
  14. package/dist/cli/args.js +2 -1
  15. package/dist/cli/args.js.map +1 -1
  16. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  17. package/dist/core/agent-session-extension-bindings.js +87 -5
  18. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  19. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  20. package/dist/core/agent-session-tool-registry.js +6 -3
  21. package/dist/core/agent-session-tool-registry.js.map +1 -1
  22. package/dist/core/extensions/context-types.d.ts +3 -1
  23. package/dist/core/extensions/context-types.d.ts.map +1 -1
  24. package/dist/core/extensions/context-types.js.map +1 -1
  25. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  26. package/dist/core/extensions/loader-api.js +4 -0
  27. package/dist/core/extensions/loader-api.js.map +1 -1
  28. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  29. package/dist/core/extensions/loader-virtual-modules.js +3 -0
  30. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  31. package/dist/core/mcp-child-policy.d.ts +11 -0
  32. package/dist/core/mcp-child-policy.d.ts.map +1 -0
  33. package/dist/core/mcp-child-policy.js +31 -0
  34. package/dist/core/mcp-child-policy.js.map +1 -0
  35. package/dist/core/mcp-servers.d.ts +32 -26
  36. package/dist/core/mcp-servers.d.ts.map +1 -1
  37. package/dist/core/mcp-servers.js +148 -1
  38. package/dist/core/mcp-servers.js.map +1 -1
  39. package/dist/core/package-manager-manifest.js.map +1 -1
  40. package/dist/core/package-manager-mcp-servers.js +1 -1
  41. package/dist/core/package-manager-mcp-servers.js.map +1 -1
  42. package/dist/core/sdk.js +10 -1
  43. package/dist/core/sdk.js.map +1 -1
  44. package/dist/core/tools/truncate.d.ts +8 -0
  45. package/dist/core/tools/truncate.d.ts.map +1 -1
  46. package/dist/core/tools/truncate.js +24 -0
  47. package/dist/core/tools/truncate.js.map +1 -1
  48. package/dist/extensions/mcp/cli.d.ts +21 -0
  49. package/dist/extensions/mcp/cli.d.ts.map +1 -0
  50. package/dist/extensions/mcp/cli.js +500 -0
  51. package/dist/extensions/mcp/cli.js.map +1 -0
  52. package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
  53. package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
  54. package/dist/extensions/mcp/cli.lazy.js +3 -0
  55. package/dist/extensions/mcp/cli.lazy.js.map +1 -0
  56. package/dist/extensions/mcp/client/auth-provider.d.ts +15 -0
  57. package/dist/extensions/mcp/client/auth-provider.d.ts.map +1 -0
  58. package/dist/extensions/mcp/client/auth-provider.js +2 -0
  59. package/dist/extensions/mcp/client/auth-provider.js.map +1 -0
  60. package/dist/extensions/mcp/client/client.d.ts +89 -0
  61. package/dist/extensions/mcp/client/client.d.ts.map +1 -0
  62. package/dist/extensions/mcp/client/client.js +457 -0
  63. package/dist/extensions/mcp/client/client.js.map +1 -0
  64. package/dist/extensions/mcp/client/index.d.ts +9 -0
  65. package/dist/extensions/mcp/client/index.d.ts.map +1 -0
  66. package/dist/extensions/mcp/client/index.js +7 -0
  67. package/dist/extensions/mcp/client/index.js.map +1 -0
  68. package/dist/extensions/mcp/client/oauth/callback.d.ts +42 -0
  69. package/dist/extensions/mcp/client/oauth/callback.d.ts.map +1 -0
  70. package/dist/extensions/mcp/client/oauth/callback.js +106 -0
  71. package/dist/extensions/mcp/client/oauth/callback.js.map +1 -0
  72. package/dist/extensions/mcp/client/oauth/discovery.d.ts +27 -0
  73. package/dist/extensions/mcp/client/oauth/discovery.d.ts.map +1 -0
  74. package/dist/extensions/mcp/client/oauth/discovery.js +153 -0
  75. package/dist/extensions/mcp/client/oauth/discovery.js.map +1 -0
  76. package/dist/extensions/mcp/client/oauth/errors.d.ts +24 -0
  77. package/dist/extensions/mcp/client/oauth/errors.d.ts.map +1 -0
  78. package/dist/extensions/mcp/client/oauth/errors.js +46 -0
  79. package/dist/extensions/mcp/client/oauth/errors.js.map +1 -0
  80. package/dist/extensions/mcp/client/oauth/flow.d.ts +82 -0
  81. package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -0
  82. package/dist/extensions/mcp/client/oauth/flow.js +292 -0
  83. package/dist/extensions/mcp/client/oauth/flow.js.map +1 -0
  84. package/dist/extensions/mcp/client/oauth/index.d.ts +7 -0
  85. package/dist/extensions/mcp/client/oauth/index.d.ts.map +1 -0
  86. package/dist/extensions/mcp/client/oauth/index.js +6 -0
  87. package/dist/extensions/mcp/client/oauth/index.js.map +1 -0
  88. package/dist/extensions/mcp/client/oauth/provider.d.ts +59 -0
  89. package/dist/extensions/mcp/client/oauth/provider.d.ts.map +1 -0
  90. package/dist/extensions/mcp/client/oauth/provider.js +116 -0
  91. package/dist/extensions/mcp/client/oauth/provider.js.map +1 -0
  92. package/dist/extensions/mcp/client/oauth/types.d.ts +77 -0
  93. package/dist/extensions/mcp/client/oauth/types.d.ts.map +1 -0
  94. package/dist/extensions/mcp/client/oauth/types.js +109 -0
  95. package/dist/extensions/mcp/client/oauth/types.js.map +1 -0
  96. package/dist/extensions/mcp/client/protocol/content.d.ts +82 -0
  97. package/dist/extensions/mcp/client/protocol/content.d.ts.map +1 -0
  98. package/dist/extensions/mcp/client/protocol/content.js +41 -0
  99. package/dist/extensions/mcp/client/protocol/content.js.map +1 -0
  100. package/dist/extensions/mcp/client/protocol/jsonrpc.d.ts +59 -0
  101. package/dist/extensions/mcp/client/protocol/jsonrpc.d.ts.map +1 -0
  102. package/dist/extensions/mcp/client/protocol/jsonrpc.js +67 -0
  103. package/dist/extensions/mcp/client/protocol/jsonrpc.js.map +1 -0
  104. package/dist/extensions/mcp/client/protocol/types.d.ts +123 -0
  105. package/dist/extensions/mcp/client/protocol/types.d.ts.map +1 -0
  106. package/dist/extensions/mcp/client/protocol/types.js +7 -0
  107. package/dist/extensions/mcp/client/protocol/types.js.map +1 -0
  108. package/dist/extensions/mcp/client/testing/index.d.ts +2 -0
  109. package/dist/extensions/mcp/client/testing/index.d.ts.map +1 -0
  110. package/dist/extensions/mcp/client/testing/index.js +2 -0
  111. package/dist/extensions/mcp/client/testing/index.js.map +1 -0
  112. package/dist/extensions/mcp/client/transports/in-memory.d.ts +19 -0
  113. package/dist/extensions/mcp/client/transports/in-memory.d.ts.map +1 -0
  114. package/dist/extensions/mcp/client/transports/in-memory.js +50 -0
  115. package/dist/extensions/mcp/client/transports/in-memory.js.map +1 -0
  116. package/dist/extensions/mcp/client/transports/stdio.d.ts +32 -0
  117. package/dist/extensions/mcp/client/transports/stdio.d.ts.map +1 -0
  118. package/dist/extensions/mcp/client/transports/stdio.js +201 -0
  119. package/dist/extensions/mcp/client/transports/stdio.js.map +1 -0
  120. package/dist/extensions/mcp/client/transports/streamable-http.d.ts +96 -0
  121. package/dist/extensions/mcp/client/transports/streamable-http.d.ts.map +1 -0
  122. package/dist/extensions/mcp/client/transports/streamable-http.js +456 -0
  123. package/dist/extensions/mcp/client/transports/streamable-http.js.map +1 -0
  124. package/dist/extensions/mcp/client/transports/transport.d.ts +28 -0
  125. package/dist/extensions/mcp/client/transports/transport.d.ts.map +1 -0
  126. package/dist/extensions/mcp/client/transports/transport.js +38 -0
  127. package/dist/extensions/mcp/client/transports/transport.js.map +1 -0
  128. package/dist/extensions/mcp/config.d.ts +72 -0
  129. package/dist/extensions/mcp/config.d.ts.map +1 -0
  130. package/dist/extensions/mcp/config.js +158 -0
  131. package/dist/extensions/mcp/config.js.map +1 -0
  132. package/dist/extensions/mcp/index.d.ts +76 -0
  133. package/dist/extensions/mcp/index.d.ts.map +1 -0
  134. package/dist/extensions/mcp/index.js +1119 -0
  135. package/dist/extensions/mcp/index.js.map +1 -0
  136. package/dist/extensions/mcp/log.d.ts +16 -0
  137. package/dist/extensions/mcp/log.d.ts.map +1 -0
  138. package/dist/extensions/mcp/log.js +66 -0
  139. package/dist/extensions/mcp/log.js.map +1 -0
  140. package/dist/extensions/mcp/oauth.d.ts +103 -0
  141. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  142. package/dist/extensions/mcp/oauth.js +382 -0
  143. package/dist/extensions/mcp/oauth.js.map +1 -0
  144. package/dist/extensions/mcp/resources.d.ts +43 -0
  145. package/dist/extensions/mcp/resources.d.ts.map +1 -0
  146. package/dist/extensions/mcp/resources.js +262 -0
  147. package/dist/extensions/mcp/resources.js.map +1 -0
  148. package/dist/extensions/mcp/runtime.d.ts +104 -0
  149. package/dist/extensions/mcp/runtime.d.ts.map +1 -0
  150. package/dist/extensions/mcp/runtime.js +546 -0
  151. package/dist/extensions/mcp/runtime.js.map +1 -0
  152. package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
  153. package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
  154. package/dist/extensions/mcp/runtime.lazy.js +3 -0
  155. package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
  156. package/dist/extensions/mcp/tools.d.ts +84 -0
  157. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  158. package/dist/extensions/mcp/tools.js +251 -0
  159. package/dist/extensions/mcp/tools.js.map +1 -0
  160. package/dist/extensions/mcp/ui.d.ts +60 -0
  161. package/dist/extensions/mcp/ui.d.ts.map +1 -0
  162. package/dist/extensions/mcp/ui.js +175 -0
  163. package/dist/extensions/mcp/ui.js.map +1 -0
  164. package/dist/index.d.ts +5 -1
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +5 -0
  167. package/dist/index.js.map +1 -1
  168. package/dist/main.d.ts.map +1 -1
  169. package/dist/main.js +7 -0
  170. package/dist/main.js.map +1 -1
  171. package/docs/extensions/api-reference.md +3 -3
  172. package/docs/extensions.md +8 -8
  173. package/docs/mcp-servers.md +153 -79
  174. package/docs/packages/authoring.md +2 -2
  175. package/npm-shrinkwrap.json +32 -32
  176. package/package.json +3 -3
  177. package/dist/builtin/mcp/app-bridge.bundle.js +0 -67
  178. package/dist/builtin/mcp/xdg-open +0 -1267
@@ -1,42 +1,48 @@
1
1
  import type { SourceInfo } from "./source-info.ts";
2
- export interface McpServerOAuthConfig {
3
- grantType?: "authorization_code" | "client_credentials";
4
- clientId?: string;
5
- clientSecret?: string;
6
- scope?: string;
7
- clientName?: string;
2
+ export type McpExposure = "codemode" | "deferred" | "direct" | "hidden";
3
+ interface McpServerConfigBase {
4
+ exposure?: McpExposure;
5
+ description?: string;
6
+ toolExposure?: Record<string, McpExposure>;
7
+ enabled?: boolean;
8
+ timeout?: number;
8
9
  }
9
- /** One MCP server definition; the same schema as an `mcpServers` entry in `mcp.json`. */
10
- export interface McpServerConfig {
11
- command?: string;
10
+ export interface McpStdioServerConfig extends McpServerConfigBase {
11
+ type?: "stdio";
12
+ command: string;
12
13
  args?: string[];
13
14
  env?: Record<string, string>;
14
15
  cwd?: string;
15
- url?: string;
16
+ }
17
+ export interface McpHttpServerConfig extends McpServerConfigBase {
18
+ type?: "http";
19
+ url: string;
16
20
  headers?: Record<string, string>;
17
- auth?: "oauth" | "bearer" | false | {
21
+ oauth?: McpOAuthConfig;
22
+ auth?: {
18
23
  provider: string;
19
24
  };
20
- bearerToken?: string;
21
- bearerTokenEnv?: string;
22
- oauth?: McpServerOAuthConfig | false;
23
- lifecycle?: "keep-alive" | "lazy" | "eager";
24
- idleTimeout?: number;
25
- exposeResources?: boolean;
26
- directTools?: boolean | string[];
27
- excludeTools?: string[];
28
- debug?: boolean;
29
- timeoutMs?: number;
30
- /** Drop the server from the effective MCP configuration. */
31
- disabled?: boolean;
32
25
  }
33
- /** An MCP server contributed by a package manifest or an extension's `pi.registerMcpServer()` call. */
26
+ export type McpServerConfig = McpStdioServerConfig | McpHttpServerConfig;
34
27
  export interface McpServerContribution {
35
28
  name: string;
36
29
  config: McpServerConfig;
37
- /** `package` for manifest `mcpServers`; `extension` for runtime registrations. */
38
30
  origin: "package" | "extension";
39
- /** Declaring manifest file for packages; registering extension path and its package source for extensions. */
40
31
  sourceInfo: SourceInfo;
41
32
  }
33
+ export interface McpOAuthConfig {
34
+ clientId?: string;
35
+ clientSecret?: string;
36
+ callbackPort?: number;
37
+ callbackUrl?: string;
38
+ scope?: string;
39
+ clientName?: string;
40
+ authServerMetadataUrl?: string;
41
+ }
42
+ export declare function mcpNamespace(server: string): string;
43
+ export declare function resolveMcpServerUrl(value: string): string;
44
+ export declare function isLoopbackRedirectUri(value: string): boolean;
45
+ export declare function getMcpToolExposure(config: McpServerConfig, toolName: string): McpExposure;
46
+ export declare function validateMcpServerConfig(name: string, raw: unknown): McpServerConfig | string;
47
+ export {};
42
48
  //# sourceMappingURL=mcp-servers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-servers.d.ts","sourceRoot":"","sources":["../../src/core/mcp-servers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,oBAAoB;IACpC,SAAS,CAAC,EAAE,oBAAoB,GAAG,oBAAoB,CAAC;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yFAAyF;AACzF,MAAM,WAAW,eAAe;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,oBAAoB,GAAG,KAAK,CAAC;IACrC,SAAS,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,uGAAuG;AACvG,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,kFAAkF;IAClF,MAAM,EAAE,SAAS,GAAG,WAAW,CAAC;IAChC,8GAA8G;IAC9G,UAAU,EAAE,UAAU,CAAC;CACvB"}
1
+ {"version":3,"file":"mcp-servers.d.ts","sourceRoot":"","sources":["../../src/core/mcp-servers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAMxE,UAAU,mBAAmB;IAC5B,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAChE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AACD,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,IAAI,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5B;AACD,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AACzE,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,SAAS,GAAG,WAAW,CAAC;IAChC,UAAU,EAAE,UAAU,CAAC;CACvB;AACD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAazD;AACD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAI5D;AAiDD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAOzF;AACD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,eAAe,GAAG,MAAM,CAkD5F"}
@@ -1,2 +1,149 @@
1
- export {};
1
+ const MCP_EXPOSURES = ["codemode", "deferred", "direct", "hidden"];
2
+ const EXPOSURE_ALIASES = { "codemode-deferred": "codemode" };
3
+ const LOOPBACK_HOSTS = ["localhost", "127.0.0.1", "[::1]"];
4
+ const SERVER_NAME = /^[A-Za-z0-9_-]+$/;
5
+ export function mcpNamespace(server) {
6
+ return `mcp__${server.replace(/-/g, "_")}`;
7
+ }
8
+ function isRecord(value) {
9
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10
+ }
11
+ function isStringRecord(value) {
12
+ return isRecord(value) && Object.values(value).every((entry) => typeof entry === "string");
13
+ }
14
+ export function resolveMcpServerUrl(value) {
15
+ const resolved = value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$env:([A-Za-z_][A-Za-z0-9_]*)/g, (_match, brace, powershell) => {
16
+ const name = brace ?? powershell;
17
+ const replacement = process.env[name];
18
+ if (replacement === undefined)
19
+ throw new Error(`MCP server URL environment variable "${name}" is not set`);
20
+ return replacement;
21
+ });
22
+ if (!URL.canParse(resolved) || !/^https?:$/.test(new URL(resolved).protocol))
23
+ throw new Error("Invalid MCP server URL after environment variable interpolation: expected HTTP(S)");
24
+ return resolved;
25
+ }
26
+ export function isLoopbackRedirectUri(value) {
27
+ if (!URL.canParse(value))
28
+ return false;
29
+ const url = new URL(value);
30
+ return url.protocol === "http:" && LOOPBACK_HOSTS.includes(url.hostname) && !url.search && !url.hash;
31
+ }
32
+ function validateOAuth(value) {
33
+ if (value === undefined)
34
+ return undefined;
35
+ if (!isRecord(value))
36
+ return "oauth must be an object";
37
+ for (const key of ["clientId", "clientSecret", "scope"])
38
+ if (value[key] !== undefined && typeof value[key] !== "string")
39
+ return `oauth.${key} must be a string`;
40
+ const port = value.callbackPort;
41
+ if (port !== undefined && (typeof port !== "number" || !Number.isInteger(port) || port < 1 || port > 65535))
42
+ return "oauth.callbackPort must be a port number";
43
+ if (value.callbackUrl !== undefined) {
44
+ if (typeof value.callbackUrl !== "string" || !isLoopbackRedirectUri(value.callbackUrl))
45
+ return "oauth.callbackUrl must be an http URI on localhost, 127.0.0.1, or [::1] without query or fragment";
46
+ const urlPort = new URL(value.callbackUrl).port;
47
+ if (urlPort && port !== undefined && Number(urlPort) !== port)
48
+ return "oauth.callbackUrl and oauth.callbackPort name different ports";
49
+ }
50
+ if (value.clientName !== undefined && (typeof value.clientName !== "string" || !value.clientName.trim()))
51
+ return "oauth.clientName must be a non-empty string";
52
+ const metadataUrl = value.authServerMetadataUrl;
53
+ if (metadataUrl !== undefined) {
54
+ const url = typeof metadataUrl === "string" && URL.canParse(metadataUrl) ? new URL(metadataUrl) : undefined;
55
+ if (!url || !(url.protocol === "https:" || (url.protocol === "http:" && LOOPBACK_HOSTS.includes(url.hostname))))
56
+ return "oauth.authServerMetadataUrl must be an https URL, or http on localhost, 127.0.0.1, or [::1]";
57
+ }
58
+ return undefined;
59
+ }
60
+ function isExposure(value) {
61
+ return typeof value === "string" && MCP_EXPOSURES.includes(value);
62
+ }
63
+ function resolveExposureAlias(value) {
64
+ return typeof value === "string" ? (EXPOSURE_ALIASES[value] ?? value) : value;
65
+ }
66
+ function resolveExposureAliases(raw) {
67
+ const value = { ...raw };
68
+ if (raw.exposure !== undefined)
69
+ value.exposure = resolveExposureAlias(raw.exposure);
70
+ if (isRecord(raw.toolExposure))
71
+ value.toolExposure = Object.fromEntries(Object.entries(raw.toolExposure).map(([tool, exposure]) => [tool, resolveExposureAlias(exposure)]));
72
+ return value;
73
+ }
74
+ function toolPatternRegExp(pattern) {
75
+ return new RegExp(`^${pattern
76
+ .split("*")
77
+ .map((part) => part.replace(/[.+?^${}()|[\]\\]/g, "\\$&"))
78
+ .join(".*")}$`);
79
+ }
80
+ export function getMcpToolExposure(config, toolName) {
81
+ const overrides = config.toolExposure ?? {};
82
+ const exact = overrides[toolName];
83
+ if (exact !== undefined)
84
+ return exact;
85
+ for (const [pattern, exposure] of Object.entries(overrides))
86
+ if (pattern.includes("*") && toolPatternRegExp(pattern).test(toolName))
87
+ return exposure;
88
+ return config.exposure ?? "codemode";
89
+ }
90
+ export function validateMcpServerConfig(name, raw) {
91
+ if (!SERVER_NAME.test(name))
92
+ return `invalid server name "${name}" (use letters, digits, "_" and "-")`;
93
+ if (!isRecord(raw))
94
+ return `server "${name}" must be an object`;
95
+ const value = resolveExposureAliases(raw);
96
+ const { type, exposure, enabled, timeout, toolExposure, description } = value;
97
+ const exposures = MCP_EXPOSURES.map((entry) => `"${entry}"`).join(", ");
98
+ if (exposure !== undefined && !isExposure(exposure))
99
+ return `server "${name}": exposure must be one of ${exposures}`;
100
+ if (toolExposure !== undefined) {
101
+ if (!isRecord(toolExposure))
102
+ return `server "${name}": toolExposure must map tool names to exposures`;
103
+ for (const [tool, entry] of Object.entries(toolExposure))
104
+ if (!isExposure(entry))
105
+ return `server "${name}": toolExposure "${tool}" must be one of ${exposures}`;
106
+ }
107
+ if (enabled !== undefined && typeof enabled !== "boolean")
108
+ return `server "${name}": enabled must be a boolean`;
109
+ if (description !== undefined && typeof description !== "string")
110
+ return `server "${name}": description must be a string`;
111
+ if (timeout !== undefined && (typeof timeout !== "number" || !(timeout > 0)))
112
+ return `server "${name}": timeout must be a positive number of seconds`;
113
+ if (type === "sse")
114
+ return `server "${name}": legacy SSE transport is not supported; use the streamable HTTP URL`;
115
+ if (typeof value.url === "string" && (type === undefined || type === "http" || type === "streamable-http")) {
116
+ let resolvedUrl;
117
+ try {
118
+ resolvedUrl = resolveMcpServerUrl(value.url);
119
+ }
120
+ catch {
121
+ return `server "${name}": url must be an http or https URL after environment variable interpolation`;
122
+ }
123
+ if (value.headers !== undefined && !isStringRecord(value.headers))
124
+ return `server "${name}": headers must map names to strings`;
125
+ const oauthError = validateOAuth(value.oauth);
126
+ if (oauthError)
127
+ return `server "${name}": ${oauthError}`;
128
+ if (value.auth !== undefined) {
129
+ if (!isRecord(value.auth) || typeof value.auth.provider !== "string" || !value.auth.provider)
130
+ return `server "${name}": auth.provider must be a provider name`;
131
+ const url = new URL(resolvedUrl);
132
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && LOOPBACK_HOSTS.includes(url.hostname)))
133
+ return `server "${name}": auth requires an https URL, or http on localhost, 127.0.0.1, or [::1]`;
134
+ }
135
+ return value;
136
+ }
137
+ if (typeof value.command === "string" && (type === undefined || type === "stdio")) {
138
+ if (value.args !== undefined &&
139
+ !(Array.isArray(value.args) && value.args.every((arg) => typeof arg === "string")))
140
+ return `server "${name}": args must be an array of strings`;
141
+ if (value.env !== undefined && !isStringRecord(value.env))
142
+ return `server "${name}": env must map names to strings`;
143
+ if (value.cwd !== undefined && typeof value.cwd !== "string")
144
+ return `server "${name}": cwd must be a string`;
145
+ return value;
146
+ }
147
+ return `server "${name}" needs either "command" (stdio) or "url" (streamable HTTP)`;
148
+ }
2
149
  //# sourceMappingURL=mcp-servers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-servers.js","sourceRoot":"","sources":["../../src/core/mcp-servers.ts"],"names":[],"mappings":"","sourcesContent":["import type { SourceInfo } from \"./source-info.ts\";\n\nexport interface McpServerOAuthConfig {\n\tgrantType?: \"authorization_code\" | \"client_credentials\";\n\tclientId?: string;\n\tclientSecret?: string;\n\tscope?: string;\n\tclientName?: string;\n}\n\n/** One MCP server definition; the same schema as an `mcpServers` entry in `mcp.json`. */\nexport interface McpServerConfig {\n\tcommand?: string;\n\targs?: string[];\n\tenv?: Record<string, string>;\n\tcwd?: string;\n\turl?: string;\n\theaders?: Record<string, string>;\n\tauth?: \"oauth\" | \"bearer\" | false | { provider: string };\n\tbearerToken?: string;\n\tbearerTokenEnv?: string;\n\toauth?: McpServerOAuthConfig | false;\n\tlifecycle?: \"keep-alive\" | \"lazy\" | \"eager\";\n\tidleTimeout?: number;\n\texposeResources?: boolean;\n\tdirectTools?: boolean | string[];\n\texcludeTools?: string[];\n\tdebug?: boolean;\n\ttimeoutMs?: number;\n\t/** Drop the server from the effective MCP configuration. */\n\tdisabled?: boolean;\n}\n\n/** An MCP server contributed by a package manifest or an extension's `pi.registerMcpServer()` call. */\nexport interface McpServerContribution {\n\tname: string;\n\tconfig: McpServerConfig;\n\t/** `package` for manifest `mcpServers`; `extension` for runtime registrations. */\n\torigin: \"package\" | \"extension\";\n\t/** Declaring manifest file for packages; registering extension path and its package source for extensions. */\n\tsourceInfo: SourceInfo;\n}\n"]}
1
+ {"version":3,"file":"mcp-servers.js","sourceRoot":"","sources":["../../src/core/mcp-servers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SourceInfo } from \"./source-info.ts\";\n\nexport type McpExposure = \"codemode\" | \"deferred\" | \"direct\" | \"hidden\";\nconst MCP_EXPOSURES: readonly string[] = [\"codemode\", \"deferred\", \"direct\", \"hidden\"];\nconst EXPOSURE_ALIASES: Readonly<Record<string, McpExposure>> = { \"codemode-deferred\": \"codemode\" };\nconst LOOPBACK_HOSTS = [\"localhost\", \"127.0.0.1\", \"[::1]\"];\nconst SERVER_NAME = /^[A-Za-z0-9_-]+$/;\n\ninterface McpServerConfigBase {\n\texposure?: McpExposure;\n\tdescription?: string;\n\ttoolExposure?: Record<string, McpExposure>;\n\tenabled?: boolean;\n\ttimeout?: number;\n}\nexport interface McpStdioServerConfig extends McpServerConfigBase {\n\ttype?: \"stdio\";\n\tcommand: string;\n\targs?: string[];\n\tenv?: Record<string, string>;\n\tcwd?: string;\n}\nexport interface McpHttpServerConfig extends McpServerConfigBase {\n\ttype?: \"http\";\n\turl: string;\n\theaders?: Record<string, string>;\n\toauth?: McpOAuthConfig;\n\tauth?: { provider: string };\n}\nexport type McpServerConfig = McpStdioServerConfig | McpHttpServerConfig;\nexport interface McpServerContribution {\n\tname: string;\n\tconfig: McpServerConfig;\n\torigin: \"package\" | \"extension\";\n\tsourceInfo: SourceInfo;\n}\nexport interface McpOAuthConfig {\n\tclientId?: string;\n\tclientSecret?: string;\n\tcallbackPort?: number;\n\tcallbackUrl?: string;\n\tscope?: string;\n\tclientName?: string;\n\tauthServerMetadataUrl?: string;\n}\n\nexport function mcpNamespace(server: string): string {\n\treturn `mcp__${server.replace(/-/g, \"_\")}`;\n}\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n\treturn isRecord(value) && Object.values(value).every((entry) => typeof entry === \"string\");\n}\nexport function resolveMcpServerUrl(value: string): string {\n\tconst resolved = value.replace(\n\t\t/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}|\\$env:([A-Za-z_][A-Za-z0-9_]*)/g,\n\t\t(_match, brace: string | undefined, powershell: string | undefined) => {\n\t\t\tconst name = brace ?? powershell!;\n\t\t\tconst replacement = process.env[name];\n\t\t\tif (replacement === undefined) throw new Error(`MCP server URL environment variable \"${name}\" is not set`);\n\t\t\treturn replacement;\n\t\t},\n\t);\n\tif (!URL.canParse(resolved) || !/^https?:$/.test(new URL(resolved).protocol))\n\t\tthrow new Error(\"Invalid MCP server URL after environment variable interpolation: expected HTTP(S)\");\n\treturn resolved;\n}\nexport function isLoopbackRedirectUri(value: string): boolean {\n\tif (!URL.canParse(value)) return false;\n\tconst url = new URL(value);\n\treturn url.protocol === \"http:\" && LOOPBACK_HOSTS.includes(url.hostname) && !url.search && !url.hash;\n}\nfunction validateOAuth(value: unknown): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (!isRecord(value)) return \"oauth must be an object\";\n\tfor (const key of [\"clientId\", \"clientSecret\", \"scope\"] as const)\n\t\tif (value[key] !== undefined && typeof value[key] !== \"string\") return `oauth.${key} must be a string`;\n\tconst port = value.callbackPort;\n\tif (port !== undefined && (typeof port !== \"number\" || !Number.isInteger(port) || port < 1 || port > 65535))\n\t\treturn \"oauth.callbackPort must be a port number\";\n\tif (value.callbackUrl !== undefined) {\n\t\tif (typeof value.callbackUrl !== \"string\" || !isLoopbackRedirectUri(value.callbackUrl))\n\t\t\treturn \"oauth.callbackUrl must be an http URI on localhost, 127.0.0.1, or [::1] without query or fragment\";\n\t\tconst urlPort = new URL(value.callbackUrl).port;\n\t\tif (urlPort && port !== undefined && Number(urlPort) !== port)\n\t\t\treturn \"oauth.callbackUrl and oauth.callbackPort name different ports\";\n\t}\n\tif (value.clientName !== undefined && (typeof value.clientName !== \"string\" || !value.clientName.trim()))\n\t\treturn \"oauth.clientName must be a non-empty string\";\n\tconst metadataUrl = value.authServerMetadataUrl;\n\tif (metadataUrl !== undefined) {\n\t\tconst url = typeof metadataUrl === \"string\" && URL.canParse(metadataUrl) ? new URL(metadataUrl) : undefined;\n\t\tif (!url || !(url.protocol === \"https:\" || (url.protocol === \"http:\" && LOOPBACK_HOSTS.includes(url.hostname))))\n\t\t\treturn \"oauth.authServerMetadataUrl must be an https URL, or http on localhost, 127.0.0.1, or [::1]\";\n\t}\n\treturn undefined;\n}\nfunction isExposure(value: unknown): value is McpExposure {\n\treturn typeof value === \"string\" && MCP_EXPOSURES.includes(value);\n}\nfunction resolveExposureAlias(value: unknown): unknown {\n\treturn typeof value === \"string\" ? (EXPOSURE_ALIASES[value] ?? value) : value;\n}\nfunction resolveExposureAliases(raw: Record<string, unknown>): Record<string, unknown> {\n\tconst value = { ...raw };\n\tif (raw.exposure !== undefined) value.exposure = resolveExposureAlias(raw.exposure);\n\tif (isRecord(raw.toolExposure))\n\t\tvalue.toolExposure = Object.fromEntries(\n\t\t\tObject.entries(raw.toolExposure).map(([tool, exposure]) => [tool, resolveExposureAlias(exposure)]),\n\t\t);\n\treturn value;\n}\nfunction toolPatternRegExp(pattern: string): RegExp {\n\treturn new RegExp(\n\t\t`^${pattern\n\t\t\t.split(\"*\")\n\t\t\t.map((part) => part.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\"))\n\t\t\t.join(\".*\")}$`,\n\t);\n}\nexport function getMcpToolExposure(config: McpServerConfig, toolName: string): McpExposure {\n\tconst overrides = config.toolExposure ?? {};\n\tconst exact = overrides[toolName];\n\tif (exact !== undefined) return exact;\n\tfor (const [pattern, exposure] of Object.entries(overrides))\n\t\tif (pattern.includes(\"*\") && toolPatternRegExp(pattern).test(toolName)) return exposure;\n\treturn config.exposure ?? \"codemode\";\n}\nexport function validateMcpServerConfig(name: string, raw: unknown): McpServerConfig | string {\n\tif (!SERVER_NAME.test(name)) return `invalid server name \"${name}\" (use letters, digits, \"_\" and \"-\")`;\n\tif (!isRecord(raw)) return `server \"${name}\" must be an object`;\n\tconst value = resolveExposureAliases(raw);\n\tconst { type, exposure, enabled, timeout, toolExposure, description } = value;\n\tconst exposures = MCP_EXPOSURES.map((entry) => `\"${entry}\"`).join(\", \");\n\tif (exposure !== undefined && !isExposure(exposure)) return `server \"${name}\": exposure must be one of ${exposures}`;\n\tif (toolExposure !== undefined) {\n\t\tif (!isRecord(toolExposure)) return `server \"${name}\": toolExposure must map tool names to exposures`;\n\t\tfor (const [tool, entry] of Object.entries(toolExposure))\n\t\t\tif (!isExposure(entry)) return `server \"${name}\": toolExposure \"${tool}\" must be one of ${exposures}`;\n\t}\n\tif (enabled !== undefined && typeof enabled !== \"boolean\") return `server \"${name}\": enabled must be a boolean`;\n\tif (description !== undefined && typeof description !== \"string\")\n\t\treturn `server \"${name}\": description must be a string`;\n\tif (timeout !== undefined && (typeof timeout !== \"number\" || !(timeout > 0)))\n\t\treturn `server \"${name}\": timeout must be a positive number of seconds`;\n\tif (type === \"sse\") return `server \"${name}\": legacy SSE transport is not supported; use the streamable HTTP URL`;\n\tif (typeof value.url === \"string\" && (type === undefined || type === \"http\" || type === \"streamable-http\")) {\n\t\tlet resolvedUrl: string;\n\t\ttry {\n\t\t\tresolvedUrl = resolveMcpServerUrl(value.url);\n\t\t} catch {\n\t\t\treturn `server \"${name}\": url must be an http or https URL after environment variable interpolation`;\n\t\t}\n\t\tif (value.headers !== undefined && !isStringRecord(value.headers))\n\t\t\treturn `server \"${name}\": headers must map names to strings`;\n\t\tconst oauthError = validateOAuth(value.oauth);\n\t\tif (oauthError) return `server \"${name}\": ${oauthError}`;\n\t\tif (value.auth !== undefined) {\n\t\t\tif (!isRecord(value.auth) || typeof value.auth.provider !== \"string\" || !value.auth.provider)\n\t\t\t\treturn `server \"${name}\": auth.provider must be a provider name`;\n\t\t\tconst url = new URL(resolvedUrl);\n\t\t\tif (url.protocol !== \"https:\" && !(url.protocol === \"http:\" && LOOPBACK_HOSTS.includes(url.hostname)))\n\t\t\t\treturn `server \"${name}\": auth requires an https URL, or http on localhost, 127.0.0.1, or [::1]`;\n\t\t}\n\t\treturn value as unknown as McpHttpServerConfig;\n\t}\n\tif (typeof value.command === \"string\" && (type === undefined || type === \"stdio\")) {\n\t\tif (\n\t\t\tvalue.args !== undefined &&\n\t\t\t!(Array.isArray(value.args) && value.args.every((arg) => typeof arg === \"string\"))\n\t\t)\n\t\t\treturn `server \"${name}\": args must be an array of strings`;\n\t\tif (value.env !== undefined && !isStringRecord(value.env))\n\t\t\treturn `server \"${name}\": env must map names to strings`;\n\t\tif (value.cwd !== undefined && typeof value.cwd !== \"string\") return `server \"${name}\": cwd must be a string`;\n\t\treturn value as unknown as McpStdioServerConfig;\n\t}\n\treturn `server \"${name}\" needs either \"command\" (stdio) or \"url\" (streamable HTTP)`;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager-manifest.js","sourceRoot":"","sources":["../../src/core/package-manager-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { APP_NAME } from \"../config.js\";\nimport { stripBom } from \"../utils/text.ts\";\nimport type { McpServerConfig } from \"./mcp-servers.ts\";\nimport type { PiManifest, ResourceType } from \"./package-manager-types.ts\";\n\nconst MANIFEST_ENTRY_FIELDS = [\"extensions\", \"skills\", \"prompts\", \"themes\", \"workflows\", \"workflow\"] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Keep the object-valued entries of an `mcpServers` map; the MCP adapter validates their fields. */\nexport function sanitizeMcpServers(value: unknown): Record<string, McpServerConfig> | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst servers: Record<string, McpServerConfig> = {};\n\tfor (const [name, entry] of Object.entries(value)) {\n\t\tif (isRecord(entry)) servers[name] = entry as McpServerConfig;\n\t}\n\treturn servers;\n}\n\nfunction sanitizeManifest(value: unknown): PiManifest | null {\n\tif (!isRecord(value)) return null;\n\tconst manifest: PiManifest = {};\n\tfor (const field of MANIFEST_ENTRY_FIELDS) {\n\t\tconst entries = value[field];\n\t\tif (Array.isArray(entries) && entries.every((entry): entry is string => typeof entry === \"string\")) {\n\t\t\tmanifest[field] = entries;\n\t\t}\n\t}\n\tconst mcpServers = typeof value.mcpServers === \"string\" ? value.mcpServers : sanitizeMcpServers(value.mcpServers);\n\tif (mcpServers !== undefined) manifest.mcpServers = mcpServers;\n\treturn manifest;\n}\n\nexport function getManifestFromPackageJson(pkg: unknown): PiManifest | null {\n\tif (!isRecord(pkg)) return null;\n\treturn sanitizeManifest(pkg[APP_NAME]) ?? sanitizeManifest(pkg.pi);\n}\n\nexport function readPiManifestFile(packageJsonPath: string): PiManifest | null {\n\ttry {\n\t\tconst content = readFileSync(packageJsonPath, \"utf-8\");\n\t\tconst pkg = JSON.parse(stripBom(content)) as Record<string, unknown>;\n\t\treturn getManifestFromPackageJson(pkg);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function readPiManifest(packageRoot: string): PiManifest | null {\n\tconst packageJsonPath = join(packageRoot, \"package.json\");\n\tif (!existsSync(packageJsonPath)) {\n\t\treturn null;\n\t}\n\treturn readPiManifestFile(packageJsonPath);\n}\n\nexport function conventionDirsForResource(packageRoot: string, resourceType: ResourceType): string[] {\n\tif (resourceType === \"workflows\") {\n\t\treturn [join(packageRoot, \"workflows\"), join(packageRoot, \"workflow\")];\n\t}\n\treturn [join(packageRoot, resourceType)];\n}\n\nexport function manifestEntriesForResource(\n\tmanifest: PiManifest | null,\n\tresourceType: ResourceType,\n): string[] | undefined {\n\tif (!manifest) return undefined;\n\tif (resourceType === \"workflows\") return manifest.workflows ?? manifest.workflow;\n\treturn manifest[resourceType];\n}\n"]}
1
+ {"version":3,"file":"package-manager-manifest.js","sourceRoot":"","sources":["../../src/core/package-manager-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5C,MAAM,qBAAqB,GAAG,CAAC,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,CAAU,CAAC;AAE9G,SAAS,QAAQ,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAChD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,OAAO,GAAoC,EAAE,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,IAAI,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,KAAmC,CAAC;IAC1E,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACvC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,QAAQ,GAAe,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,qBAAqB,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,EAAE,CAAC;YACpG,QAAQ,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;QAC3B,CAAC;IACF,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAClH,IAAI,UAAU,KAAK,SAAS;QAAE,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/D,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,GAAY;IACtD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,eAAuB;IACzD,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA4B,CAAC;QACrE,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,WAAmB;IACjD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,kBAAkB,CAAC,eAAe,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,WAAmB,EAAE,YAA0B;IACxF,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,0BAA0B,CACzC,QAA2B,EAC3B,YAA0B;IAE1B,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,YAAY,KAAK,WAAW;QAAE,OAAO,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC;IACjF,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;AAC/B,CAAC","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { APP_NAME } from \"../config.js\";\nimport { stripBom } from \"../utils/text.ts\";\nimport type { McpServerConfig } from \"./mcp-servers.ts\";\nimport type { PiManifest, ResourceType } from \"./package-manager-types.ts\";\n\nconst MANIFEST_ENTRY_FIELDS = [\"extensions\", \"skills\", \"prompts\", \"themes\", \"workflows\", \"workflow\"] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Keep the object-valued entries of an `mcpServers` map; the MCP adapter validates their fields. */\nexport function sanitizeMcpServers(value: unknown): Record<string, McpServerConfig> | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst servers: Record<string, McpServerConfig> = {};\n\tfor (const [name, entry] of Object.entries(value)) {\n\t\tif (isRecord(entry)) servers[name] = entry as unknown as McpServerConfig;\n\t}\n\treturn servers;\n}\n\nfunction sanitizeManifest(value: unknown): PiManifest | null {\n\tif (!isRecord(value)) return null;\n\tconst manifest: PiManifest = {};\n\tfor (const field of MANIFEST_ENTRY_FIELDS) {\n\t\tconst entries = value[field];\n\t\tif (Array.isArray(entries) && entries.every((entry): entry is string => typeof entry === \"string\")) {\n\t\t\tmanifest[field] = entries;\n\t\t}\n\t}\n\tconst mcpServers = typeof value.mcpServers === \"string\" ? value.mcpServers : sanitizeMcpServers(value.mcpServers);\n\tif (mcpServers !== undefined) manifest.mcpServers = mcpServers;\n\treturn manifest;\n}\n\nexport function getManifestFromPackageJson(pkg: unknown): PiManifest | null {\n\tif (!isRecord(pkg)) return null;\n\treturn sanitizeManifest(pkg[APP_NAME]) ?? sanitizeManifest(pkg.pi);\n}\n\nexport function readPiManifestFile(packageJsonPath: string): PiManifest | null {\n\ttry {\n\t\tconst content = readFileSync(packageJsonPath, \"utf-8\");\n\t\tconst pkg = JSON.parse(stripBom(content)) as Record<string, unknown>;\n\t\treturn getManifestFromPackageJson(pkg);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function readPiManifest(packageRoot: string): PiManifest | null {\n\tconst packageJsonPath = join(packageRoot, \"package.json\");\n\tif (!existsSync(packageJsonPath)) {\n\t\treturn null;\n\t}\n\treturn readPiManifestFile(packageJsonPath);\n}\n\nexport function conventionDirsForResource(packageRoot: string, resourceType: ResourceType): string[] {\n\tif (resourceType === \"workflows\") {\n\t\treturn [join(packageRoot, \"workflows\"), join(packageRoot, \"workflow\")];\n\t}\n\treturn [join(packageRoot, resourceType)];\n}\n\nexport function manifestEntriesForResource(\n\tmanifest: PiManifest | null,\n\tresourceType: ResourceType,\n): string[] | undefined {\n\tif (!manifest) return undefined;\n\tif (resourceType === \"workflows\") return manifest.workflows ?? manifest.workflow;\n\treturn manifest[resourceType];\n}\n"]}
@@ -32,7 +32,7 @@ function selectMcpServers(names, filter) {
32
32
  }
33
33
  /** A package cannot know the user's project directory, so a relative `cwd` names a directory in the package. */
34
34
  function resolvePackageCwd(config, packageRoot) {
35
- const { cwd } = config;
35
+ const cwd = "cwd" in config ? config.cwd : undefined;
36
36
  if (typeof cwd !== "string" || isAbsolute(cwd) || cwd.startsWith("~") || cwd.startsWith("$"))
37
37
  return config;
38
38
  return { ...config, cwd: resolve(packageRoot, cwd) };
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager-mcp-servers.js","sourceRoot":"","sources":["../../src/core/package-manager-mcp-servers.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport { stripBom } from \"../utils/text.ts\";\nimport type { McpServerConfig } from \"./mcp-servers.ts\";\nimport { getManifestFromPackageJson, sanitizeMcpServers } from \"./package-manager-manifest.ts\";\nimport { applyAutoloadDisabledNamePatterns, applyNamePatterns } from \"./package-manager-resource-patterns.ts\";\nimport type { PackageFilter, PathMetadata, ResolvedMcpServer } from \"./package-manager-types.ts\";\n\ninterface McpServersFile {\n\tmcpServers?: object;\n\t\"mcp-servers\"?: object;\n}\n\nasync function readJson<T>(path: string): Promise<T> {\n\treturn JSON.parse(stripBom(await readFile(path, \"utf-8\"))) as T;\n}\n\nasync function readManifestMcpServers(\n\tpackageRoot: string,\n): Promise<{ path: string; servers: Record<string, McpServerConfig> } | undefined> {\n\tconst packageJsonPath = resolve(packageRoot, \"package.json\");\n\ttry {\n\t\tconst declared = getManifestFromPackageJson(await readJson<object>(packageJsonPath))?.mcpServers;\n\t\tif (declared === undefined) return undefined;\n\t\tif (typeof declared !== \"string\") return { path: packageJsonPath, servers: declared };\n\t\tconst path = resolve(packageRoot, declared);\n\t\tconst file = await readJson<McpServersFile | null>(path);\n\t\tconst servers = sanitizeMcpServers(file?.mcpServers ?? file?.[\"mcp-servers\"]);\n\t\treturn servers ? { path, servers } : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction selectMcpServers(names: string[], filter: PackageFilter | undefined): Map<string, boolean> {\n\tconst patterns = filter?.mcpServers;\n\tif (filter?.autoload === false) return applyAutoloadDisabledNamePatterns(names, patterns ?? []);\n\tconst enabled = patterns === undefined ? new Set(names) : applyNamePatterns(names, patterns);\n\treturn new Map(names.map((name) => [name, patterns?.length !== 0 && enabled.has(name)]));\n}\n\n/** A package cannot know the user's project directory, so a relative `cwd` names a directory in the package. */\nfunction resolvePackageCwd(config: McpServerConfig, packageRoot: string): McpServerConfig {\n\tconst { cwd } = config;\n\tif (typeof cwd !== \"string\" || isAbsolute(cwd) || cwd.startsWith(\"~\") || cwd.startsWith(\"$\")) return config;\n\treturn { ...config, cwd: resolve(packageRoot, cwd) };\n}\n\n/** Add a package's manifest `mcpServers`, honoring the package filter's `mcpServers` patterns. */\nexport async function collectPackageMcpServers(\n\tpackageRoot: string,\n\ttarget: Map<string, ResolvedMcpServer>,\n\tfilter: PackageFilter | undefined,\n\tmetadata: PathMetadata,\n): Promise<void> {\n\tconst declared = await readManifestMcpServers(packageRoot);\n\tif (!declared) return;\n\tfor (const [name, enabled] of selectMcpServers(Object.keys(declared.servers), filter)) {\n\t\tconst key = `${declared.path}\\0${name}`;\n\t\tif (target.has(key)) continue;\n\t\tconst config = resolvePackageCwd(declared.servers[name], packageRoot);\n\t\ttarget.set(key, { name, config, enabled, path: declared.path, metadata });\n\t}\n}\n"]}
1
+ {"version":3,"file":"package-manager-mcp-servers.js","sourceRoot":"","sources":["../../src/core/package-manager-mcp-servers.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport { stripBom } from \"../utils/text.ts\";\nimport type { McpServerConfig } from \"./mcp-servers.ts\";\nimport { getManifestFromPackageJson, sanitizeMcpServers } from \"./package-manager-manifest.ts\";\nimport { applyAutoloadDisabledNamePatterns, applyNamePatterns } from \"./package-manager-resource-patterns.ts\";\nimport type { PackageFilter, PathMetadata, ResolvedMcpServer } from \"./package-manager-types.ts\";\n\ninterface McpServersFile {\n\tmcpServers?: object;\n\t\"mcp-servers\"?: object;\n}\n\nasync function readJson<T>(path: string): Promise<T> {\n\treturn JSON.parse(stripBom(await readFile(path, \"utf-8\"))) as T;\n}\n\nasync function readManifestMcpServers(\n\tpackageRoot: string,\n): Promise<{ path: string; servers: Record<string, McpServerConfig> } | undefined> {\n\tconst packageJsonPath = resolve(packageRoot, \"package.json\");\n\ttry {\n\t\tconst declared = getManifestFromPackageJson(await readJson<object>(packageJsonPath))?.mcpServers;\n\t\tif (declared === undefined) return undefined;\n\t\tif (typeof declared !== \"string\") return { path: packageJsonPath, servers: declared };\n\t\tconst path = resolve(packageRoot, declared);\n\t\tconst file = await readJson<McpServersFile | null>(path);\n\t\tconst servers = sanitizeMcpServers(file?.mcpServers ?? file?.[\"mcp-servers\"]);\n\t\treturn servers ? { path, servers } : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction selectMcpServers(names: string[], filter: PackageFilter | undefined): Map<string, boolean> {\n\tconst patterns = filter?.mcpServers;\n\tif (filter?.autoload === false) return applyAutoloadDisabledNamePatterns(names, patterns ?? []);\n\tconst enabled = patterns === undefined ? new Set(names) : applyNamePatterns(names, patterns);\n\treturn new Map(names.map((name) => [name, patterns?.length !== 0 && enabled.has(name)]));\n}\n\n/** A package cannot know the user's project directory, so a relative `cwd` names a directory in the package. */\nfunction resolvePackageCwd(config: McpServerConfig, packageRoot: string): McpServerConfig {\n\tconst cwd = \"cwd\" in config ? config.cwd : undefined;\n\tif (typeof cwd !== \"string\" || isAbsolute(cwd) || cwd.startsWith(\"~\") || cwd.startsWith(\"$\")) return config;\n\treturn { ...config, cwd: resolve(packageRoot, cwd) };\n}\n\n/** Add a package's manifest `mcpServers`, honoring the package filter's `mcpServers` patterns. */\nexport async function collectPackageMcpServers(\n\tpackageRoot: string,\n\ttarget: Map<string, ResolvedMcpServer>,\n\tfilter: PackageFilter | undefined,\n\tmetadata: PathMetadata,\n): Promise<void> {\n\tconst declared = await readManifestMcpServers(packageRoot);\n\tif (!declared) return;\n\tfor (const [name, enabled] of selectMcpServers(Object.keys(declared.servers), filter)) {\n\t\tconst key = `${declared.path}\\0${name}`;\n\t\tif (target.has(key)) continue;\n\t\tconst config = resolvePackageCwd(declared.servers[name], packageRoot);\n\t\ttarget.set(key, { name, config, enabled, path: declared.path, metadata });\n\t}\n}\n"]}
package/dist/core/sdk.js CHANGED
@@ -236,6 +236,15 @@ async function constructAgentSession(options, deferStart) {
236
236
  // for any user who configures it (upstream 4d9aa837 + companion fix 541045ae).
237
237
  const configuredDefaultToolNames = settingsManager.getDefaultTools();
238
238
  const allowedToolNames = options.noTools === "all" ? [] : options.tools === undefined ? undefined : [...options.tools];
239
+ const subagentPolicy = options.subagentPolicy && (options.subagentPolicy.depth ?? 0) >= 1
240
+ ? {
241
+ ...options.subagentPolicy,
242
+ tools: allowedToolNames,
243
+ mcpDirectTools: options.noTools === "all"
244
+ ? []
245
+ : (options.subagentPolicy.mcpDirectTools ?? (allowedToolNames === undefined ? undefined : [])),
246
+ }
247
+ : options.subagentPolicy;
239
248
  const initialActiveToolNames = allowedToolNames
240
249
  ? [...allowedToolNames]
241
250
  : options.noTools
@@ -515,7 +524,7 @@ async function constructAgentSession(options, deferStart) {
515
524
  extensionRunnerRef,
516
525
  sessionStartEvent: options.sessionStartEvent,
517
526
  orchestrationContext: options.orchestrationContext,
518
- subagentPolicy: options.subagentPolicy,
527
+ subagentPolicy,
519
528
  parentCommandTaskOwner: options.parentCommandTaskOwner,
520
529
  systemPromptTransform: options.systemPromptTransform,
521
530
  contextProjectionTransform: options.initialContextTransform,