@truefoundry/trueforge-ui 0.3.0-rc.1 → 0.3.0-rc.10

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 (111) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/README.md +23 -8
  3. package/dist/{AgentCodeSnippets-NZOFJE57.js → AgentCodeSnippets-RJBB4DDE.js} +38 -23
  4. package/dist/AgentCodeSnippets-RJBB4DDE.js.map +1 -0
  5. package/dist/AgentMetricChart-UPGSJ2WP.js +15 -0
  6. package/dist/{AgentOverview-EEBHJC32.js → AgentOverview-U5WIQXZN.js} +11 -9
  7. package/dist/AgentOverview-U5WIQXZN.js.map +1 -0
  8. package/dist/{AgentSessionEventTimeline-26Z6IB3B.js → AgentSessionEventTimeline-GRGIQTRE.js} +19 -10
  9. package/dist/AgentSessionEventTimeline-GRGIQTRE.js.map +1 -0
  10. package/dist/{AgentSessionEventTimelineChart-CGCU7WBK.js → AgentSessionEventTimelineChart-GNF4VOUT.js} +144 -57
  11. package/dist/AgentSessionEventTimelineChart-GNF4VOUT.js.map +1 -0
  12. package/dist/{AgentSessions-3MPDZASK.js → AgentSessions-5OTF2BUW.js} +72 -24
  13. package/dist/AgentSessions-5OTF2BUW.js.map +1 -0
  14. package/dist/{ConnectorSettings-MXFRWWR6.js → ConnectorSettings-HDKGLDCY.js} +162 -126
  15. package/dist/ConnectorSettings-HDKGLDCY.js.map +1 -0
  16. package/dist/{DockLayout-LM4AFMFY.js → DockLayout-D2FPQCAL.js} +10 -10
  17. package/dist/{DrawerLayout-JR3O6RRB.js → DrawerLayout-HUV7RAWL.js} +14 -12
  18. package/dist/DrawerLayout-HUV7RAWL.js.map +1 -0
  19. package/dist/{ModelSettings-G7IFNC2Y.js → ModelSettings-VNQ7HPKH.js} +22 -28
  20. package/dist/ModelSettings-VNQ7HPKH.js.map +1 -0
  21. package/dist/OpenUiFenceBlock-KPZFLUSC.js +9 -0
  22. package/dist/{SandboxSettings-NXAANMAX.js → SandboxSettings-ZLXGMFBF.js} +17 -21
  23. package/dist/SandboxSettings-ZLXGMFBF.js.map +1 -0
  24. package/dist/SchedulesPage-QKYI2Z3A.js +15 -0
  25. package/dist/{SettingsBuilder-L34IQ56S.js → SettingsBuilder-RVVYXOJW.js} +9 -9
  26. package/dist/{SettingsBuilder-L34IQ56S.js.map → SettingsBuilder-RVVYXOJW.js.map} +1 -1
  27. package/dist/{ShellRouteSync-CEBETGEJ.js → ShellRouteSync-SJXFKUAJ.js} +171 -26
  28. package/dist/ShellRouteSync-SJXFKUAJ.js.map +1 -0
  29. package/dist/{SidebarLayout-A2HJPPHS.js → SidebarLayout-KYA76FQ7.js} +80 -58
  30. package/dist/SidebarLayout-KYA76FQ7.js.map +1 -0
  31. package/dist/{SkillSettings-FGGMSUNO.js → SkillSettings-7OHT7FPI.js} +24 -22
  32. package/dist/SkillSettings-7OHT7FPI.js.map +1 -0
  33. package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js → TrueForgeUIWithRouter-LKG4XLW6.js} +9 -9
  34. package/dist/{WidgetLayout-6QM45OQQ.js → WidgetLayout-W2RGGOQ3.js} +10 -10
  35. package/dist/{chunk-U7KURWW3.js → chunk-2GIZY3JJ.js} +276 -54
  36. package/dist/chunk-2GIZY3JJ.js.map +1 -0
  37. package/dist/{chunk-WVE3F724.js → chunk-2QTH6JHX.js} +21 -4
  38. package/dist/chunk-2QTH6JHX.js.map +1 -0
  39. package/dist/{chunk-XAU7QFG3.js → chunk-3ZW74FHC.js} +68 -256
  40. package/dist/chunk-3ZW74FHC.js.map +1 -0
  41. package/dist/{chunk-FJW36PD7.js → chunk-67ZO7Z2W.js} +28 -24
  42. package/dist/chunk-67ZO7Z2W.js.map +1 -0
  43. package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
  44. package/dist/chunk-7AAO4UDQ.js.map +1 -0
  45. package/dist/{chunk-MPNSO7E6.js → chunk-CG75X77Q.js} +2 -2
  46. package/dist/chunk-DPPOEFBD.js +517 -0
  47. package/dist/chunk-DPPOEFBD.js.map +1 -0
  48. package/dist/{chunk-6O6FWUDW.js → chunk-EPAL2HD5.js} +641 -388
  49. package/dist/chunk-EPAL2HD5.js.map +1 -0
  50. package/dist/{chunk-ZTMKFZQ3.js → chunk-GG23N2GW.js} +5099 -3295
  51. package/dist/chunk-GG23N2GW.js.map +1 -0
  52. package/dist/chunk-JCL3Q7RW.js +587 -0
  53. package/dist/chunk-JCL3Q7RW.js.map +1 -0
  54. package/dist/{chunk-M62XY4NC.js → chunk-JKEBMGLH.js} +235 -108
  55. package/dist/chunk-JKEBMGLH.js.map +1 -0
  56. package/dist/{chunk-DMMZSZTN.js → chunk-KSGNKS2D.js} +60 -16
  57. package/dist/chunk-KSGNKS2D.js.map +1 -0
  58. package/dist/{chunk-CYHJDKFB.js → chunk-PCI6VMB5.js} +189 -52
  59. package/dist/chunk-PCI6VMB5.js.map +1 -0
  60. package/dist/{chunk-ZKNUMH2M.js → chunk-PQ7VWBQQ.js} +13 -11
  61. package/dist/chunk-PQ7VWBQQ.js.map +1 -0
  62. package/dist/chunk-T6QQV5LK.js +238 -0
  63. package/dist/chunk-T6QQV5LK.js.map +1 -0
  64. package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
  65. package/dist/index.d.ts +369 -108
  66. package/dist/index.js +69 -488
  67. package/dist/index.js.map +1 -1
  68. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +49 -14
  69. package/dist/plugins/trueforge-agent-server-adapter/index.js +138 -50
  70. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  71. package/dist/styles.css +1 -1
  72. package/package.json +5 -4
  73. package/dist/AgentCodeSnippets-NZOFJE57.js.map +0 -1
  74. package/dist/AgentMetricChart-JPU3MFQ2.js +0 -15
  75. package/dist/AgentOverview-EEBHJC32.js.map +0 -1
  76. package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +0 -1
  77. package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +0 -1
  78. package/dist/AgentSessions-3MPDZASK.js.map +0 -1
  79. package/dist/ConnectorSettings-MXFRWWR6.js.map +0 -1
  80. package/dist/DrawerLayout-JR3O6RRB.js.map +0 -1
  81. package/dist/ModelSettings-G7IFNC2Y.js.map +0 -1
  82. package/dist/OpenUiFenceBlock-2TV5TQ6P.js +0 -9
  83. package/dist/SandboxSettings-NXAANMAX.js.map +0 -1
  84. package/dist/SchedulesPage-KKLUDO6B.js +0 -15
  85. package/dist/ShellRouteSync-CEBETGEJ.js.map +0 -1
  86. package/dist/SidebarLayout-A2HJPPHS.js.map +0 -1
  87. package/dist/SkillSettings-FGGMSUNO.js.map +0 -1
  88. package/dist/chunk-2XPPBEYF.js +0 -74
  89. package/dist/chunk-2XPPBEYF.js.map +0 -1
  90. package/dist/chunk-6O6FWUDW.js.map +0 -1
  91. package/dist/chunk-7Z2C2K7F.js +0 -578
  92. package/dist/chunk-7Z2C2K7F.js.map +0 -1
  93. package/dist/chunk-CYHJDKFB.js.map +0 -1
  94. package/dist/chunk-DMMZSZTN.js.map +0 -1
  95. package/dist/chunk-FJW36PD7.js.map +0 -1
  96. package/dist/chunk-M62XY4NC.js.map +0 -1
  97. package/dist/chunk-QC42MLAK.js.map +0 -1
  98. package/dist/chunk-SFZNIO6U.js +0 -18
  99. package/dist/chunk-SFZNIO6U.js.map +0 -1
  100. package/dist/chunk-U7KURWW3.js.map +0 -1
  101. package/dist/chunk-WVE3F724.js.map +0 -1
  102. package/dist/chunk-XAU7QFG3.js.map +0 -1
  103. package/dist/chunk-ZKNUMH2M.js.map +0 -1
  104. package/dist/chunk-ZTMKFZQ3.js.map +0 -1
  105. /package/dist/{AgentMetricChart-JPU3MFQ2.js.map → AgentMetricChart-UPGSJ2WP.js.map} +0 -0
  106. /package/dist/{DockLayout-LM4AFMFY.js.map → DockLayout-D2FPQCAL.js.map} +0 -0
  107. /package/dist/{OpenUiFenceBlock-2TV5TQ6P.js.map → OpenUiFenceBlock-KPZFLUSC.js.map} +0 -0
  108. /package/dist/{SchedulesPage-KKLUDO6B.js.map → SchedulesPage-QKYI2Z3A.js.map} +0 -0
  109. /package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js.map → TrueForgeUIWithRouter-LKG4XLW6.js.map} +0 -0
  110. /package/dist/{WidgetLayout-6QM45OQQ.js.map → WidgetLayout-W2RGGOQ3.js.map} +0 -0
  111. /package/dist/{chunk-MPNSO7E6.js.map → chunk-CG75X77Q.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,148 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0-rc.10
4
+
5
+ ### Patch Changes
6
+
7
+ - 584e815: Gate Save Agent (create) on tenant CREATE from list-permissions, keep Update Agent on agent MANAGE, unwrap `{ type, permissions }`, and bump `@truefoundry/assistant-ui-runtime` to `0.1.39`.
8
+
9
+ ## 0.3.0-rc.9
10
+
11
+ ### Patch Changes
12
+
13
+ - fd1bf7f: Bump `@truefoundry/assistant-ui-runtime` to `0.1.38` for assistant completion timestamps and keep-alive turn streams on session switch.
14
+ - 079f832: Show an optional tooltip when sandbox artifact downloads are read-only.
15
+ - Updated dependencies [648273b]
16
+ - Updated dependencies [134dcb9]
17
+ - @truefoundry/trueforge-sdk@0.2.0-rc.8
18
+
19
+ ## 0.3.0-rc.8
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [648273b]
24
+ - @truefoundry/trueforge-sdk@0.2.0-rc.7
25
+
26
+ ## 0.3.0-rc.7
27
+
28
+ ### Patch Changes
29
+
30
+ - 531f0ce: Keep close-on-click dropdown menus and bottom sheets open when a click or drag lands on their own scrollbar, so scrolling a long menu no longer dismisses it before a choice is made.
31
+ - 531f0ce: Cap the skill version menu height and scroll it, so skills with many versions no longer run off screen. While it is open, scrolling is confined to the menu.
32
+ - Updated dependencies [648273b]
33
+ - @truefoundry/trueforge-sdk@0.2.0-rc.6
34
+
35
+ ## 0.3.0-rc.6
36
+
37
+ ### Patch Changes
38
+
39
+ - 8c31eae: Round-trip agent description through save/load and show it in the library and agent details.
40
+ - d7136a1: Avatar fallbacks use a light primary-button gradient in light mode, a solid primary gradient in dark mode, and show a single initial character.
41
+ - d7136a1: Assistant message loading indicator uses ThinkingOrb with left-to-right shimmering Working... text.
42
+ - b316430: Slide SideDrawer/BottomSheet and add a light fade+scale enter on dropdowns and popup cards.
43
+ - dc2151f: Paginate `GET /api/v1/agents` with `limit` / `page_token` and a `pagination` envelope; optional `agent_name` filters by case-insensitive substring. Agents library uses rows-per-page and prev/next against the token-paginated API. Schedule create and the schedules listing agent filter use a searchable agent combobox backed by the same filtered list API.
44
+ - d7136a1: Flip PopoverSelect menus when the preferred side lacks viewport room (e.g. table rows-per-page).
45
+ - 04460fb: Prevent the schedule search field from shrinking and clipping its placeholder.
46
+ - fa0730b: Reduce the agent code snippet font size to match its surrounding controls.
47
+ - d7136a1: Stop draining the full agents catalog on Schedules mount; load agents only when the filter opens (infinite scroll).
48
+ - d7136a1: Settings sidebar uses a subtle primary tint for the selected section instead of a solid fill.
49
+ - Updated dependencies [648273b]
50
+ - Updated dependencies [9501536]
51
+ - Updated dependencies [dc2151f]
52
+ - @truefoundry/trueforge-sdk@0.2.0-rc.5
53
+
54
+ ## 0.3.0-rc.5
55
+
56
+ ### Patch Changes
57
+
58
+ - 4e72afc: Announce boot loading with a light-themed orb for contrast outside ThemeProvider.
59
+ - ea86853: Move the agent metrics time range filter into the active Metrics tab row.
60
+ - 98ab384: Preserve the active agent draft when returning to Build Agent from another page.
61
+ - 4e72afc: Use an animated thinking orb for application boot and server initialization.
62
+
63
+ ## 0.3.0-rc.4
64
+
65
+ ### Patch Changes
66
+
67
+ - 629b6e9: Paginate the Agent Sessions list on scroll instead of a "Load more" button, showing a skeleton row while the next page loads.
68
+ - 629b6e9: Fix Agents library table scrolling when rows exceed the viewport
69
+ - 629b6e9: Show Created by (avatar + name) on Agents and Schedules tables when creator info is present.
70
+ - 629b6e9: Portal PopoverSelect menus so table page-size and other selects are not clipped by overflow parents.
71
+ - ef278dd: Stop highlighting New Chat while trying a named agent, and clear the Try Agent URL and history filter when starting a new chat.
72
+ - ceeb56f: Show turn and duration statistics alongside the featured agent metric cards.
73
+ - Updated dependencies [648273b]
74
+ - @truefoundry/trueforge-sdk@0.2.0-rc.4
75
+
76
+ ## 0.3.0-rc.3
77
+
78
+ ### Minor Changes
79
+
80
+ - 1d31116: Open agent model settings inline and support typed custom model parameters.
81
+ - 74eae6c: Remove pagination from list MCP servers across the API, SDK, and UI; return and search the complete configured MCP catalog client-side.
82
+ - 12b02ff: Open Runtime Config in a right-side drawer and label scheduled sessions consistently.
83
+ - 7e25f68: Open Save Agent in a right-side drawer with only the agent name while preserving configuration from Agent Config.
84
+ - f8b5eeb: Add optional resource permissions and gate agent, schedule, and session mutations.
85
+
86
+ ### Patch Changes
87
+
88
+ - 762ecc0: TrueFoundry skills catalog: proxy GET /skills and /skills/versions from ServiceFoundry; settings skill writes return 424. SkillManifest is a type-discriminated oneOf of GitSkill | TrueFoundryRegistrySkill (`type: truefoundry`; name is FQN, display_name is short). AvailableSkill exposes optional metadata (display_name, repository_name, version). AgentSpec skill refs allow opaque FQN names, optional preload (registry), and max 50. UI draft skill mounts map catalog `id` to AgentSpec `name`.
89
+ - 26a9b80: Add an agent-scoped Schedules tab and route library schedule actions into it.
90
+ - 1b8a3f7: Add documentation links to the code snippets view and shell actions.
91
+ - d2fdfc9: Add agent-filtered chat history labels, preserve Try Agent and explicit history-filter intent in URL query state while resolving backend IDs, reset active chats when users change filters, keep Try Agent highlighted as chat, and route fresh agent builders at `/build-agent` before their session URL is assigned.
92
+ - 26a9b80: Allow sending user messages that contain attachments without text.
93
+ - 26a9b80: Add an empty state and Build Agent action to the schedule agent picker.
94
+ - 4c522e2: Bump `@truefoundry/assistant-ui-runtime` to `0.1.30`.
95
+ - 4c522e2: Bump `@truefoundry/assistant-ui-runtime` to `0.1.31`.
96
+ - d719155: Keep composer catalogs cached when starting a new chat.
97
+ - c0359ca: Strip a trailing slash from the `base_url` passed to agent code-snippets.
98
+ - 57f1fc2: Improve compact agent building with model configuration bottom sheets, provider-first model selection, and a contextual composer actions menu.
99
+ - e3973a5: Show the selected connector and skill count beside the composer tools icon.
100
+ - 26a9b80: Hide model selection in the Build Agent composer and correct concurrent sub-agent timeline bars.
101
+ - 26a9b80: Require direct switch clicks in the Runtime Config sidebar.
102
+ - 1ec19f0: Replace API key replacement with connector configuration editing from the connector list and details view.
103
+ - b482cdd: Show the four primary agent metrics in a compact summary-card layout.
104
+ - b32d2be: Filter chat history to sessions created by the current user, and bump `@truefoundry/assistant-ui-runtime` to `0.1.34`.
105
+ - a9430bd: Accept optional `base_url` on agent code-snippets (FE public host); fall back to request origin + `PUBLIC_BASE_URL` path.
106
+ - 54e4ec4: Keep Settings hidden until the server explicitly enables it.
107
+ - 4c522e2: Hide session cost metrics when cost data is unavailable.
108
+ - 4e7b67a: Check live per-user MCP authentication before loading tools in the agent builder.
109
+ - d2fdfc9: Section MCP tools in the Build Agent selector by read-only, others, and destructive annotations, with a read-only enable-all toggle.
110
+ - 26a9b80: Show agent names without an icon in the Agents table.
111
+ - 4cea38c: Show draft and named sessions in the history panel, exclude agent-builder sessions, cache session pages, and switch history sessions in place without remounting the chat runtime.
112
+ - 2284d3b: Polish the MCP tool selector controls, loading state, and API error messages.
113
+ - e3973a5: Group schedule recurrence controls and display the cadence in an attached summary footer.
114
+ - f2ca338: Show active/paused schedule counts in the Agents library, pin selected MCPs when reopening the tools modal, and align paused schedule badge colors.
115
+ - 77c5c33: Show TrueFoundry skill repositories and versions in skill pickers, load version choices lazily, preserve the chosen version FQN when attaching skills, keep picker ordering stable while open, and add registry-only preload controls to selected skill pills.
116
+ - 26a9b80: Show weekly schedule days before the time controls.
117
+ - 1b8a3f7: Match the Build Agent configuration panel width to the agent playground and identify sessions created by schedule runs.
118
+ - adaf532: Widen the sidebar rail and its nav buttons so labels like "Build Agent" have more breathing room.
119
+ - Updated dependencies [648273b]
120
+ - Updated dependencies [648273b]
121
+ - Updated dependencies [648273b]
122
+ - Updated dependencies [74eae6c]
123
+ - Updated dependencies [44f9cbe]
124
+ - @truefoundry/trueforge-sdk@0.2.0-rc.3
125
+
126
+ ## 0.3.0-rc.2
127
+
128
+ ### Minor Changes
129
+
130
+ - 04d2ee6: Add a `sidebarText` semantic token for sidebar nav labels, refresh trueforge sidebar colors, set trueforge base `radius` to `0.375rem` (6px), and set sidebar / thread-list control corners to `0.75rem` (12px).
131
+
132
+ Expose design-system `Button` (`Button.Primary` / `.Secondary` / `.Ghost` / `.Destructive`). `ButtonVariant` is now `primary | secondary | ghost | destructive` (`default` renamed to `primary`; `outline` removed — use `secondary`). Button sizes are `large` (default) and `small` (`icon` for icon-only).
133
+
134
+ ### Patch Changes
135
+
136
+ - 2a0ae4c: Show connector catalog logos in the composer Tools picker, matching the Connectors settings page.
137
+ - 2a0ae4c: Align AttachmentCard with assistant-ui's default square thumbnail, filename tooltip, and overlay remove control.
138
+ - fe6a14b: Improve session timelines with sub-agent wait states, grouped point-event markers, clean linear ticks, and readable summary durations.
139
+ - d5b479d: Clamp optional sessions/schedules chrome and unregister `/sessions`, `/schedules`, and `/library/:agentId` when those server ports are omitted, matching the Settings Lego gate.
140
+ - 5d72138: Keep `npx @truefoundry/trueforge` working on native Windows: import Kysely migrations with `pathToFileURL`, and keep sandbox guest paths POSIX. Source development stays Unix/WSL; CI also runs unit and SQLite store tests on Windows.
141
+ - Updated dependencies [a000b47]
142
+ - Updated dependencies [0ec8dc6]
143
+ - Updated dependencies [11865b4]
144
+ - @truefoundry/trueforge-sdk@0.1.4-rc.2
145
+
3
146
  ## 0.3.0-rc.1
4
147
 
5
148
  ### Minor Changes
package/README.md CHANGED
@@ -407,7 +407,7 @@ show the title text (see [Custom layouts](#custom-layouts)).
407
407
 
408
408
  In library modes, picking an agent from Agents switches to a named chat for that agent **and remounts the runtime** so the new agent starts from a clean conversation. Draft chats can be promoted via **Save agent** (`server.saveAgent` on the resolved `AgentUIServer`). **Clear Chat** (thread header) resets the current named or draft session.
409
409
 
410
- Mutable composers expose **Agent Config** for live model parameters, instructions, runtime behavior, per-connector MCP tools, and skills. The compact Tools picker contains only Connectors and Skills. The Save Agent dialog keeps a local editable copy of the same configuration and shares the same selector dialogs; cancelling it leaves the active draft unchanged. Model context and output limits render when the server supplies that optional catalog metadata.
410
+ Mutable composers expose **Agent Config** for live model parameters, instructions, runtime behavior, per-connector MCP tools, and skills. Runtime Config opens in a second right-side drawer. The compact Tools picker contains only Connectors and Skills. The Save Agent drawer only edits the agent name while preserving the active draft configuration; cancelling it discards that local edit. Model context and output limits render when the server supplies that optional catalog metadata.
411
411
 
412
412
  ```tsx
413
413
  {
@@ -446,12 +446,12 @@ Mutable composers expose **Agent Config** for live model parameters, instruction
446
446
 
447
447
  Built-in `layout` values:
448
448
 
449
- | Value | Description |
450
- | --------- | -------------------------------------------------------- |
451
- | `sidebar` | Left session list + main thread (ChatGPT / Claude style) |
452
- | `drawer` | Full-bleed thread; sessions open in a slide-over |
453
- | `dock` | Fixed-width right panel; list XOR thread stack |
454
- | `widget` | Same stack as `dock`, opened from a bottom-right FAB |
449
+ | Value | Description |
450
+ | --------- | ---------------------------------------------------- |
451
+ | `sidebar` | Icon rail + recent session history + active thread |
452
+ | `drawer` | Full-bleed thread; sessions open in a slide-over |
453
+ | `dock` | Fixed-width right panel; list XOR thread stack |
454
+ | `widget` | Same stack as `dock`, opened from a bottom-right FAB |
455
455
 
456
456
  ---
457
457
 
@@ -517,7 +517,7 @@ function MyBubble({ children, error, actionBar, className }: AssistantMessageBub
517
517
  />;
518
518
  ```
519
519
 
520
- Overridable slots include composer pieces (`ComposerShell`, `ComposerLeftSection`, `ComposerRightSection`, `ComposerSendButton`), messages (`AssistantMessageBubble`, `UserMessageBubble`, `UserMessageEdit`), `Markdown`, `WelcomeScreen`, thread-list atoms, agent metrics (`AgentMetrics`, `AgentMetricsView`, `AgentMetricsTimeRangeFilter`, `AgentMetricCard`, `AgentMetricChart`), and tool/prompt cards (`ToolCallCard`, `ToolApprovalBar`, `ToolGroupCard`, `SubAgentCard`, `SandboxToolCallCard`, `AgentStepsCard`, `ReasoningCard`, `AskUserPrompt`, `McpAuthPrompt`, and more).
520
+ Overridable slots include composer pieces (`ComposerShell`, `ComposerLeftSection`, `ComposerRightSection`, `ComposerSendButton`), messages (`AssistantMessageBubble`, `UserMessageBubble`, `UserMessageEdit`), `Markdown`, `WelcomeScreen`, thread-list atoms, agent metrics (`AgentMetrics`, `AgentMetricsView`, `AgentMetricsTimeRangeFilter`, `AgentMetricCard`, `AgentMetricStatistics`, `AgentMetricChart`), and tool/prompt cards (`ToolCallCard`, `ToolApprovalBar`, `ToolGroupCard`, `SubAgentCard`, `SandboxToolCallCard`, `AgentStepsCard`, `ReasoningCard`, `AskUserPrompt`, `McpAuthPrompt`, and more).
521
521
 
522
522
  See [docs/customization.md](./docs/customization.md) for the full slot list.
523
523
 
@@ -535,6 +535,7 @@ type TrueForgeServerConfig =
535
535
  apiKey: string;
536
536
  controlPlaneURL: string;
537
537
  gatewayPlaneURL?: string;
538
+ permissions?: PermissionsServer;
538
539
  }
539
540
  | {
540
541
  type: 'trueforge';
@@ -542,6 +543,7 @@ type TrueForgeServerConfig =
542
543
  token?: string;
543
544
  fetch?: typeof fetch;
544
545
  catalog?: CatalogServer;
546
+ permissions?: PermissionsServer;
545
547
  }
546
548
  | AgentUIServer;
547
549
 
@@ -550,6 +552,8 @@ type AgentUIServer = AgentChatServer &
550
552
  catalog?: CatalogServer;
551
553
  sessions?: AgentSessionsServer;
552
554
  metrics?: AgentMetricsServer;
555
+ schedules?: ScheduleServer;
556
+ permissions?: PermissionsServer;
553
557
  };
554
558
  ```
555
559
 
@@ -557,7 +561,18 @@ type AgentUIServer = AgentChatServer &
557
561
  | -------------------- | ------------------------------------------------------------------- |
558
562
  | `AgentChatServer` | Sessions, turns, streaming, draft `AgentSpec` sync |
559
563
  | `AgentBuilderServer` | `getModels` / `getSkills` / `getMcp` / `searchAgents` / `saveAgent` |
564
+ | `catalog` | Settings CRUD (models / connectors / optional skills & sandbox) |
565
+ | `sessions` | Agent details + sessions browser (`/sessions`, `/library/:agentId`) |
566
+ | `schedules` | Schedules page (`/schedules`) |
560
567
  | `AgentMetricsServer` | Agent meter aggregates, chart definitions, and chart data |
568
+ | `PermissionsServer` | Per-resource `USE`, `MANAGE`, and `DELETE` grants |
569
+
570
+ Omit a chrome port such as `catalog` or `schedules` to hide and unregister its routes.
571
+
572
+ When `permissions` is omitted from a custom or TrueFoundry server, actions remain enabled for backward compatibility.
573
+ When provided, denied mutation controls stay visible but disabled with an explanatory tooltip. The built-in
574
+ `type: "trueforge"` server enables checks automatically through the Harness permissions endpoint; an explicit
575
+ `PermissionsServer` overrides that default.
561
576
 
562
577
  **Zero-config TrueFoundry** — see [Getting started](#getting-started). The SDK calls `createTrueFoundryAgentUIServer` for you.
563
578
 
@@ -1,17 +1,17 @@
1
1
  "use client";
2
2
  import {
3
3
  useSlot
4
- } from "./chunk-ZTMKFZQ3.js";
5
- import "./chunk-2XPPBEYF.js";
4
+ } from "./chunk-GG23N2GW.js";
5
+ import "./chunk-T6QQV5LK.js";
6
6
  import {
7
7
  Icon
8
- } from "./chunk-XAU7QFG3.js";
9
- import "./chunk-U7KURWW3.js";
8
+ } from "./chunk-3ZW74FHC.js";
9
+ import "./chunk-2GIZY3JJ.js";
10
10
  import "./chunk-M6MHLVSO.js";
11
- import "./chunk-MPNSO7E6.js";
11
+ import "./chunk-CG75X77Q.js";
12
12
  import {
13
13
  cn
14
- } from "./chunk-7Z2C2K7F.js";
14
+ } from "./chunk-JCL3Q7RW.js";
15
15
 
16
16
  // src/atoms/agent-details/AgentCodeSnippets.tsx
17
17
  import { useEffect, useState } from "react";
@@ -48,22 +48,37 @@ function AgentCodeSnippets({ snippets }) {
48
48
  snippet.language
49
49
  )) }),
50
50
  /* @__PURE__ */ jsxs("section", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden rounded-lg border border-border bg-card-bg", children: [
51
- /* @__PURE__ */ jsx("div", { className: "flex h-10 shrink-0 items-end gap-1 border-b border-border px-3", children: [
52
- ["stream", "Stream"],
53
- ["nonStream", "Non-stream"]
54
- ].map(([id, label]) => /* @__PURE__ */ jsx(
55
- "button",
56
- {
57
- type: "button",
58
- className: cn(
59
- "relative h-10 cursor-pointer px-3 text-xs font-medium text-text-secondary",
60
- mode === id && "text-primary-button-bg after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:bg-primary-button-bg"
61
- ),
62
- onClick: () => setMode(id),
63
- children: label
64
- },
65
- id
66
- )) }),
51
+ /* @__PURE__ */ jsxs("div", { className: "flex h-10 shrink-0 items-center justify-between gap-1 border-b border-border px-3", children: [
52
+ /* @__PURE__ */ jsx("div", { className: "flex items-end gap-1", children: [
53
+ ["stream", "Stream"],
54
+ ["nonStream", "Non-stream"]
55
+ ].map(([id, label]) => /* @__PURE__ */ jsx(
56
+ "button",
57
+ {
58
+ type: "button",
59
+ className: cn(
60
+ "relative h-10 cursor-pointer px-3 text-xs font-medium text-text-secondary",
61
+ mode === id && "text-primary-button-bg after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:bg-primary-button-bg"
62
+ ),
63
+ onClick: () => setMode(id),
64
+ children: label
65
+ },
66
+ id
67
+ )) }),
68
+ /* @__PURE__ */ jsxs(
69
+ "a",
70
+ {
71
+ href: "https://trueforge.dev/api/use-agent",
72
+ target: "_blank",
73
+ rel: "noopener noreferrer",
74
+ className: "flex items-center gap-1 text-xs text-text-secondary",
75
+ children: [
76
+ /* @__PURE__ */ jsx("span", { children: "View Docs" }),
77
+ /* @__PURE__ */ jsx(Icon, { name: "external-link", className: "size-3 shrink-0" })
78
+ ]
79
+ }
80
+ )
81
+ ] }),
67
82
  /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto", children: /* @__PURE__ */ jsx(AgentCodeBlock, { code: selected.sampleCode[mode], language: selected.language }) })
68
83
  ] })
69
84
  ] });
@@ -71,4 +86,4 @@ function AgentCodeSnippets({ snippets }) {
71
86
  export {
72
87
  AgentCodeSnippets as default
73
88
  };
74
- //# sourceMappingURL=AgentCodeSnippets-NZOFJE57.js.map
89
+ //# sourceMappingURL=AgentCodeSnippets-RJBB4DDE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/atoms/agent-details/AgentCodeSnippets.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState, type ComponentType } from 'react';\nimport { Icon } from '../../icons/Icon.js';\nimport { useSlot } from '../../theme/SlotsProvider.js';\nimport { cn } from '../lib/cn.js';\nimport type { AgentCodeSnippetsProps } from './types.js';\n\ntype SnippetMode = 'stream' | 'nonStream';\n\nexport default function AgentCodeSnippets({ snippets }: AgentCodeSnippetsProps) {\n const AgentCodeBlock = useSlot('AgentCodeBlock');\n const [selectedLanguage, setSelectedLanguage] = useState(snippets[0]?.language);\n const [mode, setMode] = useState<SnippetMode>('stream');\n\n useEffect(() => {\n setSelectedLanguage(snippets[0]?.language);\n setMode('stream');\n }, [snippets]);\n\n const selected = snippets.find(snippet => snippet.language === selectedLanguage) ?? snippets[0];\n\n if (selected === undefined) {\n return (\n <div className=\"flex h-full min-h-64 items-center justify-center px-6 text-sm text-text-secondary\">\n No code samples for this agent.\n </div>\n );\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 p-3 md:flex-row\">\n <nav aria-label=\"Code sample languages\" className=\"flex shrink-0 gap-1 overflow-auto md:w-44 md:flex-col\">\n {snippets.map(snippet => (\n <button\n key={snippet.language}\n type=\"button\"\n aria-current={selected.language === snippet.language ? 'page' : undefined}\n className={cn(\n 'flex h-9 shrink-0 cursor-pointer items-center gap-2 rounded-md px-2.5 text-left text-xs text-text-secondary',\n 'hover:bg-ghost-button-hover hover:text-text-primary',\n selected.language === snippet.language && 'bg-primary-button-bg/10 font-medium text-primary-button-bg',\n )}\n onClick={() => setSelectedLanguage(snippet.language)}\n >\n {snippet.icon ? (\n <img src={snippet.icon} alt=\"\" className=\"size-4 shrink-0 object-contain\" />\n ) : (\n <Icon name=\"code\" className=\"size-4 shrink-0\" />\n )}\n {snippet.labelName}\n </button>\n ))}\n </nav>\n\n <section className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden rounded-lg border border-border bg-card-bg\">\n <div className=\"flex h-10 shrink-0 items-center justify-between gap-1 border-b border-border px-3\">\n <div className=\"flex items-end gap-1\">\n {(\n [\n ['stream', 'Stream'],\n ['nonStream', 'Non-stream'],\n ] satisfies Array<[SnippetMode, string]>\n ).map(([id, label]) => (\n <button\n key={id}\n type=\"button\"\n className={cn(\n 'relative h-10 cursor-pointer px-3 text-xs font-medium text-text-secondary',\n mode === id &&\n 'text-primary-button-bg after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:bg-primary-button-bg',\n )}\n onClick={() => setMode(id)}\n >\n {label}\n </button>\n ))}\n </div>\n <a\n href=\"https://trueforge.dev/api/use-agent\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 text-xs text-text-secondary\"\n >\n <span>View Docs</span>\n <Icon name=\"external-link\" className=\"size-3 shrink-0\" />\n </a>\n </div>\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <AgentCodeBlock code={selected.sampleCode[mode]} language={selected.language} />\n </div>\n </section>\n </div>\n );\n}\n\ndeclare module '../../theme/SlotsProvider.js' {\n interface AtomSlots {\n AgentCodeSnippets: ComponentType<AgentCodeSnippetsProps>;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAEA,SAAS,WAAW,gBAAoC;AAsBlD,cAUI,YAVJ;AAdS,SAAR,kBAAmC,EAAE,SAAS,GAA2B;AAC9E,QAAM,iBAAiB,QAAQ,gBAAgB;AAC/C,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,SAAS,CAAC,GAAG,QAAQ;AAC9E,QAAM,CAAC,MAAM,OAAO,IAAI,SAAsB,QAAQ;AAEtD,YAAU,MAAM;AACd,wBAAoB,SAAS,CAAC,GAAG,QAAQ;AACzC,YAAQ,QAAQ;AAAA,EAClB,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,WAAW,SAAS,KAAK,aAAW,QAAQ,aAAa,gBAAgB,KAAK,SAAS,CAAC;AAE9F,MAAI,aAAa,QAAW;AAC1B,WACE,oBAAC,SAAI,WAAU,qFAAoF,6CAEnG;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,sDACb;AAAA,wBAAC,SAAI,cAAW,yBAAwB,WAAU,yDAC/C,mBAAS,IAAI,aACZ;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,gBAAc,SAAS,aAAa,QAAQ,WAAW,SAAS;AAAA,QAChE,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA,SAAS,aAAa,QAAQ,YAAY;AAAA,QAC5C;AAAA,QACA,SAAS,MAAM,oBAAoB,QAAQ,QAAQ;AAAA,QAElD;AAAA,kBAAQ,OACP,oBAAC,SAAI,KAAK,QAAQ,MAAM,KAAI,IAAG,WAAU,kCAAiC,IAE1E,oBAAC,QAAK,MAAK,QAAO,WAAU,mBAAkB;AAAA,UAE/C,QAAQ;AAAA;AAAA;AAAA,MAfJ,QAAQ;AAAA,IAgBf,CACD,GACH;AAAA,IAEA,qBAAC,aAAQ,WAAU,mGACjB;AAAA,2BAAC,SAAI,WAAU,qFACb;AAAA,4BAAC,SAAI,WAAU,wBAEX;AAAA,UACE,CAAC,UAAU,QAAQ;AAAA,UACnB,CAAC,aAAa,YAAY;AAAA,QAC5B,EACA,IAAI,CAAC,CAAC,IAAI,KAAK,MACf;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,WAAW;AAAA,cACT;AAAA,cACA,SAAS,MACP;AAAA,YACJ;AAAA,YACA,SAAS,MAAM,QAAQ,EAAE;AAAA,YAExB;AAAA;AAAA,UATI;AAAA,QAUP,CACD,GACH;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,QAAO;AAAA,YACP,KAAI;AAAA,YACJ,WAAU;AAAA,YAEV;AAAA,kCAAC,UAAK,uBAAS;AAAA,cACf,oBAAC,QAAK,MAAK,iBAAgB,WAAU,mBAAkB;AAAA;AAAA;AAAA,QACzD;AAAA,SACF;AAAA,MACA,oBAAC,SAAI,WAAU,gCACb,8BAAC,kBAAe,MAAM,SAAS,WAAW,IAAI,GAAG,UAAU,SAAS,UAAU,GAChF;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import {
3
+ AgentMetricChart
4
+ } from "./chunk-PQ7VWBQQ.js";
5
+ import "./chunk-GG23N2GW.js";
6
+ import "./chunk-T6QQV5LK.js";
7
+ import "./chunk-3ZW74FHC.js";
8
+ import "./chunk-2GIZY3JJ.js";
9
+ import "./chunk-M6MHLVSO.js";
10
+ import "./chunk-CG75X77Q.js";
11
+ import "./chunk-JCL3Q7RW.js";
12
+ export {
13
+ AgentMetricChart
14
+ };
15
+ //# sourceMappingURL=AgentMetricChart-UPGSJ2WP.js.map
@@ -1,17 +1,17 @@
1
1
  "use client";
2
2
  import {
3
3
  useSlot
4
- } from "./chunk-ZTMKFZQ3.js";
5
- import "./chunk-2XPPBEYF.js";
4
+ } from "./chunk-GG23N2GW.js";
5
+ import "./chunk-T6QQV5LK.js";
6
6
  import {
7
7
  Icon
8
- } from "./chunk-XAU7QFG3.js";
9
- import "./chunk-U7KURWW3.js";
8
+ } from "./chunk-3ZW74FHC.js";
9
+ import "./chunk-2GIZY3JJ.js";
10
10
  import "./chunk-M6MHLVSO.js";
11
- import "./chunk-MPNSO7E6.js";
11
+ import "./chunk-CG75X77Q.js";
12
12
  import {
13
13
  cn
14
- } from "./chunk-7Z2C2K7F.js";
14
+ } from "./chunk-JCL3Q7RW.js";
15
15
 
16
16
  // src/atoms/agent-details/AgentOverview.tsx
17
17
  import { useState } from "react";
@@ -54,6 +54,7 @@ function AgentOverview({ detail }) {
54
54
  const config = isRecord(spec.config) ? spec.config : null;
55
55
  const sandbox = isRecord(config?.sandbox) ? config.sandbox : null;
56
56
  const instructions = spec.instructions?.trim() ? spec.instructions : null;
57
+ const description = detail.description?.trim() ? detail.description : null;
57
58
  const execution = [
58
59
  ["Sandbox", typeof sandbox?.enabled === "boolean" ? sandbox.enabled ? "Enabled" : "Disabled" : void 0],
59
60
  ["Iteration limit", readRecordValue(config, "iterationLimit", "iteration_limit")],
@@ -67,7 +68,7 @@ function AgentOverview({ detail }) {
67
68
  ["Ask user questions", spec.config?.askUserQuestions?.enabled]
68
69
  ].filter((entry) => typeof entry[1] === "boolean");
69
70
  const toggleLabel = instructionsView === "markdown" ? "Raw" : "Markdown";
70
- return /* @__PURE__ */ jsxs("div", { className: "grid min-h-0 flex-1 gap-3 overflow-auto p-4 md:grid-cols-[minmax(0,1fr)_18rem] md:overflow-hidden", children: [
71
+ return /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-auto p-4 md:overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: "grid min-h-0 flex-1 gap-3 md:grid-cols-[minmax(0,1fr)_18rem] md:overflow-hidden", children: [
71
72
  /* @__PURE__ */ jsxs("section", { className: "flex min-h-64 flex-col rounded-lg border border-border bg-card-bg p-4 text-text-primary", children: [
72
73
  /* @__PURE__ */ jsxs("div", { className: "mb-3 flex shrink-0 items-center justify-between gap-2", children: [
73
74
  /* @__PURE__ */ jsxs("h2", { className: "flex items-center gap-1.5 text-sm font-semibold text-text-primary", children: [
@@ -115,6 +116,7 @@ function AgentOverview({ detail }) {
115
116
  /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto", children: instructions ? instructionsView === "markdown" ? /* @__PURE__ */ jsx(Markdown, { content: instructions, readOnly: true, className: "text-sm" }) : /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap break-words font-mono text-sm text-text-primary", children: instructions }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary", children: "No instructions for this agent." }) })
116
117
  ] }),
117
118
  /* @__PURE__ */ jsxs("aside", { className: "flex min-h-0 min-w-0 flex-col gap-3 md:overflow-auto", children: [
119
+ description ? /* @__PURE__ */ jsx(AgentOverviewCard, { title: "Description", icon: "file", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: description }) }) : null,
118
120
  /* @__PURE__ */ jsx(AgentOverviewCard, { title: "Model Configuration", icon: "cpu", children: /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs", children: [
119
121
  /* @__PURE__ */ jsx("dt", { className: "text-text-secondary", children: "Model" }),
120
122
  /* @__PURE__ */ jsx("dd", { className: cn(valueClassName, "truncate"), title: spec.model.name, children: displayModelName(spec.model.name) }),
@@ -159,9 +161,9 @@ function AgentOverview({ detail }) {
159
161
  /* @__PURE__ */ jsx("dd", { className: valueClassName, children: enabled ? "Enabled" : "Disabled" })
160
162
  ] }, label)) }) }) : null
161
163
  ] })
162
- ] });
164
+ ] }) });
163
165
  }
164
166
  export {
165
167
  AgentOverview as default
166
168
  };
167
- //# sourceMappingURL=AgentOverview-EEBHJC32.js.map
169
+ //# sourceMappingURL=AgentOverview-U5WIQXZN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/atoms/agent-details/AgentOverview.tsx"],"sourcesContent":["'use client';\n\nimport { useState, type ComponentType } from 'react';\nimport { Icon } from '../../icons/Icon.js';\nimport { useSlot } from '../../theme/SlotsProvider.js';\nimport { cn } from '../lib/cn.js';\nimport type { AgentOverviewProps } from './types.js';\n\ntype InstructionsView = 'markdown' | 'raw';\n\nconst valueClassName = 'text-right font-mono text-primary-button-bg';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value != null;\n}\n\nfunction readName(value: object): string | null {\n if (!('name' in value) || typeof value.name !== 'string') return null;\n return value.name;\n}\n\nfunction readRecordValue(record: Record<string, unknown> | null, ...keys: string[]): unknown {\n for (const key of keys) {\n const value = record?.[key];\n if (value !== undefined) return value;\n }\n return undefined;\n}\n\nfunction hasAllTools(value: object): boolean {\n if (!isRecord(value)) return false;\n const tools = readRecordValue(value, 'enableTools', 'enable_tools');\n return tools === undefined || (Array.isArray(tools) && tools.includes('@all'));\n}\n\nfunction displayModelName(name: string): string {\n const slash = name.lastIndexOf('/');\n return slash >= 0 ? name.slice(slash + 1) : name;\n}\n\nexport default function AgentOverview({ detail }: AgentOverviewProps) {\n const Markdown = useSlot('Markdown');\n const AgentOverviewCard = useSlot('AgentOverviewCard');\n const [instructionsView, setInstructionsView] = useState<InstructionsView>('markdown');\n const [copied, setCopied] = useState(false);\n const spec = detail.agentSpec;\n const skills = spec.skills ?? [];\n const connectors = spec.mcpServers ?? [];\n const modelParams = isRecord(spec.model.params) ? spec.model.params : null;\n const maxTokens = readRecordValue(modelParams, 'maxTokens', 'max_tokens');\n const temperature = readRecordValue(modelParams, 'temperature');\n const config = isRecord(spec.config) ? spec.config : null;\n const sandbox = isRecord(config?.sandbox) ? config.sandbox : null;\n const instructions = spec.instructions?.trim() ? spec.instructions : null;\n const description = detail.description?.trim() ? detail.description : null;\n const execution = [\n ['Sandbox', typeof sandbox?.enabled === 'boolean' ? (sandbox.enabled ? 'Enabled' : 'Disabled') : undefined],\n ['Iteration limit', readRecordValue(config, 'iterationLimit', 'iteration_limit')],\n ['Response format', readRecordValue(config, 'responseFormat', 'response_format')],\n ].filter((entry): entry is [string, string | number] => {\n return typeof entry[1] === 'string' || typeof entry[1] === 'number';\n });\n const capabilities = [\n ['Generative UI', spec.config?.generativeUi?.enabled],\n ['Dynamic sub-agents', spec.config?.dynamicSubAgents?.enabled],\n ['Ask user questions', spec.config?.askUserQuestions?.enabled],\n ].filter((entry): entry is [string, boolean] => typeof entry[1] === 'boolean');\n const toggleLabel = instructionsView === 'markdown' ? 'Raw' : 'Markdown';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-auto p-4 md:overflow-hidden\">\n <div className=\"grid min-h-0 flex-1 gap-3 md:grid-cols-[minmax(0,1fr)_18rem] md:overflow-hidden\">\n <section className=\"flex min-h-64 flex-col rounded-lg border border-border bg-card-bg p-4 text-text-primary\">\n <div className=\"mb-3 flex shrink-0 items-center justify-between gap-2\">\n <h2 className=\"flex items-center gap-1.5 text-sm font-semibold text-text-primary\">\n <Icon name=\"book-open\" className=\"size-4 text-text-secondary\" />\n Instructions\n </h2>\n {instructions ? (\n <div\n className=\"inline-flex h-7 items-stretch overflow-hidden rounded-md border border-border bg-primary-bg text-xs font-medium text-text-secondary\"\n role=\"group\"\n aria-label=\"Instructions actions\"\n >\n <button\n type=\"button\"\n aria-label={`Show ${toggleLabel}`}\n onClick={() => setInstructionsView(view => (view === 'markdown' ? 'raw' : 'markdown'))}\n className=\"cursor-pointer px-2.5 transition-colors hover:bg-ghost-button-hover hover:text-text-primary\"\n >\n {toggleLabel}\n </button>\n <span className=\"w-px self-stretch bg-border\" aria-hidden />\n <button\n type=\"button\"\n title={copied ? 'Copied!' : 'Copy'}\n aria-label={copied ? 'Copied!' : 'Copy'}\n onClick={() => {\n void navigator.clipboard.writeText(instructions).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }}\n className=\"inline-flex cursor-pointer items-center justify-center px-2 transition-colors hover:bg-ghost-button-hover hover:text-text-primary\"\n >\n <Icon name={copied ? 'check' : 'copy'} size={12} />\n </button>\n </div>\n ) : null}\n </div>\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {instructions ? (\n instructionsView === 'markdown' ? (\n <Markdown content={instructions} readOnly className=\"text-sm\" />\n ) : (\n <pre className=\"whitespace-pre-wrap break-words font-mono text-sm text-text-primary\">\n {instructions}\n </pre>\n )\n ) : (\n <p className=\"text-sm text-text-secondary\">No instructions for this agent.</p>\n )}\n </div>\n </section>\n\n <aside className=\"flex min-h-0 min-w-0 flex-col gap-3 md:overflow-auto\">\n {description ? (\n <AgentOverviewCard title=\"Description\" icon=\"file\">\n <p className=\"text-xs text-text-secondary\">{description}</p>\n </AgentOverviewCard>\n ) : null}\n <AgentOverviewCard title=\"Model Configuration\" icon=\"cpu\">\n <dl className=\"grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs\">\n <dt className=\"text-text-secondary\">Model</dt>\n <dd className={cn(valueClassName, 'truncate')} title={spec.model.name}>\n {displayModelName(spec.model.name)}\n </dd>\n {typeof maxTokens === 'number' ? (\n <>\n <dt className=\"text-text-secondary\">Max tokens</dt>\n <dd className={valueClassName}>{maxTokens}</dd>\n </>\n ) : null}\n {spec.model.params?.reasoningEffort !== undefined ? (\n <>\n <dt className=\"text-text-secondary\">Reasoning</dt>\n <dd className={valueClassName}>{spec.model.params.reasoningEffort}</dd>\n </>\n ) : null}\n {typeof temperature === 'number' ? (\n <>\n <dt className=\"text-text-secondary\">Temperature</dt>\n <dd className={valueClassName}>{temperature}</dd>\n </>\n ) : null}\n </dl>\n </AgentOverviewCard>\n <AgentOverviewCard title=\"MCP Servers\" icon=\"plug\" count={connectors.length}>\n {connectors.length === 0 ? (\n <p className=\"text-xs text-text-secondary\">No connectors attached.</p>\n ) : (\n <ul className=\"space-y-1.5\">\n {connectors.map((connector, index) => (\n <li\n key={`${readName(connector) ?? 'connector'}-${index}`}\n className=\"rounded-md bg-secondary-bg px-2 py-1.5 text-xs\"\n >\n <span className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate\">{readName(connector) ?? `Connector ${index + 1}`}</span>\n {hasAllTools(connector) ? (\n <span className=\"shrink-0 rounded-full bg-primary-button-bg/10 px-1.5 py-0.5 text-[10px] text-primary-button-bg\">\n All tools\n </span>\n ) : null}\n </span>\n </li>\n ))}\n </ul>\n )}\n </AgentOverviewCard>\n\n <AgentOverviewCard title=\"Attached Skills\" icon=\"lightbulb\" count={skills.length}>\n {skills.length === 0 ? (\n <p className=\"text-xs text-text-secondary\">No skills attached.</p>\n ) : (\n <ul className=\"space-y-1.5\">\n {skills.map((skill, index) => (\n <li\n key={`${readName(skill) ?? 'skill'}-${index}`}\n className=\"rounded-md bg-secondary-bg px-2 py-1.5 text-xs\"\n >\n {readName(skill) ?? `Skill ${index + 1}`}\n </li>\n ))}\n </ul>\n )}\n </AgentOverviewCard>\n\n {execution.length > 0 ? (\n <AgentOverviewCard title=\"Execution\" icon=\"terminal\">\n <dl className=\"space-y-1 text-xs\">\n {execution.map(([label, value]) => (\n <div key={label} className=\"flex justify-between gap-3\">\n <dt className=\"text-text-secondary\">{label}</dt>\n <dd className={valueClassName}>{value}</dd>\n </div>\n ))}\n </dl>\n </AgentOverviewCard>\n ) : null}\n\n {capabilities.length > 0 ? (\n <AgentOverviewCard title=\"Capabilities\" icon=\"cube\">\n <dl className=\"space-y-1 text-xs\">\n {capabilities.map(([label, enabled]) => (\n <div key={label} className=\"flex justify-between gap-3\">\n <dt className=\"text-text-secondary\">{label}</dt>\n <dd className={valueClassName}>{enabled ? 'Enabled' : 'Disabled'}</dd>\n </div>\n ))}\n </dl>\n </AgentOverviewCard>\n ) : null}\n </aside>\n </div>\n </div>\n );\n}\n\ndeclare module '../../theme/SlotsProvider.js' {\n interface AtomSlots {\n AgentOverview: ComponentType<AgentOverviewProps>;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,22 +1,25 @@
1
1
  "use client";
2
2
  import {
3
3
  SESSION_EVENT_TYPES,
4
- useSlot
5
- } from "./chunk-ZTMKFZQ3.js";
6
- import "./chunk-2XPPBEYF.js";
7
- import "./chunk-XAU7QFG3.js";
8
- import "./chunk-U7KURWW3.js";
4
+ getSessionEventColor,
5
+ useSlot,
6
+ useThemeMode
7
+ } from "./chunk-GG23N2GW.js";
8
+ import "./chunk-T6QQV5LK.js";
9
+ import "./chunk-3ZW74FHC.js";
10
+ import "./chunk-2GIZY3JJ.js";
9
11
  import "./chunk-M6MHLVSO.js";
10
- import "./chunk-MPNSO7E6.js";
12
+ import "./chunk-CG75X77Q.js";
11
13
  import {
12
14
  cn
13
- } from "./chunk-7Z2C2K7F.js";
15
+ } from "./chunk-JCL3Q7RW.js";
14
16
 
15
17
  // src/atoms/agent-details/AgentSessionEventTimeline.tsx
16
18
  import { useCallback, useMemo, useState } from "react";
17
19
  import { jsx, jsxs } from "react/jsx-runtime";
18
20
  function AgentSessionEventTimeline({ turns, segments, onSelectTurn }) {
19
21
  const AgentSessionEventTimelineChart = useSlot("AgentSessionEventTimelineChart");
22
+ const isDark = useThemeMode() === "dark";
20
23
  const [hiddenTypes, setHiddenTypes] = useState(() => /* @__PURE__ */ new Set());
21
24
  const availableEventTypes = useMemo(() => {
22
25
  const available = new Set(segments.map((segment) => segment.type));
@@ -52,7 +55,13 @@ function AgentSessionEventTimeline({ turns, segments, onSelectTurn }) {
52
55
  ),
53
56
  onClick: () => handleToggleType(eventType.id),
54
57
  children: [
55
- /* @__PURE__ */ jsx("span", { className: "size-2 rounded-sm", style: { backgroundColor: eventType.color } }),
58
+ /* @__PURE__ */ jsx(
59
+ "span",
60
+ {
61
+ className: "size-2 rounded-sm",
62
+ style: { backgroundColor: getSessionEventColor(eventType.id, isDark) }
63
+ }
64
+ ),
56
65
  eventType.label
57
66
  ]
58
67
  },
@@ -62,7 +71,7 @@ function AgentSessionEventTimeline({ turns, segments, onSelectTurn }) {
62
71
  ]
63
72
  }
64
73
  ),
65
- /* @__PURE__ */ jsx("div", { className: "w-full py-2", children: /* @__PURE__ */ jsx(
74
+ /* @__PURE__ */ jsx("div", { className: "w-full p-2", children: /* @__PURE__ */ jsx(
66
75
  AgentSessionEventTimelineChart,
67
76
  {
68
77
  turns,
@@ -76,4 +85,4 @@ function AgentSessionEventTimeline({ turns, segments, onSelectTurn }) {
76
85
  export {
77
86
  AgentSessionEventTimeline
78
87
  };
79
- //# sourceMappingURL=AgentSessionEventTimeline-26Z6IB3B.js.map
88
+ //# sourceMappingURL=AgentSessionEventTimeline-GRGIQTRE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/atoms/agent-details/AgentSessionEventTimeline.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useState, type ComponentType } from 'react';\n\nimport { useSlot, useThemeMode } from '../../theme/SlotsProvider.js';\nimport { getSessionEventColor, SESSION_EVENT_TYPES, type SessionEventType } from '../../utils/sessionEventTimeline.js';\nimport { cn } from '../lib/cn.js';\nimport type { AgentSessionEventTimelineProps } from './types.js';\n\nexport function AgentSessionEventTimeline({ turns, segments, onSelectTurn }: AgentSessionEventTimelineProps) {\n const AgentSessionEventTimelineChart = useSlot('AgentSessionEventTimelineChart');\n const isDark = useThemeMode() === 'dark';\n const [hiddenTypes, setHiddenTypes] = useState<Set<SessionEventType>>(() => new Set());\n\n const availableEventTypes = useMemo(() => {\n const available = new Set(segments.map(segment => segment.type));\n return SESSION_EVENT_TYPES.filter(eventType => available.has(eventType.id));\n }, [segments]);\n\n const handleToggleType = useCallback((type: SessionEventType) => {\n setHiddenTypes(previous => {\n const next = new Set(previous);\n if (next.has(type)) next.delete(type);\n else next.add(type);\n return next;\n });\n }, []);\n\n if (segments.length === 0) return null;\n\n return (\n <div className=\"w-full\" data-slot=\"agent-session-event-timeline\">\n <div\n className=\"flex flex-wrap items-center gap-2 border-b border-border px-3 py-2\"\n data-slot=\"agent-session-event-types\"\n >\n <span className=\"text-xs font-medium uppercase text-text-secondary\">Event types</span>\n <div className=\"flex flex-wrap items-center gap-1\">\n {availableEventTypes.map(eventType => {\n const isVisible = !hiddenTypes.has(eventType.id);\n return (\n <button\n key={eventType.id}\n type=\"button\"\n aria-pressed={isVisible}\n className={cn(\n 'flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium',\n isVisible ? 'border-border text-text-primary' : 'border-transparent text-text-secondary opacity-80',\n )}\n onClick={() => handleToggleType(eventType.id)}\n >\n <span\n className=\"size-2 rounded-sm\"\n style={{ backgroundColor: getSessionEventColor(eventType.id, isDark) }}\n />\n {eventType.label}\n </button>\n );\n })}\n </div>\n </div>\n <div className=\"w-full p-2\">\n <AgentSessionEventTimelineChart\n turns={turns}\n segments={segments}\n hiddenTypes={hiddenTypes}\n onSelectTurn={onSelectTurn}\n />\n </div>\n </div>\n );\n}\n\ndeclare module '../../theme/SlotsProvider.js' {\n interface AtomSlots {\n AgentSessionEventTimeline: ComponentType<AgentSessionEventTimelineProps>;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAEA,SAAS,aAAa,SAAS,gBAAoC;AAkC3D,cAKM,YALN;AA3BD,SAAS,0BAA0B,EAAE,OAAO,UAAU,aAAa,GAAmC;AAC3G,QAAM,iCAAiC,QAAQ,gCAAgC;AAC/E,QAAM,SAAS,aAAa,MAAM;AAClC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAgC,MAAM,oBAAI,IAAI,CAAC;AAErF,QAAM,sBAAsB,QAAQ,MAAM;AACxC,UAAM,YAAY,IAAI,IAAI,SAAS,IAAI,aAAW,QAAQ,IAAI,CAAC;AAC/D,WAAO,oBAAoB,OAAO,eAAa,UAAU,IAAI,UAAU,EAAE,CAAC;AAAA,EAC5E,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,mBAAmB,YAAY,CAAC,SAA2B;AAC/D,mBAAe,cAAY;AACzB,YAAM,OAAO,IAAI,IAAI,QAAQ;AAC7B,UAAI,KAAK,IAAI,IAAI,EAAG,MAAK,OAAO,IAAI;AAAA,UAC/B,MAAK,IAAI,IAAI;AAClB,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,SACE,qBAAC,SAAI,WAAU,UAAS,aAAU,gCAChC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,aAAU;AAAA,QAEV;AAAA,8BAAC,UAAK,WAAU,qDAAoD,yBAAW;AAAA,UAC/E,oBAAC,SAAI,WAAU,qCACZ,8BAAoB,IAAI,eAAa;AACpC,kBAAM,YAAY,CAAC,YAAY,IAAI,UAAU,EAAE;AAC/C,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,gBAAc;AAAA,gBACd,WAAW;AAAA,kBACT;AAAA,kBACA,YAAY,oCAAoC;AAAA,gBAClD;AAAA,gBACA,SAAS,MAAM,iBAAiB,UAAU,EAAE;AAAA,gBAE5C;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,WAAU;AAAA,sBACV,OAAO,EAAE,iBAAiB,qBAAqB,UAAU,IAAI,MAAM,EAAE;AAAA;AAAA,kBACvE;AAAA,kBACC,UAAU;AAAA;AAAA;AAAA,cAbN,UAAU;AAAA,YAcjB;AAAA,UAEJ,CAAC,GACH;AAAA;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,SAAI,WAAU,cACb;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;","names":[]}