@noodleseed/one 0.169.0 → 0.171.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +6 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/capabilities.d.ts +19 -0
  5. package/dist/commands/capabilities.d.ts.map +1 -0
  6. package/dist/commands/capabilities.js +128 -0
  7. package/dist/commands/capabilities.js.map +1 -0
  8. package/dist/commands/catalog.d.ts.map +1 -1
  9. package/dist/commands/catalog.js +2 -1
  10. package/dist/commands/catalog.js.map +1 -1
  11. package/dist/commands/whatsapp-ops.d.ts +13 -0
  12. package/dist/commands/whatsapp-ops.d.ts.map +1 -0
  13. package/dist/commands/whatsapp-ops.js +244 -0
  14. package/dist/commands/whatsapp-ops.js.map +1 -0
  15. package/dist/commands/whatsapp-output.d.ts +3 -0
  16. package/dist/commands/whatsapp-output.d.ts.map +1 -0
  17. package/dist/commands/whatsapp-output.js +70 -0
  18. package/dist/commands/whatsapp-output.js.map +1 -0
  19. package/dist/dev.js +2 -0
  20. package/dist/dev.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/plugin-mode/plugin-operation-contract.d.ts +3 -3
  26. package/node_modules/@noodle-borg/agent-kit/dist/curated/command-groups.js +8 -0
  27. package/node_modules/@noodle-borg/agent-kit/dist/curated/error-fixes.js +1 -0
  28. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +2 -2
  29. package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +5 -0
  30. package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +3 -2
  31. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +6 -0
  32. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  33. package/node_modules/@noodle-borg/app-audit/dist/audit-embedded-assistant.js +2 -0
  34. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-configuration.js +2 -1
  35. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interactive.d.ts +1 -0
  36. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interactive.js +4 -1
  37. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-model-context.js +9 -4
  38. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-turn-context.d.ts +16 -0
  39. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-turn-context.js +19 -0
  40. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-coordinator.d.ts +145 -0
  41. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-coordinator.js +378 -0
  42. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-inbox.js +160 -0
  43. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-provider-blocks.d.ts +18 -0
  44. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-provider-blocks.js +69 -0
  45. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-spend.js +82 -0
  46. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-store.d.ts +42 -0
  47. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-store.js +76 -0
  48. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-types.d.ts +134 -0
  49. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-types.js +72 -0
  50. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-work.d.ts +20 -0
  51. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-work.js +221 -0
  52. package/node_modules/@noodle-borg/assistant-gateway/dist/messaging-tool-dispatch.d.ts +15 -0
  53. package/node_modules/@noodle-borg/assistant-gateway/dist/messaging-tool-dispatch.js +34 -0
  54. package/node_modules/@noodle-borg/assistant-gateway/dist/model-request.d.ts +19 -1
  55. package/node_modules/@noodle-borg/assistant-gateway/dist/model-request.js +22 -6
  56. package/node_modules/@noodle-borg/assistant-gateway/dist/portable.d.ts +7 -0
  57. package/node_modules/@noodle-borg/assistant-gateway/dist/portable.js +7 -0
  58. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-assistant-appearance-store.js +83 -0
  59. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-assistant-elevation.js +151 -0
  60. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-assistant-interaction-writes.js +45 -0
  61. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-assistant-interactions.js +340 -0
  62. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-assistant.js +439 -0
  63. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-channel-store.js +102 -0
  64. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-continuity-store.js +159 -0
  65. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-elevation-store.js +110 -0
  66. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres-embed-store.js +134 -0
  67. package/node_modules/@noodle-borg/assistant-gateway/dist/postgres.js +11 -0
  68. package/node_modules/@noodle-borg/assistant-gateway/dist/public-surface.d.ts +8 -0
  69. package/node_modules/@noodle-borg/assistant-gateway/dist/public-surface.js +23 -0
  70. package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts +19 -4
  71. package/node_modules/@noodle-borg/authoring/dist/assistant.js +51 -20
  72. package/node_modules/@noodle-borg/authoring/dist/index.d.ts +2 -1
  73. package/node_modules/@noodle-borg/authoring/dist/index.js +2 -1
  74. package/node_modules/@noodle-borg/authoring/dist/load-authored.js +1 -1
  75. package/node_modules/@noodle-borg/authoring/dist/recording.d.ts +2 -1
  76. package/node_modules/@noodle-borg/authoring/dist/recording.js +29 -1
  77. package/node_modules/@noodle-borg/authoring/dist/server.d.ts +3 -0
  78. package/node_modules/@noodle-borg/authoring/dist/server.js +5 -1
  79. package/node_modules/@noodle-borg/authoring/dist/web-capabilities.d.ts +17 -0
  80. package/node_modules/@noodle-borg/authoring/dist/web-capabilities.js +15 -0
  81. package/node_modules/@noodle-borg/authoring/package.json +1 -0
  82. package/node_modules/@noodle-borg/capabilities/dist/index.js +7 -0
  83. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-channels.js +121 -0
  84. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-hosted-observability.js +102 -0
  85. package/node_modules/@noodle-borg/cli-catalog/dist/index.js +1 -0
  86. package/node_modules/@noodle-borg/compiler/dist/artifact/assemble.js +3 -0
  87. package/node_modules/@noodle-borg/compiler/dist/artifact/config.js +1 -1
  88. package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +2 -0
  89. package/node_modules/@noodle-borg/compiler/dist/artifact/version.d.ts +2 -1
  90. package/node_modules/@noodle-borg/compiler/dist/artifact/version.js +2 -1
  91. package/node_modules/@noodle-borg/compiler/dist/compile.js +2 -0
  92. package/node_modules/@noodle-borg/compiler/dist/errors.d.ts +1 -1
  93. package/node_modules/@noodle-borg/compiler/dist/fulfilment-emit.js +18 -3
  94. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +106 -12
  95. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +60 -29
  96. package/node_modules/@noodle-borg/compiler/dist/manifest/website-projection.d.ts +1 -0
  97. package/node_modules/@noodle-borg/compiler/dist/manifest/website-projection.js +19 -0
  98. package/node_modules/@noodle-borg/compiler/dist/web-capabilities.js +55 -0
  99. package/node_modules/@noodle-borg/compiler/package.json +1 -0
  100. package/node_modules/@noodle-borg/connector-http/dist/ssrf.js +5 -0
  101. package/node_modules/@noodle-borg/knowledge-crawl/dist/bounded-body.js +38 -0
  102. package/node_modules/@noodle-borg/knowledge-crawl/dist/first-party.js +2 -3
  103. package/node_modules/@noodle-borg/knowledge-crawl/dist/html-text.js +10 -2
  104. package/node_modules/@noodle-borg/knowledge-crawl/dist/index.d.ts +1 -0
  105. package/node_modules/@noodle-borg/knowledge-crawl/dist/index.js +1 -0
  106. package/node_modules/@noodle-borg/knowledge-crawl/dist/page-reader.d.ts +26 -0
  107. package/node_modules/@noodle-borg/knowledge-crawl/dist/page-reader.js +127 -0
  108. package/node_modules/@noodle-borg/knowledge-crawl/dist/robots.js +48 -23
  109. package/node_modules/@noodle-borg/knowledge-crawl/package.json +1 -0
  110. package/node_modules/@noodle-borg/managed-capabilities/dist/budget.d.ts +29 -0
  111. package/node_modules/@noodle-borg/managed-capabilities/dist/budget.js +124 -0
  112. package/node_modules/@noodle-borg/managed-capabilities/dist/contracts.d.ts +212 -0
  113. package/node_modules/@noodle-borg/managed-capabilities/dist/contracts.js +113 -0
  114. package/node_modules/@noodle-borg/managed-capabilities/dist/errors.d.ts +8 -0
  115. package/node_modules/@noodle-borg/managed-capabilities/dist/errors.js +21 -0
  116. package/node_modules/@noodle-borg/managed-capabilities/dist/executor.d.ts +26 -0
  117. package/node_modules/@noodle-borg/managed-capabilities/dist/executor.js +156 -0
  118. package/node_modules/@noodle-borg/managed-capabilities/dist/limits.d.ts +15 -0
  119. package/node_modules/@noodle-borg/managed-capabilities/dist/limits.js +15 -0
  120. package/node_modules/@noodle-borg/managed-capabilities/dist/operator-contracts.d.ts +159 -0
  121. package/node_modules/@noodle-borg/managed-capabilities/dist/operator-contracts.js +69 -0
  122. package/node_modules/@noodle-borg/managed-capabilities/dist/operator-route.d.ts +5 -0
  123. package/node_modules/@noodle-borg/managed-capabilities/dist/operator-route.js +160 -0
  124. package/node_modules/@noodle-borg/managed-capabilities/dist/policy-store.d.ts +34 -0
  125. package/node_modules/@noodle-borg/managed-capabilities/dist/policy-store.js +61 -0
  126. package/node_modules/@noodle-borg/managed-capabilities/dist/portable.d.ts +10 -0
  127. package/node_modules/@noodle-borg/managed-capabilities/dist/portable.js +10 -0
  128. package/node_modules/@noodle-borg/managed-capabilities/dist/service.d.ts +83 -0
  129. package/node_modules/@noodle-borg/managed-capabilities/dist/service.js +139 -0
  130. package/node_modules/@noodle-borg/managed-capabilities/dist/urls.d.ts +3 -0
  131. package/node_modules/@noodle-borg/managed-capabilities/dist/urls.js +30 -0
  132. package/node_modules/@noodle-borg/managed-capabilities/package.json +49 -0
  133. package/node_modules/@noodle-borg/module/dist/contract.d.ts +11 -0
  134. package/node_modules/@noodle-borg/module-audit/dist/index.js +37 -0
  135. package/node_modules/@noodle-borg/module-audit/dist/postgres-audit.js +126 -0
  136. package/node_modules/@noodle-borg/module-audit/dist/route.js +66 -0
  137. package/node_modules/@noodle-borg/runtime/dist/confirmation.js +29 -0
  138. package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts +2 -0
  139. package/node_modules/@noodle-borg/runtime/dist/execute.d.ts +3 -0
  140. package/node_modules/@noodle-borg/runtime/dist/execute.js +6 -1
  141. package/node_modules/@noodle-borg/runtime/dist/index.d.ts +2 -1
  142. package/node_modules/@noodle-borg/runtime/dist/index.js +2 -1
  143. package/node_modules/@noodle-borg/runtime/dist/interactive.js +10 -1
  144. package/node_modules/@noodle-borg/runtime/dist/managed-origins.js +8 -4
  145. package/node_modules/@noodle-borg/runtime/dist/operation-execution.js +3 -0
  146. package/node_modules/@noodle-borg/runtime/dist/postgres-state-handles.js +311 -0
  147. package/node_modules/@noodle-borg/runtime/dist/postgres.js +4 -0
  148. package/node_modules/@noodle-borg/runtime/dist/result-meta.d.ts +2 -0
  149. package/node_modules/@noodle-borg/runtime/dist/result-meta.js +6 -0
  150. package/node_modules/@noodle-borg/runtime/dist/result.d.ts +4 -0
  151. package/node_modules/@noodle-borg/runtime/dist/web-capabilities.d.ts +71 -0
  152. package/node_modules/@noodle-borg/runtime/dist/web-capabilities.js +41 -0
  153. package/node_modules/@noodle-borg/runtime/package.json +1 -0
  154. package/node_modules/@noodle-borg/service/dist/assistant-composition.js +18 -0
  155. package/node_modules/@noodle-borg/service/dist/build-info.js +5 -2
  156. package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-coordinator.js +7 -0
  157. package/node_modules/@noodle-borg/service/dist/channels/360dialog.js +233 -0
  158. package/node_modules/@noodle-borg/service/dist/channels/cipher.js +37 -0
  159. package/node_modules/@noodle-borg/service/dist/channels/composition.js +37 -0
  160. package/node_modules/@noodle-borg/service/dist/channels/inference-guard.js +53 -0
  161. package/node_modules/@noodle-borg/service/dist/channels/runtime.js +337 -0
  162. package/node_modules/@noodle-borg/service/dist/channels/worker-loop.js +50 -0
  163. package/node_modules/@noodle-borg/service/dist/local-options.d.ts +1 -0
  164. package/node_modules/@noodle-borg/service/dist/local-web-capabilities.js +13 -0
  165. package/node_modules/@noodle-borg/service/dist/mcp-protocol-runtime.js +21 -0
  166. package/node_modules/@noodle-borg/service/dist/modules/route-dispatch.js +13 -0
  167. package/node_modules/@noodle-borg/service/dist/registry-compile.js +3 -0
  168. package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +1 -0
  169. package/node_modules/@noodle-borg/service/dist/registry.js +3 -0
  170. package/node_modules/@noodle-borg/service/dist/routes/assistant-agent.js +66 -35
  171. package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js +7 -4
  172. package/node_modules/@noodle-borg/service/dist/routes/assistant-model-binding.js +6 -2
  173. package/node_modules/@noodle-borg/service/dist/routes/business-information-channels.js +14 -1
  174. package/node_modules/@noodle-borg/service/dist/routes/whatsapp.js +238 -0
  175. package/node_modules/@noodle-borg/service/dist/serve-local.js +14 -0
  176. package/node_modules/@noodle-borg/service/dist/serve-resource-auth.js +10 -0
  177. package/node_modules/@noodle-borg/service/dist/service.js +37 -33
  178. package/node_modules/@noodle-borg/service/dist/web-capabilities.js +39 -0
  179. package/node_modules/@noodle-borg/service/package.json +3 -1
  180. package/node_modules/@noodle-borg/wire-contracts/dist/application-channels.d.ts +33 -0
  181. package/node_modules/@noodle-borg/wire-contracts/dist/application-channels.js +9 -0
  182. package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +2 -0
  183. package/node_modules/@noodle-borg/wire-contracts/dist/index.js +2 -0
  184. package/node_modules/@noodle-borg/wire-contracts/dist/service-info.d.ts +2 -0
  185. package/node_modules/@noodle-borg/wire-contracts/dist/service-info.js +10 -2
  186. package/node_modules/@noodle-borg/wire-contracts/dist/whatsapp.d.ts +426 -0
  187. package/node_modules/@noodle-borg/wire-contracts/dist/whatsapp.js +213 -0
  188. package/node_modules/@noodle-borg/wire-contracts/package.json +1 -0
  189. package/package.json +3 -2
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- export { authenticatedWebsite, embeddedAssistant, noodleManaged, openAICompatible, publicWebsite, } from './assistant.js';
2
+ export { authenticatedWebsite, embeddedAssistant, noodleManaged, openAICompatible, publicMessaging, publicWebsite, } from './assistant.js';
3
3
  export { secret, variable, } from './config.js';
4
4
  export { bind, clientCredentials, connection, externalExchange, googleWorkloadIdentity, managedSecret, } from './connections.js';
5
5
  export { ConnectorBuilder, connector, } from './connectors.js';
@@ -12,5 +12,6 @@ export { managedCollection, } from './managed-collection.js';
12
12
  export { noodlePlatform, noodlePlatformCatalog } from './platform.js';
13
13
  export { when, } from './recording.js';
14
14
  export { annotations, asset, isServerDefinition, prompt, resource, server, tool, widgetResult, } from './server.js';
15
+ export { webExtract, } from './web-capabilities.js';
15
16
  export { z };
16
17
  //# sourceMappingURL=index.js.map
@@ -33,7 +33,7 @@ export function prepareAuthoringRuntimeDir(dir, options) {
33
33
  './react': './react.mjs',
34
34
  },
35
35
  }));
36
- writeFileSync(join(self, 'index.mjs'), "export { algolia, annotations, asset, authenticatedWebsite, bind, clientCredentials, connector, connection, customerAuth, customerEndpoint, embeddedAssistant, externalExchange, file, firecrawl, gmailConnector, googleWorkloadIdentity, handoffSession, knowledge, managedCollection, managedSecret, meilisearch, noodleManaged, noodlePlatform, openAICompatible, prompt, publicWebsite, resource, secret, server, site, tavily, tool, variable, when, z } from '@noodle-borg/authoring';\n");
36
+ writeFileSync(join(self, 'index.mjs'), "export { algolia, annotations, asset, authenticatedWebsite, bind, clientCredentials, connector, connection, customerAuth, customerEndpoint, embeddedAssistant, externalExchange, file, firecrawl, gmailConnector, googleWorkloadIdentity, handoffSession, knowledge, managedCollection, managedSecret, meilisearch, noodleManaged, noodlePlatform, openAICompatible, prompt, publicMessaging, publicWebsite, resource, secret, server, site, tavily, tool, variable, webExtract, when, z } from '@noodle-borg/authoring';\n");
37
37
  writeFileSync(join(self, 'platform.mjs'), "export { noodlePlatform, noodlePlatformCatalog } from '@noodle-borg/authoring';\n");
38
38
  writeFileSync(join(self, 'react.mjs'), "export * from '@noodle-borg/authoring/react';\n");
39
39
  }
@@ -1,6 +1,7 @@
1
1
  import type { ConnectorRef } from './connectors.js';
2
2
  import type { AmbientContextOptions } from './context.js';
3
3
  import type { ResourceContext, ToolOptions } from './server.js';
4
+ import type { WebExtractDeclaration } from './web-capabilities.js';
4
5
  export type SymbolicScope = Ref & Record<string, Ref>;
5
6
  export type ConnectorClient = Record<string, (args?: Readonly<Record<string, unknown>>) => SymbolicScope>;
6
7
  type RecordedStep = {
@@ -17,7 +18,7 @@ type RecordedStep = {
17
18
  readonly if?: string;
18
19
  };
19
20
  export declare function when<T>(condition: Cond, record: () => T): T;
20
- export declare function recordTool(fulfil: ToolOptions['fulfil'], connectors: Readonly<Record<string, ConnectorRef>>): Promise<{
21
+ export declare function recordTool(fulfil: ToolOptions['fulfil'], connectors: Readonly<Record<string, ConnectorRef>>, capabilities?: readonly WebExtractDeclaration[]): Promise<{
21
22
  steps: RecordedStep[];
22
23
  output: Record<string, unknown>;
23
24
  }>;
@@ -17,7 +17,7 @@ export function when(condition, record) {
17
17
  activeRecording.pendingCondition = previous;
18
18
  }
19
19
  }
20
- export async function recordTool(fulfil, connectors) {
20
+ export async function recordTool(fulfil, connectors, capabilities = []) {
21
21
  const ctx = newRecordingContext();
22
22
  activeRecording = ctx;
23
23
  try {
@@ -26,6 +26,7 @@ export async function recordTool(fulfil, connectors) {
26
26
  user: makeScope('user'),
27
27
  context: makeScope('context'),
28
28
  connectors: makeConnectors(connectors, ctx),
29
+ capabilities: makeCapabilities(capabilities, ctx),
29
30
  elicit: makeElicitor(ctx),
30
31
  });
31
32
  return { steps: ctx.steps, output: serializeMap(result) };
@@ -91,6 +92,33 @@ export async function recordAmbientContext(fulfil, connectors) {
91
92
  function newRecordingContext() {
92
93
  return { steps: [], counts: new Map(), stepIds: new Set() };
93
94
  }
95
+ function makeCapabilities(declarations, ctx) {
96
+ const names = new Set(declarations.map((value) => value.name));
97
+ return new Proxy({}, {
98
+ get(_target, name) {
99
+ if (typeof name !== 'string')
100
+ return undefined;
101
+ if (!names.has(name))
102
+ throw new Error(`unknown capability "${name}"`);
103
+ return new Proxy({}, {
104
+ get(_client, method) {
105
+ if (method !== 'extract')
106
+ throw new Error(`unknown capability method "${String(method)}"`);
107
+ return (request) => {
108
+ const id = nextStepId(ctx, 'extract');
109
+ ctx.steps.push({
110
+ id,
111
+ use: 'noodle_web.extract',
112
+ args: serializeConnectorArgs({ name, request }),
113
+ ...(ctx.pendingCondition ? { if: ctx.pendingCondition } : {}),
114
+ });
115
+ return makeScope(`steps.${id}`);
116
+ };
117
+ },
118
+ });
119
+ },
120
+ });
121
+ }
94
122
  function makeElicitor(ctx) {
95
123
  return ((options) => {
96
124
  if (!isValidName(options.id)) {
@@ -12,6 +12,7 @@ import { type JsonSchema } from './json-schema.js';
12
12
  import { type KnowledgeDeclaration } from './knowledge.js';
13
13
  import * as collections from './managed-collection.js';
14
14
  import { type ConnectorClient, type SymbolicScope } from './recording.js';
15
+ import { type WebExtractDeclaration } from './web-capabilities.js';
15
16
  export type StateHandleKind = 'session' | 'draft' | 'selection' | 'search' | 'cart' | 'workflow';
16
17
  export type StateHandleScope = 'deployment' | 'caller';
17
18
  export interface StateHandleOptions {
@@ -53,6 +54,7 @@ export interface ServerOptions {
53
54
  readonly assistant?: EmbeddedAssistantConfig;
54
55
  /** Customer-owned knowledge components (ADR 0202): compile to generated `search_<name>` capabilities. */
55
56
  readonly knowledge?: readonly KnowledgeDeclaration[];
57
+ readonly capabilities?: readonly WebExtractDeclaration[];
56
58
  /** Typed managed records; operator-owned lifecycle and policy are bound outside reusable source. */
57
59
  readonly collections?: readonly collections.ManagedCollectionDeclaration[];
58
60
  readonly branding?: {
@@ -180,6 +182,7 @@ export interface ToolContext {
180
182
  readonly user: SymbolicScope;
181
183
  readonly context: SymbolicScope;
182
184
  readonly connectors: Record<string, ConnectorClient>;
185
+ readonly capabilities: Record<string, ConnectorClient>;
183
186
  /** Request one bounded, non-sensitive form input and continue with its symbolic response. */
184
187
  readonly elicit: (options: ElicitationOptions) => SymbolicScope;
185
188
  }
@@ -14,6 +14,7 @@ import { manifestKnowledge } from './knowledge.js';
14
14
  import * as collections from './managed-collection.js';
15
15
  import { manifestToolAnnotations } from './model-tool-visibility.js';
16
16
  import { recordFulfilment, recordTool, } from './recording.js';
17
+ import { manifestWebCapability } from './web-capabilities.js';
17
18
  const WIDGET_RESULT_META_KEY = '__noodleResultMeta';
18
19
  export function server(name, options, definitions = []) {
19
20
  const { use = {}, provides = {} } = options;
@@ -127,7 +128,7 @@ class ServerBuilder {
127
128
  : await manifestContext(this.options.context, this.connectors);
128
129
  const tools = [];
129
130
  for (const tool of this.tools) {
130
- const recorded = await recordTool(tool.options.fulfil, this.connectors);
131
+ const recorded = await recordTool(tool.options.fulfil, this.connectors, this.options.capabilities);
131
132
  const { discovery, requiredScopes, allowedRoles, ...authorization } = tool.options.authorization ?? {};
132
133
  tools.push({
133
134
  name: tool.name,
@@ -209,6 +210,9 @@ class ServerBuilder {
209
210
  ...(this.options.knowledge && this.options.knowledge.length > 0
210
211
  ? { knowledge: this.options.knowledge.map(manifestKnowledge) }
211
212
  : {}),
213
+ ...(this.options.capabilities?.length
214
+ ? { capabilities: this.options.capabilities.map(manifestWebCapability) }
215
+ : {}),
212
216
  ...collections.manifestCollections(this.options.collections, this.connectors),
213
217
  ...manifestVariables(this.options.variables),
214
218
  ...(this.options.branding ? { branding: this.options.branding } : {}),
@@ -0,0 +1,17 @@
1
+ import { type WebCapability, type WebPolicy } from '@noodle-borg/managed-capabilities';
2
+ import type { NoodleManagedModel } from './assistant.js';
3
+ import type { ToolAuthorizationOptions } from './server.js';
4
+ export interface WebExtractOptions {
5
+ readonly title: string;
6
+ readonly description: string;
7
+ readonly provider: NoodleManagedModel;
8
+ readonly policy?: WebPolicy;
9
+ readonly authorization?: ToolAuthorizationOptions;
10
+ }
11
+ export type WebExtractDeclaration = WebCapability & {
12
+ readonly kind: 'web-extract';
13
+ };
14
+ /** Read explicit public pages through the platform's governed extraction capability. */
15
+ export declare function webExtract(name: string, options: WebExtractOptions): WebExtractDeclaration;
16
+ export declare function manifestWebCapability(value: WebExtractDeclaration): WebCapability;
17
+ //# sourceMappingURL=web-capabilities.d.ts.map
@@ -0,0 +1,15 @@
1
+ import { webCapabilityBaseSchema, } from '@noodle-borg/managed-capabilities';
2
+ /** Read explicit public pages through the platform's governed extraction capability. */
3
+ export function webExtract(name, options) {
4
+ const { authorization, ...base } = options;
5
+ return {
6
+ kind: 'web-extract',
7
+ ...webCapabilityBaseSchema.parse({ name, class: 'web.extract.v1', ...base }),
8
+ ...(authorization === undefined ? {} : { authorization: structuredClone(authorization) }),
9
+ };
10
+ }
11
+ export function manifestWebCapability(value) {
12
+ const { kind: _kind, ...declaration } = value;
13
+ return structuredClone(declaration);
14
+ }
15
+ //# sourceMappingURL=web-capabilities.js.map
@@ -30,6 +30,7 @@
30
30
  "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.type-tests.json --noEmit"
31
31
  },
32
32
  "dependencies": {
33
+ "@noodle-borg/managed-capabilities": "0.0.0",
33
34
  "typescript": "^6.0.3",
34
35
  "@noodle-borg/compiler": "0.0.0",
35
36
  "@noodle-borg/connector-defs": "0.0.0",
@@ -10,6 +10,13 @@ export const CAPABILITY_NAMES = [
10
10
  ];
11
11
  /** Single public compatibility registry used by CLI output, docs, and release notes. */
12
12
  export const PRODUCT_FEATURES = [
13
+ {
14
+ id: 'bounded-public-page-extraction',
15
+ title: 'Bounded public-page extraction',
16
+ since: 'next',
17
+ description: 'Managed-only learning cohort: explicit public HTTPS pages through ordinary tools, with revisioned operator policy, shared budgets and evidence references. General search and BYO are not included.',
18
+ hosts: { claude: 'preview', chatgpt: 'preview', embedded: 'preview' },
19
+ },
13
20
  {
14
21
  id: 'mcp-core',
15
22
  title: 'MCP tools, resources, and prompts',
@@ -0,0 +1,121 @@
1
+ const flag = (name, summary, type = 'string') => ({
2
+ name,
3
+ summary,
4
+ type,
5
+ ...(type === 'boolean' ? {} : { value: '<value>' }),
6
+ required: false,
7
+ repeatable: false,
8
+ sensitive: name === 'auth-token',
9
+ aliases: [],
10
+ conflictsWith: [],
11
+ });
12
+ const scope = [
13
+ flag('org', 'Organization.'),
14
+ flag('app', 'Application.'),
15
+ flag('env', 'Environment.'),
16
+ flag('service', 'Service URL.'),
17
+ flag('auth-token', 'Control-plane token.'),
18
+ flag('json', 'Machine-readable output.', 'boolean'),
19
+ ];
20
+ const mutation = [flag('idempotency-key', 'Stable key for retrying this logical change.')];
21
+ const revision = flag('expected-revision', 'Current revision from status; zero when creating.', 'number');
22
+ const blockScope = flag('scope', 'local (default) or explicit provider block.');
23
+ const participant = flag('participant-id', 'Protected participant identifier from events list.');
24
+ const limits = [
25
+ 'per-minute',
26
+ 'per-hour',
27
+ 'per-day',
28
+ 'channel-per-day',
29
+ 'new-participants-per-day',
30
+ 'concurrent',
31
+ 'pending-per-participant',
32
+ 'pending',
33
+ 'text-characters',
34
+ 'daily-micro-usd',
35
+ ].map((name) => flag(name, `Lower the ${name} ceiling; zero disables this allowance.`, 'number'));
36
+ const leaf = (name, summary, flags = []) => ({
37
+ name,
38
+ summary,
39
+ flags: [...scope, ...flags],
40
+ arguments: [],
41
+ jsonOutput: { mode: 'single' },
42
+ });
43
+ const group = (name, summary, subcommands) => ({ name, summary, subcommands, flags: [], arguments: [] });
44
+ export const CHANNELS_COMMAND = {
45
+ name: 'channels',
46
+ section: 'operate',
47
+ summary: 'Connect and operate the same application on messaging channels.',
48
+ arguments: [],
49
+ flags: [],
50
+ subcommands: [
51
+ group('whatsapp', 'Configure the 360dialog channel, test readiness, and control public messaging.', [
52
+ leaf('status', 'Show configuration and current revision.'),
53
+ leaf('configure', 'Save a paused binding using managed secret references.', [
54
+ revision,
55
+ ...mutation,
56
+ flag('phone-number-id', '360dialog/Meta phone-number asset ID.'),
57
+ flag('api-key-secret', 'Managed secret name for the 360dialog key.'),
58
+ flag('webhook-secret', 'Independent managed callback secret name.'),
59
+ flag('capabilities', 'Comma-separated knowledge:name or tool:name selections.'),
60
+ flag('support-email', 'Contact shown when an answer cannot be completed.'),
61
+ ...limits,
62
+ ]),
63
+ leaf('doctor', 'Check deployment, storage, worker, model cost bound, and provider setup.', mutation),
64
+ leaf('enable', 'Enable after a successful current readiness check.', [
65
+ revision,
66
+ ...mutation,
67
+ ]),
68
+ leaf('pause', 'Stop new work and unsent replies.', [revision, ...mutation]),
69
+ leaf('disconnect', 'Fence this binding and retain governed receipts.', [
70
+ revision,
71
+ ...mutation,
72
+ ]),
73
+ group('webhook', 'Inspect or configure the owned provider callback.', [
74
+ leaf('inspect', 'Check URL and authentication without disclosing headers.'),
75
+ leaf('configure', 'Register the service-owned callback.', [revision, ...mutation]),
76
+ ]),
77
+ group('limits', 'Inspect or lower the approved limits.', [
78
+ leaf('get', 'Show limits.'),
79
+ leaf('set', 'Lower selected limits.', [revision, ...mutation, ...limits]),
80
+ ]),
81
+ leaf('usage', 'Show UTC-day settled and reserved inference spend.'),
82
+ group('blocks', 'Inspect local blocks.', [
83
+ leaf('list', 'List local and provider block evidence.', [
84
+ flag('after', 'Cursor from the previous page.'),
85
+ ]),
86
+ ]),
87
+ leaf('block', 'Block locally; optionally request a provider block.', [
88
+ participant,
89
+ blockScope,
90
+ flag('phone-stdin', 'Read a phone number securely from standard input.', 'boolean'),
91
+ flag('until', 'Expiry as an ISO timestamp.'),
92
+ flag('indefinite', 'Explicitly retain this block until removed.', 'boolean'),
93
+ ...mutation,
94
+ ]),
95
+ leaf('unblock', 'Remove an explicitly selected block without resetting usage.', [
96
+ participant,
97
+ blockScope,
98
+ flag('phone-stdin', 'Supply the number if retained participant context has expired.', 'boolean'),
99
+ ...mutation,
100
+ ]),
101
+ group('cooldown', 'Inspect or clear an automatic cooldown.', [
102
+ leaf('inspect', 'Show a participant cooldown.', [participant]),
103
+ leaf('clear', 'Clear cooldown without resetting quotas.', [participant, ...mutation]),
104
+ ]),
105
+ group('events', 'Inspect content-free transport receipts.', [
106
+ leaf('list', 'List a page of events.', [
107
+ flag('after', 'Cursor returned by the previous page.'),
108
+ ]),
109
+ leaf('inspect', 'Inspect one event.', [flag('event-id', 'Event identifier.')]),
110
+ leaf('reconcile', 'Read current receipt evidence without resending.', [
111
+ flag('event-id', 'Event identifier.'),
112
+ ...mutation,
113
+ ]),
114
+ ]),
115
+ group('conversation', 'Erase conversation content.', [
116
+ leaf('forget', 'Erase participant context and message content while preserving safeguards.', [participant, ...mutation]),
117
+ ]),
118
+ ]),
119
+ ],
120
+ };
121
+ //# sourceMappingURL=catalog-data-channels.js.map
@@ -67,6 +67,108 @@ const TENANT_TARGET_FLAGS = [
67
67
  JSON_FLAG,
68
68
  ];
69
69
  export const CATALOG_HOSTED_OBSERVABILITY = [
70
+ {
71
+ name: 'capabilities',
72
+ section: 'operate',
73
+ helpRank: 16,
74
+ summary: 'Inspect, configure and test bounded managed capabilities for an exact app/environment.',
75
+ arguments: [],
76
+ flags: [],
77
+ subcommands: [
78
+ {
79
+ ...SUBCOMMAND_FIELDS,
80
+ name: 'inspect',
81
+ summary: 'List capabilities or inspect one with effective policy.',
82
+ arguments: [
83
+ {
84
+ ...ARGUMENT_FIELDS,
85
+ name: 'name',
86
+ type: 'string',
87
+ summary: 'Capability name.',
88
+ required: false,
89
+ },
90
+ ],
91
+ flags: TENANT_TARGET_FLAGS,
92
+ jsonOutput: { mode: 'single' },
93
+ },
94
+ {
95
+ ...SUBCOMMAND_FIELDS,
96
+ name: 'configure',
97
+ summary: 'Replace policy with a revision and retry-safe mutation ID.',
98
+ arguments: [
99
+ {
100
+ ...ARGUMENT_FIELDS,
101
+ name: 'name',
102
+ type: 'string',
103
+ summary: 'Capability name.',
104
+ required: true,
105
+ },
106
+ ],
107
+ flags: [
108
+ ...TENANT_TARGET_FLAGS,
109
+ {
110
+ ...FLAG_FIELDS,
111
+ name: 'policy-file',
112
+ type: 'string',
113
+ value: '<path>',
114
+ required: true,
115
+ summary: 'Bounded JSON policy file.',
116
+ },
117
+ {
118
+ ...FLAG_FIELDS,
119
+ name: 'expected-revision',
120
+ type: 'string',
121
+ value: '<revision>',
122
+ required: true,
123
+ summary: 'Current policy revision; zero creates it.',
124
+ },
125
+ {
126
+ ...FLAG_FIELDS,
127
+ name: 'mutation-id',
128
+ type: 'string',
129
+ value: '<id>',
130
+ required: true,
131
+ summary: 'Stable ID reused for identical retries.',
132
+ },
133
+ ],
134
+ jsonOutput: { mode: 'single' },
135
+ },
136
+ {
137
+ ...SUBCOMMAND_FIELDS,
138
+ name: 'test',
139
+ summary: 'Run a governed diagnostic without returning page bodies.',
140
+ arguments: [
141
+ {
142
+ ...ARGUMENT_FIELDS,
143
+ name: 'name',
144
+ type: 'string',
145
+ summary: 'Capability name.',
146
+ required: true,
147
+ },
148
+ ],
149
+ flags: [
150
+ ...TENANT_TARGET_FLAGS,
151
+ {
152
+ ...FLAG_FIELDS,
153
+ name: 'request-file',
154
+ type: 'string',
155
+ value: '<path>',
156
+ required: true,
157
+ summary: 'JSON request containing explicit public URLs.',
158
+ },
159
+ {
160
+ ...FLAG_FIELDS,
161
+ name: 'mode',
162
+ type: 'string',
163
+ value: '<fixture|live>',
164
+ required: true,
165
+ summary: 'Fixture performs no website I/O; live fetches the specified pages.',
166
+ },
167
+ ],
168
+ jsonOutput: { mode: 'single' },
169
+ },
170
+ ],
171
+ },
70
172
  {
71
173
  name: 'knowledge',
72
174
  section: 'operate',
@@ -4,6 +4,7 @@ export * from './catalog-data-auth-discovery.js';
4
4
  export * from './catalog-data-billing.js';
5
5
  export * from './catalog-data-bootstrap-authoring.js';
6
6
  export * from './catalog-data-bootstrap-pre-auth.js';
7
+ export * from './catalog-data-channels.js';
7
8
  export * from './catalog-data-config.js';
8
9
  export * from './catalog-data-core.js';
9
10
  export * from './catalog-data-distributions.js';
@@ -40,6 +40,9 @@ export function assembleRuntimeArtifact({ manifest, options, runtimeBranding, ru
40
40
  : {}),
41
41
  ...(manifest.server.auth !== undefined ? { auth: manifest.server.auth } : {}),
42
42
  ...(knowledge !== undefined && knowledge.length > 0 ? { knowledge } : {}),
43
+ ...(manifest.manifestVersion === '2' && manifest.server.capabilities?.length
44
+ ? { capabilities: manifest.server.capabilities }
45
+ : {}),
43
46
  ...(variables !== undefined && variables.length > 0 ? { variables } : {}),
44
47
  ...(managedCollections !== undefined && managedCollections.length > 0
45
48
  ? { managedCollections }
@@ -20,7 +20,7 @@ function collectVariablesFromManagedOrigins(manifest, out) {
20
20
  const assistant = manifest.server.assistant;
21
21
  const values = [
22
22
  ...(assistant?.allowedOrigins ?? []),
23
- ...(assistant?.surfaces?.flatMap((surface) => surface.origins) ?? []),
23
+ ...(assistant?.surfaces?.flatMap((surface) => surface.kind === 'messaging' ? [] : surface.origins) ?? []),
24
24
  ...(manifest.handoff?.allowedDomains ?? []),
25
25
  ];
26
26
  for (const value of values) {
@@ -1,5 +1,6 @@
1
1
  import type { CapabilityRequirementName } from '@noodle-borg/capabilities';
2
2
  import type { CompiledKnowledgeComponent } from '@noodle-borg/knowledge/portable';
3
+ import type { WebCapability } from '@noodle-borg/managed-capabilities';
3
4
  import type { ArtifactVariableDeclaration } from '../business-variables.js';
4
5
  import type { CustomerEndpointPolicy } from '../customer-endpoint.js';
5
6
  import type { ManagedCollectionControls } from '../managed-collection-controls.js';
@@ -251,6 +252,7 @@ export interface ArtifactServer {
251
252
  readonly auth?: ArtifactAuth;
252
253
  /** Compiled knowledge components (ADR 0202, Core v2): descriptors + generated tool metadata, never bytes. */
253
254
  readonly knowledge?: readonly CompiledKnowledgeComponent[];
255
+ readonly capabilities?: readonly WebCapability[];
254
256
  /** Compiled managed-record schema intent; lifecycle and operator state remain outside artifacts. */
255
257
  readonly managedCollections?: readonly ArtifactManagedCollection[];
256
258
  /** Typed reusable managed-variable declarations, never live operator values. */
@@ -63,7 +63,8 @@
63
63
  * including independently validated credential bindings for sandboxed compute dependencies.
64
64
  */
65
65
  /** `0.21.0`: protected tools may opt into public descriptor discovery without execution permission. */
66
- export declare const ARTIFACT_SCHEMA_VERSION = "0.21.0";
66
+ /** `0.22.0`: governed public-page extraction declarations and ordinary generated tools. */
67
+ export declare const ARTIFACT_SCHEMA_VERSION = "0.22.0";
67
68
  /** mimeType for an MCP Apps UI resource (SEP-1865). Widgets are served under this profile. */
68
69
  export declare const MCP_APP_MIME_TYPE = "text/html;profile=mcp-app";
69
70
  //# sourceMappingURL=version.d.ts.map
@@ -63,7 +63,8 @@
63
63
  * including independently validated credential bindings for sandboxed compute dependencies.
64
64
  */
65
65
  /** `0.21.0`: protected tools may opt into public descriptor discovery without execution permission. */
66
- export const ARTIFACT_SCHEMA_VERSION = '0.21.0';
66
+ /** `0.22.0`: governed public-page extraction declarations and ordinary generated tools. */
67
+ export const ARTIFACT_SCHEMA_VERSION = '0.22.0';
67
68
  /** mimeType for an MCP Apps UI resource (SEP-1865). Widgets are served under this profile. */
68
69
  export const MCP_APP_MIME_TYPE = 'text/html;profile=mcp-app';
69
70
  //# sourceMappingURL=version.js.map
@@ -21,6 +21,7 @@ import { resolveSchemaUses } from './manifest/schema-refs.js';
21
21
  import { validateWebsiteProjection } from './manifest/website-projection.js';
22
22
  import { compileState } from './state-handles.js';
23
23
  import { suggestionFields } from './suggest.js';
24
+ import { expandWebCapabilities } from './web-capabilities.js';
24
25
  import { openAiWidgetCsp, withAssetResourceDomain } from './widget-compile-helpers.js';
25
26
  import { resourceUiMeta, widgetHtml, widgetUri } from './widget-emit.js';
26
27
  import { widgetHtmlSizeErrors } from './widget-size-validation.js';
@@ -145,6 +146,7 @@ export function compileManifest(raw, options = {}) {
145
146
  // 2. Structural passes (catalog-independent): duplicate names, `$use` resolution, external refs,
146
147
  // fulfilment parsing. `$use` is resolved first so external-ref detection also scans bundled defs.
147
148
  const errors = widgetHtmlSizeErrors(manifest, runtimeBranding);
149
+ expandWebCapabilities(manifest, errors);
148
150
  const variables = compileVariableDeclarations(manifest.manifestVersion === '2' ? (manifest.server.variables ?? []) : [], manifest.tools.map((tool) => tool.name), errors);
149
151
  const managedCollections = compileManagedCollections(manifest.manifestVersion === '2' ? (manifest.server.collections ?? []) : [], manifest.tools.map((tool) => tool.name), errors, {
150
152
  ...(options.catalog === undefined ? {} : { catalog: options.catalog }),
@@ -1,7 +1,7 @@
1
1
  import type { AppPackageArtifactV1 } from '@noodle-borg/app-package';
2
2
  import type { RuntimeArtifact } from './artifact/types.js';
3
3
  import type { PackagedAsset } from './assets.js';
4
- export type CompileErrorCode = 'invalid_context_provider' | 'yaml_parse_error' | 'invalid_shape' | 'invalid_name' | 'duplicate_name' | 'reserved_name' | 'unsupported_manifest_version' | 'reserved_for_future_version' | 'invalid_operation_ref' | 'external_ref' | 'invalid_schema_ref' | 'unknown_schema_ref' | 'schema_ref_conflict' | 'invalid_expression' | 'expr_unknown_root' | 'expr_root_unavailable' | 'expr_operator_not_allowed' | 'expr_if_not_boolean' | 'unknown_step_ref' | 'forward_step_ref' | 'self_step_ref' | 'duplicate_step_id' | 'invalid_fulfilment' | 'invalid_elicitation_schema' | 'invalid_elicitation_flow' | 'invalid_confirmation_flow' | 'arg_type_mismatch' | 'ambient_context_action' | 'duplicate_resource' | 'duplicate_prompt' | 'duplicate_resource_uri' | 'unsupported_uri_template' | 'duplicate_widget' | 'unknown_widget_tool' | 'unknown_widget_action_tool' | 'duplicate_widget_tool' | 'invalid_widget_binding' | 'invalid_widget_state_handle' | 'widget_html_too_large' | 'widget_html_total_too_large' | 'invalid_asset' | 'invalid_capability_requirement' | 'state_secret_field' | 'invalid_knowledge' | 'knowledge_unhashed' | 'invalid_managed_collection' | 'invalid_variable_declaration' | 'invalid_managed_collection_source' | 'unknown_connector_alias' | 'connector_not_in_catalog' | 'unknown_operation' | 'connector_binding_required' | 'ambiguous_nested_connector_binding' | 'invalid_connector_call_graph' | 'unsupported_credential_profile' | 'credential_scope_mismatch' | 'credential_audience_mismatch' | 'customer_endpoint_auth_required' | 'customer_endpoint_mapping_required' | 'customer_endpoint_unknown_mapping' | 'customer_endpoint_bridge_unsupported' | 'assistant_capability_unknown' | 'assistant_public_user_reference' | 'assistant_public_effect_unconfirmed' | 'customer_endpoint_action_unsupported' | 'customer_endpoint_surface_unsupported' | 'customer_endpoint_credential_source_unsupported' | 'customer_endpoint_policy_conflict' | 'customer_endpoint_routing_inconsistent' | 'unused_connector_alias' | 'arg_mismatch' | 'agent_guide_invalid' | 'agent_guide_duplicate_workflow' | 'agent_guide_duplicate_example' | 'agent_guide_example_workflow_missing' | 'agent_guide_capability_missing' | 'agent_guide_capability_kind' | 'app_package_sensitive_content';
4
+ export type CompileErrorCode = 'invalid_context_provider' | 'yaml_parse_error' | 'invalid_shape' | 'invalid_name' | 'duplicate_name' | 'reserved_name' | 'unsupported_manifest_version' | 'reserved_for_future_version' | 'invalid_operation_ref' | 'external_ref' | 'invalid_schema_ref' | 'unknown_schema_ref' | 'schema_ref_conflict' | 'invalid_expression' | 'expr_unknown_root' | 'expr_root_unavailable' | 'expr_operator_not_allowed' | 'expr_if_not_boolean' | 'unknown_step_ref' | 'forward_step_ref' | 'self_step_ref' | 'duplicate_step_id' | 'invalid_fulfilment' | 'invalid_elicitation_schema' | 'invalid_elicitation_flow' | 'invalid_confirmation_flow' | 'arg_type_mismatch' | 'ambient_context_action' | 'duplicate_resource' | 'duplicate_prompt' | 'duplicate_resource_uri' | 'unsupported_uri_template' | 'duplicate_widget' | 'unknown_widget_tool' | 'unknown_widget_action_tool' | 'duplicate_widget_tool' | 'invalid_widget_binding' | 'invalid_widget_state_handle' | 'widget_html_too_large' | 'widget_html_total_too_large' | 'invalid_asset' | 'invalid_capability_requirement' | 'state_secret_field' | 'invalid_knowledge' | 'knowledge_unhashed' | 'invalid_managed_collection' | 'invalid_variable_declaration' | 'invalid_managed_collection_source' | 'unknown_connector_alias' | 'connector_not_in_catalog' | 'unknown_operation' | 'connector_binding_required' | 'ambiguous_nested_connector_binding' | 'invalid_connector_call_graph' | 'unsupported_credential_profile' | 'credential_scope_mismatch' | 'credential_audience_mismatch' | 'customer_endpoint_auth_required' | 'customer_endpoint_mapping_required' | 'customer_endpoint_unknown_mapping' | 'customer_endpoint_bridge_unsupported' | 'assistant_messaging_unsupported' | 'assistant_capability_unknown' | 'assistant_public_user_reference' | 'assistant_public_effect_unconfirmed' | 'customer_endpoint_action_unsupported' | 'customer_endpoint_surface_unsupported' | 'customer_endpoint_credential_source_unsupported' | 'customer_endpoint_policy_conflict' | 'customer_endpoint_routing_inconsistent' | 'unused_connector_alias' | 'arg_mismatch' | 'agent_guide_invalid' | 'agent_guide_duplicate_workflow' | 'agent_guide_duplicate_example' | 'agent_guide_example_workflow_missing' | 'agent_guide_capability_missing' | 'agent_guide_capability_kind' | 'app_package_sensitive_content';
5
5
  export interface CompileError {
6
6
  readonly code: CompileErrorCode;
7
7
  /** Dotted path to the offending location (e.g. `tools.1.name`); empty string for the document root. */
@@ -1,4 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
+ import { WEB_CATALOG_CONNECTOR, WEB_CONNECTOR_ID, WEB_CONNECTOR_VERSION, } from '@noodle-borg/managed-capabilities';
2
3
  import { computeSignatureHash } from './catalog/signature.js';
3
4
  import { resolveNestedOperations } from './nested-operations.js';
4
5
  import { docAnchorFor, suggestionFields } from './suggest.js';
@@ -38,7 +39,8 @@ function resolveOp(op, catalog, declared, usedAliases, errors, options, traversa
38
39
  operation: op.operation,
39
40
  resolved: false,
40
41
  };
41
- if (!catalog)
42
+ const isWeb = declared[op.connectorAlias]?.id === WEB_CONNECTOR_ID;
43
+ if (!catalog && !isWeb)
42
44
  return unresolved;
43
45
  usedAliases.add(op.connectorAlias);
44
46
  const connectorRef = declared[op.connectorAlias];
@@ -52,7 +54,20 @@ function resolveOp(op, catalog, declared, usedAliases, errors, options, traversa
52
54
  });
53
55
  return unresolved;
54
56
  }
55
- const connector = catalog.get(connectorRef.id, connectorRef.version);
57
+ const effectiveCatalog = {
58
+ get: (id, version) => id === WEB_CONNECTOR_ID && version === WEB_CONNECTOR_VERSION
59
+ ? WEB_CATALOG_CONNECTOR
60
+ : catalog?.get(id, version),
61
+ };
62
+ const connector = effectiveCatalog.get(connectorRef.id, connectorRef.version);
63
+ if (isWeb && (options.surface !== 'tool' || options.readOnly === true)) {
64
+ errors.push({
65
+ code: 'invalid_fulfilment',
66
+ path: `${op.path}.use`,
67
+ message: 'web extraction is available only in ordinary tools, never ambient context, resources or prompts',
68
+ });
69
+ return unresolved;
70
+ }
56
71
  if (!connector) {
57
72
  errors.push({
58
73
  code: 'connector_not_in_catalog',
@@ -96,7 +111,7 @@ function resolveOp(op, catalog, declared, usedAliases, errors, options, traversa
96
111
  connector,
97
112
  operation: op.operation,
98
113
  path: op.path,
99
- catalog,
114
+ catalog: effectiveCatalog,
100
115
  declared,
101
116
  errors,
102
117
  ...(traversal === undefined ? {} : { traversal }),