@tutti-os/agent-gui 0.0.33 → 0.0.35

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 (46) hide show
  1. package/README.md +5 -0
  2. package/dist/{AgentMessageMarkdown-Cp70W-Z2.d.ts → AgentMessageMarkdown-0sV8Biv3.d.ts} +53 -5
  3. package/dist/agent-conversation/index.d.ts +4 -4
  4. package/dist/agent-conversation/index.js +5 -5
  5. package/dist/agent-message-center/index.d.ts +2 -2
  6. package/dist/agent-message-center/index.js +29 -8
  7. package/dist/agent-message-center/index.js.map +1 -1
  8. package/dist/{agentConversationVM-BElW2LNR.d.ts → agentConversationVM-xuzmD5IL.d.ts} +2 -0
  9. package/dist/app/renderer/agentactivity.css +54 -128
  10. package/dist/{chunk-SGQ4C7JE.js → chunk-2ADVHCST.js} +2 -1
  11. package/dist/chunk-2ADVHCST.js.map +1 -0
  12. package/dist/{chunk-WPWZKKKV.js → chunk-3LEUGNCT.js} +2 -2
  13. package/dist/{chunk-AFTAFV2C.js → chunk-CMXRLF64.js} +85 -13
  14. package/dist/chunk-CMXRLF64.js.map +1 -0
  15. package/dist/{chunk-RDCBACWR.js → chunk-JYH2ITNL.js} +5 -5
  16. package/dist/{chunk-RQ3HEF42.js → chunk-KFMD33UD.js} +36 -12
  17. package/dist/chunk-KFMD33UD.js.map +1 -0
  18. package/dist/{chunk-ZWYHKGQ7.js → chunk-NCS7X3XY.js} +11 -9
  19. package/dist/{chunk-ZWYHKGQ7.js.map → chunk-NCS7X3XY.js.map} +1 -1
  20. package/dist/{chunk-GSZPMKFW.js → chunk-O56P2KSZ.js} +237 -26
  21. package/dist/chunk-O56P2KSZ.js.map +1 -0
  22. package/dist/{chunk-ERRANBGS.js → chunk-U3D7YI47.js} +7 -11
  23. package/dist/chunk-U3D7YI47.js.map +1 -0
  24. package/dist/{chunk-OOQIJXCA.js → chunk-UN4XGHLQ.js} +3 -2
  25. package/dist/{chunk-A4KUAXE5.js → chunk-VPC55T7P.js} +2 -2
  26. package/dist/context-mention-palette/index.js +6 -6
  27. package/dist/i18n/index.d.ts +34 -10
  28. package/dist/i18n/index.js +1 -1
  29. package/dist/index.d.ts +5 -4
  30. package/dist/index.js +1012 -477
  31. package/dist/index.js.map +1 -1
  32. package/dist/plan-decision-ops.d.ts +1 -1
  33. package/dist/workbench/contribution.js +1 -1
  34. package/dist/workbench/index.js +1 -1
  35. package/dist/workspace-agent-generated-files.js +2 -2
  36. package/dist/{workspaceLinkActions-CqWZaCY4.d.ts → workspaceLinkActions-C6POH38D.d.ts} +7 -1
  37. package/package.json +12 -12
  38. package/dist/chunk-AFTAFV2C.js.map +0 -1
  39. package/dist/chunk-ERRANBGS.js.map +0 -1
  40. package/dist/chunk-GSZPMKFW.js.map +0 -1
  41. package/dist/chunk-RQ3HEF42.js.map +0 -1
  42. package/dist/chunk-SGQ4C7JE.js.map +0 -1
  43. /package/dist/{chunk-WPWZKKKV.js.map → chunk-3LEUGNCT.js.map} +0 -0
  44. /package/dist/{chunk-RDCBACWR.js.map → chunk-JYH2ITNL.js.map} +0 -0
  45. /package/dist/{chunk-OOQIJXCA.js.map → chunk-UN4XGHLQ.js.map} +0 -0
  46. /package/dist/{chunk-A4KUAXE5.js.map → chunk-VPC55T7P.js.map} +0 -0
@@ -18,6 +18,7 @@ interface WorkspaceAgentSessionDetailMessage {
18
18
  systemNotice?: {
19
19
  noticeKind: string | null;
20
20
  severity: string | null;
21
+ source?: string | null;
21
22
  title: string | null;
22
23
  detail: string | null;
23
24
  retryable: boolean | null;
@@ -158,6 +159,7 @@ interface AgentMessageContentVM {
158
159
  systemNotice?: {
159
160
  noticeKind: string | null;
160
161
  severity: string | null;
162
+ source?: string | null;
161
163
  title: string | null;
162
164
  detail: string | null;
163
165
  retryable: boolean | null;
@@ -162,9 +162,9 @@
162
162
  [data-testid="workspace-agent-message-center"] {
163
163
  --agent-gui-package-accent: var(--accent-codex);
164
164
  --agent-gui-package-accent-strong: var(--accent-codex);
165
- --agent-gui-package-success: rgb(34 197 94);
166
- --agent-gui-package-warning: rgb(234 121 8);
167
- --agent-gui-package-danger: rgb(220 38 38);
165
+ --agent-gui-package-success: var(--state-success);
166
+ --agent-gui-package-warning: var(--state-warning);
167
+ --agent-gui-package-danger: var(--state-danger);
168
168
  --agent-gui-accent: var(--agent-gui-package-accent);
169
169
  --agent-gui-accent-strong: var(--agent-gui-package-accent-strong);
170
170
  --agent-gui-success: var(--agent-gui-package-success);
@@ -3131,6 +3131,7 @@ aside.workspace-agents-status-panel
3131
3131
  }
3132
3132
 
3133
3133
  .agent-gui-conversation__user-message-flow {
3134
+ row-gap: 14px;
3134
3135
  justify-items: end;
3135
3136
  }
3136
3137
 
@@ -3808,9 +3809,9 @@ aside.workspace-agents-status-panel
3808
3809
  var(--agent-gui-package-accent) 12%
3809
3810
  );
3810
3811
  --agent-gui-package-border-focus: var(--accent-codex-border);
3811
- --agent-gui-package-success: rgb(34 197 94);
3812
- --agent-gui-package-warning: rgb(234 121 8);
3813
- --agent-gui-package-danger: rgb(220 38 38);
3812
+ --agent-gui-package-success: var(--state-success);
3813
+ --agent-gui-package-warning: var(--state-warning);
3814
+ --agent-gui-package-danger: var(--state-danger);
3814
3815
  --agent-gui-accent: var(--agent-gui-package-accent);
3815
3816
  --agent-gui-accent-strong: var(--agent-gui-package-accent-strong);
3816
3817
  --agent-gui-accent-bg: var(--agent-gui-package-accent-bg);
@@ -3856,12 +3857,13 @@ aside.workspace-agents-status-panel
3856
3857
  }
3857
3858
 
3858
3859
  .agent-gui-node__rail-panel {
3860
+ position: relative;
3861
+ z-index: 2;
3859
3862
  min-width: 0;
3860
3863
  min-height: 0;
3861
3864
  height: 100%;
3862
- border-right: 1px solid var(--line-1);
3863
- overflow: hidden;
3864
- position: relative;
3865
+ border-right: 1px solid var(--agent-gui-border-subtle, var(--line-2));
3866
+ overflow: visible;
3865
3867
  isolation: isolate;
3866
3868
  }
3867
3869
 
@@ -3983,6 +3985,8 @@ aside.workspace-agents-status-panel
3983
3985
  }
3984
3986
 
3985
3987
  .agent-gui-node__rail-toolbar {
3988
+ --agent-gui-rail-control-radius: 6px;
3989
+
3986
3990
  display: grid;
3987
3991
  grid-template-columns: minmax(0, 1fr) max-content;
3988
3992
  align-items: center;
@@ -4104,8 +4108,23 @@ aside.workspace-agents-status-panel
4104
4108
  flex: 1 1 auto;
4105
4109
  width: 100%;
4106
4110
  min-width: 0;
4111
+ box-sizing: border-box;
4112
+ height: 32px !important;
4113
+ min-height: 32px;
4114
+ max-height: 32px;
4115
+ border: 0 !important;
4116
+ border-radius: var(--agent-gui-rail-control-radius) !important;
4107
4117
  padding-left: 12px;
4108
4118
  padding-right: 36px;
4119
+ font-size: 13px !important;
4120
+ line-height: 18px;
4121
+ appearance: none;
4122
+ }
4123
+
4124
+ .room-issue-node__search-input:hover,
4125
+ .room-issue-node__search-input:focus,
4126
+ .room-issue-node__search-input:focus-visible {
4127
+ background: var(--transparency-hover);
4109
4128
  }
4110
4129
 
4111
4130
  .room-issue-node__search-field[data-has-value="false"]
@@ -4170,16 +4189,20 @@ aside.workspace-agents-status-panel
4170
4189
  flex: 0 0 auto;
4171
4190
  width: auto;
4172
4191
  min-width: max-content;
4192
+ box-sizing: border-box;
4173
4193
  height: 32px;
4174
4194
  min-height: 32px;
4175
- padding-inline: 12px;
4195
+ max-height: 32px;
4196
+ border: 0 !important;
4197
+ border-radius: var(--agent-gui-rail-control-radius) !important;
4198
+ font-size: 13px;
4176
4199
  gap: 8px;
4177
4200
  white-space: nowrap;
4178
4201
  }
4179
4202
 
4180
4203
  .agent-gui-node__new-conversation-icon-button svg {
4181
- width: 16px;
4182
- height: 16px;
4204
+ width: 14px;
4205
+ height: 14px;
4183
4206
  flex-shrink: 0;
4184
4207
  }
4185
4208
 
@@ -4436,45 +4459,16 @@ button.agent-gui-node__conversation-section-toggle:hover
4436
4459
  }
4437
4460
 
4438
4461
  .agent-gui-node__conversation-section-action-tooltip-wrap {
4439
- position: relative;
4440
4462
  display: inline-flex;
4441
4463
  flex: none;
4442
4464
  }
4443
4465
 
4444
4466
  .agent-gui-node__conversation-section-action-tooltip {
4445
- position: absolute;
4446
- top: calc(100% + 6px);
4447
- left: 50%;
4448
- z-index: var(--z-tooltip);
4449
4467
  max-width: 180px;
4450
- padding: 5px 8px;
4451
- border: 1px solid var(--line-2, var(--tutti-line-2));
4452
- border-radius: 6px;
4453
- background: var(--background-fronted);
4454
- box-shadow: 0 10px 26px rgb(0 0 0 / 0.18);
4455
- color: var(--text-primary);
4456
- font-size: 11px;
4457
- font-weight: 500;
4458
- line-height: 1.2;
4459
- opacity: 0;
4460
- overflow: hidden;
4461
- pointer-events: none;
4462
4468
  text-overflow: ellipsis;
4463
- transform: translate(-50%, -2px);
4464
- transition:
4465
- opacity 120ms ease,
4466
- transform 120ms ease;
4467
4469
  white-space: nowrap;
4468
4470
  }
4469
4471
 
4470
- .agent-gui-node__conversation-section-action-tooltip-wrap:hover
4471
- .agent-gui-node__conversation-section-action-tooltip,
4472
- .agent-gui-node__conversation-section-action-tooltip-wrap:focus-within
4473
- .agent-gui-node__conversation-section-action-tooltip {
4474
- opacity: 1;
4475
- transform: translate(-50%, 0);
4476
- }
4477
-
4478
4472
  .agent-gui-node__conversation-section-more-button {
4479
4473
  flex: none;
4480
4474
  opacity: 0;
@@ -5439,100 +5433,32 @@ button.agent-gui-node__conversation-section-toggle:hover
5439
5433
  outline: none;
5440
5434
  }
5441
5435
 
5442
- .agent-gui-node__usage-alert-banner {
5443
- display: flex;
5444
- align-items: center;
5445
- justify-content: space-between;
5446
- gap: 8px;
5447
- margin: 0 24px;
5448
- border-radius: 8px 8px 0 0;
5449
- padding: 6px 10px;
5450
- font-size: 13px;
5451
- font-weight: 400;
5452
- line-height: 16px;
5453
- color: var(--agent-gui-warning, var(--cove-label-orange));
5454
- background: color-mix(
5455
- in srgb,
5456
- var(--agent-gui-warning, var(--cove-label-orange)) 12%,
5457
- transparent
5458
- );
5459
- }
5460
-
5461
- .agent-gui-node__usage-alert-banner[data-usage-alert-tier="critical"] {
5462
- color: var(--agent-gui-danger, var(--state-danger));
5463
- background: color-mix(
5464
- in srgb,
5465
- var(--agent-gui-danger, var(--state-danger)) 12%,
5466
- transparent
5467
- );
5468
- }
5469
-
5470
- .agent-gui-node__usage-alert-message {
5471
- min-width: 0;
5472
- overflow-wrap: anywhere;
5473
- }
5474
-
5475
- .agent-gui-node__usage-alert-actions {
5476
- display: inline-flex;
5477
- flex: 0 0 auto;
5478
- align-items: center;
5479
- gap: 4px;
5480
- }
5481
-
5482
- .agent-gui-node__usage-alert-dismiss {
5483
- flex: 0 0 auto;
5484
- border-radius: 4px;
5485
- color: inherit;
5486
- }
5487
-
5488
- .agent-gui-node__usage-alert-dismiss:hover,
5489
- .agent-gui-node__usage-alert-dismiss:focus-visible {
5490
- background: color-mix(in srgb, currentColor 12%, transparent);
5491
- color: inherit;
5492
- }
5493
-
5494
5436
  .agent-gui-node__provider-setup-notice {
5495
5437
  position: absolute;
5496
- top: 16px;
5497
- right: var(--agent-gui-detail-padding-x);
5438
+ top: 8px;
5498
5439
  left: var(--agent-gui-detail-padding-x);
5499
5440
  z-index: 2;
5500
- display: flex;
5501
- align-items: center;
5502
- gap: 8px;
5503
5441
  box-sizing: border-box;
5442
+ width: max-content;
5443
+ max-width: min(calc(100% - (var(--agent-gui-detail-padding-x) * 2)), 420px);
5504
5444
  margin: 0;
5505
- border: 1px solid
5506
- color-mix(
5507
- in srgb,
5508
- var(--agent-gui-warning, var(--state-warning)) 26%,
5509
- transparent
5510
- );
5511
- border-radius: 8px;
5512
- padding: 8px 10px;
5513
- color: var(--agent-gui-warning, var(--state-warning));
5514
- background: color-mix(
5515
- in srgb,
5516
- var(--agent-gui-warning, var(--state-warning)) 9%,
5517
- transparent
5518
- );
5519
- font-size: 13px;
5520
- line-height: 18px;
5521
5445
  pointer-events: auto;
5522
5446
  }
5523
5447
 
5524
5448
  .agent-gui-node__detail-header + .agent-gui-node__provider-setup-notice {
5525
- top: calc(64px + 8px);
5449
+ top: calc(64px + 4px);
5526
5450
  }
5527
5451
 
5528
- .agent-gui-node__provider-setup-notice-icon {
5452
+ .agent-gui-node__provider-setup-notice-action {
5529
5453
  flex: 0 0 auto;
5454
+ margin-left: auto;
5455
+ border: 0;
5456
+ padding: 0;
5457
+ background: transparent;
5530
5458
  color: currentColor;
5531
- }
5532
-
5533
- .agent-gui-node__provider-setup-notice-text {
5534
- min-width: 0;
5535
- overflow-wrap: anywhere;
5459
+ font: inherit;
5460
+ text-decoration: underline;
5461
+ cursor: pointer;
5536
5462
  }
5537
5463
 
5538
5464
  .agent-gui-node__layout [data-slot="status-dot"],
@@ -5580,25 +5506,25 @@ button.agent-gui-node__conversation-section-toggle:hover
5580
5506
  .agent-gui-node__layout [data-slot="status-dot"][data-tone="green"],
5581
5507
  [data-testid="workspace-agent-message-center"]
5582
5508
  [data-slot="status-dot"][data-tone="green"] {
5583
- --agent-gui-status-dot-color: var(--agent-gui-success, var(--state-success));
5509
+ --agent-gui-status-dot-color: var(--state-success);
5584
5510
  }
5585
5511
 
5586
5512
  .agent-gui-node__layout [data-slot="status-dot"][data-tone="blue"],
5587
5513
  [data-testid="workspace-agent-message-center"]
5588
5514
  [data-slot="status-dot"][data-tone="blue"] {
5589
- --agent-gui-status-dot-color: var(--agent-gui-accent);
5515
+ --agent-gui-status-dot-color: var(--status-running);
5590
5516
  }
5591
5517
 
5592
5518
  .agent-gui-node__layout [data-slot="status-dot"][data-tone="amber"],
5593
5519
  [data-testid="workspace-agent-message-center"]
5594
5520
  [data-slot="status-dot"][data-tone="amber"] {
5595
- --agent-gui-status-dot-color: var(--agent-gui-warning, var(--state-warning));
5521
+ --agent-gui-status-dot-color: var(--state-warning);
5596
5522
  }
5597
5523
 
5598
5524
  .agent-gui-node__layout [data-slot="status-dot"][data-tone="red"],
5599
5525
  [data-testid="workspace-agent-message-center"]
5600
5526
  [data-slot="status-dot"][data-tone="red"] {
5601
- --agent-gui-status-dot-color: var(--agent-gui-danger, var(--state-danger));
5527
+ --agent-gui-status-dot-color: var(--state-danger);
5602
5528
  }
5603
5529
 
5604
5530
  .agent-gui-node__layout [data-slot="status-dot"][data-pulse="true"],
@@ -6828,9 +6754,9 @@ html[data-theme="light"] [data-message-center-item-id].agent-gui-edge-glow {
6828
6754
  --agent-gui-border-subtle: var(--line-2);
6829
6755
  --agent-gui-package-accent: var(--tutti-purple);
6830
6756
  --agent-gui-package-accent-strong: var(--tutti-purple);
6831
- --agent-gui-package-success: rgb(34 197 94);
6832
- --agent-gui-package-warning: rgb(234 121 8);
6833
- --agent-gui-package-danger: rgb(220 38 38);
6757
+ --agent-gui-package-success: var(--state-success);
6758
+ --agent-gui-package-warning: var(--state-warning);
6759
+ --agent-gui-package-danger: var(--state-danger);
6834
6760
  --agent-gui-accent: var(--agent-gui-package-accent);
6835
6761
  --agent-gui-accent-strong: var(--agent-gui-package-accent-strong);
6836
6762
  --agent-gui-success: var(--agent-gui-package-success);
@@ -107,6 +107,7 @@ function toAgentHostRuntimeApi(hostApi) {
107
107
  filesystem: hostApi.filesystem,
108
108
  meta: hostApi.meta,
109
109
  onHostEvent: hostApi.onHostEvent,
110
+ persistence: hostApi.persistence,
110
111
  runtime: hostApi.runtime,
111
112
  userProjects: hostApi.userProjects,
112
113
  workspace: hostApi.workspace,
@@ -193,4 +194,4 @@ export {
193
194
  useOptionalAgentHostApi,
194
195
  getOptionalAgentHostApi
195
196
  };
196
- //# sourceMappingURL=chunk-SGQ4C7JE.js.map
197
+ //# sourceMappingURL=chunk-2ADVHCST.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../agentActivityRuntime.tsx","../agentActivityHost.tsx","../host/agentHostApi.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n useSyncExternalStore,\n type JSX,\n type PropsWithChildren\n} from \"react\";\nimport type {\n AgentActivityCancelSessionInput,\n AgentActivityCancelSessionResult,\n AgentActivityCreateSessionInput,\n AgentActivityDeleteSessionInput,\n AgentActivityDeleteSessionResult,\n AgentActivityMessageOrder,\n AgentActivityMessagePage,\n AgentActivitySendInput,\n AgentActivitySendInputResult,\n AgentActivitySession,\n AgentActivitySnapshot,\n AgentActivitySnapshotListener,\n AgentActivitySubmitInteractiveInput\n} from \"@tutti-os/agent-activity-core\";\nimport type {\n AgentHostAgentSessionComposerSettings,\n AgentHostActivateAgentSessionResult,\n AgentHostRuntimeOpenclawGatewayWarmupResult,\n AgentHostUpdateAgentSessionSettingsResult,\n AgentHostUnactivateAgentSessionResult,\n AgentHostAgentSessionState\n} from \"./shared/contracts/dto\";\n\nexport interface AgentActivityRuntimeListSessionMessagesInput {\n afterVersion?: number;\n beforeVersion?: number;\n cache?: boolean;\n agentSessionId: string;\n limit?: number;\n order?: AgentActivityMessageOrder;\n signal?: AbortSignal;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeListGeneratedFilesInput {\n limit?: number;\n query?: string;\n sessionCwd?: string;\n signal?: AbortSignal;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeGeneratedFile {\n label: string;\n path: string;\n}\n\nexport interface AgentActivityRuntimeGeneratedFileList {\n entries: AgentActivityRuntimeGeneratedFile[];\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeEnsureSessionSynchronizedInput {\n afterVersion?: number;\n agentSessionId: string;\n onError?: (error: unknown) => void;\n workspaceId: string;\n}\n\nexport type AgentActivityRuntimeRetainSessionEventsInput =\n AgentActivityRuntimeEnsureSessionSynchronizedInput;\n\nexport interface AgentActivityRuntimeSetSessionPinnedInput {\n agentSessionId: string;\n pinned: boolean;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeTrackSettingsProjectChangeInput {\n action: \"clear\" | \"create_new\" | \"select_existing\";\n agentSessionId: string;\n provider?: string | null;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeGetSessionControlStateInput {\n agentSessionId: string;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeGetComposerOptionsInput {\n cwd?: string | null;\n force?: boolean;\n provider?: string;\n settings?: AgentHostAgentSessionComposerSettings | null;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeUpdateSessionSettingsInput {\n agentSessionId: string;\n settings: AgentHostAgentSessionComposerSettings;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeTrackDraftComposerSettingsChangeInput {\n nextSettings: AgentHostAgentSessionComposerSettings;\n previousSettings: AgentHostAgentSessionComposerSettings;\n provider: string;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeWarmupOpenclawGatewayInput {\n workspaceId?: string | null;\n}\n\nexport interface AgentActivityRuntimeDiagnosticInput {\n details?: Record<string, unknown>;\n event: string;\n level?: \"debug\" | \"info\" | \"warn\" | \"error\";\n source?: string;\n workspaceId?: string | null;\n}\n\nexport interface AgentActivityRuntimeActivateSessionInput {\n agentSessionId: string;\n cwd?: string;\n initialContent?: AgentActivitySendInput[\"content\"];\n /** 仅展示用首轮文本(bundle 折叠成一个 chip);initialContent 仍带展开后的文件。 */\n initialDisplayPrompt?: string | null;\n metadata?: Record<string, unknown>;\n mode: \"existing\" | \"new\";\n openclawGatewayReady?: boolean;\n provider?: string;\n settings?: AgentHostAgentSessionComposerSettings;\n title?: string;\n visible?: boolean;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeUnactivateSessionInput {\n agentSessionId: string;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeReadSessionAttachmentInput {\n agentSessionId: string;\n attachmentId: string;\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeReadPromptAssetInput {\n agentSessionId?: string | null;\n assetId?: string | null;\n hostPath?: string | null;\n kind?: string | null;\n mimeType: string;\n name?: string | null;\n path?: string | null;\n sha256?: string | null;\n uploadStatus?: string | null;\n uri?: string | null;\n workspaceId: string;\n}\n\nexport type AgentActivityRuntimePromptContentBlock =\n AgentActivitySendInput[\"content\"][number] & {\n assetId?: string;\n hostPath?: string;\n kind?: string;\n path?: string;\n sizeBytes?: number;\n uploadStatus?: string;\n uri?: string;\n };\n\nexport interface AgentActivityRuntimeUploadPromptContentInput {\n content: AgentActivityRuntimePromptContentBlock[];\n workspaceId: string;\n}\n\nexport interface AgentActivityRuntimeUploadPromptContentResult {\n content: AgentActivityRuntimePromptContentBlock[];\n}\n\nexport interface AgentActivityRuntimeSessionAttachment {\n attachmentId: string;\n mimeType: string;\n name?: string;\n data: string;\n}\n\nexport interface AgentActivityRuntimePromptAsset {\n assetId?: string;\n hostPath?: string;\n kind?: string;\n mimeType: string;\n name?: string;\n path: string;\n uploadStatus?: string;\n uri?: string;\n data: string;\n}\n\nexport interface AgentActivityRuntime {\n cancelSession(\n input: AgentActivityCancelSessionInput\n ): Promise<AgentActivityCancelSessionResult>;\n createSession(\n input: AgentActivityCreateSessionInput\n ): Promise<AgentActivitySession>;\n deleteSession(\n input: AgentActivityDeleteSessionInput\n ): Promise<AgentActivityDeleteSessionResult>;\n activateSession(\n input: AgentActivityRuntimeActivateSessionInput\n ): Promise<AgentHostActivateAgentSessionResult>;\n getSession(\n workspaceId: string,\n agentSessionId: string\n ): Promise<AgentActivitySession>;\n getComposerOptions(\n input: AgentActivityRuntimeGetComposerOptionsInput\n ): Promise<unknown>;\n updateSessionSettings(\n input: AgentActivityRuntimeUpdateSessionSettingsInput\n ): Promise<AgentHostUpdateAgentSessionSettingsResult>;\n warmupOpenclawGateway?(\n input?: AgentActivityRuntimeWarmupOpenclawGatewayInput\n ): Promise<AgentHostRuntimeOpenclawGatewayWarmupResult>;\n getSessionControlState(\n input: AgentActivityRuntimeGetSessionControlStateInput\n ): Promise<AgentHostAgentSessionState>;\n getSnapshot(workspaceId: string): AgentActivitySnapshot;\n listSessionMessages(\n input: AgentActivityRuntimeListSessionMessagesInput\n ): Promise<AgentActivityMessagePage>;\n listAgentGeneratedFiles?(\n input: AgentActivityRuntimeListGeneratedFilesInput\n ): Promise<AgentActivityRuntimeGeneratedFileList>;\n load(\n workspaceId: string,\n signal?: AbortSignal\n ): Promise<AgentActivitySnapshot>;\n ensureSessionSynchronized?(\n input: AgentActivityRuntimeEnsureSessionSynchronizedInput\n ): () => void;\n /** @deprecated Use ensureSessionSynchronized. */\n retainSessionEvents(\n input: AgentActivityRuntimeRetainSessionEventsInput\n ): () => void;\n sendInput(\n input: AgentActivitySendInput\n ): Promise<AgentActivitySendInputResult>;\n uploadPromptContent?(\n input: AgentActivityRuntimeUploadPromptContentInput\n ): Promise<AgentActivityRuntimeUploadPromptContentResult>;\n readSessionAttachment?(\n input: AgentActivityRuntimeReadSessionAttachmentInput\n ): Promise<AgentActivityRuntimeSessionAttachment>;\n readPromptAsset?(\n input: AgentActivityRuntimeReadPromptAssetInput\n ): Promise<AgentActivityRuntimePromptAsset>;\n setSessionPinned(\n input: AgentActivityRuntimeSetSessionPinnedInput\n ): Promise<AgentActivitySession>;\n trackSettingsProjectChange?(\n input: AgentActivityRuntimeTrackSettingsProjectChangeInput\n ): Promise<void>;\n trackDraftComposerSettingsChange?(\n input: AgentActivityRuntimeTrackDraftComposerSettingsChangeInput\n ): Promise<void>;\n reportDiagnostic?(\n input: AgentActivityRuntimeDiagnosticInput\n ): Promise<void> | void;\n unactivateSession(\n input: AgentActivityRuntimeUnactivateSessionInput\n ): Promise<AgentHostUnactivateAgentSessionResult>;\n submitInteractive(\n input: AgentActivitySubmitInteractiveInput\n ): Promise<unknown>;\n subscribeSessionEvents(\n workspaceId: string,\n listener: (event: unknown) => void\n ): () => void;\n subscribe(\n workspaceId: string,\n listener: AgentActivitySnapshotListener\n ): () => void;\n}\n\nconst AgentActivityRuntimeContext = createContext<AgentActivityRuntime | null>(\n null\n);\n\nlet currentAgentActivityRuntime: AgentActivityRuntime | null = null;\n\nexport interface AgentActivityRuntimeProviderProps extends PropsWithChildren {\n runtime?: AgentActivityRuntime | null;\n}\n\nexport function AgentActivityRuntimeProvider({\n children,\n runtime\n}: AgentActivityRuntimeProviderProps): JSX.Element {\n currentAgentActivityRuntime = runtime ?? null;\n return (\n <AgentActivityRuntimeContext.Provider value={runtime ?? null}>\n {children}\n </AgentActivityRuntimeContext.Provider>\n );\n}\n\nexport function useAgentActivityRuntime(): AgentActivityRuntime {\n const runtime =\n useContext(AgentActivityRuntimeContext) ?? getTestAgentActivityRuntime();\n if (!runtime) {\n throw new Error(\n \"AgentActivityRuntimeProvider is missing an AgentActivityRuntime instance.\"\n );\n }\n return runtime;\n}\n\nexport function useOptionalAgentActivityRuntime(): AgentActivityRuntime | null {\n return (\n useContext(AgentActivityRuntimeContext) ?? getTestAgentActivityRuntime()\n );\n}\n\nexport function useAgentActivitySnapshot(\n workspaceId: string\n): AgentActivitySnapshot {\n const runtime = useAgentActivityRuntime();\n const normalizedWorkspaceId = workspaceId.trim();\n return useSyncExternalStore(\n (listener) => runtime.subscribe(normalizedWorkspaceId, listener),\n () => runtime.getSnapshot(normalizedWorkspaceId),\n () => runtime.getSnapshot(normalizedWorkspaceId)\n );\n}\n\nexport function getAgentActivityRuntime(): AgentActivityRuntime {\n const runtime =\n getExplicitWindowTestAgentActivityRuntime() ??\n currentAgentActivityRuntime ??\n getTestAgentActivityRuntime();\n if (!runtime) {\n throw new Error(\n \"AgentActivityRuntimeProvider is missing an AgentActivityRuntime instance.\"\n );\n }\n return runtime;\n}\n\nexport function getOptionalAgentActivityRuntime(): AgentActivityRuntime | null {\n return (\n getExplicitWindowTestAgentActivityRuntime() ??\n currentAgentActivityRuntime ??\n getTestAgentActivityRuntime()\n );\n}\n\nexport function resetAgentActivityRuntimeForTests(): void {\n if (process.env.NODE_ENV === \"test\") {\n currentAgentActivityRuntime = null;\n }\n}\n\nexport function setAgentActivityRuntimeForTests(\n runtime: AgentActivityRuntime | null\n): void {\n if (process.env.NODE_ENV === \"test\") {\n currentAgentActivityRuntime = runtime;\n }\n}\n\nfunction getTestAgentActivityRuntime(): AgentActivityRuntime | null {\n if (process.env.NODE_ENV !== \"test\") {\n return null;\n }\n if (typeof window === \"undefined\") {\n return null;\n }\n const explicitRuntime = getExplicitWindowTestAgentActivityRuntime();\n if (explicitRuntime) {\n return explicitRuntime;\n }\n if (currentAgentActivityRuntime) {\n return currentAgentActivityRuntime;\n }\n const testRuntime = (\n window as unknown as Window & {\n agentActivityRuntime?: AgentActivityRuntime;\n }\n ).agentActivityRuntime;\n return testRuntime ?? null;\n}\n\nfunction getExplicitWindowTestAgentActivityRuntime(): AgentActivityRuntime | null {\n if (process.env.NODE_ENV !== \"test\" || typeof window === \"undefined\") {\n return null;\n }\n const testDescriptor = Object.getOwnPropertyDescriptor(\n window,\n \"agentActivityRuntime\"\n );\n if (!testDescriptor || !(\"value\" in testDescriptor)) {\n return null;\n }\n return (testDescriptor.value as AgentActivityRuntime | undefined) ?? null;\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type JSX,\n type PropsWithChildren\n} from \"react\";\nimport {\n toAgentHostRuntimeApi,\n type AgentHostInputApi,\n type AgentHostRuntimeApi\n} from \"./host/agentHostApi\";\nimport {\n AgentActivityRuntimeProvider,\n type AgentActivityRuntime\n} from \"./agentActivityRuntime\";\n\nconst AgentActivityHostContext = createContext<AgentHostRuntimeApi | null>(\n null\n);\n\nlet currentAgentHostApi: AgentHostRuntimeApi | null = null;\n\nexport interface AgentActivityHostProviderProps extends PropsWithChildren {\n agentActivityRuntime?: AgentActivityRuntime | null;\n agentHostApi?: AgentHostInputApi | null;\n}\n\nexport function AgentActivityHostProvider({\n agentActivityRuntime,\n agentHostApi,\n children\n}: AgentActivityHostProviderProps): JSX.Element {\n const resolvedAgentHostApi = useMemo(\n () => (agentHostApi ? toAgentHostRuntimeApi(agentHostApi) : null),\n [agentHostApi]\n );\n currentAgentHostApi = resolvedAgentHostApi;\n return (\n <AgentActivityRuntimeProvider runtime={agentActivityRuntime}>\n <AgentActivityHostContext.Provider value={resolvedAgentHostApi}>\n {children}\n </AgentActivityHostContext.Provider>\n </AgentActivityRuntimeProvider>\n );\n}\n\nexport function useAgentHostApi(): AgentHostRuntimeApi {\n const agentHostApi =\n useContext(AgentActivityHostContext) ?? getTestAgentHostApi();\n if (!agentHostApi) {\n throw new Error(\n \"AgentActivityHostProvider is missing an agentHostApi instance.\"\n );\n }\n return agentHostApi;\n}\n\nexport function useOptionalAgentHostApi(): AgentHostRuntimeApi | null {\n return useContext(AgentActivityHostContext) ?? getTestAgentHostApi();\n}\n\nexport function getAgentHostApi(): AgentHostRuntimeApi {\n const agentHostApi =\n getExplicitWindowTestAgentHostApi() ??\n currentAgentHostApi ??\n getTestAgentHostApi();\n if (!agentHostApi) {\n throw new Error(\n \"AgentActivityHostProvider is missing an agentHostApi instance.\"\n );\n }\n return agentHostApi;\n}\n\nexport function getOptionalAgentHostApi(): AgentHostRuntimeApi | null {\n return (\n getExplicitWindowTestAgentHostApi() ??\n currentAgentHostApi ??\n getTestAgentHostApi()\n );\n}\n\nexport function resetAgentHostApiForTests(): void {\n if (process.env.NODE_ENV === \"test\") {\n currentAgentHostApi = null;\n }\n}\n\nexport function setAgentHostApiForTests(\n agentHostApi: AgentHostInputApi | AgentHostRuntimeApi | null\n): void {\n if (process.env.NODE_ENV === \"test\") {\n currentAgentHostApi = agentHostApi\n ? toAgentHostRuntimeApi(agentHostApi)\n : null;\n }\n}\n\nfunction getTestAgentHostApi(): AgentHostRuntimeApi | null {\n if (process.env.NODE_ENV !== \"test\") {\n return null;\n }\n if (typeof window === \"undefined\") {\n return null;\n }\n const explicitAgentHostApi = getExplicitWindowTestAgentHostApi();\n if (explicitAgentHostApi) {\n return explicitAgentHostApi;\n }\n if (currentAgentHostApi) {\n return currentAgentHostApi;\n }\n const testAgentHostApi = (\n window as unknown as Window & {\n agentHostApi?: AgentHostInputApi | AgentHostRuntimeApi;\n }\n ).agentHostApi;\n return testAgentHostApi ? toAgentHostRuntimeApi(testAgentHostApi) : null;\n}\n\nfunction getExplicitWindowTestAgentHostApi(): AgentHostRuntimeApi | null {\n if (process.env.NODE_ENV !== \"test\" || typeof window === \"undefined\") {\n return null;\n }\n const testDescriptor = Object.getOwnPropertyDescriptor(\n window,\n \"agentHostApi\"\n );\n if (!testDescriptor || !(\"value\" in testDescriptor)) {\n return null;\n }\n const testAgentHostApi = testDescriptor.value as\n | AgentHostInputApi\n | AgentHostRuntimeApi\n | undefined;\n return testAgentHostApi ? toAgentHostRuntimeApi(testAgentHostApi) : null;\n}\n","import type {\n AgentHostBatchUserInfoInput,\n AgentHostBatchUserInfoResult,\n AgentHostDeleteWorkspaceAgentSessionInput,\n AgentHostWorkspaceAgentListInput as AgentHostListWorkspaceAgentsInput,\n AgentHostListWorkspaceAgentProbesInput,\n AgentHostWorkspaceAgentSessionMessages,\n AgentHostWorkspaceAgentSessionMessagesInput,\n AgentHostWorkspaceAgentSessionSummary,\n AgentHostWorkspaceAgentSessionSummaryInput,\n AgentHostWorkspaceAgentProbesResult,\n AgentHostWorkspaceAgentSnapshot,\n PersistWriteResult,\n ReadWorkspaceAgentReadStateInput,\n ReadWorkspaceFileResult as AgentHostReadWorkspaceFileResult,\n WorkspaceAgentReadStateSnapshot,\n WriteWorkspaceAgentReadStateInput\n} from \"../shared/contracts/dto\";\nimport type { WorkspaceUserProjectService } from \"@tutti-os/workspace-user-project/contracts\";\n\ntype AgentHostAsyncResult<T = any> = Promise<T>;\ntype AgentHostRecord = Record<string, unknown>;\ntype AgentHostUnsubscribe = () => void;\ntype AgentHostWorkspaceScopedInput<\n T extends {\n workspaceId?: string | null;\n }\n> = Omit<T, \"workspaceId\"> & {\n workspaceId: string;\n};\ntype AgentHostWorkspaceAgentsListInput =\n AgentHostWorkspaceScopedInput<AgentHostListWorkspaceAgentsInput>;\ntype AgentHostWorkspaceAgentSessionMessagesRuntimeInput =\n AgentHostWorkspaceScopedInput<AgentHostWorkspaceAgentSessionMessagesInput>;\ntype AgentHostWorkspaceAgentSessionSummaryRuntimeInput =\n AgentHostWorkspaceScopedInput<AgentHostWorkspaceAgentSessionSummaryInput>;\ntype AgentHostDeleteWorkspaceAgentSessionRuntimeInput =\n AgentHostWorkspaceScopedInput<AgentHostDeleteWorkspaceAgentSessionInput>;\n\nexport type AgentHostClipboardApi = {\n writeText: (text: string) => AgentHostAsyncResult<void>;\n};\n\nexport type AgentHostDebugApi = {\n logRuntimeDiagnostics: (\n payload: unknown\n ) => AgentHostAsyncResult<void> | void;\n logTerminalDiagnostics?: (\n payload: unknown\n ) => AgentHostAsyncResult<void> | void;\n};\n\nexport type AgentHostFilesystemApi = AgentHostRecord & {\n readFileText: (payload: {\n path?: string;\n uri?: string;\n }) => AgentHostAsyncResult<{\n content: string;\n name?: string;\n path?: string;\n }>;\n};\n\nexport type AgentHostMetaApi = AgentHostRecord & {\n appVersion?: string | null;\n isPackaged?: boolean;\n isTest?: boolean;\n mainPid?: number | null;\n platform?: string;\n workspaceId?: string;\n};\n\nexport type AgentHostEnvironmentApi = AgentHostRecord & {\n getBaseUrl?: () => AgentHostAsyncResult<string>;\n warmupOpenclawGateway?: (input?: unknown) => AgentHostAsyncResult<unknown>;\n};\n\nexport type AgentHostPersistenceApi = AgentHostRecord & {\n readWorkspaceAgentReadState: (\n input: ReadWorkspaceAgentReadStateInput\n ) => AgentHostAsyncResult<WorkspaceAgentReadStateSnapshot>;\n writeWorkspaceAgentReadState: (\n input: WriteWorkspaceAgentReadStateInput\n ) => AgentHostAsyncResult<PersistWriteResult>;\n};\n\nexport interface AgentHostSelectedFile {\n name?: string;\n path: string;\n}\n\nexport interface AgentHostSelectFilesInput {\n allowDirectories?: boolean;\n}\n\nexport type AgentHostWorkspaceApi = AgentHostRecord & {\n copyPath?: (input: { path: string }) => AgentHostAsyncResult<void>;\n ensureDirectory: (input: { path: string }) => AgentHostAsyncResult<void>;\n getPathForFile: (file: File) => string;\n readFile: (input: {\n path: string;\n }) => AgentHostAsyncResult<AgentHostReadWorkspaceFileResult>;\n selectContextEntries?: () => AgentHostAsyncResult<{ entries: unknown[] }>;\n selectDirectory: () => AgentHostAsyncResult<{ path: string } | null>;\n selectFiles: (\n input?: AgentHostSelectFilesInput\n ) => AgentHostAsyncResult<AgentHostSelectedFile[]>;\n writeFileText: (input: {\n content: string;\n path: string;\n }) => AgentHostAsyncResult<unknown>;\n};\n\nexport interface AgentHostInputApi {\n account?: AgentHostAccountApi;\n agentGuiBatch?: AgentHostAgentGuiBatchApi;\n agentSessions?: AgentHostAgentSessionsApi;\n clipboard: AgentHostClipboardApi;\n debug?: AgentHostDebugApi;\n filesystem: AgentHostFilesystemApi;\n meta?: AgentHostMetaApi;\n onHostEvent?: (listener: (event: any) => void) => AgentHostUnsubscribe;\n persistence?: AgentHostPersistenceApi;\n runtime?: AgentHostEnvironmentApi;\n userProjects?: AgentHostUserProjectsApi;\n workspace: AgentHostWorkspaceApi;\n workspaceAgentProbes?: AgentHostWorkspaceAgentProbesApi;\n workspaceAgents?: AgentHostWorkspaceAgentsApi;\n}\n\nexport type AgentHostApi = AgentHostInputApi;\n\nexport type AgentHostAccountApi = AgentHostRecord & {\n batchGetUserInfo: (\n input: AgentHostBatchUserInfoInput\n ) => AgentHostAsyncResult<AgentHostBatchUserInfoResult>;\n ensureProfiles?: (input: any) => AgentHostAsyncResult<any>;\n};\n\nexport type AgentHostAgentGuiBatchApi = AgentHostRecord & {\n exportRun: (input: any) => AgentHostAsyncResult<any>;\n};\n\nexport type AgentHostWorkspaceAgentProbesApi = AgentHostRecord & {\n list: (\n input: AgentHostListWorkspaceAgentProbesInput\n ) => AgentHostAsyncResult<AgentHostWorkspaceAgentProbesResult>;\n};\n\nexport type AgentProviderProbeListInput =\n AgentHostListWorkspaceAgentProbesInput;\nexport type AgentProviderProbeListResult = AgentHostWorkspaceAgentProbesResult;\n\nexport interface AgentHostUserProject {\n id: string;\n path: string;\n label: string;\n createdAtUnixMs?: number;\n updatedAtUnixMs?: number;\n lastUsedAtUnixMs?: number;\n}\n\nexport type AgentHostUserProjectsApi = AgentHostRecord & {\n service?: WorkspaceUserProjectService;\n checkPath?: (input: { path: string }) => AgentHostAsyncResult<{\n exists: boolean;\n isDirectory: boolean;\n path: string;\n }>;\n create?: (input: {\n name: string;\n }) => AgentHostAsyncResult<AgentHostUserProject>;\n getDefaultSelection?: () => AgentHostAsyncResult<{\n path: string | null;\n } | null>;\n list: () => AgentHostAsyncResult<{\n projects: AgentHostUserProject[];\n }>;\n subscribe?: (listener: () => void) => AgentHostUnsubscribe;\n prepareSelection?: (input: {\n projectLocked: boolean;\n selectedPath: string | null;\n }) => AgentHostAsyncResult<{\n isSelectedPathMissing: boolean;\n projects: AgentHostUserProject[];\n selection:\n | {\n kind: \"clear\";\n suppressedPath: string;\n }\n | {\n kind: \"none\";\n }\n | {\n kind: \"select\";\n path: string;\n };\n }>;\n remove?: (input: { path: string }) => AgentHostAsyncResult<void>;\n isNoProjectPath?: (input: { path: string }) => boolean;\n rememberDefaultSelection?: (input: {\n path: string | null;\n }) => AgentHostAsyncResult<void>;\n use: (input: { path: string }) => AgentHostAsyncResult<AgentHostUserProject>;\n};\n\nexport type AgentHostAgentSessionsApi = AgentHostRecord & {\n activate: (input: any) => AgentHostAsyncResult<any>;\n /**\n * @deprecated AgentGUI production writes must use AgentActivityRuntime.cancelSession.\n */\n cancel: (input: any) => AgentHostAsyncResult<any>;\n /**\n * @deprecated AgentGUI production writes must use AgentActivityRuntime.sendInput.\n */\n exec: (input: any) => AgentHostAsyncResult<any>;\n getComposerOptions?: (input: any) => AgentHostAsyncResult<any>;\n getState: (input: any) => AgentHostAsyncResult<any>;\n onEvent?: (listener: (event: any) => void) => AgentHostUnsubscribe;\n /**\n * @deprecated AgentGUI production writes must use AgentActivityRuntime.setSessionPinned.\n */\n pinSession?: (input: any) => AgentHostAsyncResult<any>;\n /**\n * @deprecated AgentGUI production sync must use AgentActivityRuntime.ensureSessionSynchronized.\n */\n releaseEventStream?: (input?: any) => AgentHostAsyncResult;\n /**\n * @deprecated AgentGUI production sync must use AgentActivityRuntime.ensureSessionSynchronized.\n */\n retainEventStream?: (input: any) => AgentHostAsyncResult;\n /**\n * @deprecated AgentGUI production writes must use AgentActivityRuntime.submitInteractive.\n */\n submitInteractive: (input: any) => AgentHostAsyncResult<any>;\n /**\n * @deprecated AgentGUI production UI must derive events from AgentActivityRuntime snapshots.\n */\n trackSettingsProjectChange?: (input: {\n action: \"clear\" | \"create_new\" | \"select_existing\";\n agentSessionId: string;\n provider?: string | null;\n }) => AgentHostAsyncResult<void>;\n subscribeEvents: (\n input: any,\n listener: (event: any) => void\n ) => AgentHostUnsubscribe;\n unactivate: (input: any) => AgentHostAsyncResult<any>;\n updateSettings: (input: any) => AgentHostAsyncResult<any>;\n};\n\n/**\n * @deprecated Legacy host DTO projection. AgentGUI production reads and writes\n * must use AgentActivityRuntime and AgentActivity* models.\n */\nexport type AgentHostWorkspaceAgentsApi = AgentHostRecord & {\n /**\n * @deprecated Use AgentActivityRuntime.deleteSession.\n */\n deleteSession: (\n input: AgentHostDeleteWorkspaceAgentSessionRuntimeInput\n ) => AgentHostAsyncResult<any>;\n /**\n * @deprecated Derive summaries from AgentActivitySnapshot/session messages.\n */\n getSessionSummary: (\n input: AgentHostWorkspaceAgentSessionSummaryRuntimeInput\n ) => AgentHostAsyncResult<AgentHostWorkspaceAgentSessionSummary>;\n /**\n * @deprecated Use AgentActivityRuntime.load/getSnapshot.\n */\n list: (\n input: string | AgentHostWorkspaceAgentsListInput\n ) => AgentHostAsyncResult<AgentHostWorkspaceAgentSnapshot>;\n /**\n * @deprecated Use AgentActivityRuntime.listSessionMessages.\n */\n listSessionMessages: (\n input: AgentHostWorkspaceAgentSessionMessagesRuntimeInput\n ) => AgentHostAsyncResult<AgentHostWorkspaceAgentSessionMessages>;\n};\n\nexport interface AgentHostRuntimeApi {\n account?: AgentHostAccountApi;\n agentGuiBatch: AgentHostAgentGuiBatchApi;\n clipboard: AgentHostClipboardApi;\n debug?: AgentHostDebugApi;\n filesystem: AgentHostFilesystemApi;\n meta?: AgentHostMetaApi;\n onHostEvent?: (listener: (event: any) => void) => AgentHostUnsubscribe;\n persistence?: AgentHostPersistenceApi;\n runtime?: AgentHostEnvironmentApi;\n userProjects?: AgentHostUserProjectsApi;\n workspace: AgentHostWorkspaceApi;\n workspaceAgentProbes?: AgentHostWorkspaceAgentProbesApi;\n}\n\nexport function toAgentHostRuntimeApi(\n hostApi: AgentHostInputApi | AgentHostRuntimeApi\n): AgentHostRuntimeApi {\n return {\n account: hostApi.account,\n agentGuiBatch: hostApi.agentGuiBatch ?? ({} as AgentHostAgentGuiBatchApi),\n clipboard: hostApi.clipboard,\n debug: hostApi.debug,\n filesystem: hostApi.filesystem,\n meta: hostApi.meta,\n onHostEvent: hostApi.onHostEvent,\n persistence: hostApi.persistence,\n runtime: hostApi.runtime,\n userProjects: hostApi.userProjects,\n workspace: hostApi.workspace,\n workspaceAgentProbes: hostApi.workspaceAgentProbes\n };\n}\n"],"mappings":"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","names":["createContext","useContext","jsx","createContext","useContext"]}
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-MTFSQWZ6.js";
15
15
  import {
16
16
  translate
17
- } from "./chunk-RQ3HEF42.js";
17
+ } from "./chunk-KFMD33UD.js";
18
18
 
19
19
  // shared/managedAgentProviders.ts
20
20
  function normalizeManagedAgentProvider(provider) {
@@ -113,4 +113,4 @@ export {
113
113
  userAvatarPlaceholderUrl,
114
114
  workspaceAgentActivityStatusLabel
115
115
  };
116
- //# sourceMappingURL=chunk-WPWZKKKV.js.map
116
+ //# sourceMappingURL=chunk-3LEUGNCT.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  getOptionalAgentHostApi,
3
3
  useOptionalAgentHostApi
4
- } from "./chunk-SGQ4C7JE.js";
4
+ } from "./chunk-2ADVHCST.js";
5
5
  import {
6
6
  useTranslation
7
- } from "./chunk-RQ3HEF42.js";
7
+ } from "./chunk-KFMD33UD.js";
8
8
  import {
9
9
  resolveAgentWorkspaceFileVisualKind
10
10
  } from "./chunk-PJP5BUU6.js";
@@ -312,16 +312,23 @@ function resolveWebsiteNavigationUrl(rawUrl) {
312
312
  // actions/workspaceLinkActions.ts
313
313
  import { parseRichTextMentionHref } from "@tutti-os/ui-rich-text/core";
314
314
  var URL_LIKE_LINK_PATTERN = /^[a-zA-Z][a-zA-Z\d+.-]*:|^#/;
315
+ var LOCAL_ASSET_ROOT = "/var/cache/tsh/local-assets";
315
316
  function resolveWorkspaceFilePathCandidate({
316
317
  path,
317
318
  workspaceRoot,
318
319
  basePath
319
320
  }) {
320
321
  const rawPath = decodeWorkspaceLinkPath(path.trim());
321
- if (!rawPath || isUrlLikeWorkspaceFilePath(rawPath)) {
322
+ if (!rawPath || isUrlLikeWorkspaceFilePath(rawPath) || isUncWorkspaceFilePath(rawPath)) {
322
323
  return null;
323
324
  }
324
325
  const normalizedPath = normalizeWorkspaceFilePath(rawPath);
326
+ if (isUnsupportedSpecialWorkspaceFilePath(normalizedPath)) {
327
+ return null;
328
+ }
329
+ if (isStagedLocalAssetPath(normalizedPath)) {
330
+ return null;
331
+ }
325
332
  if (isAbsoluteLocalPath(normalizedPath) && (isDirectAgentGeneratedMediaPath(normalizedPath) || isDirectWorkspaceAppDataPath(normalizedPath))) {
326
333
  const directoryPath = dirname(normalizedPath);
327
334
  return {
@@ -334,6 +341,14 @@ function resolveWorkspaceFilePathCandidate({
334
341
  if (!root) {
335
342
  return null;
336
343
  }
344
+ if (isAbsoluteLocalPath(normalizedPath)) {
345
+ const directoryPath = dirname(normalizedPath);
346
+ return {
347
+ path: normalizedPath,
348
+ directoryPath,
349
+ workspaceRoot: root
350
+ };
351
+ }
337
352
  const base = normalizeWorkspaceFilePath(basePath?.trim() || root);
338
353
  const resolvedPath = isAbsoluteLocalPath(normalizedPath) ? normalizedPath : normalizeWorkspaceFilePath(`${base}/${normalizedPath}`);
339
354
  if (!isInsideOrEqual(resolvedPath, root) && !isDirectAgentGeneratedMediaPath(resolvedPath)) {
@@ -367,6 +382,28 @@ function resolveWorkspaceFileLinkAction({
367
382
  source
368
383
  };
369
384
  }
385
+ function resolveLocalAssetPreviewLinkAction({
386
+ path,
387
+ source
388
+ }) {
389
+ const rawPath = decodeWorkspaceLinkPath(path.trim());
390
+ if (!rawPath || isUrlLikeWorkspaceFilePath(rawPath)) {
391
+ return null;
392
+ }
393
+ const resolvedPath = normalizeWorkspaceFilePath(rawPath);
394
+ if (resolvedPath === LOCAL_ASSET_ROOT || !isInsideOrEqual(resolvedPath, LOCAL_ASSET_ROOT)) {
395
+ return null;
396
+ }
397
+ if (resolvedPath.endsWith(".metadata.json")) {
398
+ return null;
399
+ }
400
+ return {
401
+ type: "open-local-asset-preview",
402
+ path: resolvedPath,
403
+ name: basename(resolvedPath),
404
+ source
405
+ };
406
+ }
370
407
  function resolveWorkspaceUrlLinkAction({
371
408
  url,
372
409
  source
@@ -446,7 +483,10 @@ function resolveWorkspaceLinkAction({
446
483
  basePath,
447
484
  source
448
485
  }) {
449
- return resolveWorkspaceMentionLinkAction({ href, source }) ?? resolveWorkspaceFileLinkAction({
486
+ return resolveWorkspaceMentionLinkAction({ href, source }) ?? resolveLocalAssetPreviewLinkAction({
487
+ path: href,
488
+ source
489
+ }) ?? resolveWorkspaceFileLinkAction({
450
490
  path: href,
451
491
  workspaceRoot,
452
492
  basePath,
@@ -492,6 +532,32 @@ function isAbsoluteLocalPath(path) {
492
532
  function isWindowsAbsolutePath(path) {
493
533
  return /^[A-Za-z]:\//.test(path);
494
534
  }
535
+ function isUncWorkspaceFilePath(path) {
536
+ return /^(?:\\\\|\/\/)[^/\\]+[/\\][^/\\]+/.test(path);
537
+ }
538
+ function isUnsupportedSpecialWorkspaceFilePath(path) {
539
+ const comparisonPath = cleanWorkspaceFilePathForComparison(path);
540
+ return comparisonPath === "/dev/null" || comparisonPath.split("/").some((segment) => {
541
+ const normalized = segment.trim().replace(/[. ]+$/g, "");
542
+ const deviceName = normalized.split(".", 1)[0]?.toUpperCase();
543
+ return deviceName === "NUL";
544
+ });
545
+ }
546
+ function cleanWorkspaceFilePathForComparison(path) {
547
+ const normalized = path.replace(/\/+/g, "/");
548
+ const parts = [];
549
+ for (const part of normalized.split("/")) {
550
+ if (!part || part === ".") {
551
+ continue;
552
+ }
553
+ if (part === "..") {
554
+ parts.pop();
555
+ continue;
556
+ }
557
+ parts.push(part);
558
+ }
559
+ return normalized.startsWith("/") ? `/${parts.join("/")}` : parts.join("/");
560
+ }
495
561
  function decodeWorkspaceLinkPath(path) {
496
562
  if (!path.includes("%")) {
497
563
  return path;
@@ -509,6 +575,9 @@ function dirname(path) {
509
575
  }
510
576
  return path.slice(0, index);
511
577
  }
578
+ function basename(path) {
579
+ return path.split("/").filter(Boolean).at(-1) ?? path;
580
+ }
512
581
  function isInsideOrEqual(path, root) {
513
582
  if (root === "/") {
514
583
  return path.startsWith("/");
@@ -516,6 +585,9 @@ function isInsideOrEqual(path, root) {
516
585
  const comparison = isWindowsAbsolutePath(root) || isWindowsAbsolutePath(path) ? { path: path.toLowerCase(), root: root.toLowerCase() } : { path, root };
517
586
  return comparison.path === comparison.root || comparison.path.startsWith(`${comparison.root}/`);
518
587
  }
588
+ function isStagedLocalAssetPath(path) {
589
+ return path !== LOCAL_ASSET_ROOT && isInsideOrEqual(path, LOCAL_ASSET_ROOT);
590
+ }
519
591
  function isDirectAgentGeneratedMediaPath(path) {
520
592
  if (!isAbsoluteLocalPath(path)) {
521
593
  return false;
@@ -1369,8 +1441,8 @@ function resolveWorkspaceFileMentionEntryKind(path, label, explicitKind) {
1369
1441
  if (resolveWorkspaceFileExtension(path)) {
1370
1442
  return "file";
1371
1443
  }
1372
- const basename = basenameWorkspacePath(path);
1373
- return basename === label ? "directory" : "file";
1444
+ const basename2 = basenameWorkspacePath(path);
1445
+ return basename2 === label ? "directory" : "file";
1374
1446
  }
1375
1447
  function parseWorkspaceFileMentionLink(href, rawLabel) {
1376
1448
  const label = rawLabel.trim();
@@ -1638,7 +1710,7 @@ function MarkdownMedia({
1638
1710
  playsInline: true,
1639
1711
  preload: "metadata",
1640
1712
  className: cn(
1641
- "block max-h-[360px] max-w-full rounded-[8px] border border-[var(--line-2)] bg-[var(--background-panel)]",
1713
+ "mt-2 block max-h-[360px] max-w-full rounded-[8px] bg-[var(--transparency-block)]",
1642
1714
  className
1643
1715
  )
1644
1716
  }
@@ -1680,7 +1752,7 @@ function MarkdownMedia({
1680
1752
  playsInline: true,
1681
1753
  preload: "metadata",
1682
1754
  className: cn(
1683
- "block max-h-[360px] max-w-full rounded-[8px] border border-[var(--line-2)] bg-[var(--background-panel)]",
1755
+ "mt-2 block max-h-[360px] max-w-full rounded-[8px] bg-[var(--transparency-block)]",
1684
1756
  className
1685
1757
  )
1686
1758
  }
@@ -1695,7 +1767,7 @@ function MarkdownMedia({
1695
1767
  alt,
1696
1768
  title,
1697
1769
  className: cn(
1698
- "block max-h-[360px] max-w-full rounded-[8px] border border-[var(--line-2)] bg-[var(--background-panel)] object-contain",
1770
+ "mt-2 block max-h-[360px] max-w-full rounded-[8px] bg-[var(--transparency-block)] object-contain",
1699
1771
  className
1700
1772
  )
1701
1773
  }
@@ -1709,20 +1781,20 @@ function MarkdownMedia({
1709
1781
  alt,
1710
1782
  title,
1711
1783
  className: cn(
1712
- "block max-h-[360px] max-w-full rounded-[8px] border border-[var(--line-2)] bg-[var(--background-panel)] object-contain",
1784
+ "mt-2 block max-h-[360px] max-w-full rounded-[8px] bg-[var(--transparency-block)] object-contain",
1713
1785
  className
1714
1786
  ),
1715
1787
  wrapElement: "span"
1716
1788
  }
1717
1789
  );
1718
1790
  }
1719
- return /* @__PURE__ */ jsx2("span", { className: "flex min-h-[160px] w-full items-center justify-center rounded-[8px] border border-[var(--line-2)] bg-[var(--background-panel)] px-5 py-5 text-center text-[13px] leading-5 text-[var(--text-tertiary)]", children: state?.status === "error" ? state.reason === "unsupported" ? t("agentHost.workspaceFileManager.previewUnsupported") : t("agentHost.workspaceFileManager.previewReadFailed", {
1791
+ return /* @__PURE__ */ jsx2("span", { className: "mt-2 flex min-h-[160px] w-full items-center justify-center rounded-[8px] bg-[var(--transparency-block)] px-5 py-5 text-center text-[13px] leading-5 text-[var(--text-tertiary)]", children: state?.status === "error" ? state.reason === "unsupported" ? t("agentHost.workspaceFileManager.previewUnsupported") : t("agentHost.workspaceFileManager.previewReadFailed", {
1720
1792
  message: state.detail ?? ""
1721
1793
  }) : t("agentHost.workspaceFileManager.previewLoading") });
1722
1794
  }
1723
1795
  function UnsupportedMarkdownMediaPreview() {
1724
1796
  const { t } = useTranslation();
1725
- return /* @__PURE__ */ jsx2("span", { className: "flex min-h-[160px] w-full items-center justify-center rounded-[8px] border border-[var(--line-2)] bg-[var(--background-panel)] px-5 py-5 text-center text-[13px] leading-5 text-[var(--text-tertiary)]", children: t("agentHost.workspaceFileManager.previewUnsupported") });
1797
+ return /* @__PURE__ */ jsx2("span", { className: "mt-2 flex min-h-[160px] w-full items-center justify-center rounded-[8px] bg-[var(--transparency-block)] px-5 py-5 text-center text-[13px] leading-5 text-[var(--text-tertiary)]", children: t("agentHost.workspaceFileManager.previewUnsupported") });
1726
1798
  }
1727
1799
  var MARKDOWN_ORDERED_LIST_STYLE = {
1728
1800
  listStylePosition: "outside",
@@ -2668,4 +2740,4 @@ export {
2668
2740
  CustomScrollArea,
2669
2741
  MessageSquareMoreIcon
2670
2742
  };
2671
- //# sourceMappingURL=chunk-AFTAFV2C.js.map
2743
+ //# sourceMappingURL=chunk-CMXRLF64.js.map