@noodleseed/one 0.135.0 → 0.137.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 (34) hide show
  1. package/dist/bin.js +0 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +15 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/auth-google-ops.d.ts.map +1 -1
  6. package/dist/commands/auth-google-ops.js +3 -1
  7. package/dist/commands/auth-google-ops.js.map +1 -1
  8. package/dist/commands/config-values.d.ts.map +1 -1
  9. package/dist/commands/config-values.js +6 -2
  10. package/dist/commands/config-values.js.map +1 -1
  11. package/dist/commands/distribution-ops-support.d.ts +1 -1
  12. package/dist/commands/distribution-ops-support.d.ts.map +1 -1
  13. package/dist/commands/distribution-ops-support.js +2 -2
  14. package/dist/commands/distribution-ops-support.js.map +1 -1
  15. package/dist/commands/distributions-ops.js +1 -1
  16. package/dist/commands/distributions-ops.js.map +1 -1
  17. package/dist/commands/feedback-ops.d.ts.map +1 -1
  18. package/dist/commands/feedback-ops.js +4 -2
  19. package/dist/commands/feedback-ops.js.map +1 -1
  20. package/dist/commands/session.d.ts.map +1 -1
  21. package/dist/commands/session.js +3 -1
  22. package/dist/commands/session.js.map +1 -1
  23. package/dist/control-plane.d.ts +3 -0
  24. package/dist/control-plane.d.ts.map +1 -1
  25. package/dist/control-plane.js +24 -4
  26. package/dist/control-plane.js.map +1 -1
  27. package/dist/first-run.d.ts.map +1 -1
  28. package/dist/first-run.js +3 -1
  29. package/dist/first-run.js.map +1 -1
  30. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +1 -1
  31. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +16 -6
  32. package/node_modules/@noodleseed/assistant/README.md +43 -8
  33. package/node_modules/@noodleseed/assistant/package.json +15 -1
  34. package/package.json +1 -1
@@ -516,14 +516,19 @@ export function renderEmbeddedAssistantReference() {
516
516
  '',
517
517
  '`settle` must await or catch the command promise; the same structured failure also appears in the hook `error` state.',
518
518
  '',
519
- 'The sample fails closed on input requests until you replace that branch with a form generated from `requestedSchema`. A custom renderer must show the complete confirmation review and both decisions, handle every part it supports, and surface an explicit unsupported state for the rest. For `data-view`, use `NoodleAppView` to render the linked App or deliberately map `resourceUri`/tool plus the bounded redacted `result` to an application-trusted native component. JSON result data is not the linked App UI. Never inject `part.data.html`, assign it to `srcdoc`, fetch a `ui://` URI, or reproduce the bridge with a direct Ext Apps dependency. Do not wrap this client in another chat transport or invent user messages for interaction continuations.',
519
+ 'The sample fails closed on input requests until you replace that branch with a form generated from `requestedSchema`. A custom renderer must show the complete confirmation review and both decisions, handle every part it supports, and surface an explicit unsupported state for the rest. For `data-view`, use the canonical `<noodle-app-view>` host (or its React `NoodleAppView` adapter) to render the linked App, or deliberately map `resourceUri`/tool plus the bounded redacted `result` to an application-trusted native component. JSON result data is not the linked App UI. Never inject `part.data.html`, assign it to `srcdoc`, fetch a `ui://` URI, or reproduce the bridge with a direct Ext Apps dependency. Do not wrap this client in another chat transport or invent user messages for interaction continuations.',
520
520
  '',
521
- '`NoodleAppView` owns one bridge for the semantic view identity: client + `view.id` + `view.resourceUri`. It retains the iframe across fresh payload/callback/theme rerenders, reads current payloads through refs, publishes later resolved-theme changes through MCP Apps host context, and sends standard App teardown only when that semantic identity changes or the component unmounts. Pass the same resolved application theme used by the conversation shell. Do not key an ancestor by a view object or callback. If the embedding page sets Content-Security-Policy, include the Noodle service origin in both `connect-src` and `frame-src`.',
521
+ '`<noodle-app-view>` owns one bridge for the semantic view identity: client + `view.id` + `view.resourceUri`; `NoodleAppView` delegates to it. The host retains the iframe across fresh payload/callback/theme rerenders, publishes later resolved-theme changes through MCP Apps host context, and sends standard App teardown when that semantic identity changes, the element disconnects, or the App requests teardown. App views remain inline by default; the host advertises only inline presentation and rejects widget fullscreen requests. Opt in with `allowFullscreen` on `NoodleAppView` or `allow-fullscreen` on `<noodle-app-view>` only when fullscreen is an intentional part of the customer-owned experience. When fullscreen is accepted, the shared host adds an accessible top-right exit control that returns the same mounted App to inline mode without losing its state. Pass the same resolved application theme used by the conversation shell. Do not key an ancestor by a view object or callback. If the embedding page sets Content-Security-Policy, include the Noodle service origin in both `connect-src` and `frame-src`.',
522
522
  '',
523
- 'Outside React, use the same DOM-free client directly. It keeps the session token in memory, exposes a React-free `UIMessage` transcript with typed parts, and never registers a custom element:',
523
+ 'Outside React, use the same DOM-free client directly and import the isolated App-view entry only when rendering linked Apps. The client keeps the session token in memory, the transcript stays React-free, and the element owns only App presentation:',
524
+ '',
525
+ '```html',
526
+ '<noodle-app-view id="assistant-app-view"></noodle-app-view>',
527
+ '```',
524
528
  '',
525
529
  '```ts',
526
530
  'import { createAssistantClient } from "@noodleseed/assistant/client";',
531
+ 'import "@noodleseed/assistant/app-view";',
527
532
  '',
528
533
  'const assistant = createAssistantClient({',
529
534
  ' sessionEndpoint: "/api/assistant/session",',
@@ -533,6 +538,11 @@ export function renderEmbeddedAssistantReference() {
533
538
  ' }),',
534
539
  '});',
535
540
  '',
541
+ 'const appView = document.querySelector("#assistant-app-view");',
542
+ 'if (!appView) throw new Error("Missing App view host");',
543
+ 'appView.client = assistant;',
544
+ "appView.theme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';",
545
+ '',
536
546
  'assistant.updateModelContext({',
537
547
  " content: [{ type: 'text', text: 'The time-off form is mounted.' }],",
538
548
  " structuredContent: { widget: { name: 'time-off', lifecycle: 'mounted' } },",
@@ -551,7 +561,7 @@ export function renderEmbeddedAssistantReference() {
551
561
  ' pending = { id: part.data.id, requestedSchema: part.data.requestedSchema };',
552
562
  ' }',
553
563
  " if (part.type === 'data-view') {",
554
- ' renderRegisteredView(part.data.resourceUri, part.data.result);',
564
+ ' appView.view = part.data;',
555
565
  ' }',
556
566
  ' }',
557
567
  ' }',
@@ -590,7 +600,7 @@ export function renderEmbeddedAssistantReference() {
590
600
  '});',
591
601
  '```',
592
602
  '',
593
- '`data-view` means a completed tool has a linked MCP App view. In a customer-owned React renderer, pass that typed part and the existing client to `NoodleAppView`; it retains one bridge for client + `view.id` + `view.resourceUri` and requests standard App teardown on semantic replacement or unmount. That pair is transport identity: different call ids are distinct invocations and must not be deduplicated generically. If the product intentionally owns one current panel for a known resource, declare an application-owned slot map and replace only that slot. Deliberately map the bounded result to an application-trusted native component only when replacing the linked App UI.',
603
+ '`data-view` means a completed tool has a linked MCP App view. Pass that typed part and the existing client to `<noodle-app-view>` in Vue, Angular, or plain DOM, or to its `NoodleAppView` React adapter. It retains one bridge for client + `view.id` + `view.resourceUri` and requests standard App teardown on semantic replacement, disconnect, or App request. That pair is transport identity: different call ids are distinct invocations and must not be deduplicated generically. If the product intentionally owns one current panel for a known resource, declare an application-owned slot map and replace only that slot. Deliberately map the bounded result to an application-trusted native component only when replacing the linked App UI.',
594
604
  '',
595
605
  '`clientContext` and typed `pageContext` are recomputed for each turn. `updateContext(...)` remains the legacy session-exchange context; `updatePageContext(...)` replaces the fresh per-turn application hint. `updateModelContext({ content, structuredContent })` publishes one cohesive renderer snapshot for later message turns without starting a turn; every call replaces the prior snapshot rather than merging fields. These are untrusted data, not conversation history or authorization input, and the boundaries reject credential-shaped or unbounded updates. A message may re-exchange once after a pre-execution `401`; the client never auto-retries interaction decisions. `tool_proposed.arguments` is a complete schema-aware review projection and, for connector-backed tools, names the sole exact connector version/operation/resolved arguments. Sensitive/write-only fields are redacted; truncating or omitting any non-sensitive action field fails closed. Accept is bound to the server-held action and claims at most one execution attempt—clients cannot replace it. Normal terminal outcomes scrub private arguments and continuations immediately; only an accepted action still executing retains them for the one-hour unknown-outcome recovery window, after which it records `interaction_outcome_unknown` and scrubs. Without downstream idempotency this is not an exactly-once business-effect guarantee. To reconcile a lost response, explicitly repeat the same id and decision: the service returns its durable stored outcome without re-execution.',
596
606
  '',
@@ -615,7 +625,7 @@ export function renderEmbeddedAssistantReference() {
615
625
  '',
616
626
  '- Node.js 20+ for `@noodleseed/assistant/server`.',
617
627
  '- The package ships ESM and CommonJS with full export conditions; no bundler aliases, `transpilePackages`, or ambient type shims are needed. If resolution fails, the installed package version is outdated: update `@noodleseed/assistant` instead of adding workarounds.',
618
- '- TypeScript `moduleResolution` `bundler` or `node16` recommended; classic `node` also resolves the `/client`, `/react`, `/react/client`, and `/server` subpaths.',
628
+ '- TypeScript `moduleResolution` `bundler` or `node16` recommended; classic `node` also resolves the `/app-view`, `/client`, `/react`, `/react/client`, and `/server` subpaths.',
619
629
  '',
620
630
  '## Verify the boundary',
621
631
  '',
@@ -2,8 +2,9 @@
2
2
 
3
3
  Customer-branded embedded assistant surfaces for Noodle Seed deployments.
4
4
 
5
- The package exports the canonical `<noodle-assistant>` Web Component, a managed React wrapper and secure
6
- `NoodleAppView` MCP App renderer from `@noodleseed/assistant/react`, a renderer-free React hook from
5
+ The package exports the canonical `<noodle-assistant>` managed Web Component, the framework-neutral
6
+ `<noodle-app-view>` MCP App host from `@noodleseed/assistant/app-view`, a managed React wrapper and
7
+ `NoodleAppView` adapter from `@noodleseed/assistant/react`, a renderer-free React hook from
7
8
  `@noodleseed/assistant/react/client`, a DOM-free client from `@noodleseed/assistant/client`, and the
8
9
  backend-only `createAssistantSession` helper from `@noodleseed/assistant/server`. Light, dark, and automatic
9
10
  themes work without configuration; the component inherits the deployed MCP server's brand kit while slots,
@@ -376,20 +377,54 @@ if (part.type === "data-view") {
376
377
  }
377
378
  ```
378
379
 
379
- `NoodleAppView` owns the double iframe and AppBridge. Its lifecycle identity is the supplied client plus
380
+ `<noodle-app-view>` owns the double iframe and AppBridge; `NoodleAppView` delegates to it. Its lifecycle identity is the supplied client plus
380
381
  `view.id` plus `view.resourceUri`: ordinary parent rerenders and fresh view/callback objects retain the
381
382
  iframe, while a semantic view replacement or unmount requests standard App teardown and closes the bridge.
382
383
  Do not also key an ancestor by the whole view object or a callback. Pass the embedding application's
383
384
  resolved `"light"` or `"dark"` theme; later changes are published through MCP Apps host context without
384
385
  replacing the iframe.
385
386
 
387
+ App views stay inline by default. The host advertises only inline presentation and rejects an untrusted
388
+ App's fullscreen request, so stale or third-party widget code cannot take over the embedding application's
389
+ viewport. If fullscreen is an intentional part of the customer-owned experience, opt in explicitly with
390
+ `allowFullscreen` on `NoodleAppView` or `allow-fullscreen` on `<noodle-app-view>`; do not enable it merely
391
+ because a widget requests it. After an accepted fullscreen request, the host displays an accessible exit
392
+ control in the top-right corner. It returns the same mounted App to inline mode without resetting its state.
393
+
394
+ Vue, Angular, and plain DOM renderers use the same host without installing React. Import its dedicated entry
395
+ once, then assign the complex values as element properties. In Vue, the explicit `.prop` modifier makes that
396
+ boundary unambiguous:
397
+
398
+ ```vue
399
+ <script setup lang="ts">
400
+ import "@noodleseed/assistant/app-view";
401
+ </script>
402
+
403
+ <template>
404
+ <noodle-app-view
405
+ :client.prop="assistant"
406
+ :view.prop="part.data"
407
+ :theme="resolvedTheme"
408
+ @assistant-error="reportAssistantError"
409
+ />
410
+ </template>
411
+ ```
412
+
413
+ Configure Vue's `isCustomElement` for `noodle-app-view`. Angular uses the same element with `[client]`,
414
+ `[view]`, and `[theme]` property bindings. Do not serialize `client` or `view` into attributes.
415
+
416
+ `<noodle-app-view>` is the canonical host; `NoodleAppView` delegates to it. Both use the
417
+ service-advertised sandbox URL, route App calls through the supplied client, publish theme changes without
418
+ replacing the iframe, and request standard teardown on semantic replacement, disconnect, or an App teardown
419
+ request.
420
+
386
421
  The App document owns its action intent: it calls standard `tools/call` after connecting and never relies on
387
422
  native form navigation. If that call needs input or confirmation, the same `client` publishes the normal
388
423
  pending interaction part for either managed or customer-owned rendering. The original App call stays pending
389
424
  and receives its MCP result after `client.respond(...)`; applications must not retry or translate the click.
390
425
 
391
- Outside React, subscribe to the DOM-free AI SDK `UIMessage` state without registering a custom element or
392
- touching browser storage:
426
+ Outside React, subscribe to the DOM-free AI SDK `UIMessage` state without touching browser storage. The
427
+ client itself registers no element; import `/app-view` only when the transcript renders linked MCP Apps:
393
428
 
394
429
  ```ts
395
430
  import { createAssistantClient } from "@noodleseed/assistant/client";
@@ -491,8 +526,8 @@ flow collects all elicited input before its first connector operation.
491
526
 
492
527
  A completed widget-linked tool emits typed `view_available` data with its call/interaction id, tool,
493
528
  `ui://` resource identity, optional title, bounded/redacted public result, and—on current services—the
494
- self-contained App document. This is an availability signal, not proof of rendering. A customer-owned React
495
- renderer either mounts the actual App with `NoodleAppView` or deliberately substitutes a component already
529
+ self-contained App document. This is an availability signal, not proof of rendering. A customer-owned
530
+ renderer either mounts the actual App with `<noodle-app-view>` (or its React `NoodleAppView` adapter) or deliberately substitutes a component already
496
531
  trusted by the application and selected by `resourceUri`/tool. The JSON `result` is data for a native
497
532
  component; serializing it is not a rendering of the linked App. Never fetch the `ui://` URI, inject
498
533
  `part.data.html`, or assign it to `srcdoc` yourself. The standard element also forwards the same detail as a
@@ -615,7 +650,7 @@ shadow-DOM selectors and classes are not public API.
615
650
 
616
651
  `theme="auto"` follows the browser's operating-system color preference. When the embedding application has
617
652
  its own theme toggle, pass its resolved `"light"` or `"dark"` value to `NoodleAssistant` and every
618
- `NoodleAppView`. Updates change the assistant in place and notify mounted MCP Apps through standard host
653
+ `<noodle-app-view>`/`NoodleAppView`. Updates change the assistant in place and notify mounted MCP Apps through standard host
619
654
  context.
620
655
 
621
656
  Server branding controls customer name, themed logo/mark/avatar assets, semantic light/dark colors, density,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@noodleseed/assistant",
3
3
  "version": "1.22.0",
4
- "description": "Embed the Noodle Seed customer-branded assistant in your web app with a Web Component, managed or custom React UI, DOM-free client, and backend session helper. Authoring and deploying the server is @noodleseed/one.",
4
+ "description": "Embed the Noodle Seed customer-branded assistant in your web app with managed or framework-owned UI, a framework-neutral MCP App host, a DOM-free client, and a backend session helper. Authoring and deploying the server is @noodleseed/one.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -26,6 +26,17 @@
26
26
  },
27
27
  "default": "./dist/index.js"
28
28
  },
29
+ "./app-view": {
30
+ "import": {
31
+ "types": "./dist/app-view.d.ts",
32
+ "default": "./dist/app-view.js"
33
+ },
34
+ "require": {
35
+ "types": "./dist/app-view.d.cts",
36
+ "default": "./dist/app-view.cjs"
37
+ },
38
+ "default": "./dist/app-view.js"
39
+ },
29
40
  "./client": {
30
41
  "import": {
31
42
  "types": "./dist/client.d.ts",
@@ -103,6 +114,9 @@
103
114
  "module": "./dist/index.js",
104
115
  "typesVersions": {
105
116
  "*": {
117
+ "app-view": [
118
+ "./dist/app-view.d.ts"
119
+ ],
106
120
  "react": [
107
121
  "./dist/react.d.ts"
108
122
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noodleseed/one",
3
- "version": "0.135.0",
3
+ "version": "0.137.0",
4
4
  "private": false,
5
5
  "description": "Noodle CLI by Noodle Seed — author, run, and deploy declarative MCP servers. Embedding the assistant in your own web app is @noodleseed/assistant.",
6
6
  "license": "Apache-2.0",