@tutti-os/agent-gui 0.0.145 → 0.0.147

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.
package/README.md CHANGED
@@ -49,15 +49,20 @@ contract; it is not a pasted-text or external-file capability signal.
49
49
 
50
50
  ## External File Preparation
51
51
 
52
- OS clipboard and drop files use the required workspace
53
- `prepareExternalPromptFiles` host port. AgentGUI owns classification, pending
54
- mentions, and draft reconciliation. The host owns native-path lookup, size
55
- enforcement, persistence, and remote transport.
56
-
57
- The preparer returns one result per input `sourceIndex`. Prepared files require
58
- a provider-readable `path` or `url`; failures require a typed `errorCode`.
59
- Hosts must isolate per-file failures and reject oversized inputs before reading
60
- or persisting their bytes.
52
+ OS clipboard and drop entries first use the optional synchronous workspace
53
+ `resolveExternalPromptEntries` host port. The host classifies every input as a
54
+ live `WorkspaceFileReference` or a snapshot that needs preparation. AgentGUI
55
+ inserts references directly as ordinary file/folder mentions, preserves mixed
56
+ input order, and sends only `prepare` entries to `prepareExternalPromptFiles`.
57
+ Without the resolver, every input uses preparation.
58
+
59
+ Both ports return one result per input `sourceIndex`. The resolver is
60
+ synchronous so paste/drop insertion position remains stable. Prepared files
61
+ require a provider-readable `path` or `url`; failures require a typed
62
+ `errorCode`. Hosts must isolate per-file failures and reject oversized inputs
63
+ before reading or persisting their bytes. A host that resolves path-backed
64
+ entries as references must also reject any such entry that unexpectedly reaches
65
+ preparation, preventing a resolver failure from creating a duplicate snapshot.
61
66
 
62
67
  Slash commands come from the runtime session command snapshot. AgentGUI keeps
63
68
  legacy provider-default slash entries unless the host passes
@@ -3,8 +3,8 @@ import { ReactNode, JSX } from 'react';
3
3
  import { c as AgentConversationVM, g as WorkspaceLinkAction, f as WorkspaceAgentSessionDetailViewModel } from '../agentConversationVM-DWEy7jzx.js';
4
4
  export { B as BuildWorkspaceAgentSessionDetailInput, W as WorkspaceAgentActivityCard, e as WorkspaceAgentActivityTimelineItem, h as buildWorkspaceAgentSessionDetailViewModel } from '../agentConversationVM-DWEy7jzx.js';
5
5
  import { d as AgentGUIProviderSkillOption, h as AgentMessageMarkdownWorkspaceAppIcon } from '../agentGuiNodeTypes-D3f1yiEL.js';
6
+ import { AgentActivityMessage } from '@tutti-os/agent-activity-core';
6
7
  import '@tutti-os/workspace-issue-manager/core';
7
- import '@tutti-os/agent-activity-core';
8
8
  import '../types-DVmB_kyD.js';
9
9
  import '@tutti-os/workspace-user-project/contracts';
10
10
 
@@ -81,4 +81,38 @@ declare function useProjectedAgentConversation({ conversation, detail, avoidGrou
81
81
  avoidGroupingEdits?: boolean;
82
82
  }): AgentConversationVM | null;
83
83
 
84
- export { AgentConversationFlow, AgentConversationVM, AgentTranscriptSkeleton, AgentTranscriptView, WorkspaceAgentSessionDetail, WorkspaceAgentSessionDetailViewModel, projectAgentConversationVM, reconcileProjectedAgentConversationVM, useProjectedAgentConversation };
84
+ type AgentGUIConversationCopyAction = "copy-markdown" | "copy-reference";
85
+ interface AgentGUIConversationCopyLabels {
86
+ file: string;
87
+ image: string;
88
+ mentionPrefix: string;
89
+ /** Template for the collapsed-interim summary; contains `{{count}}`. */
90
+ previousMessages: string;
91
+ }
92
+ interface AgentGUIConversationAttachment {
93
+ data: string;
94
+ mimeType: string;
95
+ name?: string;
96
+ }
97
+ /** Hydrates a local workspace image path into base64 bytes at copy time. */
98
+ type AgentGUIConversationLocalImageReader = (input: {
99
+ path: string;
100
+ mimeType: string | null;
101
+ }) => Promise<AgentGUIConversationAttachment>;
102
+ interface AgentGUIConversationSerializedTranscript {
103
+ /** Hydrated variant for the text/html flavor: images embed as data URIs. */
104
+ hydratedMarkdown: string;
105
+ /** Lean variant for text/plain: short image references, never base64. */
106
+ markdown: string;
107
+ /** Hydratable images left unembedded (oversized or failed reads). */
108
+ omittedImages: number;
109
+ }
110
+ declare function serializeAgentConversationForClipboard(input: {
111
+ labels: AgentGUIConversationCopyLabels;
112
+ messages: readonly AgentActivityMessage[];
113
+ readAttachment?: (attachmentId: string) => Promise<AgentGUIConversationAttachment>;
114
+ readLocalImage?: AgentGUIConversationLocalImageReader;
115
+ title: string;
116
+ }): Promise<AgentGUIConversationSerializedTranscript>;
117
+
118
+ export { AgentConversationFlow, AgentConversationVM, type AgentGUIConversationAttachment, type AgentGUIConversationCopyAction, type AgentGUIConversationCopyLabels, type AgentGUIConversationLocalImageReader, type AgentGUIConversationSerializedTranscript, AgentTranscriptSkeleton, AgentTranscriptView, WorkspaceAgentSessionDetail, WorkspaceAgentSessionDetailViewModel, projectAgentConversationVM, reconcileProjectedAgentConversationVM, serializeAgentConversationForClipboard, useProjectedAgentConversation };
@@ -5,8 +5,9 @@ import {
5
5
  buildWorkspaceAgentSessionDetailViewModel,
6
6
  projectAgentConversationVM,
7
7
  reconcileProjectedAgentConversationVM,
8
+ serializeAgentConversationForClipboard,
8
9
  useProjectedAgentConversation
9
- } from "../chunk-4DIYEFHH.js";
10
+ } from "../chunk-3CZYC2YN.js";
10
11
  import "../chunk-JNC4FCUV.js";
11
12
  import "../chunk-FM42UN2J.js";
12
13
  import "../chunk-XJ34OIEQ.js";
@@ -86,6 +87,7 @@ export {
86
87
  buildWorkspaceAgentSessionDetailViewModel,
87
88
  projectAgentConversationVM,
88
89
  reconcileProjectedAgentConversationVM,
90
+ serializeAgentConversationForClipboard,
89
91
  useProjectedAgentConversation
90
92
  };
91
93
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../shared/WorkspaceAgentSessionDetail.tsx"],"sourcesContent":["import { useMemo, type JSX } from \"react\";\nimport type { WorkspaceLinkAction } from \"../contexts/workspace/presentation/renderer/actions/workspaceLinkActions\";\nimport { translate } from \"../i18n/index\";\nimport { AgentConversationFlow } from \"./agentConversation/components/AgentConversationFlow\";\nimport { useProjectedAgentConversation } from \"./agentConversation/projection/useProjectedAgentConversation\";\nimport type { WorkspaceAgentSessionDetailViewModel } from \"./workspaceAgentSessionDetailViewModel\";\n\ninterface WorkspaceAgentSessionDetailProps {\n detail: WorkspaceAgentSessionDetailViewModel;\n avoidGroupingEdits?: boolean;\n isLoading: boolean;\n timelineItemCount: number;\n onLinkAction?: (action: WorkspaceLinkAction) => void;\n toolCallsLabel: (count: number) => string;\n thinkingLabel?: string;\n loadingLabel?: string;\n rawTimelineJsonLabel?: string;\n showRawTimelineJson?: boolean;\n}\n\nexport function WorkspaceAgentSessionDetail({\n detail,\n avoidGroupingEdits = false,\n isLoading,\n timelineItemCount,\n onLinkAction,\n toolCallsLabel,\n thinkingLabel = translate(\"agentHost.workspaceAgentSessionDetailThinking\"),\n loadingLabel = translate(\"common.loading\"),\n rawTimelineJsonLabel,\n showRawTimelineJson = false\n}: WorkspaceAgentSessionDetailProps): JSX.Element {\n const conversation = useProjectedAgentConversation({\n detail,\n avoidGroupingEdits\n });\n const showLoadingSkeleton =\n detail.turns.length === 0 &&\n (isLoading ||\n detail.activity.status === \"waiting\" ||\n detail.activity.status === \"working\");\n const emptySummary =\n detail.activity.latestActivitySummary ||\n (timelineItemCount > 0\n ? translate(\"agentHost.workspaceAgentSessionDetailEmptyWithTimeline\")\n : translate(\"agentHost.workspaceAgentSessionDetailEmptyNoTimeline\"));\n const flowLabels = useMemo(\n () => ({\n thinkingLabel,\n toolCallsLabel,\n processing: translate(\"agentHost.agentGui.processing\"),\n turnSummary: translate(\"agentHost.agentGui.turnSummary\"),\n rawTimelineJson: rawTimelineJsonLabel\n }),\n [rawTimelineJsonLabel, thinkingLabel, toolCallsLabel]\n );\n const emptyState = useMemo(\n () => (\n <div className=\"workspace-agents-status-panel__detail-empty\">\n {emptySummary}\n </div>\n ),\n [emptySummary]\n );\n\n return (\n <div className=\"workspace-agents-status-panel__detail\">\n <AgentConversationFlow\n conversation={detail.turns.length > 0 ? conversation : null}\n isLoading={showLoadingSkeleton}\n loadingLabel={loadingLabel}\n empty={emptyState}\n onLinkAction={onLinkAction}\n showRawTimelineJson={showRawTimelineJson}\n labels={flowLabels}\n />\n </div>\n );\n}\n\nexport function WorkspaceAgentSessionDetailSkeleton({\n loading = true,\n loadingLabel = translate(\"common.loading\")\n}: {\n loading?: boolean;\n loadingLabel?: string;\n}): JSX.Element {\n const flowLabels = useMemo(\n () => ({\n thinkingLabel: translate(\"agentHost.workspaceAgentSessionDetailThinking\"),\n toolCallsLabel: (count: number) =>\n translate(\"agentHost.workspaceAgentSessionDetailToolCalls\", { count }),\n processing: translate(\"agentHost.agentGui.processing\"),\n turnSummary: translate(\"agentHost.agentGui.turnSummary\")\n }),\n []\n );\n\n if (!loading) {\n return <></>;\n }\n\n return (\n <div\n className=\"workspace-agents-status-panel__detail-skeleton\"\n data-testid=\"workspace-agents-status-panel-detail-skeleton\"\n role=\"status\"\n aria-busy=\"true\"\n aria-label={loadingLabel}\n >\n <AgentConversationFlow\n conversation={null}\n isLoading\n loadingLabel={loadingLabel}\n loadingTestId=\"workspace-agents-status-panel-detail-skeleton\"\n empty={null}\n labels={flowLabels}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAyB;AA0D5B,SAyCK,UAzCL;AAtCC,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA,qBAAqB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB,UAAU,+CAA+C;AAAA,EACzE,eAAe,UAAU,gBAAgB;AAAA,EACzC;AAAA,EACA,sBAAsB;AACxB,GAAkD;AAChD,QAAM,eAAe,8BAA8B;AAAA,IACjD;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,sBACJ,OAAO,MAAM,WAAW,MACvB,aACC,OAAO,SAAS,WAAW,aAC3B,OAAO,SAAS,WAAW;AAC/B,QAAM,eACJ,OAAO,SAAS,0BACf,oBAAoB,IACjB,UAAU,wDAAwD,IAClE,UAAU,sDAAsD;AACtE,QAAM,aAAa;AAAA,IACjB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,YAAY,UAAU,+BAA+B;AAAA,MACrD,aAAa,UAAU,gCAAgC;AAAA,MACvD,iBAAiB;AAAA,IACnB;AAAA,IACA,CAAC,sBAAsB,eAAe,cAAc;AAAA,EACtD;AACA,QAAM,aAAa;AAAA,IACjB,MACE,oBAAC,SAAI,WAAU,+CACZ,wBACH;AAAA,IAEF,CAAC,YAAY;AAAA,EACf;AAEA,SACE,oBAAC,SAAI,WAAU,yCACb;AAAA,IAAC;AAAA;AAAA,MACC,cAAc,OAAO,MAAM,SAAS,IAAI,eAAe;AAAA,MACvD,WAAW;AAAA,MACX;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,QAAQ;AAAA;AAAA,EACV,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../shared/WorkspaceAgentSessionDetail.tsx"],"sourcesContent":["import { useMemo, type JSX } from \"react\";\nimport type { WorkspaceLinkAction } from \"../contexts/workspace/presentation/renderer/actions/workspaceLinkActions\";\nimport { translate } from \"../i18n/index\";\nimport { AgentConversationFlow } from \"./agentConversation/components/AgentConversationFlow\";\nimport { useProjectedAgentConversation } from \"./agentConversation/projection/useProjectedAgentConversation\";\nimport type { WorkspaceAgentSessionDetailViewModel } from \"./workspaceAgentSessionDetailViewModel\";\n\ninterface WorkspaceAgentSessionDetailProps {\n detail: WorkspaceAgentSessionDetailViewModel;\n avoidGroupingEdits?: boolean;\n isLoading: boolean;\n timelineItemCount: number;\n onLinkAction?: (action: WorkspaceLinkAction) => void;\n toolCallsLabel: (count: number) => string;\n thinkingLabel?: string;\n loadingLabel?: string;\n rawTimelineJsonLabel?: string;\n showRawTimelineJson?: boolean;\n}\n\nexport function WorkspaceAgentSessionDetail({\n detail,\n avoidGroupingEdits = false,\n isLoading,\n timelineItemCount,\n onLinkAction,\n toolCallsLabel,\n thinkingLabel = translate(\"agentHost.workspaceAgentSessionDetailThinking\"),\n loadingLabel = translate(\"common.loading\"),\n rawTimelineJsonLabel,\n showRawTimelineJson = false\n}: WorkspaceAgentSessionDetailProps): JSX.Element {\n const conversation = useProjectedAgentConversation({\n detail,\n avoidGroupingEdits\n });\n const showLoadingSkeleton =\n detail.turns.length === 0 &&\n (isLoading ||\n detail.activity.status === \"waiting\" ||\n detail.activity.status === \"working\");\n const emptySummary =\n detail.activity.latestActivitySummary ||\n (timelineItemCount > 0\n ? translate(\"agentHost.workspaceAgentSessionDetailEmptyWithTimeline\")\n : translate(\"agentHost.workspaceAgentSessionDetailEmptyNoTimeline\"));\n const flowLabels = useMemo(\n () => ({\n thinkingLabel,\n toolCallsLabel,\n processing: translate(\"agentHost.agentGui.processing\"),\n turnSummary: translate(\"agentHost.agentGui.turnSummary\"),\n rawTimelineJson: rawTimelineJsonLabel\n }),\n [rawTimelineJsonLabel, thinkingLabel, toolCallsLabel]\n );\n const emptyState = useMemo(\n () => (\n <div className=\"workspace-agents-status-panel__detail-empty\">\n {emptySummary}\n </div>\n ),\n [emptySummary]\n );\n\n return (\n <div className=\"workspace-agents-status-panel__detail\">\n <AgentConversationFlow\n conversation={detail.turns.length > 0 ? conversation : null}\n isLoading={showLoadingSkeleton}\n loadingLabel={loadingLabel}\n empty={emptyState}\n onLinkAction={onLinkAction}\n showRawTimelineJson={showRawTimelineJson}\n labels={flowLabels}\n />\n </div>\n );\n}\n\nexport function WorkspaceAgentSessionDetailSkeleton({\n loading = true,\n loadingLabel = translate(\"common.loading\")\n}: {\n loading?: boolean;\n loadingLabel?: string;\n}): JSX.Element {\n const flowLabels = useMemo(\n () => ({\n thinkingLabel: translate(\"agentHost.workspaceAgentSessionDetailThinking\"),\n toolCallsLabel: (count: number) =>\n translate(\"agentHost.workspaceAgentSessionDetailToolCalls\", { count }),\n processing: translate(\"agentHost.agentGui.processing\"),\n turnSummary: translate(\"agentHost.agentGui.turnSummary\")\n }),\n []\n );\n\n if (!loading) {\n return <></>;\n }\n\n return (\n <div\n className=\"workspace-agents-status-panel__detail-skeleton\"\n data-testid=\"workspace-agents-status-panel-detail-skeleton\"\n role=\"status\"\n aria-busy=\"true\"\n aria-label={loadingLabel}\n >\n <AgentConversationFlow\n conversation={null}\n isLoading\n loadingLabel={loadingLabel}\n loadingTestId=\"workspace-agents-status-panel-detail-skeleton\"\n empty={null}\n labels={flowLabels}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAyB;AA0D5B,SAyCK,UAzCL;AAtCC,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA,qBAAqB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB,UAAU,+CAA+C;AAAA,EACzE,eAAe,UAAU,gBAAgB;AAAA,EACzC;AAAA,EACA,sBAAsB;AACxB,GAAkD;AAChD,QAAM,eAAe,8BAA8B;AAAA,IACjD;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,sBACJ,OAAO,MAAM,WAAW,MACvB,aACC,OAAO,SAAS,WAAW,aAC3B,OAAO,SAAS,WAAW;AAC/B,QAAM,eACJ,OAAO,SAAS,0BACf,oBAAoB,IACjB,UAAU,wDAAwD,IAClE,UAAU,sDAAsD;AACtE,QAAM,aAAa;AAAA,IACjB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,YAAY,UAAU,+BAA+B;AAAA,MACrD,aAAa,UAAU,gCAAgC;AAAA,MACvD,iBAAiB;AAAA,IACnB;AAAA,IACA,CAAC,sBAAsB,eAAe,cAAc;AAAA,EACtD;AACA,QAAM,aAAa;AAAA,IACjB,MACE,oBAAC,SAAI,WAAU,+CACZ,wBACH;AAAA,IAEF,CAAC,YAAY;AAAA,EACf;AAEA,SACE,oBAAC,SAAI,WAAU,yCACb;AAAA,IAAC;AAAA;AAAA,MACC,cAAc,OAAO,MAAM,SAAS,IAAI,eAAe;AAAA,MACvD,WAAW;AAAA,MACX;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,QAAQ;AAAA;AAAA,EACV,GACF;AAEJ;","names":[]}
@@ -492,6 +492,16 @@ interface AgentGUIAccountMenuState {
492
492
  onOpenExternal(url: string): void;
493
493
  }
494
494
 
495
+ type AgentExternalPromptEntryResolution = {
496
+ disposition: "reference";
497
+ reference: WorkspaceFileReference;
498
+ sourceIndex: number;
499
+ } | {
500
+ disposition: "prepare";
501
+ sourceIndex: number;
502
+ };
503
+ type AgentExternalPromptEntryResolver = (files: readonly File[]) => readonly AgentExternalPromptEntryResolution[];
504
+
495
505
  interface AgentPreparedExternalPromptFileMetadata {
496
506
  assetId?: string;
497
507
  mimeType?: string;
@@ -826,6 +836,7 @@ interface AgentComposerProps {
826
836
  }) => void;
827
837
  onLinkAction?: (action: WorkspaceLinkAction) => void;
828
838
  onRequestWorkspaceReferences?: ((entity?: AgentContextMentionItem | null) => Promise<WorkspaceReferencePickResult>) | null;
839
+ resolveExternalPromptEntries?: AgentExternalPromptEntryResolver | null;
829
840
  prepareExternalPromptFiles?: AgentExternalPromptFilePreparer | null;
830
841
  promptAssetLimit?: number | null;
831
842
  selectProjectDirectory?: () => Promise<{
@@ -994,6 +1005,7 @@ interface AgentGUINodeWorkspace {
994
1005
  selectProjectDirectory?: () => Promise<{
995
1006
  path: string;
996
1007
  } | null>;
1008
+ resolveExternalPromptEntries?: AgentComposerProps["resolveExternalPromptEntries"];
997
1009
  prepareExternalPromptFiles?: AgentComposerProps["prepareExternalPromptFiles"];
998
1010
  promptAssetLimit?: number | null;
999
1011
  referenceSourceAggregator?: ReferenceSourceAggregator | null;
package/dist/agent-gui.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  AgentGUI
3
- } from "./chunk-57W6N7EW.js";
3
+ } from "./chunk-LWXHBRDO.js";
4
4
  import "./chunk-A4WCTHWS.js";
5
- import "./chunk-EGEYJLG2.js";
5
+ import "./chunk-ZF65NZ4B.js";
6
6
  import "./chunk-TUWQV2MC.js";
7
7
  import "./chunk-MHOYBRCY.js";
8
8
  import "./chunk-Q2WMHYIB.js";
9
9
  import "./chunk-5HIF53K5.js";
10
10
  import "./chunk-R2ZADXRB.js";
11
- import "./chunk-4DIYEFHH.js";
11
+ import "./chunk-3CZYC2YN.js";
12
12
  import "./chunk-JNC4FCUV.js";
13
13
  import "./chunk-FM42UN2J.js";
14
14
  import "./chunk-UP3ZDYTN.js";
@@ -4557,13 +4557,17 @@ aside.workspace-agents-status-panel
4557
4557
  transition: none;
4558
4558
  }
4559
4559
 
4560
- .workbench-window:has([data-agent-gui-workbench-header="true"]) {
4560
+ .workbench-window:has(
4561
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
4562
+ ) {
4561
4563
  --agent-gui-workbench-header-height: 44px;
4562
4564
 
4563
4565
  grid-template-rows: minmax(0, 1fr);
4564
4566
  }
4565
4567
 
4566
- .workbench-window:has([data-agent-gui-workbench-header="true"])
4568
+ .workbench-window:has(
4569
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
4570
+ )
4567
4571
  .workbench-window__header {
4568
4572
  position: absolute !important;
4569
4573
  top: 0 !important;
@@ -4583,41 +4587,48 @@ aside.workspace-agents-status-panel
4583
4587
  }
4584
4588
 
4585
4589
  .workbench-window:has(
4586
- .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4590
+ > .workbench-window__header
4591
+ .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4587
4592
  )
4588
4593
  .workbench-window__header {
4589
4594
  cursor: grab !important;
4590
4595
  }
4591
4596
 
4592
4597
  .workbench-window:has(
4593
- .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4598
+ > .workbench-window__header
4599
+ .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4594
4600
  )
4595
4601
  .workbench-window__header:active {
4596
4602
  cursor: grabbing !important;
4597
4603
  }
4598
4604
 
4599
4605
  .workbench-window:has(
4600
- .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4606
+ > .workbench-window__header
4607
+ .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4601
4608
  )
4602
4609
  .workbench-window__header {
4603
4610
  z-index: calc(var(--z-panel) + 1);
4604
4611
  }
4605
4612
 
4606
4613
  .workbench-window:has(
4607
- .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4614
+ > .workbench-window__header
4615
+ .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4608
4616
  )
4609
4617
  .agent-gui-workbench-header::after {
4610
4618
  display: none;
4611
4619
  }
4612
4620
 
4613
- .workbench-window:has([data-agent-gui-workbench-header="true"])
4621
+ .workbench-window:has(
4622
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
4623
+ )
4614
4624
  .workbench-window__body {
4615
4625
  grid-row: 1;
4616
4626
  overflow: hidden;
4617
4627
  }
4618
4628
 
4619
4629
  .workbench-window:has(
4620
- .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4630
+ > .workbench-window__header
4631
+ .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
4621
4632
  )
4622
4633
  .workbench-window__body {
4623
4634
  display: flex;
@@ -4680,7 +4691,9 @@ aside.workspace-agents-status-panel
4680
4691
  overscroll-behavior: contain;
4681
4692
  }
4682
4693
 
4683
- .workbench-window:has([data-agent-gui-workbench-header="true"])
4694
+ .workbench-window:has(
4695
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
4696
+ )
4684
4697
  .agent-gui-node__provider-rail-panel {
4685
4698
  padding-top: var(--agent-gui-workbench-header-height);
4686
4699
  }
@@ -4689,22 +4702,30 @@ aside.workspace-agents-status-panel
4689
4702
  breathing room on the inner rail, so the "All" tile sits at header + 2px. The
4690
4703
  toolbar has no such wrapper, so fold the same 2px into its offset to keep the
4691
4704
  search field top aligned with the provider tiles. */
4692
- .workbench-window:has([data-agent-gui-workbench-header="true"])
4705
+ .workbench-window:has(
4706
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
4707
+ )
4693
4708
  .agent-gui-node__rail-toolbar {
4694
4709
  padding-top: calc(var(--agent-gui-workbench-header-height) + 2px);
4695
4710
  }
4696
4711
 
4697
- .workbench-window:has([data-agent-gui-workbench-header="true"])
4712
+ .workbench-window:has(
4713
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
4714
+ )
4698
4715
  .agent-gui-node__detail-panel {
4699
4716
  position: relative;
4700
4717
  }
4701
4718
 
4702
- .workbench-window:has([data-agent-gui-workbench-header="true"])
4719
+ .workbench-window:has(
4720
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
4721
+ )
4703
4722
  .agent-gui-node__detail {
4704
4723
  padding-top: var(--agent-gui-workbench-header-height);
4705
4724
  }
4706
4725
 
4707
- .workbench-window:has([data-agent-gui-workbench-header="true"])
4726
+ .workbench-window:has(
4727
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
4728
+ )
4708
4729
  .agent-gui-node__timeline-with-composer {
4709
4730
  padding-top: 20px;
4710
4731
  }
@@ -5198,11 +5219,13 @@ aside.workspace-agents-status-panel
5198
5219
  }
5199
5220
 
5200
5221
  .workbench-window:has(
5201
- .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
5222
+ > .workbench-window__header
5223
+ .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
5202
5224
  )
5203
5225
  .agent-gui-workbench-header__session-title,
5204
5226
  .workbench-window:has(
5205
- .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
5227
+ > .workbench-window__header
5228
+ .agent-gui-workbench-header[data-agent-gui-standalone-window-header="true"]
5206
5229
  )
5207
5230
  .agent-gui-workbench-header__detail-title {
5208
5231
  box-sizing: border-box;
@@ -5478,7 +5501,9 @@ aside.workspace-agents-status-panel
5478
5501
  );
5479
5502
  }
5480
5503
 
5481
- .workbench-window:has([data-agent-gui-workbench-header="true"])
5504
+ .workbench-window:has(
5505
+ > .workbench-window__header [data-agent-gui-workbench-header="true"]
5506
+ )
5482
5507
  .agent-gui-node__provider-rail-panel::after {
5483
5508
  top: var(--agent-gui-workbench-header-height);
5484
5509
  }