@noodleseed/agent-kit 0.44.1 → 0.45.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 (30) hide show
  1. package/manifest.json +241 -241
  2. package/package.json +1 -1
  3. package/skills/claude-code/SKILL.md +1 -1
  4. package/skills/claude-code/authoring-mcp-servers/SKILL.md +1 -1
  5. package/skills/claude-code/building-mcp-apps/SKILL.md +1 -1
  6. package/skills/claude-code/connecting-apis-to-mcp/SKILL.md +1 -1
  7. package/skills/claude-code/debugging-mcp-delivery/SKILL.md +1 -1
  8. package/skills/claude-code/deploying-mcp-services/SKILL.md +1 -1
  9. package/skills/claude-code/designing-mcp-products/SKILL.md +1 -1
  10. package/skills/claude-code/embedding-mcp-assistants/SKILL.md +1 -1
  11. package/skills/claude-code/examples/customer-auth/README.md +12 -5
  12. package/skills/claude-code/executing-noodle-plans/SKILL.md +1 -1
  13. package/skills/claude-code/publishing-mcp-integrations/SKILL.md +1 -1
  14. package/skills/claude-code/references/embedded-assistant.md +10 -5
  15. package/skills/claude-code/reporting-noodle-feedback/SKILL.md +1 -1
  16. package/skills/claude-code/verifying-mcp-delivery/SKILL.md +1 -1
  17. package/skills/codex/SKILL.md +1 -1
  18. package/skills/codex/authoring-mcp-servers/SKILL.md +1 -1
  19. package/skills/codex/building-mcp-apps/SKILL.md +1 -1
  20. package/skills/codex/connecting-apis-to-mcp/SKILL.md +1 -1
  21. package/skills/codex/debugging-mcp-delivery/SKILL.md +1 -1
  22. package/skills/codex/deploying-mcp-services/SKILL.md +1 -1
  23. package/skills/codex/designing-mcp-products/SKILL.md +1 -1
  24. package/skills/codex/embedding-mcp-assistants/SKILL.md +1 -1
  25. package/skills/codex/examples/customer-auth/README.md +12 -5
  26. package/skills/codex/executing-noodle-plans/SKILL.md +1 -1
  27. package/skills/codex/publishing-mcp-integrations/SKILL.md +1 -1
  28. package/skills/codex/references/embedded-assistant.md +10 -5
  29. package/skills/codex/reporting-noodle-feedback/SKILL.md +1 -1
  30. package/skills/codex/verifying-mcp-delivery/SKILL.md +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noodleseed/agent-kit",
3
- "version": "0.44.1",
3
+ "version": "0.45.0",
4
4
  "private": false,
5
5
  "description": "Self-checking, self-updating agent skills for the Noodle Seed CLI. Authored in this repo by @noodle-borg/agent-kit; this is the published, independently-versioned canonical skills artifact the CLI fetches and verifies.",
6
6
  "license": "Apache-2.0",
@@ -3,7 +3,7 @@ name: noodle-seed
3
3
  description: "Use when building, validating, testing, deploying, or operating a local or hosted Noodle Seed MCP server or app authored in TypeScript with the noodle CLI."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:cd6ca0d915e6acb9 -->
6
+ <!-- noodle-skill version:0.45.0 hash:cd6ca0d915e6acb9 -->
7
7
 
8
8
  # Noodle Seed
9
9
 
@@ -3,7 +3,7 @@ name: authoring-mcp-servers
3
3
  description: "Use when creating or extending a headless Noodle Seed MCP server, tool, resource, prompt, or typed model-facing capability."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:0b2fd8c7e43fc69f -->
6
+ <!-- noodle-skill version:0.45.0 hash:0b2fd8c7e43fc69f -->
7
7
 
8
8
  # authoring-mcp-servers
9
9
 
@@ -3,7 +3,7 @@ name: building-mcp-apps
3
3
  description: "Use when a Noodle Seed MCP App, widget, interactive card, visual interaction, or host-visible UI is the primary requested outcome."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:f7fa54992c8d7692 -->
6
+ <!-- noodle-skill version:0.45.0 hash:f7fa54992c8d7692 -->
7
7
 
8
8
  # building-mcp-apps
9
9
 
@@ -3,7 +3,7 @@ name: connecting-apis-to-mcp
3
3
  description: "Use when credentials, an API URL, an OpenAPI document, or an observed response must become real Noodle Seed MCP behavior."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:1e86b8704f407bd3 -->
6
+ <!-- noodle-skill version:0.45.0 hash:1e86b8704f407bd3 -->
7
7
 
8
8
  # connecting-apis-to-mcp
9
9
 
@@ -3,7 +3,7 @@ name: debugging-mcp-delivery
3
3
  description: "Use when an existing Noodle Seed MCP project has a concrete validation, runtime, connector, App, host, deployment, or production failure."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.45.0 hash:aa715bae12041d7c -->
7
7
 
8
8
  # debugging-mcp-delivery
9
9
 
@@ -3,7 +3,7 @@ name: deploying-mcp-services
3
3
  description: "Use when the user explicitly requests a Noodle Seed hosted link, configuration write, deployment, access change, rollback, or connection write."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.45.0 hash:93e735b7ffb45df1 -->
7
7
 
8
8
  # deploying-mcp-services
9
9
 
@@ -3,7 +3,7 @@ name: designing-mcp-products
3
3
  description: "Use when a Noodle Seed MCP product idea needs conversational fit, user benefit, scope, interaction, or evidence design before implementation."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:76cce86729cffbee -->
6
+ <!-- noodle-skill version:0.45.0 hash:76cce86729cffbee -->
7
7
 
8
8
  # designing-mcp-products
9
9
 
@@ -3,7 +3,7 @@ name: embedding-mcp-assistants
3
3
  description: "Use when embedding a Noodle assistant into an existing SaaS or web application with browser, identity, session, and credential boundaries."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:5d8f40f904d6ab4b -->
6
+ <!-- noodle-skill version:0.45.0 hash:5d8f40f904d6ab4b -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -205,6 +205,7 @@ and returns the AI SDK transcript plus the canonical client commands:
205
205
  'use client';
206
206
 
207
207
  import { useState } from 'react';
208
+ import { NoodleAppView } from '@noodleseed/assistant/react';
208
209
  import { useNoodleAssistant } from '@noodleseed/assistant/react/client';
209
210
 
210
211
  export function CustomerAssistant({ principalKey }: { principalKey: string }) {
@@ -274,9 +275,11 @@ export function CustomerAssistant({ principalKey }: { principalKey: string }) {
274
275
  }
275
276
  if (part.type === 'data-view') {
276
277
  return (
277
- <p key={part.data.id}>
278
- Trusted app view available: {part.data.title ?? part.data.resourceUri}
279
- </p>
278
+ <NoodleAppView
279
+ key={`${part.data.id}:${part.data.resourceUri}`}
280
+ client={client}
281
+ view={part.data}
282
+ />
280
283
  );
281
284
  }
282
285
  return <p key={index}>Unsupported assistant content.</p>;
@@ -315,8 +318,12 @@ export function CustomerAssistant({ principalKey }: { principalKey: string }) {
315
318
  then aborts and clears the prior session and transcript. The sample fails closed on input requests until its
316
319
  fallback is replaced with a form generated from `requestedSchema`. A production renderer must show the
317
320
  complete confirmation review and both decisions. For `data-view`, map `resourceUri` or `tool` and the
318
- bounded/redacted result to a component already trusted by this application. Never inject `part.data.html`,
319
- assign it to `srcdoc`, or fetch a `ui://` URI.
321
+ bounded/redacted result to a component already trusted by this application only when intentionally replacing
322
+ the linked App with a native UI. Otherwise use `NoodleAppView`; JSON result data is not the App UI. Its
323
+ semantic lifecycle identity is the client plus `view.id` plus `view.resourceUri`, so parent payload/callback
324
+ rerenders keep the iframe and only a different view or unmount tears down the bridge.
325
+ Never inject `part.data.html`, assign it to `srcdoc`, fetch a `ui://` URI, or reproduce the bridge directly. Pages with a
326
+ Content-Security-Policy must include the Noodle service origin in both `connect-src` and `frame-src`.
320
327
 
321
328
  Outside React, subscribe to the DOM-free client directly. It exposes the same conversation as headless AI
322
329
  SDK `UIMessage` state, including typed confirmation, input, tool-result, and linked-view parts:
@@ -3,7 +3,7 @@ name: executing-noodle-plans
3
3
  description: "Use when the user asks to execute an approved, decision-complete implementation plan for a Noodle Seed project task by task with test-first changes, review, recovery, and final verification."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.45.0 hash:6a9f132ddb79352e -->
7
7
 
8
8
  # Execute a Noodle Seed implementation plan
9
9
 
@@ -3,7 +3,7 @@ name: publishing-mcp-integrations
3
3
  description: "Use when preparing, reviewing, or submitting a Noodle Seed MCP integration to a host or app directory."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.45.0 hash:efffbf82007f935d -->
7
7
 
8
8
  # publishing-mcp-integrations
9
9
 
@@ -254,6 +254,7 @@ For a customer-owned React renderer, use the renderer-free hook. It owns client
254
254
  "use client";
255
255
 
256
256
  import { useState } from "react";
257
+ import { NoodleAppView } from "@noodleseed/assistant/react";
257
258
  import { useNoodleAssistant } from "@noodleseed/assistant/react/client";
258
259
 
259
260
  export function CustomAssistant({ principalKey }: { principalKey: string }) {
@@ -327,9 +328,11 @@ export function CustomAssistant({ principalKey }: { principalKey: string }) {
327
328
  }
328
329
  if (part.type === "data-view") {
329
330
  return (
330
- <p key={part.data.id}>
331
- Trusted app view available: {part.data.title ?? part.data.resourceUri}
332
- </p>
331
+ <NoodleAppView
332
+ key={`${part.data.id}:${part.data.resourceUri}`}
333
+ client={client}
334
+ view={part.data}
335
+ />
333
336
  );
334
337
  }
335
338
  return <p key={index}>Unsupported assistant content.</p>;
@@ -364,7 +367,9 @@ export function CustomAssistant({ principalKey }: { principalKey: string }) {
364
367
 
365
368
  `principalKey` is a browser-local identity for the authenticated user/tenant and is never sent to Noodle. Change it whenever that principal changes; the hook then aborts and clears the previous session and transcript. The hook does not register `<noodle-assistant>` or render Noodle markup.
366
369
 
367
- 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`, map `resourceUri` or `tool` plus the bounded/redacted `result` to a component already trusted by the application. Never inject `part.data.html`, assign it to `srcdoc`, or fetch a `ui://` URI; the managed element alone supplies Noodle’s sandbox host. Do not wrap this client in another chat transport or invent user messages for interaction continuations.
370
+ 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.
371
+
372
+ `NoodleAppView` owns one bridge for the semantic view identity: client + `view.id` + `view.resourceUri`. It retains the iframe across fresh payload/callback objects from parent rerenders, reads current payloads through refs, and sends standard App teardown only when that semantic identity changes or the component unmounts. 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`.
368
373
 
369
374
  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:
370
375
 
@@ -416,7 +421,7 @@ if (pending) {
416
421
 
417
422
  `subscribeChat` immediately emits a detached `{ messages, status, error? }` snapshot and then emits as `UIMessage.parts` change. Text uses `text`; Noodle confirmations, input requests, tool results, and linked views use `data-confirmation`, `data-input-request`, `data-tool-result`, and `data-view`. Interaction data moves through pending/submitting/accepted/declined/cancelled. Use raw `subscribe(...)` only for transport/session lifecycle events that are not transcript content.
418
423
 
419
- `data-view` means a completed tool has a linked MCP App view. It carries the call/interaction id, tool, `ui://` identity, optional title, bounded/redacted public result, and—on current services—the self-contained bridged document. The standard element is an MCP Apps host and mounts that document behind a double iframe; a customer renderer ignores it and maps the identity/result to an application-trusted component. The standard element supports lifecycle, app tool/resource calls, ui/message, ui/update-model-context, links, resize, and inline/fullscreen; sampling, tasks, downloads, and remote DOM are not advertised. It also dispatches `assistant-view-available` for a customer-owned renderer.
424
+ `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. Deliberately map the bounded result to an application-trusted native component only when replacing the linked App UI.
420
425
 
421
426
  `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.
422
427
 
@@ -3,7 +3,7 @@ name: reporting-noodle-feedback
3
3
  description: "Use when a Noodle Seed bug, misleading instruction, missing capability, or concrete product improvement should be proposed to the user."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.45.0 hash:0f404109f4845683 -->
7
7
 
8
8
  # reporting-noodle-feedback
9
9
 
@@ -3,7 +3,7 @@ name: verifying-mcp-delivery
3
3
  description: "Use when proving a Noodle Seed MCP project works at a named compile, local, connector, App, host, deployment, or production evidence level."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.45.0 hash:6ef6ef551e26b78e -->
7
7
 
8
8
  # verifying-mcp-delivery
9
9
 
@@ -3,7 +3,7 @@ name: noodle-seed
3
3
  description: "Use when building, validating, testing, deploying, or operating a local or hosted Noodle Seed MCP server or app authored in TypeScript with the noodle CLI."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:cd6ca0d915e6acb9 -->
6
+ <!-- noodle-skill version:0.45.0 hash:cd6ca0d915e6acb9 -->
7
7
 
8
8
  # Noodle Seed
9
9
 
@@ -3,7 +3,7 @@ name: authoring-mcp-servers
3
3
  description: "Use when creating or extending a headless Noodle Seed MCP server, tool, resource, prompt, or typed model-facing capability."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:0b2fd8c7e43fc69f -->
6
+ <!-- noodle-skill version:0.45.0 hash:0b2fd8c7e43fc69f -->
7
7
 
8
8
  # authoring-mcp-servers
9
9
 
@@ -3,7 +3,7 @@ name: building-mcp-apps
3
3
  description: "Use when a Noodle Seed MCP App, widget, interactive card, visual interaction, or host-visible UI is the primary requested outcome."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:f7fa54992c8d7692 -->
6
+ <!-- noodle-skill version:0.45.0 hash:f7fa54992c8d7692 -->
7
7
 
8
8
  # building-mcp-apps
9
9
 
@@ -3,7 +3,7 @@ name: connecting-apis-to-mcp
3
3
  description: "Use when credentials, an API URL, an OpenAPI document, or an observed response must become real Noodle Seed MCP behavior."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:1e86b8704f407bd3 -->
6
+ <!-- noodle-skill version:0.45.0 hash:1e86b8704f407bd3 -->
7
7
 
8
8
  # connecting-apis-to-mcp
9
9
 
@@ -3,7 +3,7 @@ name: debugging-mcp-delivery
3
3
  description: "Use when an existing Noodle Seed MCP project has a concrete validation, runtime, connector, App, host, deployment, or production failure."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:aa715bae12041d7c -->
6
+ <!-- noodle-skill version:0.45.0 hash:aa715bae12041d7c -->
7
7
 
8
8
  # debugging-mcp-delivery
9
9
 
@@ -3,7 +3,7 @@ name: deploying-mcp-services
3
3
  description: "Use when the user explicitly requests a Noodle Seed hosted link, configuration write, deployment, access change, rollback, or connection write."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:93e735b7ffb45df1 -->
6
+ <!-- noodle-skill version:0.45.0 hash:93e735b7ffb45df1 -->
7
7
 
8
8
  # deploying-mcp-services
9
9
 
@@ -3,7 +3,7 @@ name: designing-mcp-products
3
3
  description: "Use when a Noodle Seed MCP product idea needs conversational fit, user benefit, scope, interaction, or evidence design before implementation."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:76cce86729cffbee -->
6
+ <!-- noodle-skill version:0.45.0 hash:76cce86729cffbee -->
7
7
 
8
8
  # designing-mcp-products
9
9
 
@@ -3,7 +3,7 @@ name: embedding-mcp-assistants
3
3
  description: "Use when embedding a Noodle assistant into an existing SaaS or web application with browser, identity, session, and credential boundaries."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:5d8f40f904d6ab4b -->
6
+ <!-- noodle-skill version:0.45.0 hash:5d8f40f904d6ab4b -->
7
7
 
8
8
  # embedding-mcp-assistants
9
9
 
@@ -205,6 +205,7 @@ and returns the AI SDK transcript plus the canonical client commands:
205
205
  'use client';
206
206
 
207
207
  import { useState } from 'react';
208
+ import { NoodleAppView } from '@noodleseed/assistant/react';
208
209
  import { useNoodleAssistant } from '@noodleseed/assistant/react/client';
209
210
 
210
211
  export function CustomerAssistant({ principalKey }: { principalKey: string }) {
@@ -274,9 +275,11 @@ export function CustomerAssistant({ principalKey }: { principalKey: string }) {
274
275
  }
275
276
  if (part.type === 'data-view') {
276
277
  return (
277
- <p key={part.data.id}>
278
- Trusted app view available: {part.data.title ?? part.data.resourceUri}
279
- </p>
278
+ <NoodleAppView
279
+ key={`${part.data.id}:${part.data.resourceUri}`}
280
+ client={client}
281
+ view={part.data}
282
+ />
280
283
  );
281
284
  }
282
285
  return <p key={index}>Unsupported assistant content.</p>;
@@ -315,8 +318,12 @@ export function CustomerAssistant({ principalKey }: { principalKey: string }) {
315
318
  then aborts and clears the prior session and transcript. The sample fails closed on input requests until its
316
319
  fallback is replaced with a form generated from `requestedSchema`. A production renderer must show the
317
320
  complete confirmation review and both decisions. For `data-view`, map `resourceUri` or `tool` and the
318
- bounded/redacted result to a component already trusted by this application. Never inject `part.data.html`,
319
- assign it to `srcdoc`, or fetch a `ui://` URI.
321
+ bounded/redacted result to a component already trusted by this application only when intentionally replacing
322
+ the linked App with a native UI. Otherwise use `NoodleAppView`; JSON result data is not the App UI. Its
323
+ semantic lifecycle identity is the client plus `view.id` plus `view.resourceUri`, so parent payload/callback
324
+ rerenders keep the iframe and only a different view or unmount tears down the bridge.
325
+ Never inject `part.data.html`, assign it to `srcdoc`, fetch a `ui://` URI, or reproduce the bridge directly. Pages with a
326
+ Content-Security-Policy must include the Noodle service origin in both `connect-src` and `frame-src`.
320
327
 
321
328
  Outside React, subscribe to the DOM-free client directly. It exposes the same conversation as headless AI
322
329
  SDK `UIMessage` state, including typed confirmation, input, tool-result, and linked-view parts:
@@ -3,7 +3,7 @@ name: executing-noodle-plans
3
3
  description: "Use when the user asks to execute an approved, decision-complete implementation plan for a Noodle Seed project task by task with test-first changes, review, recovery, and final verification."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:6a9f132ddb79352e -->
6
+ <!-- noodle-skill version:0.45.0 hash:6a9f132ddb79352e -->
7
7
 
8
8
  # Execute a Noodle Seed implementation plan
9
9
 
@@ -3,7 +3,7 @@ name: publishing-mcp-integrations
3
3
  description: "Use when preparing, reviewing, or submitting a Noodle Seed MCP integration to a host or app directory."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:efffbf82007f935d -->
6
+ <!-- noodle-skill version:0.45.0 hash:efffbf82007f935d -->
7
7
 
8
8
  # publishing-mcp-integrations
9
9
 
@@ -254,6 +254,7 @@ For a customer-owned React renderer, use the renderer-free hook. It owns client
254
254
  "use client";
255
255
 
256
256
  import { useState } from "react";
257
+ import { NoodleAppView } from "@noodleseed/assistant/react";
257
258
  import { useNoodleAssistant } from "@noodleseed/assistant/react/client";
258
259
 
259
260
  export function CustomAssistant({ principalKey }: { principalKey: string }) {
@@ -327,9 +328,11 @@ export function CustomAssistant({ principalKey }: { principalKey: string }) {
327
328
  }
328
329
  if (part.type === "data-view") {
329
330
  return (
330
- <p key={part.data.id}>
331
- Trusted app view available: {part.data.title ?? part.data.resourceUri}
332
- </p>
331
+ <NoodleAppView
332
+ key={`${part.data.id}:${part.data.resourceUri}`}
333
+ client={client}
334
+ view={part.data}
335
+ />
333
336
  );
334
337
  }
335
338
  return <p key={index}>Unsupported assistant content.</p>;
@@ -364,7 +367,9 @@ export function CustomAssistant({ principalKey }: { principalKey: string }) {
364
367
 
365
368
  `principalKey` is a browser-local identity for the authenticated user/tenant and is never sent to Noodle. Change it whenever that principal changes; the hook then aborts and clears the previous session and transcript. The hook does not register `<noodle-assistant>` or render Noodle markup.
366
369
 
367
- 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`, map `resourceUri` or `tool` plus the bounded/redacted `result` to a component already trusted by the application. Never inject `part.data.html`, assign it to `srcdoc`, or fetch a `ui://` URI; the managed element alone supplies Noodle’s sandbox host. Do not wrap this client in another chat transport or invent user messages for interaction continuations.
370
+ 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.
371
+
372
+ `NoodleAppView` owns one bridge for the semantic view identity: client + `view.id` + `view.resourceUri`. It retains the iframe across fresh payload/callback objects from parent rerenders, reads current payloads through refs, and sends standard App teardown only when that semantic identity changes or the component unmounts. 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`.
368
373
 
369
374
  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:
370
375
 
@@ -416,7 +421,7 @@ if (pending) {
416
421
 
417
422
  `subscribeChat` immediately emits a detached `{ messages, status, error? }` snapshot and then emits as `UIMessage.parts` change. Text uses `text`; Noodle confirmations, input requests, tool results, and linked views use `data-confirmation`, `data-input-request`, `data-tool-result`, and `data-view`. Interaction data moves through pending/submitting/accepted/declined/cancelled. Use raw `subscribe(...)` only for transport/session lifecycle events that are not transcript content.
418
423
 
419
- `data-view` means a completed tool has a linked MCP App view. It carries the call/interaction id, tool, `ui://` identity, optional title, bounded/redacted public result, and—on current services—the self-contained bridged document. The standard element is an MCP Apps host and mounts that document behind a double iframe; a customer renderer ignores it and maps the identity/result to an application-trusted component. The standard element supports lifecycle, app tool/resource calls, ui/message, ui/update-model-context, links, resize, and inline/fullscreen; sampling, tasks, downloads, and remote DOM are not advertised. It also dispatches `assistant-view-available` for a customer-owned renderer.
424
+ `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. Deliberately map the bounded result to an application-trusted native component only when replacing the linked App UI.
420
425
 
421
426
  `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.
422
427
 
@@ -3,7 +3,7 @@ name: reporting-noodle-feedback
3
3
  description: "Use when a Noodle Seed bug, misleading instruction, missing capability, or concrete product improvement should be proposed to the user."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:0f404109f4845683 -->
6
+ <!-- noodle-skill version:0.45.0 hash:0f404109f4845683 -->
7
7
 
8
8
  # reporting-noodle-feedback
9
9
 
@@ -3,7 +3,7 @@ name: verifying-mcp-delivery
3
3
  description: "Use when proving a Noodle Seed MCP project works at a named compile, local, connector, App, host, deployment, or production evidence level."
4
4
  ---
5
5
 
6
- <!-- noodle-skill version:0.44.1 hash:6ef6ef551e26b78e -->
6
+ <!-- noodle-skill version:0.45.0 hash:6ef6ef551e26b78e -->
7
7
 
8
8
  # verifying-mcp-delivery
9
9