@agent-native/core 0.157.2 → 0.157.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  3. package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +21 -0
  4. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +40 -1
  5. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  6. package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +21 -0
  7. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  8. package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +21 -0
  9. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  10. package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +21 -0
  11. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
  12. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  13. package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  14. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  15. package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +7 -7
  16. package/corpus/templates/clips/actions/approve-recording-access-request.ts +147 -0
  17. package/corpus/templates/clips/actions/request-recording-access.ts +121 -23
  18. package/corpus/templates/clips/actions/view-screen.ts +1 -1
  19. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +34 -53
  20. package/corpus/templates/clips/app/components/player/request-access-dialog.tsx +104 -0
  21. package/corpus/templates/clips/app/components/player/share-dialog.tsx +36 -45
  22. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -6
  23. package/corpus/templates/clips/app/i18n/en-US.ts +26 -1
  24. package/corpus/templates/clips/app/lib/public-meeting.ts +1 -1
  25. package/corpus/templates/clips/app/routes/access-request.approve.tsx +250 -0
  26. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +9 -32
  27. package/corpus/templates/clips/app/routes/share.$shareId.tsx +123 -37
  28. package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +41 -1
  29. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -0
  30. package/corpus/templates/clips/server/lib/emails.ts +40 -11
  31. package/corpus/templates/clips/shared/recording-link.ts +32 -1
  32. package/corpus/templates/clips/shared/share-attribution.ts +13 -0
  33. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  34. package/corpus/templates/content/.agents/skills/sharing/SKILL.md +21 -0
  35. package/corpus/templates/content/actions/add-database-item.ts +9 -0
  36. package/corpus/templates/content/actions/describe-content-database.ts +92 -0
  37. package/corpus/templates/content/actions/list-content-databases.ts +213 -72
  38. package/corpus/templates/content/actions/set-document-property.ts +9 -0
  39. package/corpus/templates/content/actions/submit-content-database-form.ts +9 -0
  40. package/corpus/templates/content/actions/update-document.ts +9 -0
  41. package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +22 -10
  42. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +2 -1
  43. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +245 -9
  44. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +192 -134
  45. package/corpus/templates/content/app/components/editor/database/settings.tsx +7 -0
  46. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +61 -45
  47. package/corpus/templates/content/app/components/editor/extensions/ImageNode.ts +6 -0
  48. package/corpus/templates/content/app/components/editor/image-upload.ts +137 -5
  49. package/corpus/templates/content/app/global.css +8 -0
  50. package/corpus/templates/content/app/hooks/use-content-database.ts +91 -11
  51. package/corpus/templates/content/changelog/2026-08-12-image-uploads-now-confirm-the-image-can-be-displayed-before-.md +6 -0
  52. package/corpus/templates/content/changelog/2026-08-14-images-fill-the-page-width-by-default-and-remain-visible-whe.md +6 -0
  53. package/corpus/templates/content/changelog/2026-08-14-images-inserted-from-the-slash-command-stay-saved-after-uplo.md +6 -0
  54. package/corpus/templates/content/changelog/2026-08-14-svg-files-can-be-selected-reliably-from-the-image-picker.md +6 -0
  55. package/corpus/templates/content/parity/matrix.md +1 -1
  56. package/corpus/templates/content/parity/matrix.ts +7 -1
  57. package/corpus/templates/content/server/plugins/agent-chat.ts +3 -0
  58. package/corpus/templates/content/shared/api.ts +9 -0
  59. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  60. package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +21 -0
  61. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  62. package/corpus/templates/design/.agents/skills/sharing/SKILL.md +21 -0
  63. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  64. package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +21 -0
  65. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  66. package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +21 -0
  67. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  68. package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +21 -0
  69. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  70. package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +21 -0
  71. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  72. package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +21 -0
  73. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +6 -1
  74. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  75. package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +21 -0
  76. package/corpus/templates/plan/app/pages/PlansPage.tsx +25 -30
  77. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  78. package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +21 -0
  79. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +2 -1
  80. package/corpus/templates/slides/app/components/editor/ShareDialog.tsx +124 -180
  81. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +1 -0
  82. package/corpus/templates/slides/app/global.css +99 -3
  83. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  84. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  85. package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +21 -0
  86. package/dist/chat-threads/schema.d.ts +1 -1
  87. package/dist/cli/code-agent-executor.js +318 -0
  88. package/dist/client/AgentPanel.d.ts +13 -1
  89. package/dist/client/AgentPanel.js +41 -3
  90. package/dist/client/AssistantChat.d.ts +9 -1
  91. package/dist/client/AssistantChat.js +26 -13
  92. package/dist/client/MultiTabAssistantChat.js +18 -5
  93. package/dist/client/agent-chat.d.ts +8 -0
  94. package/dist/client/agent-chat.js +15 -0
  95. package/dist/client/app-chat-sidebar.d.ts +23 -0
  96. package/dist/client/app-chat-sidebar.js +53 -0
  97. package/dist/client/app-providers.js +31 -2
  98. package/dist/client/frame-protocol.d.ts +20 -2
  99. package/dist/client/hooks/index.d.ts +1 -0
  100. package/dist/client/hooks/index.js +1 -0
  101. package/dist/client/sharing/AgentShareSection.d.ts +8 -0
  102. package/dist/client/sharing/AgentShareSection.js +50 -0
  103. package/dist/client/sharing/ShareButton.js +2 -1
  104. package/dist/client/sharing/ShareDialog.d.ts +2 -2
  105. package/dist/client/sharing/ShareDialog.js +21 -29
  106. package/dist/client/sharing/index.d.ts +1 -0
  107. package/dist/client/sharing/index.js +1 -0
  108. package/dist/client/sharing/useShareButtonController.d.ts +1 -0
  109. package/dist/client/sharing/useShareDialogController.d.ts +3 -0
  110. package/dist/client/sharing/useShareDialogController.js +2 -1
  111. package/dist/client/theme.d.ts +21 -0
  112. package/dist/client/theme.js +60 -0
  113. package/dist/client/ui/index.d.ts +1 -1
  114. package/dist/client/ui/index.js +1 -1
  115. package/dist/client/use-session.js +23 -0
  116. package/dist/collab/awareness.d.ts +2 -2
  117. package/dist/collab/routes.d.ts +1 -1
  118. package/dist/collab/struct-routes.d.ts +1 -1
  119. package/dist/dashboard-storage/schema.d.ts +1 -1
  120. package/dist/data-programs/schema.d.ts +1 -1
  121. package/dist/extensions/schema.d.ts +1 -1
  122. package/dist/localization/core-messages/ar-SA.js +6 -0
  123. package/dist/localization/core-messages/de-DE.js +6 -0
  124. package/dist/localization/core-messages/en-US.d.ts +6 -0
  125. package/dist/localization/core-messages/en-US.js +6 -0
  126. package/dist/localization/core-messages/es-ES.js +6 -0
  127. package/dist/localization/core-messages/fr-FR.js +6 -0
  128. package/dist/localization/core-messages/hi-IN.js +6 -0
  129. package/dist/localization/core-messages/ja-JP.js +6 -0
  130. package/dist/localization/core-messages/ko-KR.js +6 -0
  131. package/dist/localization/core-messages/pt-BR.js +6 -0
  132. package/dist/localization/core-messages/zh-CN.js +6 -0
  133. package/dist/localization/core-messages/zh-TW.js +6 -0
  134. package/dist/localization/core-messages.d.ts +6 -0
  135. package/dist/localization/default-messages.d.ts +1 -0
  136. package/dist/localization/default-messages.js +1 -0
  137. package/dist/notifications/routes.d.ts +3 -3
  138. package/dist/observability/routes.d.ts +5 -5
  139. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  140. package/dist/provider-api/actions/provider-api.d.ts +14 -14
  141. package/dist/secrets/routes.d.ts +9 -9
  142. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  143. package/dist/server/auth.js +8 -5
  144. package/dist/server/identity-sso-store.d.ts +6 -1
  145. package/dist/server/identity-sso-store.js +57 -14
  146. package/dist/server/identity-sso.d.ts +7 -8
  147. package/dist/server/identity-sso.js +15 -12
  148. package/dist/sharing/actions/list-resource-shares.d.ts +2 -0
  149. package/dist/sharing/actions/list-resource-shares.js +1 -0
  150. package/dist/sharing/schema.d.ts +1 -1
  151. package/dist/sharing/schema.js +4 -1
  152. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  153. package/dist/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  154. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  155. package/dist/templates/default/.agents/skills/sharing/SKILL.md +21 -0
  156. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  157. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  158. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
  159. package/docs/content/cross-app-sso.mdx +24 -17
  160. package/package.json +3 -3
  161. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  162. package/src/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  163. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  164. package/src/templates/default/.agents/skills/sharing/SKILL.md +21 -0
  165. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  166. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  167. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
@@ -435,11 +435,107 @@ button[title="Open agent sidebar"] {
435
435
  height: 100%;
436
436
  display: flex;
437
437
  flex-direction: column;
438
- font-family: "Poppins", sans-serif;
438
+ color: var(--ds-text, #ffffff);
439
+ background: var(--ds-bg, #0b0b0d);
440
+ font-family: var(--ds-body-font, "Poppins", sans-serif);
439
441
  box-sizing: border-box;
440
442
  overflow: hidden;
441
443
  }
442
444
 
445
+ /* Semantic slide markup is persisted by the agent. Keep the classes useful
446
+ when a later edit omits inline styles, while leaving explicit inline values
447
+ authoritative through the normal CSS cascade. */
448
+ .fmd-slide.fmd-slide--title {
449
+ justify-content: center;
450
+ align-items: flex-start;
451
+ gap: 24px;
452
+ padding: 80px 110px;
453
+ }
454
+
455
+ .fmd-slide.fmd-slide--content,
456
+ .fmd-slide.fmd-slide--two-column {
457
+ justify-content: flex-start;
458
+ gap: 24px;
459
+ padding: 64px 80px;
460
+ }
461
+
462
+ .fmd-slide.fmd-slide--statement {
463
+ align-items: center;
464
+ justify-content: center;
465
+ gap: 24px;
466
+ padding: 64px 80px;
467
+ text-align: center;
468
+ }
469
+
470
+ .fmd-slide.fmd-slide--title h1,
471
+ .fmd-slide.fmd-slide--content h1,
472
+ .fmd-slide.fmd-slide--content h2,
473
+ .fmd-slide.fmd-slide--two-column h1,
474
+ .fmd-slide.fmd-slide--two-column h2,
475
+ .fmd-slide.fmd-slide--statement h1,
476
+ .fmd-slide.fmd-slide--statement h2 {
477
+ color: var(--ds-text, #ffffff);
478
+ font-family: var(
479
+ --ds-heading-font,
480
+ var(--ds-body-font, "Poppins", sans-serif)
481
+ );
482
+ font-weight: 700;
483
+ letter-spacing: -0.03em;
484
+ }
485
+
486
+ .fmd-slide.fmd-slide--title h1 {
487
+ font-size: 46px;
488
+ line-height: 1.1;
489
+ }
490
+
491
+ .fmd-slide.fmd-slide--content h1,
492
+ .fmd-slide.fmd-slide--two-column h1,
493
+ .fmd-slide.fmd-slide--statement h1 {
494
+ font-size: 38px;
495
+ line-height: 1.15;
496
+ }
497
+
498
+ .fmd-slide.fmd-slide--content h2,
499
+ .fmd-slide.fmd-slide--two-column h2 {
500
+ font-size: 30px;
501
+ line-height: 1.2;
502
+ }
503
+
504
+ .fmd-slide.fmd-slide--statement h2 {
505
+ font-size: 42px;
506
+ line-height: 1.15;
507
+ }
508
+
509
+ .fmd-slide .fmd-subtitle,
510
+ .fmd-slide .fmd-muted {
511
+ color: var(--ds-text-muted, rgba(255, 255, 255, 0.7));
512
+ }
513
+
514
+ .fmd-slide .fmd-subtitle {
515
+ font-size: 22px;
516
+ line-height: 1.4;
517
+ }
518
+
519
+ .fmd-slide .fmd-columns {
520
+ display: grid;
521
+ grid-template-columns: repeat(2, minmax(0, 1fr));
522
+ gap: 32px;
523
+ width: 100%;
524
+ min-height: 0;
525
+ }
526
+
527
+ .fmd-slide .fmd-callout {
528
+ padding: 20px 24px;
529
+ border: 1px solid var(--ds-accent, rgba(255, 255, 255, 0.2));
530
+ border-radius: var(--ds-radius, 12px);
531
+ background: rgba(255, 255, 255, 0.05);
532
+ }
533
+
534
+ .fmd-slide .fmd-accent,
535
+ .fmd-slide .fmd-cyan {
536
+ color: var(--ds-accent, #00e5ff);
537
+ }
538
+
443
539
  .fmd-autofit-scale {
444
540
  transform: translate(var(--fmd-fit-x, 0px), var(--fmd-fit-y, 0px))
445
541
  scale(var(--fmd-fit-scale, 1));
@@ -461,7 +557,7 @@ button[title="Open agent sidebar"] {
461
557
 
462
558
  /* Section label - cyan uppercase */
463
559
  .fmd-label {
464
- color: #00e5ff;
560
+ color: var(--ds-accent, #00e5ff);
465
561
  font-size: 11px;
466
562
  font-weight: 600;
467
563
  letter-spacing: 3px;
@@ -471,7 +567,7 @@ button[title="Open agent sidebar"] {
471
567
 
472
568
  /* Cyan accent color */
473
569
  .fmd-cyan {
474
- color: #00e5ff !important;
570
+ color: var(--ds-accent, #00e5ff);
475
571
  }
476
572
 
477
573
  /* Large stat numbers */
@@ -295,6 +295,7 @@ const messages = {
295
295
  creatingLink: "Creating link...",
296
296
  createShareLink: "Create Share Link",
297
297
  copyLink: "Copy link",
298
+ copied: "Copied",
298
299
  openSharedLink: "Open shared link",
299
300
  anyoneWithLink: "Anyone with this link can view this presentation.",
300
301
  },
@@ -182,6 +182,11 @@ in the moment of agent use.
182
182
  five-item sidebar preview and a footer row with New chat followed by an
183
183
  ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
184
184
  actions.
185
+ - **Data grid kit**: provider-agnostic spreadsheet mechanics belong in
186
+ `@agent-native/toolkit/data-grid`. Apps provide rows, typed columns, editor
187
+ slots, selection and width state, persistence callbacks, and product-level
188
+ row/body slots. Keep database models, access checks, grouping, drag/drop,
189
+ and domain actions in the app adapter.
185
190
  - **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
186
191
  `@agent-native/core/client`) with Context, Files, Connections, Jobs, and
187
192
  Access tabs plus a Personal/Organization scope toggle. The canonical home
@@ -184,6 +184,27 @@ import { ShareButton } from "@agent-native/core/client/sharing";
184
184
 
185
185
  For list views, show `<VisibilityBadge visibility={row.visibility} />` next to each resource.
186
186
 
187
+ ## Standard share surface
188
+
189
+ All app share popovers should use the same compact surface contract:
190
+
191
+ - Use the text-only `ShareTrigger` from `@agent-native/toolkit/sharing`.
192
+ - Render ordinary links with `ShareCopyRow`, which exposes a Copy action without
193
+ printing the raw URL.
194
+ - Keep general access and individual people access in the standard Core sharing
195
+ flow. The people flow supports email invites, roles, notifications, and
196
+ removal through the shared share actions.
197
+ - Add `ShareAgentsSection` only when the resource has a real agent-readable
198
+ link or prompt. Keep it collapsed by default and supply domain-specific
199
+ content through the shared section shell.
200
+ - App-specific tabs or controls may remain when they represent a real domain
201
+ action (for example, an embed-code editor), but they should retain the same
202
+ trigger, copy-row, access, and spacing language.
203
+
204
+ `ShareDisclosureSection` is the toolkit-owned shell for optional expandable
205
+ share details; use its `ShareAgentsSection` or `SharePeopleSection` wrappers
206
+ instead of creating another collapsible share panel in a template.
207
+
187
208
  ## Actions available everywhere
188
209
 
189
210
  The framework auto-mounts these actions in every template — no per-template boilerplate:
@@ -463,7 +463,7 @@ export declare const chatThreadShares: import("drizzle-orm/sqlite-core").SQLiteT
463
463
  data: string;
464
464
  driverParam: string;
465
465
  notNull: true;
466
- hasDefault: false;
466
+ hasDefault: true;
467
467
  isPrimaryKey: false;
468
468
  isAutoincrement: false;
469
469
  hasRuntimeDefault: false;
@@ -23,6 +23,8 @@ const MAX_TOOL_OUTPUT_CHARS = 50_000;
23
23
  const MAX_FILE_READ_CHARS = 120_000;
24
24
  const CODEX_CLI_ENGINE_NAME = "codex-cli";
25
25
  const CLAUDE_CLI_ENGINE_NAME = "claude-cli";
26
+ const PI_CLI_ENGINE_NAME = "pi-cli";
27
+ const OPENCODE_CLI_ENGINE_NAME = "opencode-cli";
26
28
  const CLAUDE_CLI_DEFAULT_MODEL = "claude-sonnet-5";
27
29
  const RECAP_SOURCE_TOOL_PROFILE = "recap-source";
28
30
  const RECAP_SOURCE_OUTPUT_FILE = "recap-source.json";
@@ -125,6 +127,30 @@ export async function executeCodeAgentRun(options) {
125
127
  signal: options.signal,
126
128
  });
127
129
  }
130
+ if (requestedEngine === PI_CLI_ENGINE_NAME) {
131
+ return executePiCliRun({
132
+ run: existing,
133
+ prompt: executionPrompt,
134
+ model: options.model ?? metadataString(existing, "model"),
135
+ reasoningEffort: options.reasoningEffort ?? metadataReasoningEffort(existing),
136
+ permissionMode: existing.permissionMode ?? "full-auto",
137
+ stdout: options.stdout,
138
+ streamToolOutputToStdout,
139
+ signal: options.signal,
140
+ });
141
+ }
142
+ if (requestedEngine === OPENCODE_CLI_ENGINE_NAME) {
143
+ return executeOpenCodeCliRun({
144
+ run: existing,
145
+ prompt: executionPrompt,
146
+ model: options.model ?? metadataString(existing, "model"),
147
+ reasoningEffort: options.reasoningEffort ?? metadataReasoningEffort(existing),
148
+ permissionMode: existing.permissionMode ?? "full-auto",
149
+ stdout: options.stdout,
150
+ streamToolOutputToStdout,
151
+ signal: options.signal,
152
+ });
153
+ }
128
154
  const engine = options.engine ?? (await resolveExecutorEngine(requestedEngine));
129
155
  if (!engine) {
130
156
  const message = "No LLM provider key was found. Set ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, another supported provider key, or run `codex login` to use Codex CLI.";
@@ -669,6 +695,298 @@ function isRecordValue(value) {
669
695
  function asRecordValue(value) {
670
696
  return isRecordValue(value) ? value : null;
671
697
  }
698
+ async function executePiCliRun(options) {
699
+ const model = normalizeLocalCliModel(options.model, PI_CLI_ENGINE_NAME);
700
+ const thinking = normalizePiCliThinking(options.reasoningEffort);
701
+ const args = ["--print", "--mode", "text", "--no-session"];
702
+ if (options.permissionMode === "read-only") {
703
+ args.push("--tools", "read,grep,find,ls");
704
+ }
705
+ if (model)
706
+ args.push("--model", model);
707
+ if (thinking)
708
+ args.push("--thinking", thinking);
709
+ args.push(buildLocalCliPrompt(options.run, options.prompt));
710
+ return executeSimpleLocalCliRun({
711
+ ...options,
712
+ engine: PI_CLI_ENGINE_NAME,
713
+ label: "Pi",
714
+ command: "pi",
715
+ args,
716
+ model,
717
+ });
718
+ }
719
+ async function executeOpenCodeCliRun(options) {
720
+ const model = normalizeLocalCliModel(options.model, OPENCODE_CLI_ENGINE_NAME);
721
+ const variant = normalizeOpenCodeVariant(options.reasoningEffort);
722
+ const cwd = options.run.cwd || process.cwd();
723
+ const args = ["run", "--format", "default", "--dir", cwd];
724
+ if (options.permissionMode === "read-only") {
725
+ args.push("--agent", "plan");
726
+ }
727
+ if (model)
728
+ args.push("--model", model);
729
+ if (variant)
730
+ args.push("--variant", variant);
731
+ args.push(buildLocalCliPrompt(options.run, options.prompt));
732
+ return executeSimpleLocalCliRun({
733
+ ...options,
734
+ engine: OPENCODE_CLI_ENGINE_NAME,
735
+ label: "OpenCode",
736
+ command: "opencode",
737
+ args,
738
+ model,
739
+ });
740
+ }
741
+ async function executeSimpleLocalCliRun(options) {
742
+ const cwd = options.run.cwd || process.cwd();
743
+ const streamToolOutputToStdout = options.streamToolOutputToStdout ??
744
+ process.env.AGENT_NATIVE_CODE_AGENT_STRUCTURED_STDOUT !== "1";
745
+ appendCodeAgentTranscriptEvent({
746
+ runId: options.run.id,
747
+ kind: "status",
748
+ message: `Starting ${options.label} locally.`,
749
+ metadata: {
750
+ status: "running",
751
+ phase: "executing",
752
+ engine: options.engine,
753
+ },
754
+ });
755
+ try {
756
+ const result = await runLocalCliProcess({
757
+ command: options.command,
758
+ args: options.args,
759
+ cwd,
760
+ prompt: options.prompt,
761
+ stdout: options.stdout,
762
+ streamToolOutputToStdout,
763
+ signal: options.signal,
764
+ });
765
+ if (result.exitCode !== 0) {
766
+ const interrupted = options.signal?.aborted === true;
767
+ const message = result.error ||
768
+ result.stderr.trim() ||
769
+ `${options.label} exited with ${result.exitSignal ?? result.exitCode}.`;
770
+ const summary = interrupted
771
+ ? `${options.label} run paused.`
772
+ : `${options.label} run failed: ${message}`;
773
+ if (streamToolOutputToStdout)
774
+ options.stdout?.write(`\n${summary}\n`);
775
+ appendCodeAgentTranscriptEvent({
776
+ runId: options.run.id,
777
+ kind: "status",
778
+ message: summary,
779
+ metadata: {
780
+ status: interrupted ? "paused" : "errored",
781
+ phase: interrupted ? "paused" : "error",
782
+ engine: options.engine,
783
+ exitCode: result.exitCode,
784
+ exitSignal: result.exitSignal,
785
+ },
786
+ });
787
+ return updateCodeAgentRunRecord(options.run.id, {
788
+ status: interrupted ? "paused" : "errored",
789
+ phase: interrupted ? "paused" : "error",
790
+ progress: {
791
+ label: interrupted ? "Paused" : "Error",
792
+ completed: 0,
793
+ total: 1,
794
+ failed: interrupted ? 0 : 1,
795
+ percent: 0,
796
+ },
797
+ metadata: {
798
+ ...(interrupted
799
+ ? { executionPausedAt: new Date().toISOString() }
800
+ : {
801
+ executionError: message,
802
+ executionErroredAt: new Date().toISOString(),
803
+ }),
804
+ engine: options.engine,
805
+ ...(options.model ? { model: options.model } : {}),
806
+ },
807
+ });
808
+ }
809
+ const finalMessage = result.stdout.trim() || `${options.label} run completed.`;
810
+ appendCodeAgentTranscriptEvent({
811
+ runId: options.run.id,
812
+ kind: "system",
813
+ message: finalMessage,
814
+ metadata: {
815
+ role: "assistant",
816
+ engine: options.engine,
817
+ ...(options.model ? { model: options.model } : {}),
818
+ },
819
+ });
820
+ const pendingFollowUp = dequeueCodeAgentFollowUp(options.run.id);
821
+ if (pendingFollowUp) {
822
+ const message = pendingFollowUp.mode === "queued"
823
+ ? `${options.label} run completed; running queued follow-up.`
824
+ : `${options.label} run completed; applying steering follow-up.`;
825
+ appendCodeAgentTranscriptEvent({
826
+ runId: options.run.id,
827
+ kind: "status",
828
+ message,
829
+ metadata: {
830
+ status: "running",
831
+ phase: "follow-up",
832
+ followUpId: pendingFollowUp.id,
833
+ followUpMode: pendingFollowUp.mode,
834
+ engine: options.engine,
835
+ },
836
+ });
837
+ if (pendingFollowUp.permissionMode) {
838
+ updateCodeAgentRunRecord(options.run.id, {
839
+ permissionMode: pendingFollowUp.permissionMode,
840
+ });
841
+ }
842
+ return executeCodeAgentRun({
843
+ runId: options.run.id,
844
+ prompt: pendingFollowUp.prompt,
845
+ attachments: pendingFollowUp.attachments ??
846
+ userPromptAttachmentsForEvent(options.run.id, pendingFollowUp.eventId),
847
+ appendUserEvent: false,
848
+ stdout: options.stdout,
849
+ streamToolOutputToStdout: options.streamToolOutputToStdout,
850
+ signal: options.signal,
851
+ });
852
+ }
853
+ appendCodeAgentTranscriptEvent({
854
+ runId: options.run.id,
855
+ kind: "status",
856
+ message: `${options.label} run completed.`,
857
+ metadata: {
858
+ status: "completed",
859
+ phase: "complete",
860
+ engine: options.engine,
861
+ },
862
+ });
863
+ return updateCodeAgentRunRecord(options.run.id, {
864
+ status: "completed",
865
+ phase: "complete",
866
+ needsApproval: false,
867
+ progress: {
868
+ label: "Complete",
869
+ completed: 1,
870
+ total: 1,
871
+ percent: 100,
872
+ },
873
+ metadata: {
874
+ executionCompletedAt: new Date().toISOString(),
875
+ engine: options.engine,
876
+ ...(options.model ? { model: options.model } : {}),
877
+ permissionMode: options.permissionMode,
878
+ },
879
+ });
880
+ }
881
+ catch (error) {
882
+ const interrupted = options.signal?.aborted === true;
883
+ const message = error instanceof Error ? error.message : String(error);
884
+ const summary = interrupted
885
+ ? `${options.label} run paused.`
886
+ : `${options.label} run failed: ${message}`;
887
+ if (streamToolOutputToStdout)
888
+ options.stdout?.write(`\n${summary}\n`);
889
+ appendCodeAgentTranscriptEvent({
890
+ runId: options.run.id,
891
+ kind: "status",
892
+ message: summary,
893
+ metadata: {
894
+ status: interrupted ? "paused" : "errored",
895
+ phase: interrupted ? "paused" : "error",
896
+ engine: options.engine,
897
+ },
898
+ });
899
+ return updateCodeAgentRunRecord(options.run.id, {
900
+ status: interrupted ? "paused" : "errored",
901
+ phase: interrupted ? "paused" : "error",
902
+ progress: {
903
+ label: interrupted ? "Paused" : "Error",
904
+ completed: 0,
905
+ total: 1,
906
+ failed: interrupted ? 0 : 1,
907
+ percent: 0,
908
+ },
909
+ metadata: {
910
+ ...(interrupted
911
+ ? { executionPausedAt: new Date().toISOString() }
912
+ : {
913
+ executionError: message,
914
+ executionErroredAt: new Date().toISOString(),
915
+ }),
916
+ engine: options.engine,
917
+ ...(options.model ? { model: options.model } : {}),
918
+ },
919
+ });
920
+ }
921
+ }
922
+ function runLocalCliProcess(options) {
923
+ return new Promise((resolve) => {
924
+ let stdout = "";
925
+ let stderr = "";
926
+ let settled = false;
927
+ const child = spawn(options.command, options.args, {
928
+ cwd: options.cwd,
929
+ stdio: ["pipe", "pipe", "pipe"],
930
+ env: process.env,
931
+ });
932
+ const finish = (result) => {
933
+ if (settled)
934
+ return;
935
+ settled = true;
936
+ options.signal?.removeEventListener("abort", onAbort);
937
+ resolve({ ...result, stdout, stderr });
938
+ };
939
+ const onAbort = () => child.kill("SIGTERM");
940
+ if (options.signal) {
941
+ if (options.signal.aborted)
942
+ onAbort();
943
+ else
944
+ options.signal.addEventListener("abort", onAbort, { once: true });
945
+ }
946
+ child.stdout?.on("data", (chunk) => {
947
+ const text = chunk.toString();
948
+ stdout += text;
949
+ if (options.streamToolOutputToStdout ?? true) {
950
+ options.stdout?.write(text);
951
+ }
952
+ });
953
+ child.stderr?.on("data", (chunk) => {
954
+ const text = chunk.toString();
955
+ stderr += text;
956
+ if (options.streamToolOutputToStdout ?? true) {
957
+ options.stdout?.write(text);
958
+ }
959
+ });
960
+ child.on("error", (error) => finish({
961
+ exitCode: null,
962
+ exitSignal: null,
963
+ error: error.message,
964
+ }));
965
+ child.on("close", (exitCode, exitSignal) => finish({ exitCode, exitSignal }));
966
+ // Pi and OpenCode receive the prompt as a positional argument. Close the
967
+ // pipe without sending it a second time.
968
+ child.stdin?.end();
969
+ });
970
+ }
971
+ function buildLocalCliPrompt(run, prompt) {
972
+ return buildClaudeCliPrompt(run, prompt);
973
+ }
974
+ function normalizeLocalCliModel(model, engine) {
975
+ const trimmed = model?.trim();
976
+ if (!trimmed || trimmed === "auto" || trimmed === engine)
977
+ return undefined;
978
+ return trimmed;
979
+ }
980
+ function normalizePiCliThinking(effort) {
981
+ if (!effort || effort === "auto" || effort === "none")
982
+ return undefined;
983
+ return effort === "max" ? "xhigh" : effort;
984
+ }
985
+ function normalizeOpenCodeVariant(effort) {
986
+ if (!effort || effort === "auto" || effort === "none")
987
+ return undefined;
988
+ return effort;
989
+ }
672
990
  async function executeCodexCliRun(options) {
673
991
  const cwd = options.run.cwd || process.cwd();
674
992
  const outputDir = fs.mkdtempSync(path.join(os.tmpdir(), "agent-native-code-codex-"));
@@ -173,6 +173,18 @@ export interface AgentSidebarProps {
173
173
  onComposerTextChange?: AssistantChatProps["onComposerTextChange"];
174
174
  /** Optional secondary model menu shown inside the chat composer model picker. */
175
175
  imageModelMenu?: AssistantChatProps["imageModelMenu"];
176
+ /** Local or hosted agent runtimes shown above the model list. */
177
+ availableAgents?: AssistantChatProps["availableAgents"];
178
+ /** Selected agent runtime identifier. */
179
+ selectedAgent?: AssistantChatProps["selectedAgent"];
180
+ /** Callback when the user picks an agent runtime. */
181
+ onAgentChange?: AssistantChatProps["onAgentChange"];
182
+ /** Route local runtime setup through the host's native bridge. */
183
+ onConnectLocalRuntime?: AssistantChatProps["onConnectLocalRuntime"];
184
+ /** Bring-your-own runtime used by embedded hosts such as Electron. */
185
+ runtime?: AssistantChatProps["runtime"];
186
+ /** Explicit key for recreating an injected runtime adapter. */
187
+ adapterReloadKey?: AssistantChatProps["adapterReloadKey"];
176
188
  /** Optional content rendered at the bottom of the chat thread. */
177
189
  threadFooterSlot?: AssistantChatProps["threadFooterSlot"];
178
190
  /** Initial sidebar width in pixels. Mount-only; user resize and a saved
@@ -234,7 +246,7 @@ export interface AgentSidebarProps {
234
246
  * Wraps app content with a toggleable agent sidebar.
235
247
  * Use AgentToggleButton in your header to open/close it.
236
248
  */
237
- export declare function AgentSidebar({ children, emptyStateText, suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position, defaultOpen, animateMobile, animateDesktop, chatViewTransition, chatViewTransitionHandoff, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding, }: AgentSidebarProps): React.JSX.Element;
249
+ export declare function AgentSidebar({ children, emptyStateText, suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, availableAgents, selectedAgent, onAgentChange, onConnectLocalRuntime, runtime, adapterReloadKey, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position, defaultOpen, animateMobile, animateDesktop, chatViewTransition, chatViewTransitionHandoff, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding, }: AgentSidebarProps): React.JSX.Element;
238
250
  /**
239
251
  * Focus the agent chat composer input.
240
252
  * Opens the sidebar if closed, then focuses the text input.
@@ -44,6 +44,7 @@ import { withBuilderUtmTrackingParams } from "../shared/builder-link-tracking.js
44
44
  import { AGENT_SIDEBAR_MIN_WIDTH, consumeAgentSidebarUrlOpenOverride, clampAgentSidebarWidth, dispatchAgentSidebarStateChange, getAgentSidebarMaxWidth, getInitialAgentSidebarOpen, getAgentSidebarWideWidth, setAgentSidebarOpenPreference, subscribeAgentSidebarUrlChanges, SIDEBAR_STATE_CHANGE_EVENT, } from "./agent-sidebar-state.js";
45
45
  import { trackEvent } from "./analytics.js";
46
46
  import { agentNativePath, appPath, isWorkspaceAppPath } from "./api-path.js";
47
+ import { APP_CHAT_SIDEBAR_STATE_EVENT, APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE, buildAppChatSidebarStateMessage, isPerAppChatStorageKey, } from "./app-chat-sidebar.js";
47
48
  import { readClientAppState } from "./application-state.js";
48
49
  import { assistantUiRecoverableRenderErrorKind } from "./assistant-ui-recovery.js";
49
50
  import { shouldParentFrameOwnAgentPanel } from "./builder-frame.js";
@@ -65,6 +66,12 @@ const AgentTerminal = lazy(() => import("./terminal/index.js").then((m) => ({ de
65
66
  const AGENT_PANEL_PREPARE_EVENT = "agent-panel:prepare";
66
67
  const AGENT_PANEL_SET_MODE_EVENT = "agent-panel:set-mode";
67
68
  const AGENT_PANEL_OPEN_SETTINGS_EVENT = "agent-panel:open-settings";
69
+ function postPerAppChatSidebarStateToEmbeddedFrames(open) {
70
+ const message = buildAppChatSidebarStateMessage(open);
71
+ for (const frame of document.querySelectorAll("iframe")) {
72
+ frame.contentWindow?.postMessage(message, "*");
73
+ }
74
+ }
68
75
  function settingsRouteHashForSection(section) {
69
76
  const normalized = section?.replace(/^#/, "").toLowerCase() ?? "";
70
77
  if (normalized === "voice")
@@ -1407,8 +1414,9 @@ export function AgentChatSurface({ mode = "panel", className, defaultMode = "cha
1407
1414
  * Wraps app content with a toggleable agent sidebar.
1408
1415
  * Use AgentToggleButton in your header to open/close it.
1409
1416
  */
1410
- export function AgentSidebar({ children, emptyStateText = "How can I help you?", suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position = "right", defaultOpen = false, animateMobile = true, animateDesktop = true, chatViewTransition = false, chatViewTransitionHandoff = false, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar = true, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning = false, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding = false, }) {
1417
+ export function AgentSidebar({ children, emptyStateText = "How can I help you?", suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, availableAgents, selectedAgent, onAgentChange, onConnectLocalRuntime, runtime, adapterReloadKey, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position = "right", defaultOpen = false, animateMobile = true, animateDesktop = true, chatViewTransition = false, chatViewTransitionHandoff = false, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar = true, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning = false, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding = false, }) {
1411
1418
  const sidebarOpenStorageKey = openStorageKey ?? storageKey;
1419
+ const isPerAppChatSidebar = isPerAppChatStorageKey(sidebarOpenStorageKey);
1412
1420
  const onboardingPreviewMode = useOnboardingPreviewMode();
1413
1421
  const firstRunOnboardingGateOwnsSurface = useFirstRunOnboardingGateOwnsSurface();
1414
1422
  const showFirstRunOnboarding = !firstRunOnboardingGateOwnsSurface &&
@@ -1537,6 +1545,36 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1537
1545
  presentationMode,
1538
1546
  hasFrameSidebarState,
1539
1547
  ]);
1548
+ useEffect(() => {
1549
+ if (!isPerAppChatSidebar)
1550
+ return;
1551
+ const frameOwned = frameCodeMode && shouldParentFrameOwnAgentPanel();
1552
+ if (frameOwned && !hasFrameSidebarState)
1553
+ return;
1554
+ const openState = !presentationMode && (frameOwned ? frameSidebarOpen : open);
1555
+ const message = buildAppChatSidebarStateMessage(openState);
1556
+ window.dispatchEvent(new CustomEvent(APP_CHAT_SIDEBAR_STATE_EVENT, {
1557
+ detail: message.data,
1558
+ }));
1559
+ postPerAppChatSidebarStateToEmbeddedFrames(openState);
1560
+ const handleStateRequest = (event) => {
1561
+ if (event.data?.type !== APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE)
1562
+ return;
1563
+ const frame = Array.from(document.querySelectorAll("iframe")).find((candidate) => candidate.contentWindow === event.source);
1564
+ if (!frame)
1565
+ return;
1566
+ frame.contentWindow?.postMessage(message, event.origin || "*");
1567
+ };
1568
+ window.addEventListener("message", handleStateRequest);
1569
+ return () => window.removeEventListener("message", handleStateRequest);
1570
+ }, [
1571
+ frameCodeMode,
1572
+ frameSidebarOpen,
1573
+ hasFrameSidebarState,
1574
+ isPerAppChatSidebar,
1575
+ open,
1576
+ presentationMode,
1577
+ ]);
1540
1578
  useEffect(() => {
1541
1579
  const preparePanel = () => setBackgroundPanelActive(true);
1542
1580
  const handleChatRunning = (event) => {
@@ -1924,9 +1962,9 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1924
1962
  ? "mobile"
1925
1963
  : desktopAnimationEnabled
1926
1964
  ? "desktop"
1927
- : undefined, "data-agent-sidebar-layout": panelLayout, "data-agent-sidebar-position": position, "data-agent-sidebar-state": panelOpen ? "open" : "closed", "data-agent-sidebar-resizing": isResizing ? "true" : undefined, "data-agent-sidebar-chat-handoff": chatViewTransitionHandoff ? "true" : undefined, style: chatViewTransition
1965
+ : undefined, "data-agent-sidebar-layout": panelLayout, "data-agent-sidebar-position": position, "data-agent-sidebar-state": panelOpen ? "open" : "closed", "data-agent-sidebar-per-app-chat": isPerAppChatSidebar ? "true" : undefined, "data-agent-sidebar-resizing": isResizing ? "true" : undefined, "data-agent-sidebar-chat-handoff": chatViewTransitionHandoff ? "true" : undefined, style: chatViewTransition
1928
1966
  ? getAgentChatViewTransitionStyle(panelStyle)
1929
- : panelStyle, inert: sidebarAnimationEnabled && !panelOpen ? true : undefined, "aria-hidden": sidebarAnimationEnabled && !panelOpen ? true : undefined, children: _jsx("div", { className: "agent-sidebar-panel-inner flex min-h-0 flex-1 flex-col", children: _jsx(AgentPanel, { emptyStateText: emptyStateText, suggestions: suggestions, dynamicSuggestions: dynamicSuggestions, composerToolbarSlot: composerToolbarSlot, composerSlot: composerSlot, onComposerTextChange: onComposerTextChange, imageModelMenu: imageModelMenu, threadFooterSlot: threadFooterSlot, apiUrl: apiUrl, agentChatSurface: agentChatSurface, showTabBar: showTabBar, suppressInlineOpenApp: suppressInlineOpenApp, composerPlaceholder: composerPlaceholder, missingApiKeySetupLayout: "sidebar", onCollapse: () => setOpenPersisted(false), onSnapTo75Percent: isMobile ? undefined : snapTo75Percent, isWideDrawer: isMobile ? false : isWideDrawer, onExitWideDrawer: isMobile ? undefined : exitWideDrawer, onFullViewRequest: onFullscreenRequest, storageKey: storageKey, scope: scope, showScopeBadge: showScopeBadge, browserTabId: browserTabId, threadUrlSync: threadUrlSync, agentPageHref: agentPageHref, allowSettingsMode: false, chatOnly: true }) }) }), showResizeHandle && isLeft && (_jsx(ResizeHandle, { position: position, onDrag: handleDrag, onResizeStart: handleResizeStart, onResizeEnd: handleResizeEnd }))] })) : null;
1967
+ : panelStyle, inert: sidebarAnimationEnabled && !panelOpen ? true : undefined, "aria-hidden": sidebarAnimationEnabled && !panelOpen ? true : undefined, children: _jsx("div", { className: "agent-sidebar-panel-inner flex min-h-0 flex-1 flex-col", children: _jsx(AgentPanel, { emptyStateText: emptyStateText, suggestions: suggestions, dynamicSuggestions: dynamicSuggestions, composerToolbarSlot: composerToolbarSlot, composerSlot: composerSlot, onComposerTextChange: onComposerTextChange, imageModelMenu: imageModelMenu, availableAgents: availableAgents, selectedAgent: selectedAgent, onAgentChange: onAgentChange, onConnectLocalRuntime: onConnectLocalRuntime, runtime: runtime, adapterReloadKey: adapterReloadKey, threadFooterSlot: threadFooterSlot, apiUrl: apiUrl, agentChatSurface: agentChatSurface, showTabBar: showTabBar, suppressInlineOpenApp: suppressInlineOpenApp, composerPlaceholder: composerPlaceholder, missingApiKeySetupLayout: "sidebar", onCollapse: () => setOpenPersisted(false), onSnapTo75Percent: isMobile ? undefined : snapTo75Percent, isWideDrawer: isMobile ? false : isWideDrawer, onExitWideDrawer: isMobile ? undefined : exitWideDrawer, onFullViewRequest: onFullscreenRequest, storageKey: storageKey, scope: scope, showScopeBadge: showScopeBadge, browserTabId: browserTabId, threadUrlSync: threadUrlSync, agentPageHref: agentPageHref, allowSettingsMode: false, chatOnly: true }) }) }), showResizeHandle && isLeft && (_jsx(ResizeHandle, { position: position, onDrag: handleDrag, onResizeStart: handleResizeStart, onResizeEnd: handleResizeEnd }))] })) : null;
1930
1968
  const drawerPlaceholder = wideDrawerEnabled && !presentationMode && panelOpen ? (_jsx("div", { "aria-hidden": "true", className: "agent-sidebar-drawer-placeholder shrink-0", "data-agent-sidebar-placeholder": "true", style: { width: drawerPlaceholderWidth + 1 } })) : null;
1931
1969
  return (_jsx(AgentSidebarOnboardingContext.Provider, { value: true, children: _jsxs(RealtimeVoiceModeProvider, { browserTabId: browserTabId, children: [showFirstRunOnboarding && (_jsx(Suspense, { fallback: null, children: _jsx(FirstRunOnboarding, {}) })), _jsxs("div", { className: "agent-sidebar-shell flex min-w-0 flex-1 h-screen overflow-hidden", "data-agent-sidebar-position": position, "data-agent-sidebar-resizing": isResizing ? "true" : undefined, children: [isMobile &&
1932
1970
  !presentationMode &&
@@ -1,4 +1,4 @@
1
- import type { ComposerImageModelMenu } from "@agent-native/toolkit/composer/TiptapComposer";
1
+ import type { ComposerAgentOption, ComposerImageModelMenu } from "@agent-native/toolkit/composer/TiptapComposer";
2
2
  import type { ChatModelAdapter, ExportedMessageRepository } from "@assistant-ui/react";
3
3
  import React from "react";
4
4
  import type { ReasoningEffort } from "../shared/reasoning-effort.js";
@@ -262,6 +262,8 @@ export interface AssistantChatProps {
262
262
  threadId?: string;
263
263
  /** Resource scope to include with chat requests for server-side context. */
264
264
  contextScope?: ChatThreadScope | null;
265
+ /** Namespace used to hide ambient composer context from other host surfaces. */
266
+ contextNamespace?: string;
265
267
  /** Whether this chat owns the active visible composer context snapshot. */
266
268
  isActiveComposer?: boolean;
267
269
  /**
@@ -363,6 +365,12 @@ export interface AssistantChatProps {
363
365
  onModelChange?: (model: string, engine: string) => void;
364
366
  /** Callback when user picks an effort from the picker */
365
367
  onEffortChange?: (effort: ReasoningEffort) => void;
368
+ /** Local or hosted agent runtimes shown above the model list. */
369
+ availableAgents?: ComposerAgentOption[];
370
+ /** Selected agent runtime identifier. */
371
+ selectedAgent?: string;
372
+ /** Callback when the user picks an agent runtime. */
373
+ onAgentChange?: (agent: string) => void;
366
374
  /**
367
375
  * Optional secondary model menu (e.g. an image-generation model) shown inside
368
376
  * the composer's model picker. Opt-in; chat-only apps omit it.