zidane-ui 9.1.1 → 9.1.3
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 +2 -0
- package/dist/adapters/index.js +1 -1
- package/dist/adapters/server-transcript-members.d.ts +1 -1
- package/dist/adapters/server-transcript-members.js +19 -1
- package/dist/app/ModalProvider.d.ts +3 -1
- package/dist/app/ModalProvider.js +15 -9
- package/dist/approvals/headless/index.js +1 -1
- package/dist/chat/HostTranscript.d.ts +3 -1
- package/dist/chat/HostTranscript.js +5 -3
- package/dist/chat/Transcript.js +1 -1
- package/dist/chat/composer/ComposerEditor.js +1 -1
- package/dist/chat/composer/index.js +1 -1
- package/dist/chat/composer/use-composer-stores.js +1 -1
- package/dist/chat/headless/block-runs.d.ts +57 -0
- package/dist/chat/headless/block-runs.js +123 -0
- package/dist/chat/headless/composer/index.js +2 -2
- package/dist/chat/headless/fixture-transcript.d.ts +6 -1
- package/dist/chat/headless/fixture-transcript.js +49 -0
- package/dist/chat/headless/host.d.ts +3 -0
- package/dist/chat/headless/index.d.ts +2 -1
- package/dist/chat/headless/index.js +12 -11
- package/dist/chat/headless/labels.d.ts +42 -0
- package/dist/chat/headless/labels.js +42 -0
- package/dist/chat/headless/session-list.d.ts +27 -0
- package/dist/chat/headless/sidebar/index.js +1 -1
- package/dist/chat/headless/sidebar/labels.d.ts +27 -0
- package/dist/chat/headless/streams/index.js +1 -1
- package/dist/chat/headless/streams/live-events.js +2 -1
- package/dist/chat/headless/streams/session-streams.js +2 -2
- package/dist/chat/headless/streams/store.js +2 -2
- package/dist/chat/headless/transcript/batch.d.ts +21 -1
- package/dist/chat/headless/transcript/batch.js +55 -10
- package/dist/chat/headless/transcript/collapse.js +18 -3
- package/dist/chat/headless/transcript/fold.js +26 -10
- package/dist/chat/headless/transcript/index.js +1 -1
- package/dist/chat/headless/transcript/rows.d.ts +7 -1
- package/dist/chat/index.d.ts +6 -1
- package/dist/chat/index.js +7 -2
- package/dist/chat/testing/contract.d.ts +6 -1
- package/dist/chat/testing/contract.js +30 -3
- package/dist/chat/transcript/AnsiText.d.ts +27 -0
- package/dist/chat/transcript/AnsiText.js +73 -0
- package/dist/chat/transcript/CodemodeScript.d.ts +33 -0
- package/dist/chat/transcript/CodemodeScript.js +212 -0
- package/dist/chat/transcript/LiveOutput.d.ts +21 -0
- package/dist/chat/transcript/LiveOutput.js +42 -0
- package/dist/chat/transcript/TranscriptRow.js +19 -2
- package/dist/chat/transcript/actions.d.ts +6 -0
- package/dist/chat/transcript/index.d.ts +6 -1
- package/dist/chat/transcript/index.js +6 -1
- package/dist/chat/transcript/markdown.js +9 -0
- package/dist/chat/transcript/renderers.d.ts +7 -0
- package/dist/chat/transcript/script-input.d.ts +17 -0
- package/dist/chat/transcript/script-input.js +16 -0
- package/dist/chat/transcript/shell-block-scope.d.ts +29 -0
- package/dist/chat/transcript/shell-block-scope.js +18 -0
- package/dist/chat/transcript/shell-block.d.ts +27 -0
- package/dist/chat/transcript/shell-block.js +306 -0
- package/dist/chat/transcript/tool-parts.d.ts +18 -6
- package/dist/chat/transcript/tool-parts.js +15 -5
- package/dist/chat/transcript/tool-payload.js +6 -3
- package/dist/chat/transcript/tool-row.js +155 -96
- package/dist/chat/transcript/user-bash.js +3 -2
- package/dist/code/HighlightedCode.js +3 -69
- package/dist/code/highlight-lines.d.ts +24 -0
- package/dist/code/highlight-lines.js +41 -0
- package/dist/code/use-highlighted-html.d.ts +5 -0
- package/dist/code/use-highlighted-html.js +75 -0
- package/dist/core.css +6 -2
- package/dist/dist/{index-CGbOWa7y.d.ts → index-WlE93Q6d.d.ts} +101 -3
- package/dist/extensions/ExtensionSettingsSidebar.js +19 -3
- package/dist/extensions/kit.d.ts +1 -1
- package/dist/git/BranchMenu.d.ts +1 -7
- package/dist/git/BranchMenu.js +17 -40
- package/dist/git/headless/labels.d.ts +0 -2
- package/dist/git/headless/labels.js +0 -2
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/onboarding/index.js +1 -1
- package/dist/onboarding/steps/ConnectStep.js +1 -1
- package/dist/onboarding/steps/ExtensionsStep.js +1 -1
- package/dist/onboarding/steps/ReadyStep.js +1 -1
- package/dist/onboarding/steps/connect/ProviderPanel.js +1 -1
- package/dist/session/headless/index.js +2 -2
- package/dist/settings/SettingsShell.d.ts +3 -1
- package/dist/settings/SettingsShell.js +15 -8
- package/dist/settings/headless/catalog.js +5 -0
- package/dist/settings/headless/layout.js +2 -1
- package/dist/settings/headless/registry.d.ts +2 -0
- package/dist/settings/headless/search.d.ts +1 -1
- package/dist/settings/sections/environments/EnvironmentsSection.js +1 -1
- package/dist/settings/sections/extensions/ExtensionsSection.js +2 -2
- package/dist/settings/sections/models/ModelRows.js +1 -1
- package/dist/settings/sections/models/model-test.js +1 -1
- package/dist/styles.css +291 -2
- package/dist/terminal/TerminalProvider.d.ts +3 -1
- package/dist/terminal/TerminalProvider.js +5 -1
- package/dist/terminal/headless/store.d.ts +10 -0
- package/dist/terminal/headless/store.js +16 -0
- package/dist/terminal/index.d.ts +2 -2
- package/dist/terminal/index.js +2 -2
- package/dist/theme/runtime-icons.d.ts +50 -0
- package/dist/theme/runtime-icons.js +95 -0
- package/package.json +3 -6
- package/src/styles/primitives.css +5 -2
- package/src/styles/transcript.css +281 -0
- package/src/adapters/browser-appearance-host.ts +0 -51
- package/src/adapters/browser-keybindings-host.ts +0 -48
- package/src/adapters/browser-workspace-host.ts +0 -92
- package/src/adapters/closable-client.ts +0 -34
- package/src/adapters/extension-modules.ts +0 -360
- package/src/adapters/index.ts +0 -35
- package/src/adapters/live-events.ts +0 -6
- package/src/adapters/live.ts +0 -270
- package/src/adapters/run-host.ts +0 -238
- package/src/adapters/server-approvals-host.ts +0 -102
- package/src/adapters/server-client.ts +0 -15
- package/src/adapters/server-composer-host.ts +0 -459
- package/src/adapters/server-extensions-host.ts +0 -979
- package/src/adapters/server-files-host.ts +0 -287
- package/src/adapters/server-git-host.ts +0 -289
- package/src/adapters/server-host.ts +0 -489
- package/src/adapters/server-machines-host.ts +0 -283
- package/src/adapters/server-oauth-flow.ts +0 -133
- package/src/adapters/server-onboarding-host.ts +0 -363
- package/src/adapters/server-palette-host.ts +0 -134
- package/src/adapters/server-session-host.ts +0 -241
- package/src/adapters/server-settings-accounts.ts +0 -212
- package/src/adapters/server-settings-host.ts +0 -120
- package/src/adapters/server-settings-models.ts +0 -46
- package/src/adapters/server-settings-performance.ts +0 -58
- package/src/adapters/server-settings-sections.ts +0 -222
- package/src/adapters/server-sidebar-host.ts +0 -59
- package/src/adapters/server-terminal-host.ts +0 -124
- package/src/adapters/server-transcript-members.ts +0 -131
- package/src/adapters/sse-host.ts +0 -264
- package/src/adapters/sse-parser.ts +0 -82
- package/src/adapters/sse-protocol.ts +0 -118
- package/src/adapters/stream-pacer.ts +0 -122
- package/src/adapters/worker-host.ts +0 -192
- package/src/adapters/worker-protocol.ts +0 -97
- package/src/app/AppHostProvider.tsx +0 -135
- package/src/app/ModalProvider.tsx +0 -731
- package/src/app/headless/app-host.ts +0 -61
- package/src/app/headless/index.ts +0 -6
- package/src/app/headless/resource.ts +0 -444
- package/src/app/index.ts +0 -9
- package/src/app/testing/index.ts +0 -90
- package/src/app/useConfirm.tsx +0 -65
- package/src/app/useResource.ts +0 -30
- package/src/appearance/AppearanceProvider.tsx +0 -383
- package/src/appearance/apply.ts +0 -69
- package/src/appearance/headless/fixture-host.ts +0 -111
- package/src/appearance/headless/fonts.ts +0 -224
- package/src/appearance/headless/host.ts +0 -65
- package/src/appearance/headless/index.ts +0 -12
- package/src/appearance/headless/prefs.ts +0 -252
- package/src/appearance/headless/storage.ts +0 -127
- package/src/appearance/headless/zoom-commands.ts +0 -21
- package/src/appearance/index.ts +0 -11
- package/src/appearance/testing/contract.ts +0 -210
- package/src/appearance/testing/index.ts +0 -6
- package/src/approvals/ApprovalBar.tsx +0 -234
- package/src/approvals/ApprovalConcern.tsx +0 -33
- package/src/approvals/ApprovalShell.tsx +0 -69
- package/src/approvals/ApprovalsProvider.tsx +0 -110
- package/src/approvals/FileEditApproval.tsx +0 -310
- package/src/approvals/HunkPreviews.tsx +0 -225
- package/src/approvals/SafelistPanel.tsx +0 -149
- package/src/approvals/headless/fixture-host.ts +0 -73
- package/src/approvals/headless/fixtures.ts +0 -86
- package/src/approvals/headless/heads.ts +0 -81
- package/src/approvals/headless/host.ts +0 -80
- package/src/approvals/headless/index.ts +0 -12
- package/src/approvals/headless/labels.ts +0 -67
- package/src/approvals/headless/pending.ts +0 -91
- package/src/approvals/headless/preview.ts +0 -94
- package/src/approvals/headless/safelist.ts +0 -63
- package/src/approvals/index.ts +0 -13
- package/src/approvals/key-scope.ts +0 -33
- package/src/approvals/testing/contract.ts +0 -230
- package/src/approvals/testing/index.ts +0 -7
- package/src/brands/marks.ts +0 -298
- package/src/chat/ChatProvider.tsx +0 -60
- package/src/chat/DaemonOrb.tsx +0 -107
- package/src/chat/HostBadge.tsx +0 -71
- package/src/chat/HostStatusDot.tsx +0 -53
- package/src/chat/HostTranscript.tsx +0 -101
- package/src/chat/PdfPreview.tsx +0 -65
- package/src/chat/RunEstimateChip.tsx +0 -168
- package/src/chat/SessionFilterMenu.tsx +0 -397
- package/src/chat/SessionGroupHeader.tsx +0 -177
- package/src/chat/SessionHostHeader.tsx +0 -66
- package/src/chat/SessionList.tsx +0 -413
- package/src/chat/SessionListRow.tsx +0 -296
- package/src/chat/SessionStreamsProvider.tsx +0 -253
- package/src/chat/StatusDot.tsx +0 -128
- package/src/chat/TextPreview.tsx +0 -121
- package/src/chat/Throbber.tsx +0 -270
- package/src/chat/Transcript.tsx +0 -523
- package/src/chat/composer/AgentPicker.tsx +0 -155
- package/src/chat/composer/AgentPickerDialog.tsx +0 -99
- package/src/chat/composer/ApprovalDock.tsx +0 -64
- package/src/chat/composer/ArchivedBanner.tsx +0 -44
- package/src/chat/composer/AttachmentTiles.tsx +0 -211
- package/src/chat/composer/Composer.tsx +0 -500
- package/src/chat/composer/ComposerBadges.tsx +0 -339
- package/src/chat/composer/ComposerControls.tsx +0 -243
- package/src/chat/composer/ComposerEditor.tsx +0 -101
- package/src/chat/composer/ComposerHostProvider.tsx +0 -46
- package/src/chat/composer/ComposerShell.tsx +0 -129
- package/src/chat/composer/ContextBreakdown.tsx +0 -382
- package/src/chat/composer/ContextOrb.tsx +0 -176
- package/src/chat/composer/ConversationBadges.tsx +0 -168
- package/src/chat/composer/DockCard.tsx +0 -126
- package/src/chat/composer/EffortPickerDialog.tsx +0 -184
- package/src/chat/composer/HostComposer.tsx +0 -135
- package/src/chat/composer/HostContextOrb.tsx +0 -94
- package/src/chat/composer/HostModelChainList.tsx +0 -102
- package/src/chat/composer/HostPicker.tsx +0 -97
- package/src/chat/composer/HostPickers.tsx +0 -320
- package/src/chat/composer/ImageModelList.tsx +0 -151
- package/src/chat/composer/ModelChainList.tsx +0 -442
- package/src/chat/composer/ModelChainParts.tsx +0 -247
- package/src/chat/composer/ModelChainRow.tsx +0 -191
- package/src/chat/composer/ModelChainRows.tsx +0 -223
- package/src/chat/composer/ModelChainTooltip.tsx +0 -121
- package/src/chat/composer/ModelFacts.tsx +0 -204
- package/src/chat/composer/ModelOptionsPicker.tsx +0 -257
- package/src/chat/composer/ModelPicker.tsx +0 -513
- package/src/chat/composer/ModelPickerDialog.tsx +0 -99
- package/src/chat/composer/ModelProviderPills.tsx +0 -141
- package/src/chat/composer/PickerPill.tsx +0 -41
- package/src/chat/composer/ProjectMenu.tsx +0 -187
- package/src/chat/composer/PromptHistoryProvider.tsx +0 -214
- package/src/chat/composer/RetryPill.tsx +0 -47
- package/src/chat/composer/RunStatusChip.tsx +0 -150
- package/src/chat/composer/ScopeToggle.tsx +0 -94
- package/src/chat/composer/SelectTurnHint.tsx +0 -40
- package/src/chat/composer/SendButton.tsx +0 -89
- package/src/chat/composer/ServerScopeToggle.tsx +0 -188
- package/src/chat/composer/attachment-ingest.ts +0 -413
- package/src/chat/composer/attachments.tsx +0 -176
- package/src/chat/composer/badge-order.ts +0 -65
- package/src/chat/composer/composer-bus.ts +0 -317
- package/src/chat/composer/index.ts +0 -63
- package/src/chat/composer/load-composer-editor.ts +0 -25
- package/src/chat/composer/model-catalog.ts +0 -424
- package/src/chat/composer/model-list-layout.ts +0 -118
- package/src/chat/composer/prompt-history-nav.ts +0 -60
- package/src/chat/composer/scope-side.ts +0 -7
- package/src/chat/composer/suggestion-extension.ts +0 -113
- package/src/chat/composer/suggestions.tsx +0 -115
- package/src/chat/composer/use-agent-profiles.ts +0 -97
- package/src/chat/composer/use-cache-hints.ts +0 -93
- package/src/chat/composer/use-composer-stores.ts +0 -140
- package/src/chat/composer/use-draft-target.ts +0 -317
- package/src/chat/composer/use-new-session-defaults.ts +0 -201
- package/src/chat/composer/use-provider-ready-poll.ts +0 -35
- package/src/chat/composer/use-run-meter.ts +0 -140
- package/src/chat/composer/use-send-prompt.ts +0 -188
- package/src/chat/composer/use-session-meters.ts +0 -109
- package/src/chat/composer/use-sustained-work.ts +0 -74
- package/src/chat/composer/useAttachmentIngest.ts +0 -116
- package/src/chat/composer/useModelListSpy.ts +0 -19
- package/src/chat/headless/badge-refs.ts +0 -76
- package/src/chat/headless/chip-labels.ts +0 -40
- package/src/chat/headless/chip-settle.ts +0 -53
- package/src/chat/headless/chip-views.ts +0 -215
- package/src/chat/headless/composer/attachment-dedupe.ts +0 -50
- package/src/chat/headless/composer/commands.ts +0 -16
- package/src/chat/headless/composer/composer-sources.ts +0 -150
- package/src/chat/headless/composer/conversation-badges.ts +0 -227
- package/src/chat/headless/composer/draft-sync.ts +0 -199
- package/src/chat/headless/composer/editor-markdown.ts +0 -137
- package/src/chat/headless/composer/ghost-autocomplete.ts +0 -381
- package/src/chat/headless/composer/host-chrome.ts +0 -197
- package/src/chat/headless/composer/host.ts +0 -250
- package/src/chat/headless/composer/index.ts +0 -17
- package/src/chat/headless/composer/labels-chrome.ts +0 -83
- package/src/chat/headless/composer/labels-editor.ts +0 -44
- package/src/chat/headless/composer/labels.ts +0 -18
- package/src/chat/headless/composer/live-cost.ts +0 -67
- package/src/chat/headless/composer/model-knobs.ts +0 -179
- package/src/chat/headless/composer/model-names.ts +0 -145
- package/src/chat/headless/composer/model-picker-prefs.ts +0 -90
- package/src/chat/headless/composer/models.ts +0 -86
- package/src/chat/headless/composer/new-session-defaults.ts +0 -68
- package/src/chat/headless/composer/prompt-suggestions.ts +0 -72
- package/src/chat/headless/composer/remember-model-pick.ts +0 -132
- package/src/chat/headless/composer/run-meter.ts +0 -228
- package/src/chat/headless/composer-modes.ts +0 -170
- package/src/chat/headless/draft-scope.ts +0 -136
- package/src/chat/headless/draft-target.ts +0 -87
- package/src/chat/headless/extension-sources.ts +0 -64
- package/src/chat/headless/file-chip.ts +0 -175
- package/src/chat/headless/fixture-host.ts +0 -294
- package/src/chat/headless/fixture-transcript.ts +0 -125
- package/src/chat/headless/fixtures/demo-transcript-all-kinds.ts +0 -233
- package/src/chat/headless/fixtures/demo-transcript.ts +0 -244
- package/src/chat/headless/host.ts +0 -264
- package/src/chat/headless/hosts.ts +0 -55
- package/src/chat/headless/index.ts +0 -31
- package/src/chat/headless/labels.ts +0 -373
- package/src/chat/headless/markdown-chunks.ts +0 -134
- package/src/chat/headless/path-resolver.ts +0 -178
- package/src/chat/headless/prompt-origin.ts +0 -90
- package/src/chat/headless/reference-store.ts +0 -285
- package/src/chat/headless/send-flow.ts +0 -347
- package/src/chat/headless/session-list.ts +0 -400
- package/src/chat/headless/sidebar/activity.ts +0 -179
- package/src/chat/headless/sidebar/badges.ts +0 -190
- package/src/chat/headless/sidebar/compaction.ts +0 -98
- package/src/chat/headless/sidebar/directory.ts +0 -1046
- package/src/chat/headless/sidebar/dot-state.ts +0 -36
- package/src/chat/headless/sidebar/environment.ts +0 -70
- package/src/chat/headless/sidebar/estimates.ts +0 -146
- package/src/chat/headless/sidebar/host.ts +0 -41
- package/src/chat/headless/sidebar/index.ts +0 -18
- package/src/chat/headless/sidebar/labels.ts +0 -161
- package/src/chat/headless/sidebar/notifications.ts +0 -61
- package/src/chat/headless/sidebar/pinned-projects.ts +0 -51
- package/src/chat/headless/sidebar/pinned-sessions.ts +0 -27
- package/src/chat/headless/sidebar/project-icons.ts +0 -116
- package/src/chat/headless/sidebar/query.ts +0 -621
- package/src/chat/headless/sidebar/rows.ts +0 -427
- package/src/chat/headless/sidebar/types.ts +0 -96
- package/src/chat/headless/sidebar/view.ts +0 -367
- package/src/chat/headless/site-icons.ts +0 -51
- package/src/chat/headless/smooth-stream.ts +0 -76
- package/src/chat/headless/store.ts +0 -62
- package/src/chat/headless/streams/actions.ts +0 -85
- package/src/chat/headless/streams/index.ts +0 -25
- package/src/chat/headless/streams/live-events.ts +0 -124
- package/src/chat/headless/streams/merge.ts +0 -60
- package/src/chat/headless/streams/pacer.ts +0 -189
- package/src/chat/headless/streams/prompt-previews.ts +0 -64
- package/src/chat/headless/streams/scheduler.ts +0 -36
- package/src/chat/headless/streams/selectors.ts +0 -76
- package/src/chat/headless/streams/session-streams.ts +0 -407
- package/src/chat/headless/streams/store.ts +0 -1107
- package/src/chat/headless/streams/transcript.ts +0 -41
- package/src/chat/headless/streams/types.ts +0 -84
- package/src/chat/headless/transcript/batch.ts +0 -429
- package/src/chat/headless/transcript/collapse.ts +0 -789
- package/src/chat/headless/transcript/fold-actions.ts +0 -269
- package/src/chat/headless/transcript/fold-attachments.ts +0 -78
- package/src/chat/headless/transcript/fold.ts +0 -382
- package/src/chat/headless/transcript/index.ts +0 -41
- package/src/chat/headless/transcript/nesting.ts +0 -73
- package/src/chat/headless/transcript/pairing.ts +0 -124
- package/src/chat/headless/transcript/rows.ts +0 -377
- package/src/chat/headless/transcript/run-failures.ts +0 -72
- package/src/chat/headless/transcript/select-stops.ts +0 -151
- package/src/chat/headless/transcript/tool-media.ts +0 -42
- package/src/chat/headless/transcript-host.ts +0 -180
- package/src/chat/headless/transcript-labels.ts +0 -12
- package/src/chat/headless/turn-labels.ts +0 -28
- package/src/chat/headless/turn-prompt.ts +0 -32
- package/src/chat/index.ts +0 -31
- package/src/chat/interactions/HostInteractions.tsx +0 -76
- package/src/chat/interactions/InboxPanel.tsx +0 -226
- package/src/chat/interactions/InteractionCard.tsx +0 -111
- package/src/chat/interactions/PlanCard.tsx +0 -186
- package/src/chat/interactions/QuestionField.tsx +0 -336
- package/src/chat/interactions/QuestionForm.tsx +0 -283
- package/src/chat/interactions/card-ui.tsx +0 -86
- package/src/chat/interactions/hooks.ts +0 -49
- package/src/chat/interactions/index.ts +0 -8
- package/src/chat/provider-color.ts +0 -71
- package/src/chat/rich-composer/MentionList.tsx +0 -238
- package/src/chat/rich-composer/RichComposer.tsx +0 -1071
- package/src/chat/rich-composer/badge-decorations.ts +0 -157
- package/src/chat/rich-composer/composer-controls.tsx +0 -102
- package/src/chat/rich-composer/composer-extensions.ts +0 -388
- package/src/chat/rich-composer/composer-keys.ts +0 -416
- package/src/chat/rich-composer/ghost-plugin.ts +0 -89
- package/src/chat/rich-composer/index.ts +0 -3
- package/src/chat/rich-composer/mention-popover.ts +0 -336
- package/src/chat/rich-composer/slash-completion.ts +0 -143
- package/src/chat/rich-composer/use-composer-bus.ts +0 -57
- package/src/chat/rich-composer/use-composer-editor.ts +0 -216
- package/src/chat/rich-composer/use-composer-sources.ts +0 -90
- package/src/chat/rich-composer/use-draft-mirror.ts +0 -398
- package/src/chat/rich-composer/use-editor-handover.ts +0 -45
- package/src/chat/rich-composer/use-extension-composer.ts +0 -80
- package/src/chat/rich-composer/use-ghost-lifecycle.ts +0 -265
- package/src/chat/rich-composer/use-prompt-ghost.ts +0 -90
- package/src/chat/rich-composer/use-staged-attachments.ts +0 -65
- package/src/chat/sidebar/MainSessionRow.tsx +0 -102
- package/src/chat/sidebar/ProjectIcon.tsx +0 -399
- package/src/chat/sidebar/RowChips.tsx +0 -98
- package/src/chat/sidebar/SessionSidebar.tsx +0 -1039
- package/src/chat/sidebar/SidebarDecoration.tsx +0 -93
- package/src/chat/sidebar/SidebarFilterMenu.tsx +0 -270
- package/src/chat/sidebar/SidebarFooter.tsx +0 -244
- package/src/chat/sidebar/SidebarFrame.tsx +0 -154
- package/src/chat/sidebar/SidebarGroupHeader.tsx +0 -263
- package/src/chat/sidebar/SidebarHostProvider.tsx +0 -51
- package/src/chat/sidebar/SidebarRowView.tsx +0 -151
- package/src/chat/sidebar/SidebarSearchRow.tsx +0 -66
- package/src/chat/sidebar/SidebarSessionRow.tsx +0 -317
- package/src/chat/sidebar/SidebarToggleButton.tsx +0 -48
- package/src/chat/sidebar/SpaceSwitcher.tsx +0 -341
- package/src/chat/sidebar/SpacesSection.tsx +0 -259
- package/src/chat/sidebar/collapsed.ts +0 -61
- package/src/chat/sidebar/index.ts +0 -109
- package/src/chat/sidebar/session-menu.ts +0 -441
- package/src/chat/sidebar/sidebar-focus-hold.ts +0 -56
- package/src/chat/sidebar/sidebar-live.tsx +0 -666
- package/src/chat/sidebar/use-main-session.ts +0 -32
- package/src/chat/sidebar/useAgentNames.ts +0 -12
- package/src/chat/sidebar/useCompactionProgress.ts +0 -24
- package/src/chat/sidebar/usePinnedProjects.ts +0 -36
- package/src/chat/sidebar/useSaveViewAsSpace.ts +0 -42
- package/src/chat/sidebar/useSessionActivity.ts +0 -24
- package/src/chat/sidebar/useSessionBadges.ts +0 -26
- package/src/chat/sidebar/useSessionDirectoryView.ts +0 -128
- package/src/chat/sidebar/useSessionSearch.ts +0 -94
- package/src/chat/sidebar/useSidebarKeyboardNav.ts +0 -167
- package/src/chat/sidebar/useSidebarLabels.ts +0 -10
- package/src/chat/testing/composer.contract.ts +0 -508
- package/src/chat/testing/contract.ts +0 -634
- package/src/chat/testing/fixture-composer-chrome.ts +0 -159
- package/src/chat/testing/fixture-composer-host.ts +0 -147
- package/src/chat/testing/fixture-sidebar-host.ts +0 -99
- package/src/chat/testing/index.ts +0 -12
- package/src/chat/testing/sidebar.contract.ts +0 -196
- package/src/chat/transcript/BadgeMenu.tsx +0 -241
- package/src/chat/transcript/CardMarkdown.tsx +0 -102
- package/src/chat/transcript/ChipCard.tsx +0 -187
- package/src/chat/transcript/ChipCards.tsx +0 -100
- package/src/chat/transcript/DiffLines.tsx +0 -122
- package/src/chat/transcript/EarlierHistory.tsx +0 -136
- package/src/chat/transcript/EditDiffBlock.tsx +0 -176
- package/src/chat/transcript/FileChip.tsx +0 -361
- package/src/chat/transcript/ImageGenerationBlock.tsx +0 -239
- package/src/chat/transcript/InlineChipText.tsx +0 -57
- package/src/chat/transcript/InteractionToolBody.tsx +0 -211
- package/src/chat/transcript/LazyRow.tsx +0 -311
- package/src/chat/transcript/MermaidDiagram.tsx +0 -484
- package/src/chat/transcript/PromptEcho.tsx +0 -171
- package/src/chat/transcript/PromptOriginLabel.tsx +0 -44
- package/src/chat/transcript/ProseMarkdown.tsx +0 -168
- package/src/chat/transcript/ReferenceText.tsx +0 -198
- package/src/chat/transcript/SelectCursor.tsx +0 -118
- package/src/chat/transcript/SelectTurnHint.tsx +0 -81
- package/src/chat/transcript/SelectTurnProvider.tsx +0 -150
- package/src/chat/transcript/SubagentBlock.tsx +0 -224
- package/src/chat/transcript/TranscriptRow.tsx +0 -362
- package/src/chat/transcript/TranscriptSearch.tsx +0 -171
- package/src/chat/transcript/TurnMenu.tsx +0 -217
- package/src/chat/transcript/actions.tsx +0 -77
- package/src/chat/transcript/badges.tsx +0 -155
- package/src/chat/transcript/chip-details.ts +0 -169
- package/src/chat/transcript/chip-resolve.ts +0 -56
- package/src/chat/transcript/extension-renderers.tsx +0 -148
- package/src/chat/transcript/fold-attachments.tsx +0 -221
- package/src/chat/transcript/fold-status.tsx +0 -112
- package/src/chat/transcript/fold-worker.tsx +0 -160
- package/src/chat/transcript/fold.tsx +0 -522
- package/src/chat/transcript/frame.tsx +0 -326
- package/src/chat/transcript/index.ts +0 -66
- package/src/chat/transcript/markdown-cache.ts +0 -84
- package/src/chat/transcript/markdown-context.ts +0 -52
- package/src/chat/transcript/markdown.tsx +0 -351
- package/src/chat/transcript/messages.tsx +0 -169
- package/src/chat/transcript/notices.tsx +0 -508
- package/src/chat/transcript/prompt-lines.tsx +0 -55
- package/src/chat/transcript/prompt.tsx +0 -258
- package/src/chat/transcript/prose.tsx +0 -171
- package/src/chat/transcript/recent-map.ts +0 -32
- package/src/chat/transcript/references.ts +0 -108
- package/src/chat/transcript/remark-references.ts +0 -157
- package/src/chat/transcript/remark-refs.ts +0 -176
- package/src/chat/transcript/renderer-slots.tsx +0 -35
- package/src/chat/transcript/renderers.tsx +0 -251
- package/src/chat/transcript/row-estimate.ts +0 -158
- package/src/chat/transcript/run-rows.tsx +0 -291
- package/src/chat/transcript/site-icons.ts +0 -27
- package/src/chat/transcript/thumbnails.ts +0 -146
- package/src/chat/transcript/tool-batch.tsx +0 -102
- package/src/chat/transcript/tool-details.tsx +0 -31
- package/src/chat/transcript/tool-media.tsx +0 -132
- package/src/chat/transcript/tool-parts.tsx +0 -358
- package/src/chat/transcript/tool-payload.tsx +0 -76
- package/src/chat/transcript/tool-row.tsx +0 -496
- package/src/chat/transcript/turn-commands.ts +0 -101
- package/src/chat/transcript/use-transcript-rows.ts +0 -195
- package/src/chat/transcript/useComposerSearch.ts +0 -106
- package/src/chat/transcript/useSelectTurnKeys.ts +0 -204
- package/src/chat/transcript/useSettledReveal.ts +0 -57
- package/src/chat/transcript/useStickToBottom.ts +0 -600
- package/src/chat/transcript/useTranscriptFind.ts +0 -70
- package/src/chat/transcript/useTranscriptFindKey.ts +0 -52
- package/src/chat/transcript/useTranscriptScroll.ts +0 -163
- package/src/chat/transcript/useTranscriptSearch.tsx +0 -382
- package/src/chat/transcript/useTranscriptSelectionCopy.ts +0 -63
- package/src/chat/transcript/useWheelHoverPause.ts +0 -79
- package/src/chat/transcript/user-bash.tsx +0 -134
- package/src/chat/transcript-options.ts +0 -51
- package/src/chat/useChatLabels.ts +0 -14
- package/src/code/CodeHighlightProvider.tsx +0 -87
- package/src/code/HighlightedCode.tsx +0 -156
- package/src/code/code-themes.ts +0 -187
- package/src/code/editor/CodeCompletion.tsx +0 -719
- package/src/code/editor/CodeEditor.tsx +0 -480
- package/src/code/editor/CodeHover.tsx +0 -429
- package/src/code/editor/DiagnosticAnnotation.tsx +0 -73
- package/src/code/editor/DiagnosticsChip.tsx +0 -85
- package/src/code/editor/DiffView.tsx +0 -197
- package/src/code/editor/EditorColumn.tsx +0 -256
- package/src/code/editor/FileIcon.tsx +0 -89
- package/src/code/editor/FileTabPill.tsx +0 -101
- package/src/code/editor/FileTree.tsx +0 -414
- package/src/code/editor/FileView.tsx +0 -462
- package/src/code/editor/HighlightWorkers.tsx +0 -84
- package/src/code/editor/LanguageEditor.tsx +0 -210
- package/src/code/editor/_vendor/tree-icon-colors.ts +0 -72
- package/src/code/editor/diagnostics.ts +0 -140
- package/src/code/editor/edit-session.ts +0 -32
- package/src/code/editor/environment.tsx +0 -88
- package/src/code/editor/find/FindBar.tsx +0 -126
- package/src/code/editor/find/find-highlight.ts +0 -138
- package/src/code/editor/find/find-model.ts +0 -123
- package/src/code/editor/find/settle-scroll.ts +0 -77
- package/src/code/editor/find/useFind.ts +0 -203
- package/src/code/editor/fs-adapter.ts +0 -37
- package/src/code/editor/index.ts +0 -36
- package/src/code/editor/language.ts +0 -31
- package/src/code/editor/patch-parse.ts +0 -176
- package/src/code/editor/patch-parse.worker.ts +0 -12
- package/src/code/editor/pierre-theme.ts +0 -155
- package/src/code/editor/prime-diff.ts +0 -37
- package/src/code/editor/reveal.ts +0 -58
- package/src/code/editor/scroll-reach.ts +0 -28
- package/src/code/editor/useCodeDocument.ts +0 -226
- package/src/code/editor/useDefinition.ts +0 -159
- package/src/code/editor/useDetachCleanup.ts +0 -36
- package/src/code/editor/useFileDocument.ts +0 -87
- package/src/code/editor/useRevealLine.ts +0 -92
- package/src/code/editor/word-at.ts +0 -145
- package/src/code/highlight.worker.ts +0 -16
- package/src/code/highlighter.ts +0 -181
- package/src/code/highlights.ts +0 -51
- package/src/code/mermaid-lexer.ts +0 -331
- package/src/code/shiki-theme.ts +0 -46
- package/src/components/BrandMark.tsx +0 -118
- package/src/components/Breadcrumb.tsx +0 -105
- package/src/components/BrowserChrome.tsx +0 -189
- package/src/components/BrowserSignIn.tsx +0 -210
- package/src/components/ChoiceCards.tsx +0 -170
- package/src/components/CodeFrame.tsx +0 -225
- package/src/components/ConfirmDialog.tsx +0 -119
- package/src/components/CopyButton.tsx +0 -85
- package/src/components/EditableTitle.tsx +0 -199
- package/src/components/ErrorBoundary.tsx +0 -208
- package/src/components/Form.tsx +0 -593
- package/src/components/Highlighted.tsx +0 -68
- package/src/components/HowItWorks.tsx +0 -123
- package/src/components/IconButton.tsx +0 -101
- package/src/components/IconToggle.tsx +0 -71
- package/src/components/Keycap.tsx +0 -334
- package/src/components/Lightbox.tsx +0 -257
- package/src/components/LoadError.tsx +0 -45
- package/src/components/MediaNav.tsx +0 -85
- package/src/components/Menu.tsx +0 -435
- package/src/components/Overlay.tsx +0 -327
- package/src/components/PanelEmpty.tsx +0 -80
- package/src/components/PanelRows.tsx +0 -107
- package/src/components/PreviewWindow.tsx +0 -53
- package/src/components/ReorderTabs.tsx +0 -103
- package/src/components/RowActionsMenu.tsx +0 -383
- package/src/components/SegmentSpinner.tsx +0 -88
- package/src/components/Segmented.tsx +0 -126
- package/src/components/StepFrame.tsx +0 -151
- package/src/components/Stepper.tsx +0 -157
- package/src/components/Surface.tsx +0 -191
- package/src/components/SwatchPicker.tsx +0 -147
- package/src/components/SwitchGlyph.tsx +0 -56
- package/src/components/TabPill.tsx +0 -188
- package/src/components/ThemeThumb.tsx +0 -52
- package/src/components/ToggleCard.tsx +0 -120
- package/src/components/Tooltip.tsx +0 -288
- package/src/components/ZoomableImage.tsx +0 -322
- package/src/components/button.ts +0 -120
- package/src/components/floating/FloatingSurface.tsx +0 -158
- package/src/components/floating/HoverCard.tsx +0 -143
- package/src/components/floating/Popover.tsx +0 -166
- package/src/components/floating/useAnchoredPosition.ts +0 -186
- package/src/components/floating/usePopover.ts +0 -158
- package/src/components/image-clipboard.ts +0 -70
- package/src/components/keyboard-layout.ts +0 -115
- package/src/components/palette/PaletteList.tsx +0 -432
- package/src/components/palette/PalettePanel.tsx +0 -338
- package/src/components/palette/palette-layout.ts +0 -86
- package/src/components/report-error.ts +0 -142
- package/src/components/zoom.ts +0 -133
- package/src/extensions/ExtensionComponent.tsx +0 -167
- package/src/extensions/ExtensionDialogHost.tsx +0 -445
- package/src/extensions/ExtensionRenderer.tsx +0 -100
- package/src/extensions/ExtensionScreen.tsx +0 -122
- package/src/extensions/ExtensionSettingsPage.tsx +0 -112
- package/src/extensions/ExtensionSettingsPages.tsx +0 -44
- package/src/extensions/ExtensionSettingsSidebar.tsx +0 -373
- package/src/extensions/ExtensionSlot.tsx +0 -213
- package/src/extensions/ExtensionWebview.tsx +0 -104
- package/src/extensions/ExtensionsProvider.tsx +0 -124
- package/src/extensions/SettingsWireForm.tsx +0 -182
- package/src/extensions/headless/dialog-queue.ts +0 -92
- package/src/extensions/headless/effect-channel.ts +0 -50
- package/src/extensions/headless/effect-router.ts +0 -107
- package/src/extensions/headless/fixture-host.ts +0 -381
- package/src/extensions/headless/host.ts +0 -398
- package/src/extensions/headless/index.ts +0 -17
- package/src/extensions/headless/labels.ts +0 -64
- package/src/extensions/headless/links.ts +0 -56
- package/src/extensions/headless/select.ts +0 -249
- package/src/extensions/headless/webview-bridge.ts +0 -127
- package/src/extensions/headless/wire.ts +0 -175
- package/src/extensions/hooks.ts +0 -209
- package/src/extensions/index.ts +0 -25
- package/src/extensions/kit.ts +0 -79
- package/src/extensions/links.tsx +0 -165
- package/src/extensions/testing/contract.ts +0 -382
- package/src/extensions/testing/index.ts +0 -6
- package/src/extensions/useExtensionsLabels.ts +0 -14
- package/src/files/CodeViewer.tsx +0 -289
- package/src/files/DiffFileViewer.tsx +0 -143
- package/src/files/DiffsTab.tsx +0 -581
- package/src/files/EditorColumn.tsx +0 -453
- package/src/files/EditorEnvironmentRoot.tsx +0 -63
- package/src/files/FilesDiagnosticsChip.tsx +0 -32
- package/src/files/FilesProvider.tsx +0 -58
- package/src/files/FilesTab.tsx +0 -441
- package/src/files/MediaDiff.tsx +0 -61
- package/src/files/MediaView.tsx +0 -170
- package/src/files/ReviewDraft.tsx +0 -88
- package/src/files/ReviewableDiff.tsx +0 -72
- package/src/files/SearchPanel.tsx +0 -325
- package/src/files/TreeColumn.tsx +0 -229
- package/src/files/code-excerpt.ts +0 -265
- package/src/files/code-menu.ts +0 -53
- package/src/files/drafts-store.ts +0 -192
- package/src/files/file-actions.ts +0 -152
- package/src/files/headless/editor-prefs.ts +0 -230
- package/src/files/headless/entries.ts +0 -172
- package/src/files/headless/fixture-host.ts +0 -260
- package/src/files/headless/host.ts +0 -387
- package/src/files/headless/index.ts +0 -14
- package/src/files/headless/labels.ts +0 -123
- package/src/files/headless/lsp-edits.ts +0 -58
- package/src/files/headless/media.ts +0 -57
- package/src/files/headless/name-match.ts +0 -38
- package/src/files/headless/search.ts +0 -23
- package/src/files/headless/view.ts +0 -114
- package/src/files/headless/workspace-diff.ts +0 -82
- package/src/files/index.ts +0 -25
- package/src/files/lazy-tabs.tsx +0 -41
- package/src/files/session-patch.ts +0 -45
- package/src/files/tab-hooks.ts +0 -37
- package/src/files/testing/contract.ts +0 -279
- package/src/files/testing/demo.ts +0 -36
- package/src/files/testing/index.ts +0 -7
- package/src/files/useCodeReview.tsx +0 -177
- package/src/files/useDiagnostics.ts +0 -59
- package/src/files/useDiagnosticsRun.ts +0 -86
- package/src/files/useEntryActions.ts +0 -280
- package/src/files/useFilesDiagnostics.ts +0 -51
- package/src/files/useFilesLabels.ts +0 -14
- package/src/files/useFolderChanges.ts +0 -38
- package/src/files/useLsp.ts +0 -181
- package/src/files/useOpenFiles.ts +0 -402
- package/src/files/useWorkspace.ts +0 -148
- package/src/files/working-tree-diff.ts +0 -142
- package/src/git/BranchMenu.tsx +0 -988
- package/src/git/GitBar.tsx +0 -297
- package/src/git/GitProvider.tsx +0 -50
- package/src/git/ImportRepoDialog.tsx +0 -390
- package/src/git/MoveSessionDialog.tsx +0 -396
- package/src/git/RemoteFolderPicker.tsx +0 -475
- package/src/git/SyncChip.tsx +0 -275
- package/src/git/WherePicker.tsx +0 -358
- package/src/git/headless/environment.ts +0 -132
- package/src/git/headless/host.ts +0 -353
- package/src/git/headless/index.ts +0 -14
- package/src/git/headless/labels.ts +0 -230
- package/src/git/headless/move.ts +0 -101
- package/src/git/headless/remote-clone.ts +0 -44
- package/src/git/headless/status-reads.ts +0 -77
- package/src/git/headless/switcher.ts +0 -215
- package/src/git/headless/sync.ts +0 -71
- package/src/git/index.ts +0 -17
- package/src/git/testing/contract.ts +0 -551
- package/src/git/testing/index.ts +0 -537
- package/src/git/useEnvironmentChoices.ts +0 -50
- package/src/git/useGitBar.ts +0 -180
- package/src/hooks/keyed-store.ts +0 -65
- package/src/hooks/useDisplayPath.tsx +0 -93
- package/src/hooks/useHydrated.ts +0 -16
- package/src/hooks/useMinuteTick.ts +0 -49
- package/src/hooks/useNearViewport.ts +0 -111
- package/src/hooks/usePersistedState.ts +0 -98
- package/src/hooks/useResizeDrag.ts +0 -240
- package/src/hooks/useTabDrag.ts +0 -88
- package/src/index.ts +0 -119
- package/src/keybindings/KeyCommands.tsx +0 -123
- package/src/keybindings/KeyHint.tsx +0 -78
- package/src/keybindings/KeybindingsProvider.tsx +0 -231
- package/src/keybindings/headless/catalog.ts +0 -360
- package/src/keybindings/headless/commands.ts +0 -77
- package/src/keybindings/headless/fixture-host.ts +0 -51
- package/src/keybindings/headless/host.ts +0 -29
- package/src/keybindings/headless/index.ts +0 -13
- package/src/keybindings/headless/key-scope.ts +0 -91
- package/src/keybindings/headless/labels.ts +0 -14
- package/src/keybindings/headless/overrides.ts +0 -64
- package/src/keybindings/index.ts +0 -15
- package/src/keybindings/load-once.ts +0 -11
- package/src/keybindings/match.ts +0 -48
- package/src/keybindings/press.ts +0 -80
- package/src/keybindings/testing/contract.ts +0 -139
- package/src/keybindings/testing/index.ts +0 -6
- package/src/keybindings/useHelpKey.ts +0 -35
- package/src/keybindings/useKeybindingsLabels.ts +0 -14
- package/src/labels.tsx +0 -175
- package/src/machines/AddServerForm.tsx +0 -151
- package/src/machines/Banners.tsx +0 -172
- package/src/machines/DaemonMenu.tsx +0 -413
- package/src/machines/HostCapabilities.tsx +0 -245
- package/src/machines/HostSignIn.tsx +0 -63
- package/src/machines/HostSyncPanel.tsx +0 -275
- package/src/machines/HostsSection.tsx +0 -312
- package/src/machines/MachinesProvider.tsx +0 -164
- package/src/machines/ServerCard.tsx +0 -347
- package/src/machines/ServerMachinesPanel.tsx +0 -547
- package/src/machines/ServerUpdatePanel.tsx +0 -160
- package/src/machines/SyncAccounts.tsx +0 -148
- package/src/machines/SyncMarker.tsx +0 -87
- package/src/machines/SyncOutcomeBadge.tsx +0 -84
- package/src/machines/TokensPanel.tsx +0 -249
- package/src/machines/headless/fixture-host.ts +0 -519
- package/src/machines/headless/fixtures.ts +0 -164
- package/src/machines/headless/host.ts +0 -381
- package/src/machines/headless/index.ts +0 -13
- package/src/machines/headless/labels.ts +0 -364
- package/src/machines/headless/messages.ts +0 -209
- package/src/machines/headless/presence.ts +0 -110
- package/src/machines/headless/settings-focus.ts +0 -25
- package/src/machines/headless/stores.ts +0 -137
- package/src/machines/headless/sync.ts +0 -207
- package/src/machines/index.ts +0 -29
- package/src/machines/settings-section.tsx +0 -37
- package/src/machines/testing/contract.ts +0 -617
- package/src/machines/testing/index.ts +0 -7
- package/src/machines/testing/sync.contract.ts +0 -260
- package/src/motion/SwapIcon.tsx +0 -29
- package/src/motion/collapse.ts +0 -21
- package/src/motion/grow.tsx +0 -86
- package/src/motion/layout-animating.ts +0 -50
- package/src/motion/presence.ts +0 -191
- package/src/motion/provider.tsx +0 -63
- package/src/motion/reduced.ts +0 -36
- package/src/motion/roll.tsx +0 -131
- package/src/motion/shimmer.ts +0 -15
- package/src/motion/size.tsx +0 -192
- package/src/motion/springs.ts +0 -413
- package/src/motion/swap.tsx +0 -216
- package/src/motion/title-text.tsx +0 -74
- package/src/onboarding/ConnectProviderCard.tsx +0 -49
- package/src/onboarding/OnboardingFlow.tsx +0 -176
- package/src/onboarding/OnboardingProvider.tsx +0 -209
- package/src/onboarding/OnboardingStepFrame.tsx +0 -80
- package/src/onboarding/conversation.tsx +0 -196
- package/src/onboarding/demos/autonomy.tsx +0 -154
- package/src/onboarding/demos/extensions.tsx +0 -183
- package/src/onboarding/demos/features.tsx +0 -488
- package/src/onboarding/demos/how-it-works.tsx +0 -698
- package/src/onboarding/demos/index.ts +0 -11
- package/src/onboarding/demos/parts.tsx +0 -133
- package/src/onboarding/demos/tour.tsx +0 -217
- package/src/onboarding/headless/controller.ts +0 -110
- package/src/onboarding/headless/fixture-host.ts +0 -269
- package/src/onboarding/headless/fixtures.ts +0 -486
- package/src/onboarding/headless/host.ts +0 -176
- package/src/onboarding/headless/index.ts +0 -8
- package/src/onboarding/headless/labels.ts +0 -282
- package/src/onboarding/index.ts +0 -21
- package/src/onboarding/marks.tsx +0 -107
- package/src/onboarding/preview-attachments.ts +0 -39
- package/src/onboarding/skills/SkillSourceBrowser.tsx +0 -128
- package/src/onboarding/skills/parts.tsx +0 -464
- package/src/onboarding/sources/SourceBrowser.tsx +0 -400
- package/src/onboarding/steps/AutonomyStep.tsx +0 -128
- package/src/onboarding/steps/ConnectStep.tsx +0 -104
- package/src/onboarding/steps/ConnectorsStep.tsx +0 -222
- package/src/onboarding/steps/ConversationStep.tsx +0 -132
- package/src/onboarding/steps/ExtensionsStep.tsx +0 -113
- package/src/onboarding/steps/FeatureExample.tsx +0 -46
- package/src/onboarding/steps/FeaturesStep.tsx +0 -88
- package/src/onboarding/steps/ImportStep.tsx +0 -156
- package/src/onboarding/steps/LookStep.tsx +0 -276
- package/src/onboarding/steps/ReadyStep.tsx +0 -278
- package/src/onboarding/steps/SkillsStep.tsx +0 -45
- package/src/onboarding/steps/StepSection.tsx +0 -63
- package/src/onboarding/steps/Tradeoff.tsx +0 -45
- package/src/onboarding/steps/WelcomeStep.tsx +0 -147
- package/src/onboarding/steps/connect/KeyForm.tsx +0 -112
- package/src/onboarding/steps/connect/ProviderPanel.tsx +0 -149
- package/src/onboarding/steps/connect/ProviderReady.tsx +0 -171
- package/src/onboarding/steps/connect/ready-text.ts +0 -17
- package/src/onboarding/steps/index.ts +0 -12
- package/src/onboarding/steps/tasks.tsx +0 -84
- package/src/onboarding/testing/contract.ts +0 -472
- package/src/onboarding/testing/index.ts +0 -7
- package/src/onboarding/tutorials.tsx +0 -45
- package/src/onboarding/useSignIn.ts +0 -58
- package/src/palette/CommandPalette.tsx +0 -59
- package/src/palette/PaletteDialog.tsx +0 -186
- package/src/palette/PaletteProvider.tsx +0 -149
- package/src/palette/PaletteRows.tsx +0 -208
- package/src/palette/app-sources.ts +0 -62
- package/src/palette/headless/app-sources.ts +0 -515
- package/src/palette/headless/gather.ts +0 -50
- package/src/palette/headless/host.ts +0 -129
- package/src/palette/headless/index.ts +0 -15
- package/src/palette/headless/labels.ts +0 -124
- package/src/palette/headless/rank-protocol.ts +0 -23
- package/src/palette/headless/recents.ts +0 -35
- package/src/palette/headless/session-sources.ts +0 -218
- package/src/palette/headless/sources.ts +0 -313
- package/src/palette/headless/store.ts +0 -105
- package/src/palette/index.ts +0 -17
- package/src/palette/rank.worker.ts +0 -30
- package/src/palette/setup.ts +0 -19
- package/src/palette/testing/contract.ts +0 -250
- package/src/palette/testing/index.ts +0 -152
- package/src/palette/useConversationSearch.ts +0 -115
- package/src/palette/usePaletteController.ts +0 -229
- package/src/palette/useRankedItems.ts +0 -122
- package/src/path.ts +0 -199
- package/src/server/demo-tools.ts +0 -34
- package/src/server/environment.ts +0 -118
- package/src/server/index.ts +0 -7
- package/src/server/scripted-provider.ts +0 -174
- package/src/server/sse-handler.ts +0 -457
- package/src/server/testing/index.ts +0 -7
- package/src/session/ArtifactRowChips.tsx +0 -260
- package/src/session/ArtifactsPanel.tsx +0 -426
- package/src/session/DiffFileTree.tsx +0 -173
- package/src/session/PanelAttention.tsx +0 -131
- package/src/session/ProjectHome.tsx +0 -733
- package/src/session/ProviderUsageProvider.tsx +0 -113
- package/src/session/QueueTab.tsx +0 -669
- package/src/session/RunningWorkDialog.tsx +0 -178
- package/src/session/SessionCacheFacts.tsx +0 -190
- package/src/session/SessionDetailsDialog.tsx +0 -627
- package/src/session/SessionHeader.tsx +0 -242
- package/src/session/SessionProvider.tsx +0 -98
- package/src/session/SessionShell.tsx +0 -77
- package/src/session/SideChat.tsx +0 -320
- package/src/session/TodoList.tsx +0 -123
- package/src/session/TodosPanel.tsx +0 -279
- package/src/session/TurnDetailsDialog.tsx +0 -299
- package/src/session/UsagePanel.tsx +0 -358
- package/src/session/WelcomeScreen.tsx +0 -88
- package/src/session/headless/artifacts.ts +0 -101
- package/src/session/headless/diff-tree.ts +0 -167
- package/src/session/headless/fixture-host.ts +0 -362
- package/src/session/headless/home-layout.ts +0 -276
- package/src/session/headless/host.ts +0 -263
- package/src/session/headless/index.ts +0 -23
- package/src/session/headless/keyed.ts +0 -72
- package/src/session/headless/labels.ts +0 -337
- package/src/session/headless/queue-attachments.ts +0 -73
- package/src/session/headless/queue.ts +0 -122
- package/src/session/headless/running-work.ts +0 -85
- package/src/session/headless/session-actions.ts +0 -198
- package/src/session/headless/session-diffs.ts +0 -136
- package/src/session/headless/side.ts +0 -63
- package/src/session/headless/todos.ts +0 -62
- package/src/session/headless/usage-format.ts +0 -19
- package/src/session/headless/usage.ts +0 -407
- package/src/session/index.ts +0 -31
- package/src/session/modal-shell.tsx +0 -24
- package/src/session/testing/contract.ts +0 -588
- package/src/session/testing/demo.ts +0 -224
- package/src/session/testing/index.ts +0 -7
- package/src/session/useSessionLabels.ts +0 -14
- package/src/session/useUsageSummary.ts +0 -82
- package/src/settings/SettingsHeadingText.tsx +0 -54
- package/src/settings/SettingsHostSwitcher.tsx +0 -93
- package/src/settings/SettingsNav.tsx +0 -198
- package/src/settings/SettingsProvider.tsx +0 -127
- package/src/settings/SettingsRowsPage.tsx +0 -218
- package/src/settings/SettingsShell.tsx +0 -337
- package/src/settings/SettingsTutorial.tsx +0 -55
- package/src/settings/headless/catalog.ts +0 -570
- package/src/settings/headless/claude-import.ts +0 -61
- package/src/settings/headless/enabled.ts +0 -44
- package/src/settings/headless/fixture-accounts.ts +0 -260
- package/src/settings/headless/fixture-host.ts +0 -162
- package/src/settings/headless/fixture-models.ts +0 -51
- package/src/settings/headless/fixture-performance.ts +0 -350
- package/src/settings/headless/fixture-sections.ts +0 -391
- package/src/settings/headless/host.ts +0 -127
- package/src/settings/headless/index.ts +0 -22
- package/src/settings/headless/labels.ts +0 -63
- package/src/settings/headless/layout-sections.ts +0 -41
- package/src/settings/headless/layout.ts +0 -732
- package/src/settings/headless/mcp.ts +0 -319
- package/src/settings/headless/models.ts +0 -51
- package/src/settings/headless/page-counts.ts +0 -40
- package/src/settings/headless/performance.ts +0 -524
- package/src/settings/headless/providers.ts +0 -117
- package/src/settings/headless/registry.ts +0 -62
- package/src/settings/headless/resource.ts +0 -75
- package/src/settings/headless/search.ts +0 -142
- package/src/settings/headless/sections-host.ts +0 -340
- package/src/settings/index.ts +0 -32
- package/src/settings/rows.tsx +0 -152
- package/src/settings/section.tsx +0 -165
- package/src/settings/sections/appearance/AppearanceSection.tsx +0 -667
- package/src/settings/sections/appearance/labels.ts +0 -77
- package/src/settings/sections/claude-import/ClaudeImportDialog.tsx +0 -258
- package/src/settings/sections/claude-import/labels.ts +0 -42
- package/src/settings/sections/claude-import/use-claude-import-available.ts +0 -35
- package/src/settings/sections/descriptors.tsx +0 -261
- package/src/settings/sections/editor/EditorSection.tsx +0 -521
- package/src/settings/sections/editor/labels.ts +0 -84
- package/src/settings/sections/enabled-list/EnabledListSection.tsx +0 -112
- package/src/settings/sections/enabled-list/labels.ts +0 -37
- package/src/settings/sections/environments/EnvironmentsSection.tsx +0 -549
- package/src/settings/sections/environments/labels.ts +0 -31
- package/src/settings/sections/extensions/ChangeOriginDialog.tsx +0 -218
- package/src/settings/sections/extensions/CreateExtensionDialog.tsx +0 -210
- package/src/settings/sections/extensions/ExtensionConfigRows.tsx +0 -508
- package/src/settings/sections/extensions/ExtensionOptionsSection.tsx +0 -356
- package/src/settings/sections/extensions/ExtensionPicksBar.tsx +0 -112
- package/src/settings/sections/extensions/ExtensionSourceBrowser.tsx +0 -244
- package/src/settings/sections/extensions/ExtensionsSection.tsx +0 -665
- package/src/settings/sections/extensions/create-labels.ts +0 -31
- package/src/settings/sections/extensions/labels.ts +0 -64
- package/src/settings/sections/extensions/options-labels.ts +0 -34
- package/src/settings/sections/host-catalog/HostCatalogSection.tsx +0 -457
- package/src/settings/sections/host-catalog/labels.ts +0 -44
- package/src/settings/sections/index.ts +0 -60
- package/src/settings/sections/instructions/InstructionsSection.tsx +0 -385
- package/src/settings/sections/instructions/labels.ts +0 -33
- package/src/settings/sections/keybindings/KeybindingsSection.tsx +0 -124
- package/src/settings/sections/keybindings/labels.ts +0 -72
- package/src/settings/sections/keybindings/rows.ts +0 -103
- package/src/settings/sections/logs/LogsSection.tsx +0 -153
- package/src/settings/sections/logs/labels.ts +0 -20
- package/src/settings/sections/mcp/McpAddForm.tsx +0 -245
- package/src/settings/sections/mcp/McpSection.tsx +0 -358
- package/src/settings/sections/mcp/McpServerRow.tsx +0 -404
- package/src/settings/sections/mcp/labels.ts +0 -193
- package/src/settings/sections/models/AgentDefaults.tsx +0 -365
- package/src/settings/sections/models/ModelListPicker.tsx +0 -265
- package/src/settings/sections/models/ModelPickField.tsx +0 -220
- package/src/settings/sections/models/ModelRows.tsx +0 -381
- package/src/settings/sections/models/SpacesDefaultsSection.tsx +0 -102
- package/src/settings/sections/models/labels.ts +0 -119
- package/src/settings/sections/models/model-test.tsx +0 -125
- package/src/settings/sections/performance/PerfSparkline.tsx +0 -64
- package/src/settings/sections/performance/PerformanceHud.tsx +0 -110
- package/src/settings/sections/performance/PerformanceSection.tsx +0 -770
- package/src/settings/sections/performance/labels.ts +0 -114
- package/src/settings/sections/performance/use-perf-monitor.ts +0 -26
- package/src/settings/sections/plugins/PluginsSection.tsx +0 -151
- package/src/settings/sections/plugins/labels.ts +0 -23
- package/src/settings/sections/providers/CredentialSources.tsx +0 -237
- package/src/settings/sections/providers/ProvidersSection.tsx +0 -389
- package/src/settings/sections/providers/ServerProvidersSection.tsx +0 -244
- package/src/settings/sections/providers/ServerSignIn.tsx +0 -137
- package/src/settings/sections/providers/labels.ts +0 -160
- package/src/settings/sections/shared/catalog.tsx +0 -265
- package/src/settings/sections/shared/labels.ts +0 -31
- package/src/settings/sections/skills/SkillList.tsx +0 -494
- package/src/settings/sections/skills/SkillsSection.tsx +0 -249
- package/src/settings/sections/skills/labels.ts +0 -54
- package/src/settings/sections/use-section-labels.ts +0 -10
- package/src/settings/testing/accounts-demo.ts +0 -110
- package/src/settings/testing/accounts.contract.ts +0 -319
- package/src/settings/testing/claude-import.contract.ts +0 -93
- package/src/settings/testing/contract.ts +0 -192
- package/src/settings/testing/extension-options.contract.ts +0 -163
- package/src/settings/testing/index.ts +0 -11
- package/src/settings/testing/models.contract.ts +0 -135
- package/src/settings/testing/performance.contract.ts +0 -219
- package/src/settings/testing/sections.contract.ts +0 -306
- package/src/terminal/HostTerminalSurface.tsx +0 -917
- package/src/terminal/TerminalDrawer.tsx +0 -228
- package/src/terminal/TerminalPanel.tsx +0 -740
- package/src/terminal/TerminalProvider.tsx +0 -201
- package/src/terminal/TerminalSurface.tsx +0 -262
- package/src/terminal/box-glyphs.ts +0 -333
- package/src/terminal/ghostty.ts +0 -116
- package/src/terminal/grid-size.ts +0 -46
- package/src/terminal/headless/fixture-host.ts +0 -250
- package/src/terminal/headless/host.ts +0 -99
- package/src/terminal/headless/index.ts +0 -11
- package/src/terminal/headless/labels.ts +0 -69
- package/src/terminal/headless/layout.ts +0 -57
- package/src/terminal/headless/links.ts +0 -227
- package/src/terminal/headless/order.ts +0 -28
- package/src/terminal/headless/output-cursor.ts +0 -66
- package/src/terminal/headless/recent.ts +0 -20
- package/src/terminal/headless/replay.ts +0 -45
- package/src/terminal/headless/scope.ts +0 -60
- package/src/terminal/headless/store.ts +0 -637
- package/src/terminal/index.ts +0 -40
- package/src/terminal/keys.ts +0 -34
- package/src/terminal/testing/contract.ts +0 -274
- package/src/terminal/testing/demo.ts +0 -40
- package/src/terminal/testing/index.ts +0 -7
- package/src/terminal/theme.ts +0 -110
- package/src/terminal/useTerminalLabels.ts +0 -14
- package/src/theme/accents.ts +0 -46
- package/src/theme/color.ts +0 -450
- package/src/theme/css-vars.ts +0 -187
- package/src/theme/derive.ts +0 -700
- package/src/theme/from-theme.ts +0 -52
- package/src/theme/stylesheet.ts +0 -55
- package/src/theme/themes.ts +0 -767
- package/src/theme/without-transitions.ts +0 -18
- package/src/uno.ts +0 -167
- package/src/workspace/LayoutBudget.tsx +0 -143
- package/src/workspace/PanelContentView.tsx +0 -523
- package/src/workspace/PanelCorner.tsx +0 -111
- package/src/workspace/PanelGroups.tsx +0 -264
- package/src/workspace/PanelHome.tsx +0 -71
- package/src/workspace/PanelItems.tsx +0 -368
- package/src/workspace/PanelStrip.tsx +0 -316
- package/src/workspace/SidePanel.tsx +0 -240
- package/src/workspace/TabParking.tsx +0 -120
- package/src/workspace/WorkspaceProvider.tsx +0 -558
- package/src/workspace/dnd/engine.ts +0 -371
- package/src/workspace/dnd/hooks.ts +0 -72
- package/src/workspace/dnd/index.ts +0 -57
- package/src/workspace/dnd/parking.tsx +0 -181
- package/src/workspace/extension-tabs.tsx +0 -174
- package/src/workspace/frame-motion.ts +0 -160
- package/src/workspace/headless/contents.ts +0 -125
- package/src/workspace/headless/host.ts +0 -129
- package/src/workspace/headless/index.ts +0 -33
- package/src/workspace/headless/labels.ts +0 -44
- package/src/workspace/headless/layout-memory.ts +0 -649
- package/src/workspace/headless/layouts.ts +0 -224
- package/src/workspace/headless/open-target.ts +0 -125
- package/src/workspace/headless/ops.ts +0 -163
- package/src/workspace/headless/panel-focus.ts +0 -58
- package/src/workspace/headless/panel-tree.ts +0 -259
- package/src/workspace/headless/resolve.ts +0 -146
- package/src/workspace/headless/reveal-at.ts +0 -27
- package/src/workspace/headless/strip-drop.ts +0 -81
- package/src/workspace/headless/tree.ts +0 -480
- package/src/workspace/headless/view.ts +0 -164
- package/src/workspace/index.ts +0 -23
- package/src/workspace/panel-group-keys.ts +0 -36
- package/src/workspace/panel-visibility.ts +0 -28
- package/src/workspace/tab-scopes.ts +0 -245
- package/src/workspace/testing/contract.ts +0 -282
- package/src/workspace/testing/index.ts +0 -140
- package/src/workspace/use-split-drag.ts +0 -73
- package/src/workspace/useScopeLayout.ts +0 -26
- package/src/workspace/useViewport.ts +0 -22
- package/src/workspace/useWorkspaceLabels.ts +0 -14
- package/src/workspace/workspace-key-commands.ts +0 -108
- /package/dist/dist/{types-bDQagoiL.d.ts → types-2HrgolQz.d.ts} +0 -0
|
@@ -1,1046 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The session directory: every host's sessions as the sidebar lists them,
|
|
3
|
-
* kept current outside React.
|
|
4
|
-
*
|
|
5
|
-
* - Listing: one read per host (this machine plus each remote host) under
|
|
6
|
-
* the shown archive filter. Reads are versioned: only the newest refresh
|
|
7
|
-
* lands, and a host's own older answer never overwrites a newer one.
|
|
8
|
-
* - Run state: a refresh reconciles the rows' status with the stream store
|
|
9
|
-
* (a running row marks the session running, an idle one confirmed by the
|
|
10
|
-
* host clears a run this client missed the end of) unless a stream signal
|
|
11
|
-
* moved the run state while the refresh was in flight.
|
|
12
|
-
* - Live: a debounced change signal re-reads the hosts it touched; a run end
|
|
13
|
-
* re-reads its host and leaves a notification on a session not open; a
|
|
14
|
-
* runtime switch drops every stream; a reconnect (runtime or the open
|
|
15
|
-
* session's server) re-reads the open transcript when no run streams it.
|
|
16
|
-
* - Prewarm: the transcripts around the open session load in idle time.
|
|
17
|
-
* - Spaces: the shown space (kept by the views store), the slide direction of
|
|
18
|
-
* the last switch, following the open session to its space, and reopening
|
|
19
|
-
* the conversation last open in a space when switching back to it.
|
|
20
|
-
* - Actions: create (in the shown space), rename, optimistic favorite,
|
|
21
|
-
* archive, move to a space (a session or a whole project), delete.
|
|
22
|
-
* - Extensions: the spaces they add join the user's (`query.ts`), facets
|
|
23
|
-
* pushed by the host land on their rows, and the switcher keeps its own
|
|
24
|
-
* order and hidden spaces; the current view can be saved as a space (its
|
|
25
|
-
* query built by `viewQuery`, checked before it is stored). Facet pushes
|
|
26
|
-
* arriving together land in one state change.
|
|
27
|
-
*
|
|
28
|
-
* Generic over the app's row type and its transcript page type, so an app
|
|
29
|
-
* keeps its own branded session keys.
|
|
30
|
-
*/
|
|
31
|
-
import {
|
|
32
|
-
activeSpaceOf,
|
|
33
|
-
DEFAULT_SPACE_ID,
|
|
34
|
-
normalizeSpaces,
|
|
35
|
-
projectNameOf,
|
|
36
|
-
resolveSessionSpace,
|
|
37
|
-
SessionQueryError,
|
|
38
|
-
sessionDirLabel,
|
|
39
|
-
viewQuery,
|
|
40
|
-
type QueryBound,
|
|
41
|
-
} from 'zidane/chat/pure';
|
|
42
|
-
|
|
43
|
-
import { constant, writable, type Readable } from '../store';
|
|
44
|
-
import { createNotificationStore, type SessionNotificationStore } from './notifications';
|
|
45
|
-
import {
|
|
46
|
-
filterQueryOf,
|
|
47
|
-
filtersForSpace,
|
|
48
|
-
mergeSidebarSpaces,
|
|
49
|
-
NO_SIDEBAR_CONTRIBUTIONS,
|
|
50
|
-
resolveGrouping,
|
|
51
|
-
resolveSort,
|
|
52
|
-
spaceMembership,
|
|
53
|
-
switcherSpaces,
|
|
54
|
-
type SidebarContributions,
|
|
55
|
-
type SidebarSpace,
|
|
56
|
-
} from './query';
|
|
57
|
-
import { isProjectMember } from './rows';
|
|
58
|
-
import { VIEW_CHOICE, type SessionActivityFilter, type SessionArchiveFilter, type SidebarListSession } from './types';
|
|
59
|
-
import { DEFAULT_SIDEBAR_VIEW, type SidebarViews } from './view';
|
|
60
|
-
|
|
61
|
-
/** A project as one space lists it: its path (`projectPathOf`), the host it is on, the space. */
|
|
62
|
-
export interface ProjectInSpace {
|
|
63
|
-
/** The project's folder (`projectPathOf`). */
|
|
64
|
-
path: string;
|
|
65
|
-
/** A remote host's id; absent for this machine. */
|
|
66
|
-
hostId?: string;
|
|
67
|
-
/** The space it is listed in (an unknown or absent id is the default space). */
|
|
68
|
-
spaceId?: string;
|
|
69
|
-
/** Its repository, when its group also lists the repository's sessions on other machines (`isProjectMember`). */
|
|
70
|
-
repoKey?: string;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** What deleting a session did with its environment. */
|
|
74
|
-
export type SessionRemoval = { kept: false } | { kept: true; reason?: string };
|
|
75
|
-
|
|
76
|
-
/** The sessions transport the directory reads and acts through (`ChatHost.sessions`). */
|
|
77
|
-
export interface SessionDirectorySource<S extends SidebarListSession, C = unknown> {
|
|
78
|
-
/** One host's sessions under the archive filter; `hostId` absent = this machine. */
|
|
79
|
-
query(filter: { archive: SessionArchiveFilter; hostId?: string }): Promise<readonly S[]>;
|
|
80
|
-
/** Creates a session and resolves with its row. */
|
|
81
|
-
create?(input: C): Promise<S>;
|
|
82
|
-
/** Sets a session's title. */
|
|
83
|
-
rename?(sessionId: S['id'], title: string): Promise<void>;
|
|
84
|
-
/** Stars or unstars a session. */
|
|
85
|
-
setFavorite?(sessionId: S['id'], favorite: boolean): Promise<void>;
|
|
86
|
-
/** Archives or restores a session. */
|
|
87
|
-
setArchived?(sessionId: S['id'], archived: boolean): Promise<void>;
|
|
88
|
-
/** Moves a session to a space. */
|
|
89
|
-
setSpace?(sessionId: S['id'], spaceId: string): Promise<void>;
|
|
90
|
-
/** Resolves to `{ kept: true }` when the session's environment stayed on disk. */
|
|
91
|
-
remove?(sessionId: S['id']): Promise<void | SessionRemoval>;
|
|
92
|
-
/** Fires (possibly in bursts) with a session whose row changed. */
|
|
93
|
-
onChanged?(listener: (sessionId: S['id']) => void): () => void;
|
|
94
|
-
/**
|
|
95
|
-
* Fires with a session's facets when the extensions computed new ones (`sessions:facets`): every
|
|
96
|
-
* value, keyed `<extensionId>.<key>`. Absent: facets change only with a re-read.
|
|
97
|
-
*/
|
|
98
|
-
onFacets?(listener: (sessionId: S['id'], facets: Readonly<Record<string, unknown>>) => void): () => void;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/** The slice of the session stream store the directory keeps in step. */
|
|
102
|
-
export interface SessionDirectoryStreams<K extends string, P> {
|
|
103
|
-
/** A snapshot of the run state; the returned check says whether it still holds. */
|
|
104
|
-
captureRunState(): () => boolean;
|
|
105
|
-
/** A row says the session runs: show it running. */
|
|
106
|
-
markRunning(sessionId: K): void;
|
|
107
|
-
/** The host confirmed the session is idle: end a run whose end was missed. */
|
|
108
|
-
confirmIdle(sessionId: K): void;
|
|
109
|
-
/** Whether a run streams for the session here. */
|
|
110
|
-
peekRunning(sessionId: K | null): boolean;
|
|
111
|
-
/** The session's run counter (bumps on every run start). */
|
|
112
|
-
peekRunSeq(sessionId: K | null): number;
|
|
113
|
-
/** The session's transcript is cached. */
|
|
114
|
-
hasEvents(sessionId: K): boolean;
|
|
115
|
-
/** Cache a loaded transcript page. */
|
|
116
|
-
setEventsPage(sessionId: K, page: P): void;
|
|
117
|
-
/** Drop every cached transcript except these. */
|
|
118
|
-
evictExcept(keep: ReadonlySet<K>): void;
|
|
119
|
-
/** Drop every stream (a runtime switch). */
|
|
120
|
-
dropAll(): void;
|
|
121
|
-
/** Drop one session's stream (deleted). */
|
|
122
|
-
reset(sessionId: K): void;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** A remote host as the directory follows it. */
|
|
126
|
-
export interface DirectoryServer {
|
|
127
|
-
/** The host id rows carry as `hostId`. */
|
|
128
|
-
id: string;
|
|
129
|
-
/** Its connection status (`connected` when reachable). */
|
|
130
|
-
status: string;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/** The settings the directory reads. */
|
|
134
|
-
export interface DirectorySettings {
|
|
135
|
-
/** Spaces are on. */
|
|
136
|
-
spaces: boolean;
|
|
137
|
-
/** The settings' space list as stored (normalized here). */
|
|
138
|
-
spaceList: unknown;
|
|
139
|
-
/** The orchestration main session is listed. */
|
|
140
|
-
orchestration: boolean;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/** Options of {@link createSessionDirectory}: the ports it reads and acts through. */
|
|
144
|
-
export interface SessionDirectoryOptions<S extends SidebarListSession, P, C = unknown> {
|
|
145
|
-
/** The sessions transport (`ChatHost.sessions`). */
|
|
146
|
-
sessions: SessionDirectorySource<S, C>;
|
|
147
|
-
/** The stream store it keeps in step. */
|
|
148
|
-
streams: SessionDirectoryStreams<S['id'], P>;
|
|
149
|
-
/** Load a session's latest transcript page. */
|
|
150
|
-
loadEvents(sessionId: S['id'], options?: { prewarm?: boolean }): Promise<P>;
|
|
151
|
-
/** Ask whether a session runs; `false` only when the host is sure it doesn't. */
|
|
152
|
-
isRunning(sessionId: S['id']): Promise<boolean | null | undefined>;
|
|
153
|
-
/** The remote hosts listed next to this machine. */
|
|
154
|
-
servers: Readable<readonly DirectoryServer[]>;
|
|
155
|
-
/** Spaces and orchestration settings. */
|
|
156
|
-
settings: Readable<DirectorySettings>;
|
|
157
|
-
/** The views and the shown space. */
|
|
158
|
-
views: SidebarViews;
|
|
159
|
-
/** The archive filter the list shows (the shown space's view). */
|
|
160
|
-
archive?: SessionArchiveFilter;
|
|
161
|
-
/** Live signals; each one left out is not followed. */
|
|
162
|
-
signals?: {
|
|
163
|
-
/** A run ended. */
|
|
164
|
-
onRunEnd?(listener: (sessionId: S['id'], ok: boolean) => void): () => void;
|
|
165
|
-
/** The runtime connected or disconnected (a daemon, a server connection). */
|
|
166
|
-
onRuntime?(listener: (connected: boolean) => void): () => void;
|
|
167
|
-
/** A remote host was removed, with the sessions it held and the words to show. */
|
|
168
|
-
onHostRemoved?(
|
|
169
|
-
listener: (removed: { hostId: string; sessionIds: readonly S['id'][]; notice: string | null }) => void,
|
|
170
|
-
): () => void;
|
|
171
|
-
};
|
|
172
|
-
/** The remote host a session lives on, `null` on this machine. */
|
|
173
|
-
serverOf(sessionId: S['id']): string | null;
|
|
174
|
-
/** Session keys kept in the transcript cache besides the prewarmed ones (`pinnedSessions`). */
|
|
175
|
-
pinned?: () => Iterable<S['id']>;
|
|
176
|
-
/** A window that only ever shows this session (its other sessions are never opened). */
|
|
177
|
-
pinnedSession?: S['id'] | null;
|
|
178
|
-
/** Schedules prewarm reads; defaults to `requestIdleCallback` with a timer fallback. */
|
|
179
|
-
idle?: { request(run: () => void): number; cancel(handle: number): void };
|
|
180
|
-
/** Debounce of change signals. Defaults to 300 ms. */
|
|
181
|
-
changedDebounceMs?: number;
|
|
182
|
-
/** A refresh is about to list these rows (an app's per-row bookkeeping, before they render). */
|
|
183
|
-
onListed?(rows: readonly S[]): void;
|
|
184
|
-
/** A session was deleted: drop what the app keeps for it (panels, layouts). */
|
|
185
|
-
onRemoved?(sessionId: S['id']): void;
|
|
186
|
-
/** A refresh failed. */
|
|
187
|
-
onError?(error: unknown): void;
|
|
188
|
-
/**
|
|
189
|
-
* What the extensions contribute to the sidebar (`sidebarContributionsOf(host.items)`). An app whose
|
|
190
|
-
* extensions host comes later attaches it then (`attachContributions`).
|
|
191
|
-
*/
|
|
192
|
-
contributions?: Readable<SidebarContributions>;
|
|
193
|
-
/** Adds a space to the user's list (the settings' `spaceList`). Absent: a view can't be saved as a space. */
|
|
194
|
-
saveSpace?(space: SidebarSpace): Promise<void>;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/** The directory's state as one snapshot: a new object whenever any field changes. */
|
|
198
|
-
export interface SessionDirectoryState<S extends SidebarListSession> {
|
|
199
|
-
/** Every listed session, unfiltered (the archive filter is the host's). */
|
|
200
|
-
allSessions: readonly S[];
|
|
201
|
-
/** The open session. */
|
|
202
|
-
activeSessionId: S['id'] | null;
|
|
203
|
-
/** Spaces are on. */
|
|
204
|
-
spacesOn: boolean;
|
|
205
|
-
/** Every space, the default one always present: the user's in order, then the extensions'. */
|
|
206
|
-
spaces: readonly SidebarSpace[];
|
|
207
|
-
/** The spaces the switcher shows, in its order (the user's arrangement on top of `spaces`). */
|
|
208
|
-
switcherSpaces: readonly SidebarSpace[];
|
|
209
|
-
/**
|
|
210
|
-
* The spaces the user hid from the switcher on this device (`setSpaceHidden`), in `spaces` order:
|
|
211
|
-
* what the switcher's Hidden spaces menu offers to show again. A space hidden in the settings'
|
|
212
|
-
* space list (`hidden: true`) is not in it: the settings show it again.
|
|
213
|
-
*/
|
|
214
|
-
hiddenSpaces: readonly SidebarSpace[];
|
|
215
|
-
/** The space shown (the default one while spaces are off). */
|
|
216
|
-
activeSpace: SidebarSpace;
|
|
217
|
-
/** What the extensions contribute to the sidebar. */
|
|
218
|
-
contributions: SidebarContributions;
|
|
219
|
-
/** The last space switch, for the list's slide. */
|
|
220
|
-
spaceSlide: { spaceId: string; direction: 'next' | 'prev' } | null;
|
|
221
|
-
/** Why the open session closed (its host was removed), until dismissed or another opens. */
|
|
222
|
-
hostNotice: string | null;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/** The session directory: its state, notifications and views, and the actions on them. */
|
|
226
|
-
export interface SessionDirectory<S extends SidebarListSession, C = unknown> {
|
|
227
|
-
/** The state, one snapshot per change. */
|
|
228
|
-
state: Readable<SessionDirectoryState<S>>;
|
|
229
|
-
/** What finished runs left on sessions not open. */
|
|
230
|
-
notifications: SessionNotificationStore;
|
|
231
|
-
/** The views and the shown space. */
|
|
232
|
-
views: SidebarViews;
|
|
233
|
-
/** Start following hosts, signals and settings; returns the stop. */
|
|
234
|
-
start(): () => void;
|
|
235
|
-
/** Re-read every host. */
|
|
236
|
-
refresh(): Promise<void>;
|
|
237
|
-
/** The list's archive filter changed (re-reads when it did). */
|
|
238
|
-
setArchive(archive: SessionArchiveFilter): void;
|
|
239
|
-
/** Open a session (or none) and clear its notification and the host notice. */
|
|
240
|
-
select(sessionId: S['id'] | null): void;
|
|
241
|
-
/** Set the open session without clearing anything (window routing, deletes). */
|
|
242
|
-
setActive(sessionId: S['id'] | null | ((current: S['id'] | null) => S['id'] | null)): void;
|
|
243
|
-
/** Hides the host notice. */
|
|
244
|
-
dismissHostNotice(): void;
|
|
245
|
-
/** Create a session in the shown space (unless the input names one) and list it. */
|
|
246
|
-
create(input: C & { spaceId?: string }): Promise<S>;
|
|
247
|
-
/** Renames a session, then re-reads. */
|
|
248
|
-
rename(sessionId: S['id'], title: string): Promise<void>;
|
|
249
|
-
/** Stars or unstars a session at once; a failed write puts it back. */
|
|
250
|
-
setFavorite(sessionId: S['id'], favorite: boolean): Promise<void>;
|
|
251
|
-
/** Archives or restores a session, then re-reads. */
|
|
252
|
-
setArchived(sessionId: S['id'], archived: boolean): Promise<void>;
|
|
253
|
-
/** Archives sessions, then re-reads once. */
|
|
254
|
-
archiveMany(sessionIds: readonly S['id'][]): Promise<void>;
|
|
255
|
-
/** Delete one session without re-reading; the caller refreshes. */
|
|
256
|
-
drop(sessionId: S['id']): Promise<SessionRemoval>;
|
|
257
|
-
/** Delete sessions, then re-read; resolves to how many kept their environment. */
|
|
258
|
-
removeMany(sessionIds: readonly S['id'][]): Promise<{ kept: number; reason?: string }>;
|
|
259
|
-
/**
|
|
260
|
-
* Shows another space and reopens the conversation last open there, when it is still listed in it;
|
|
261
|
-
* else the open session closes when it belongs elsewhere.
|
|
262
|
-
*/
|
|
263
|
-
setActiveSpace(spaceId: string): void;
|
|
264
|
-
/** Step to the next or previous space, wrapping at either end; false with spaces off or only one space. */
|
|
265
|
-
stepSpace(delta: 1 | -1): boolean;
|
|
266
|
-
/** Moves a session to a space, then re-reads. */
|
|
267
|
-
setSessionSpace(sessionId: S['id'], spaceId: string): Promise<void>;
|
|
268
|
-
/** Hides a space from the switcher or shows it again; hiding the shown space shows the default one. */
|
|
269
|
-
setSpaceHidden(spaceId: string, hidden: boolean): void;
|
|
270
|
-
/** Moves a space one place left (-1) or right (1) in the switcher. */
|
|
271
|
-
moveSpace(spaceId: string, delta: 1 | -1): void;
|
|
272
|
-
/** Follow an extensions host's sidebar contributions from now on (replacing any); returns the detach. */
|
|
273
|
-
attachContributions(contributions: Readable<SidebarContributions>): () => void;
|
|
274
|
-
/**
|
|
275
|
-
* Saves the shown space's view as a new user space (its query, grouping and sort) and shows it.
|
|
276
|
-
* The query is `viewQuery`'s (`zidane/chat/pure`): the space's membership, then the project,
|
|
277
|
-
* activity, agent and contributed filters. Rejects with a `SessionQueryError` (nothing saved)
|
|
278
|
-
* when that query is not valid (too deep, too many nodes or values), and with `saveSpace`'s error.
|
|
279
|
-
* Undefined without `saveSpace`. The sidebar's `useSaveViewAsSpace` names the space and words a failure.
|
|
280
|
-
*/
|
|
281
|
-
saveViewAsSpace?: (name: string) => Promise<SidebarSpace>;
|
|
282
|
-
/** A project's sessions in its space (every archive state), read fresh from its host. */
|
|
283
|
-
listProjectSessions(project: ProjectInSpace): Promise<S[]>;
|
|
284
|
-
/** Move a project's sessions to another space; resolves to how many moved. */
|
|
285
|
-
setProjectSpace(project: ProjectInSpace, spaceId: string): Promise<number>;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const PREWARM_FULL_THRESHOLD = 12;
|
|
289
|
-
const PREWARM_WINDOW_RADIUS = 6;
|
|
290
|
-
|
|
291
|
-
const defaultIdle = {
|
|
292
|
-
request(run: () => void): number {
|
|
293
|
-
if (typeof requestIdleCallback === 'function') return requestIdleCallback(() => run());
|
|
294
|
-
return setTimeout(run, 150) as unknown as number;
|
|
295
|
-
},
|
|
296
|
-
cancel(handle: number): void {
|
|
297
|
-
if (typeof cancelIdleCallback === 'function') cancelIdleCallback(handle);
|
|
298
|
-
else clearTimeout(handle);
|
|
299
|
-
},
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* The directory over the app's ports; nothing runs until `start()`.
|
|
304
|
-
*
|
|
305
|
-
* @param options - The transport, stream store, settings, views and signals.
|
|
306
|
-
*/
|
|
307
|
-
export function createSessionDirectory<S extends SidebarListSession, P, C = unknown>(
|
|
308
|
-
options: SessionDirectoryOptions<S, P, C>,
|
|
309
|
-
): SessionDirectory<S, C> {
|
|
310
|
-
type K = S['id'];
|
|
311
|
-
const { sessions, streams, views } = options;
|
|
312
|
-
const idle = options.idle ?? defaultIdle;
|
|
313
|
-
const debounceMs = options.changedDebounceMs ?? 300;
|
|
314
|
-
const pinnedSession = options.pinnedSession ?? null;
|
|
315
|
-
const notifications = createNotificationStore();
|
|
316
|
-
|
|
317
|
-
let contributionsStore: Readable<SidebarContributions> = options.contributions ?? constant(NO_SIDEBAR_CONTRIBUTIONS);
|
|
318
|
-
/** Swaps the contributions store while started (set by `start`). */
|
|
319
|
-
let followContributions: ((next: Readable<SidebarContributions>) => void) | null = null;
|
|
320
|
-
|
|
321
|
-
// One merged list per settings list and extension spaces, so an unchanged input keeps every space object.
|
|
322
|
-
let mergedFrom: { list: unknown; extension: SidebarContributions['spaces'] } | null = null;
|
|
323
|
-
let merged: readonly SidebarSpace[] = [];
|
|
324
|
-
let switcherFrom: { spaces: readonly SidebarSpace[]; prefs: unknown } | null = null;
|
|
325
|
-
let switcher: readonly SidebarSpace[] = [];
|
|
326
|
-
let hiddenSpaces: readonly SidebarSpace[] = [];
|
|
327
|
-
const spacesFrom = (settings: DirectorySettings, spaceId: string) => {
|
|
328
|
-
const spacesOn = settings.spaces;
|
|
329
|
-
const contributions = contributionsStore.get();
|
|
330
|
-
if (!mergedFrom || mergedFrom.list !== settings.spaceList || mergedFrom.extension !== contributions.spaces) {
|
|
331
|
-
mergedFrom = { list: settings.spaceList, extension: contributions.spaces };
|
|
332
|
-
merged = mergeSidebarSpaces(normalizeSpaces(settings.spaceList), settings.spaceList, contributions.spaces);
|
|
333
|
-
}
|
|
334
|
-
const spaces = merged;
|
|
335
|
-
const prefs = views.switcher.get();
|
|
336
|
-
if (!switcherFrom || switcherFrom.spaces !== spaces || switcherFrom.prefs !== prefs) {
|
|
337
|
-
switcherFrom = { spaces, prefs };
|
|
338
|
-
switcher = switcherSpaces(spaces, prefs);
|
|
339
|
-
const hidden = new Set(prefs.hidden);
|
|
340
|
-
hiddenSpaces = spaces.filter((s) => s.id !== DEFAULT_SPACE_ID && hidden.has(s.id));
|
|
341
|
-
}
|
|
342
|
-
return {
|
|
343
|
-
spacesOn,
|
|
344
|
-
spaces,
|
|
345
|
-
switcherSpaces: switcher,
|
|
346
|
-
hiddenSpaces,
|
|
347
|
-
contributions,
|
|
348
|
-
activeSpace: activeSpaceOf(spaces, spacesOn ? spaceId : DEFAULT_SPACE_ID) as SidebarSpace,
|
|
349
|
-
};
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
const initialSpaces = spacesFrom(options.settings.get(), views.space.get());
|
|
353
|
-
const state = writable<SessionDirectoryState<S>>({
|
|
354
|
-
allSessions: [],
|
|
355
|
-
activeSessionId: pinnedSession,
|
|
356
|
-
...initialSpaces,
|
|
357
|
-
spaceSlide: null,
|
|
358
|
-
hostNotice: null,
|
|
359
|
-
});
|
|
360
|
-
const patch = (next: Partial<SessionDirectoryState<S>>) => {
|
|
361
|
-
const current = state.get();
|
|
362
|
-
if ((Object.keys(next) as (keyof SessionDirectoryState<S>)[]).every((k) => Object.is(current[k], next[k]))) return;
|
|
363
|
-
state.set({ ...current, ...next });
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
let archive: SessionArchiveFilter = options.archive ?? 'active';
|
|
367
|
-
let refreshVersion = 0;
|
|
368
|
-
const hostLists = new Map<string, readonly S[]>();
|
|
369
|
-
const hostReads = new Map<string, number>();
|
|
370
|
-
|
|
371
|
-
const refreshHosts = async (only?: ReadonlySet<string>): Promise<void> => {
|
|
372
|
-
const version = ++refreshVersion;
|
|
373
|
-
const unchanged = streams.captureRunState();
|
|
374
|
-
const filter = archive;
|
|
375
|
-
try {
|
|
376
|
-
// '' is this machine; a host dropped from the list leaves with its rows.
|
|
377
|
-
const hosts = ['', ...options.servers.get().map((host) => host.id)];
|
|
378
|
-
await Promise.all(
|
|
379
|
-
hosts
|
|
380
|
-
.filter((host) => !only || only.has(host) || !hostLists.has(host))
|
|
381
|
-
.map(async (host) => {
|
|
382
|
-
const read = (hostReads.get(host) ?? 0) + 1;
|
|
383
|
-
hostReads.set(host, read);
|
|
384
|
-
const rows = host
|
|
385
|
-
? await sessions.query({ archive: filter, hostId: host }).catch(() => [] as readonly S[])
|
|
386
|
-
: await sessions.query({ archive: filter });
|
|
387
|
-
if (hostReads.get(host) === read) hostLists.set(host, rows);
|
|
388
|
-
}),
|
|
389
|
-
);
|
|
390
|
-
// A newer refresh owns the host list: pruning by this one's older list would drop a host it just read.
|
|
391
|
-
if (version !== refreshVersion) return;
|
|
392
|
-
for (const host of hostLists.keys()) {
|
|
393
|
-
if (!hosts.includes(host)) hostLists.delete(host);
|
|
394
|
-
}
|
|
395
|
-
const next = hosts.flatMap((host) => hostLists.get(host) ?? []);
|
|
396
|
-
// A row the stream store thinks runs but the host lists idle: ask whether it really stopped.
|
|
397
|
-
const idleRows = await Promise.all(
|
|
398
|
-
next.map(async (row) => {
|
|
399
|
-
if (row.status === 'running' || !streams.peekRunning(row.id)) return false;
|
|
400
|
-
return Promise.resolve(options.isRunning(row.id))
|
|
401
|
-
.then((running) => running === false)
|
|
402
|
-
.catch(() => false);
|
|
403
|
-
}),
|
|
404
|
-
);
|
|
405
|
-
if (version !== refreshVersion) return;
|
|
406
|
-
const runStateStable = unchanged();
|
|
407
|
-
options.onListed?.(next);
|
|
408
|
-
patch({ allSessions: next });
|
|
409
|
-
// A signal moved the run state while this read was in flight: its rows are older than the signal.
|
|
410
|
-
if (!runStateStable) return;
|
|
411
|
-
for (const [index, row] of next.entries()) {
|
|
412
|
-
if (row.status === 'running') streams.markRunning(row.id);
|
|
413
|
-
else if (idleRows[index]) streams.confirmIdle(row.id);
|
|
414
|
-
}
|
|
415
|
-
const active = state.get().activeSessionId;
|
|
416
|
-
if (active && next.some((row, index) => row.id === active && idleRows[index])) {
|
|
417
|
-
const stillIdle = streams.captureRunState();
|
|
418
|
-
const page = await options.loadEvents(active);
|
|
419
|
-
if (
|
|
420
|
-
version === refreshVersion &&
|
|
421
|
-
stillIdle() &&
|
|
422
|
-
state.get().activeSessionId === active &&
|
|
423
|
-
!streams.peekRunning(active)
|
|
424
|
-
) {
|
|
425
|
-
streams.setEventsPage(active, page);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
} catch (err) {
|
|
429
|
-
options.onError?.(err);
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
const refresh = () => refreshHosts();
|
|
433
|
-
|
|
434
|
-
const reconvergeActiveTranscript = () => {
|
|
435
|
-
const active = state.get().activeSessionId;
|
|
436
|
-
// A streaming run owns the transcript; a reload would race it.
|
|
437
|
-
if (
|
|
438
|
-
!active ||
|
|
439
|
-
streams.peekRunning(active) ||
|
|
440
|
-
state.get().allSessions.some((s) => s.id === active && s.status === 'running')
|
|
441
|
-
) {
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
const runSeqAtKickoff = streams.peekRunSeq(active);
|
|
445
|
-
options
|
|
446
|
-
.loadEvents(active)
|
|
447
|
-
.then((events) => {
|
|
448
|
-
if (
|
|
449
|
-
state.get().activeSessionId === active &&
|
|
450
|
-
!streams.peekRunning(active) &&
|
|
451
|
-
streams.peekRunSeq(active) === runSeqAtKickoff
|
|
452
|
-
) {
|
|
453
|
-
streams.setEventsPage(active, events);
|
|
454
|
-
}
|
|
455
|
-
})
|
|
456
|
-
.catch(() => undefined);
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
const setActive: SessionDirectory<S, C>['setActive'] = (next) => {
|
|
460
|
-
const current = state.get().activeSessionId;
|
|
461
|
-
patch({ activeSessionId: typeof next === 'function' ? next(current) : next });
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
const select = (sessionId: K | null) => {
|
|
465
|
-
setActive(sessionId);
|
|
466
|
-
if (sessionId) {
|
|
467
|
-
notifications.clear(sessionId);
|
|
468
|
-
patch({ hostNotice: null });
|
|
469
|
-
}
|
|
470
|
-
};
|
|
471
|
-
|
|
472
|
-
// Prewarm: the transcripts around the open session, one per idle slot.
|
|
473
|
-
let stopPrewarm: (() => void) | null = null;
|
|
474
|
-
const prewarm = () => {
|
|
475
|
-
stopPrewarm?.();
|
|
476
|
-
stopPrewarm = null;
|
|
477
|
-
const { allSessions: raw, activeSessionId } = state.get();
|
|
478
|
-
if (raw.length === 0) return;
|
|
479
|
-
let candidates: readonly S[];
|
|
480
|
-
if (raw.length <= PREWARM_FULL_THRESHOLD) {
|
|
481
|
-
candidates = raw;
|
|
482
|
-
} else {
|
|
483
|
-
const anchor = activeSessionId ? raw.findIndex((s) => s.id === activeSessionId) : -1;
|
|
484
|
-
const center = anchor === -1 ? 0 : anchor;
|
|
485
|
-
const start = Math.max(0, center - PREWARM_WINDOW_RADIUS);
|
|
486
|
-
const end = Math.min(raw.length, center + PREWARM_WINDOW_RADIUS + 1);
|
|
487
|
-
candidates = raw.slice(start, end);
|
|
488
|
-
}
|
|
489
|
-
// The cache keeps the window, the open session and the pinned ones; the rest go.
|
|
490
|
-
const keep = new Set<K>(candidates.map((s) => s.id));
|
|
491
|
-
if (activeSessionId) keep.add(activeSessionId);
|
|
492
|
-
for (const key of options.pinned?.() ?? []) keep.add(key);
|
|
493
|
-
streams.evictExcept(keep);
|
|
494
|
-
const targets = candidates.filter((session) => !streams.hasEvents(session.id));
|
|
495
|
-
if (targets.length === 0) return;
|
|
496
|
-
let cancelled = false;
|
|
497
|
-
let handle: number | undefined;
|
|
498
|
-
const pump = (index: number): void => {
|
|
499
|
-
if (cancelled || index >= targets.length) return;
|
|
500
|
-
handle = idle.request(() => {
|
|
501
|
-
if (cancelled) return;
|
|
502
|
-
const session = targets[index]!;
|
|
503
|
-
const next = (): void => pump(index + 1);
|
|
504
|
-
if (streams.hasEvents(session.id)) {
|
|
505
|
-
next();
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
options
|
|
509
|
-
.loadEvents(session.id, { prewarm: true })
|
|
510
|
-
.then((events) => {
|
|
511
|
-
if (cancelled) return;
|
|
512
|
-
if (!streams.hasEvents(session.id)) streams.setEventsPage(session.id, events);
|
|
513
|
-
})
|
|
514
|
-
.catch(() => {
|
|
515
|
-
/* prewarm is best-effort */
|
|
516
|
-
})
|
|
517
|
-
.finally(next);
|
|
518
|
-
});
|
|
519
|
-
};
|
|
520
|
-
pump(0);
|
|
521
|
-
stopPrewarm = () => {
|
|
522
|
-
cancelled = true;
|
|
523
|
-
if (handle !== undefined) idle.cancel(handle);
|
|
524
|
-
};
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
/** `direction`: the way the list slides; by default the switcher's order (a wrapping step overrides it). */
|
|
528
|
-
const showSpace = (spaceId: string, direction?: 'next' | 'prev') => {
|
|
529
|
-
const { spaces, switcherSpaces: order, activeSpace, allSessions, activeSessionId, spacesOn } = state.get();
|
|
530
|
-
const from = order.findIndex((s) => s.id === activeSpace.id);
|
|
531
|
-
const to = order.findIndex((s) => s.id === spaceId);
|
|
532
|
-
patch({
|
|
533
|
-
spaceSlide:
|
|
534
|
-
from !== -1 && to !== -1 && from !== to
|
|
535
|
-
? { spaceId, direction: direction ?? (to > from ? 'next' : 'prev') }
|
|
536
|
-
: null,
|
|
537
|
-
});
|
|
538
|
-
const space = spaces.find((s) => s.id === spaceId) ?? activeSpaceOf(spaces, spaceId);
|
|
539
|
-
const inSpace = spaceMembership<S>(space, spaces, true);
|
|
540
|
-
const belongs = (s: S) => !s.isMain && (!spacesOn || !inSpace || inSpace(s));
|
|
541
|
-
// The conversation last open there, when it is still listed and still in that space.
|
|
542
|
-
const rememberedId = pinnedSession ? null : views.lastSessionOf(spaceId);
|
|
543
|
-
const remembered = rememberedId ? allSessions.find((s) => s.id === rememberedId && belongs(s)) : undefined;
|
|
544
|
-
// Else the open session stays open only when it belongs to the new space (closed first, so the
|
|
545
|
-
// sidebar doesn't follow it back).
|
|
546
|
-
const open = allSessions.find((s) => s.id === activeSessionId);
|
|
547
|
-
// Opened before the switch, so the sidebar's follow lands on the new space, not the old.
|
|
548
|
-
if (remembered) select(remembered.id);
|
|
549
|
-
else if (open && !open.isMain && !belongs(open)) setActive(null);
|
|
550
|
-
views.setSpace(spaceId);
|
|
551
|
-
};
|
|
552
|
-
const setActiveSpace = (spaceId: string) => showSpace(spaceId);
|
|
553
|
-
|
|
554
|
-
const listProjectSessions = async (project: ProjectInSpace): Promise<S[]> => {
|
|
555
|
-
if (!project.path) return [];
|
|
556
|
-
const { spaces } = state.get();
|
|
557
|
-
const from = resolveSessionSpace(project.spaceId, spaces);
|
|
558
|
-
// A repository's group spans machines: read every host. Otherwise only the project's own.
|
|
559
|
-
const hosts = project.repoKey ? ['', ...options.servers.get().map((host) => host.id)] : [project.hostId ?? ''];
|
|
560
|
-
const all = (
|
|
561
|
-
await Promise.all(
|
|
562
|
-
hosts.map((host) =>
|
|
563
|
-
host
|
|
564
|
-
? sessions.query({ archive: 'all', hostId: host }).catch(() => [] as readonly S[])
|
|
565
|
-
: sessions.query({ archive: 'all' }),
|
|
566
|
-
),
|
|
567
|
-
)
|
|
568
|
-
).flat();
|
|
569
|
-
return all.filter(
|
|
570
|
-
(s) => !s.isMain && isProjectMember(s, project) && resolveSessionSpace(s.spaceId, spaces) === from,
|
|
571
|
-
);
|
|
572
|
-
};
|
|
573
|
-
|
|
574
|
-
const drop = async (sessionId: K): Promise<SessionRemoval> => {
|
|
575
|
-
const removed = await sessions.remove?.(sessionId);
|
|
576
|
-
streams.reset(sessionId);
|
|
577
|
-
options.onRemoved?.(sessionId);
|
|
578
|
-
views.forgetSession(sessionId);
|
|
579
|
-
setActive((current) => (current === sessionId ? null : current));
|
|
580
|
-
notifications.clear(sessionId);
|
|
581
|
-
return removed && removed.kept ? removed : { kept: false };
|
|
582
|
-
};
|
|
583
|
-
|
|
584
|
-
/** Keep derived state in step with the settings, the space and the rows. */
|
|
585
|
-
const reconcile = () => {
|
|
586
|
-
const settings = options.settings.get();
|
|
587
|
-
const spaces = spacesFrom(settings, views.space.get());
|
|
588
|
-
patch(spaces);
|
|
589
|
-
const { allSessions, activeSessionId, activeSpace, spacesOn } = state.get();
|
|
590
|
-
const shown = spaceMembership<S>(activeSpace, spaces.spaces, spacesOn);
|
|
591
|
-
const open = allSessions.find((s) => s.id === activeSessionId);
|
|
592
|
-
// Orchestration off: the main session is unlisted, so it can't stay open.
|
|
593
|
-
if (!settings.orchestration && open?.isMain) {
|
|
594
|
-
setActive(null);
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
// Open a session from another space (a link, the palette): the sidebar follows it there.
|
|
598
|
-
if (spacesOn && !pinnedSession && open && !open.isMain) {
|
|
599
|
-
// A query space that lists it (not its own) keeps showing it.
|
|
600
|
-
if (activeSpace.query && shown?.(open)) {
|
|
601
|
-
views.rememberSession(activeSpace.id, open.id);
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
const home = resolveSessionSpace(open.spaceId, spaces.spaces);
|
|
605
|
-
if (home !== activeSpace.id) views.setSpace(home);
|
|
606
|
-
views.rememberSession(home, open.id);
|
|
607
|
-
}
|
|
608
|
-
};
|
|
609
|
-
|
|
610
|
-
return {
|
|
611
|
-
state,
|
|
612
|
-
notifications,
|
|
613
|
-
views,
|
|
614
|
-
start() {
|
|
615
|
-
const offs: (() => void)[] = [];
|
|
616
|
-
let lastRows = state.get().allSessions;
|
|
617
|
-
let lastActive = state.get().activeSessionId;
|
|
618
|
-
offs.push(
|
|
619
|
-
state.subscribe(() => {
|
|
620
|
-
const { allSessions, activeSessionId } = state.get();
|
|
621
|
-
if (allSessions === lastRows && activeSessionId === lastActive) return;
|
|
622
|
-
lastRows = allSessions;
|
|
623
|
-
lastActive = activeSessionId;
|
|
624
|
-
reconcile();
|
|
625
|
-
prewarm();
|
|
626
|
-
}),
|
|
627
|
-
);
|
|
628
|
-
offs.push(options.settings.subscribe(reconcile));
|
|
629
|
-
offs.push(views.space.subscribe(reconcile));
|
|
630
|
-
offs.push(views.switcher.subscribe(reconcile));
|
|
631
|
-
let offContributions = contributionsStore.subscribe(reconcile);
|
|
632
|
-
offs.push(() => offContributions());
|
|
633
|
-
followContributions = (next) => {
|
|
634
|
-
offContributions();
|
|
635
|
-
contributionsStore = next;
|
|
636
|
-
offContributions = next.subscribe(reconcile);
|
|
637
|
-
reconcile();
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
if (sessions.onFacets) {
|
|
641
|
-
// Pushes arriving together (a refresh computes many sessions) land in one state change.
|
|
642
|
-
let pending: Map<string, Readonly<Record<string, unknown>>> | null = null;
|
|
643
|
-
let stopped = false;
|
|
644
|
-
const flush = () => {
|
|
645
|
-
const batch = pending;
|
|
646
|
-
pending = null;
|
|
647
|
-
if (stopped || !batch) return;
|
|
648
|
-
const rows = state.get().allSessions;
|
|
649
|
-
if (!rows.some((s) => batch.has(s.id))) return;
|
|
650
|
-
patch({ allSessions: rows.map((s) => (batch.has(s.id) ? { ...s, facets: batch.get(s.id)! } : s)) });
|
|
651
|
-
};
|
|
652
|
-
const off = sessions.onFacets((sessionId, facets) => {
|
|
653
|
-
if (!pending) {
|
|
654
|
-
pending = new Map();
|
|
655
|
-
queueMicrotask(flush);
|
|
656
|
-
}
|
|
657
|
-
pending.set(sessionId, facets);
|
|
658
|
-
});
|
|
659
|
-
offs.push(() => {
|
|
660
|
-
stopped = true;
|
|
661
|
-
off();
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
let serversKey = options.servers
|
|
666
|
-
.get()
|
|
667
|
-
.map((host) => `${host.id}:${host.status}`)
|
|
668
|
-
.join('|');
|
|
669
|
-
let lastActiveServer: { id: string | null; status: string | undefined } = { id: null, status: undefined };
|
|
670
|
-
const followActiveServer = () => {
|
|
671
|
-
const active = state.get().activeSessionId;
|
|
672
|
-
const id = active ? options.serverOf(active) : null;
|
|
673
|
-
const status = id ? options.servers.get().find((host) => host.id === id)?.status : undefined;
|
|
674
|
-
const last = lastActiveServer;
|
|
675
|
-
lastActiveServer = { id, status };
|
|
676
|
-
// The open session's server came back: its transcript may have moved on.
|
|
677
|
-
const reconnected =
|
|
678
|
-
id !== null &&
|
|
679
|
-
last.id === id &&
|
|
680
|
-
last.status !== undefined &&
|
|
681
|
-
last.status !== 'connected' &&
|
|
682
|
-
status === 'connected';
|
|
683
|
-
if (reconnected) reconvergeActiveTranscript();
|
|
684
|
-
};
|
|
685
|
-
followActiveServer();
|
|
686
|
-
offs.push(state.subscribe(followActiveServer));
|
|
687
|
-
offs.push(
|
|
688
|
-
options.servers.subscribe(() => {
|
|
689
|
-
followActiveServer();
|
|
690
|
-
const key = options.servers
|
|
691
|
-
.get()
|
|
692
|
-
.map((host) => `${host.id}:${host.status}`)
|
|
693
|
-
.join('|');
|
|
694
|
-
if (key === serversKey) return;
|
|
695
|
-
serversKey = key;
|
|
696
|
-
void refresh();
|
|
697
|
-
}),
|
|
698
|
-
);
|
|
699
|
-
|
|
700
|
-
// Runtime switch (daemon on / off): every stream belongs to the old runtime.
|
|
701
|
-
let runtime: boolean | null = null;
|
|
702
|
-
const onRuntime = options.signals?.onRuntime;
|
|
703
|
-
if (onRuntime) {
|
|
704
|
-
offs.push(
|
|
705
|
-
onRuntime((connected) => {
|
|
706
|
-
const previous = runtime;
|
|
707
|
-
runtime = connected;
|
|
708
|
-
if (previous === null || previous === connected) return;
|
|
709
|
-
streams.dropAll();
|
|
710
|
-
void refresh();
|
|
711
|
-
}),
|
|
712
|
-
);
|
|
713
|
-
offs.push(
|
|
714
|
-
onRuntime((connected) => {
|
|
715
|
-
if (!connected) return;
|
|
716
|
-
void refresh();
|
|
717
|
-
reconvergeActiveTranscript();
|
|
718
|
-
}),
|
|
719
|
-
);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
const onRunEnd = options.signals?.onRunEnd;
|
|
723
|
-
if (onRunEnd) {
|
|
724
|
-
offs.push(
|
|
725
|
-
onRunEnd((sessionId, ok) => {
|
|
726
|
-
void refreshHosts(new Set([options.serverOf(sessionId) ?? '']));
|
|
727
|
-
if (sessionId === state.get().activeSessionId) return;
|
|
728
|
-
notifications.set(sessionId, ok ? 'completed' : 'error');
|
|
729
|
-
}),
|
|
730
|
-
);
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
const onHostRemoved = options.signals?.onHostRemoved;
|
|
734
|
-
if (onHostRemoved) {
|
|
735
|
-
offs.push(
|
|
736
|
-
onHostRemoved(({ hostId, sessionIds, notice }) => {
|
|
737
|
-
const active = state.get().activeSessionId;
|
|
738
|
-
if (active && (options.serverOf(active) === hostId || sessionIds.includes(active))) {
|
|
739
|
-
setActive(null);
|
|
740
|
-
patch({ hostNotice: notice });
|
|
741
|
-
}
|
|
742
|
-
void refresh();
|
|
743
|
-
}),
|
|
744
|
-
);
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
if (sessions.onChanged) {
|
|
748
|
-
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
749
|
-
let activeTouched = false;
|
|
750
|
-
let touched = new Set<string>();
|
|
751
|
-
const off = sessions.onChanged((sessionId) => {
|
|
752
|
-
activeTouched ||= sessionId === state.get().activeSessionId;
|
|
753
|
-
touched.add(options.serverOf(sessionId) ?? '');
|
|
754
|
-
if (timer !== null) clearTimeout(timer);
|
|
755
|
-
timer = setTimeout(() => {
|
|
756
|
-
timer = null;
|
|
757
|
-
const hosts = touched;
|
|
758
|
-
touched = new Set();
|
|
759
|
-
void refreshHosts(hosts);
|
|
760
|
-
if (activeTouched) {
|
|
761
|
-
activeTouched = false;
|
|
762
|
-
reconvergeActiveTranscript();
|
|
763
|
-
}
|
|
764
|
-
}, debounceMs);
|
|
765
|
-
});
|
|
766
|
-
offs.push(() => {
|
|
767
|
-
off();
|
|
768
|
-
if (timer !== null) clearTimeout(timer);
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
void refresh();
|
|
773
|
-
return () => {
|
|
774
|
-
for (const off of offs.splice(0).reverse()) off();
|
|
775
|
-
followContributions = null;
|
|
776
|
-
stopPrewarm?.();
|
|
777
|
-
stopPrewarm = null;
|
|
778
|
-
};
|
|
779
|
-
},
|
|
780
|
-
refresh,
|
|
781
|
-
setArchive(next) {
|
|
782
|
-
if (next === archive) return;
|
|
783
|
-
archive = next;
|
|
784
|
-
void refresh();
|
|
785
|
-
},
|
|
786
|
-
select,
|
|
787
|
-
setActive,
|
|
788
|
-
dismissHostNotice: () => patch({ hostNotice: null }),
|
|
789
|
-
async create(input) {
|
|
790
|
-
const { spacesOn, activeSpace } = state.get();
|
|
791
|
-
const withSpace = spacesOn && input.spaceId === undefined ? { ...input, spaceId: activeSpace.id } : input;
|
|
792
|
-
if (!sessions.create) throw new Error('This host cannot create sessions.');
|
|
793
|
-
const created = await sessions.create(withSpace);
|
|
794
|
-
return created;
|
|
795
|
-
},
|
|
796
|
-
async rename(sessionId, title) {
|
|
797
|
-
await sessions.rename?.(sessionId, title);
|
|
798
|
-
await refresh();
|
|
799
|
-
},
|
|
800
|
-
async setFavorite(sessionId, favorite) {
|
|
801
|
-
// Optimistic: the star moves now; a failed write puts it back.
|
|
802
|
-
const flip = (value: boolean) => {
|
|
803
|
-
refreshVersion += 1;
|
|
804
|
-
patch({
|
|
805
|
-
allSessions: state.get().allSessions.map((s) => (s.id === sessionId ? { ...s, favorite: value } : s)),
|
|
806
|
-
});
|
|
807
|
-
};
|
|
808
|
-
flip(favorite);
|
|
809
|
-
try {
|
|
810
|
-
await sessions.setFavorite?.(sessionId, favorite);
|
|
811
|
-
} catch (err) {
|
|
812
|
-
flip(!favorite);
|
|
813
|
-
throw err;
|
|
814
|
-
}
|
|
815
|
-
await refresh();
|
|
816
|
-
},
|
|
817
|
-
async setArchived(sessionId, archived) {
|
|
818
|
-
await sessions.setArchived?.(sessionId, archived);
|
|
819
|
-
await refresh();
|
|
820
|
-
},
|
|
821
|
-
async archiveMany(sessionIds) {
|
|
822
|
-
try {
|
|
823
|
-
for (const id of sessionIds) await sessions.setArchived?.(id, true);
|
|
824
|
-
} finally {
|
|
825
|
-
await refresh();
|
|
826
|
-
}
|
|
827
|
-
},
|
|
828
|
-
drop,
|
|
829
|
-
async removeMany(sessionIds) {
|
|
830
|
-
let kept = 0;
|
|
831
|
-
let reason: string | undefined;
|
|
832
|
-
try {
|
|
833
|
-
for (const id of sessionIds) {
|
|
834
|
-
const result = await drop(id);
|
|
835
|
-
if (result.kept) {
|
|
836
|
-
kept += 1;
|
|
837
|
-
reason ??= result.reason;
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
} finally {
|
|
841
|
-
await refresh();
|
|
842
|
-
}
|
|
843
|
-
return reason ? { kept, reason } : { kept };
|
|
844
|
-
},
|
|
845
|
-
setActiveSpace,
|
|
846
|
-
stepSpace(delta) {
|
|
847
|
-
const { spacesOn, switcherSpaces: spaces, activeSpace } = state.get();
|
|
848
|
-
if (!spacesOn || spaces.length < 2) return false;
|
|
849
|
-
const at = spaces.findIndex((s) => s.id === activeSpace.id);
|
|
850
|
-
// Wraps: past the last space comes the first, and before the first the last.
|
|
851
|
-
const next = spaces[(at + delta + spaces.length) % spaces.length]!;
|
|
852
|
-
showSpace(next.id, delta === 1 ? 'next' : 'prev');
|
|
853
|
-
return true;
|
|
854
|
-
},
|
|
855
|
-
async setSessionSpace(sessionId, spaceId) {
|
|
856
|
-
await sessions.setSpace?.(sessionId, spaceId);
|
|
857
|
-
views.forgetSession(sessionId, spaceId);
|
|
858
|
-
await refresh();
|
|
859
|
-
},
|
|
860
|
-
setSpaceHidden(spaceId, hidden) {
|
|
861
|
-
if (spaceId === DEFAULT_SPACE_ID) return;
|
|
862
|
-
const prefs = views.switcher.get();
|
|
863
|
-
const rest = prefs.hidden.filter((id) => id !== spaceId);
|
|
864
|
-
views.setSwitcher({ ...prefs, hidden: hidden ? [...rest, spaceId] : rest });
|
|
865
|
-
if (hidden && state.get().activeSpace.id === spaceId) showSpace(DEFAULT_SPACE_ID);
|
|
866
|
-
},
|
|
867
|
-
moveSpace(spaceId, delta) {
|
|
868
|
-
const order = state.get().switcherSpaces.map((s) => s.id);
|
|
869
|
-
const at = order.indexOf(spaceId);
|
|
870
|
-
const to = at + delta;
|
|
871
|
-
if (at === -1 || to < 0 || to >= order.length) return;
|
|
872
|
-
order.splice(at, 1);
|
|
873
|
-
order.splice(to, 0, spaceId);
|
|
874
|
-
// Hidden spaces keep their place in the stored order, after the shown ones.
|
|
875
|
-
const prefs = views.switcher.get();
|
|
876
|
-
const kept = prefs.order.filter((id) => !order.includes(id));
|
|
877
|
-
views.setSwitcher({ ...prefs, order: [...order, ...kept] });
|
|
878
|
-
},
|
|
879
|
-
attachContributions(next) {
|
|
880
|
-
if (followContributions) followContributions(next);
|
|
881
|
-
else {
|
|
882
|
-
contributionsStore = next;
|
|
883
|
-
reconcile();
|
|
884
|
-
}
|
|
885
|
-
return () => {
|
|
886
|
-
if (contributionsStore !== next) return;
|
|
887
|
-
const none = constant(NO_SIDEBAR_CONTRIBUTIONS);
|
|
888
|
-
if (followContributions) followContributions(none);
|
|
889
|
-
else {
|
|
890
|
-
contributionsStore = none;
|
|
891
|
-
reconcile();
|
|
892
|
-
}
|
|
893
|
-
};
|
|
894
|
-
},
|
|
895
|
-
...(options.saveSpace
|
|
896
|
-
? {
|
|
897
|
-
saveViewAsSpace: async (name: string) => {
|
|
898
|
-
const { activeSpace, spaces, spacesOn, contributions } = state.get();
|
|
899
|
-
const view = views.viewOf(activeSpace.id);
|
|
900
|
-
const grouping = resolveGrouping(view, activeSpace, contributions.groups);
|
|
901
|
-
const sort = resolveSort(view, activeSpace, contributions.sorts);
|
|
902
|
-
const values = view.extension?.filters ?? {};
|
|
903
|
-
const filters = filtersForSpace(contributions.filters, activeSpace.id).flatMap(({ item }) => {
|
|
904
|
-
const query = filterQueryOf(item, values[item.id]);
|
|
905
|
-
return query ? [query] : [];
|
|
906
|
-
});
|
|
907
|
-
// The archive axis stays the new space's view's own (copied below), not part of its query.
|
|
908
|
-
const result = viewQuery({
|
|
909
|
-
space: spacesOn
|
|
910
|
-
? { id: activeSpace.id, ...(activeSpace.query ? { query: activeSpace.query } : {}) }
|
|
911
|
-
: null,
|
|
912
|
-
view: {
|
|
913
|
-
project: view.project,
|
|
914
|
-
agent: view.agent ?? null,
|
|
915
|
-
...(view.activity !== 'all' ? { updatedSince: ACTIVITY_BOUND[view.activity] } : {}),
|
|
916
|
-
filters,
|
|
917
|
-
},
|
|
918
|
-
knownSpaceIds: spaces.map((s) => s.id),
|
|
919
|
-
});
|
|
920
|
-
if (result.issues) throw new SessionQueryError(result.issues);
|
|
921
|
-
const taken = new Set(spaces.map((s) => s.id));
|
|
922
|
-
let n = 1;
|
|
923
|
-
while (taken.has(`view-${n}`)) n += 1;
|
|
924
|
-
const space: SidebarSpace = {
|
|
925
|
-
id: `view-${n}`,
|
|
926
|
-
name,
|
|
927
|
-
query: result.query,
|
|
928
|
-
...(grouping.kind === 'query' ? { groupBy: grouping.groupBy } : {}),
|
|
929
|
-
...(sort ? { sortBy: [...sort] } : {}),
|
|
930
|
-
};
|
|
931
|
-
await options.saveSpace!(space);
|
|
932
|
-
// The new space starts on the view's built-in axes; its filters are in its query now.
|
|
933
|
-
const { agent: _agent, extension: _extension, ...axes } = { ...DEFAULT_SIDEBAR_VIEW, ...view };
|
|
934
|
-
views.patch(space.id, {
|
|
935
|
-
...axes,
|
|
936
|
-
project: null,
|
|
937
|
-
activity: 'all',
|
|
938
|
-
extension: { filters: {}, ...(grouping.kind === 'builtin' ? { group: VIEW_CHOICE } : {}) },
|
|
939
|
-
});
|
|
940
|
-
showSpace(space.id);
|
|
941
|
-
return space;
|
|
942
|
-
},
|
|
943
|
-
}
|
|
944
|
-
: {}),
|
|
945
|
-
listProjectSessions,
|
|
946
|
-
async setProjectSpace(project, spaceId) {
|
|
947
|
-
const members = await listProjectSessions(project);
|
|
948
|
-
for (const member of members) {
|
|
949
|
-
await sessions.setSpace?.(member.id, spaceId);
|
|
950
|
-
views.forgetSession(member.id, spaceId);
|
|
951
|
-
}
|
|
952
|
-
await refresh();
|
|
953
|
-
return members.length;
|
|
954
|
-
},
|
|
955
|
-
};
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
/** The activity axis as a relative `updatedAt` bound, for a saved view's query. */
|
|
959
|
-
const ACTIVITY_BOUND: Record<Exclude<SessionActivityFilter, 'all'>, QueryBound> = {
|
|
960
|
-
'1d': '-1d',
|
|
961
|
-
'3d': '-3d',
|
|
962
|
-
'7d': '-7d',
|
|
963
|
-
'30d': '-30d',
|
|
964
|
-
};
|
|
965
|
-
|
|
966
|
-
const ACTIVITY_FILTER_MS: Record<Exclude<SessionActivityFilter, 'all'>, number> = {
|
|
967
|
-
'1d': 24 * 60 * 60 * 1000,
|
|
968
|
-
'3d': 3 * 24 * 60 * 60 * 1000,
|
|
969
|
-
'7d': 7 * 24 * 60 * 60 * 1000,
|
|
970
|
-
'30d': 30 * 24 * 60 * 60 * 1000,
|
|
971
|
-
};
|
|
972
|
-
|
|
973
|
-
/**
|
|
974
|
-
* The project filter's key for a session: its folder's name, as a query's
|
|
975
|
-
* `projectName` reads it (`projectNameOf`: `/` and `\` both separate), so a
|
|
976
|
-
* view saved from the filter matches the same sessions.
|
|
977
|
-
*
|
|
978
|
-
* @param session - Its folder and project root.
|
|
979
|
-
*/
|
|
980
|
-
export function projectKeyOf(session: Pick<SidebarListSession, 'projectRoot' | 'cwd'>): string {
|
|
981
|
-
return projectNameOf({ projectRoot: session.projectRoot ?? null, cwd: session.cwd }) ?? '';
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
/**
|
|
985
|
-
* Every project the sessions belong to, by folder name, sorted.
|
|
986
|
-
*
|
|
987
|
-
* @param sessions - The listed sessions.
|
|
988
|
-
*/
|
|
989
|
-
export function availableProjectsOf(sessions: readonly SidebarListSession[]): string[] {
|
|
990
|
-
const seen = new Set<string>();
|
|
991
|
-
for (const s of sessions) {
|
|
992
|
-
const key = projectKeyOf(s);
|
|
993
|
-
if (key) seen.add(key);
|
|
994
|
-
}
|
|
995
|
-
return Array.from(seen).sort();
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
/** How a reference names a session: its title, and its folder's name when it has one. */
|
|
999
|
-
export interface SessionRef {
|
|
1000
|
-
/** The session's title. */
|
|
1001
|
-
title: string;
|
|
1002
|
-
/** Directory basename — the sidebar's project label. Absent for a directory-less session. */
|
|
1003
|
-
dir?: string;
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
/**
|
|
1007
|
-
* Each session's {@link SessionRef}, by id.
|
|
1008
|
-
*
|
|
1009
|
-
* @param sessions - The listed sessions.
|
|
1010
|
-
*/
|
|
1011
|
-
export function sessionRefsOf(sessions: readonly SidebarListSession[]): Map<string, SessionRef> {
|
|
1012
|
-
return new Map(
|
|
1013
|
-
sessions.map((s) => {
|
|
1014
|
-
const dir = sessionDirLabel(s.projectRoot);
|
|
1015
|
-
return [s.id, dir ? { title: s.title, dir } : { title: s.title }];
|
|
1016
|
-
}),
|
|
1017
|
-
);
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
/**
|
|
1021
|
-
* The sessions the list shows: the space's (a remote session without a space
|
|
1022
|
-
* shows in every space), then the project and activity filters. The same
|
|
1023
|
-
* array when nothing filters.
|
|
1024
|
-
*
|
|
1025
|
-
* @param sessions - Every listed session.
|
|
1026
|
-
* @param filter - The space predicate (`null`: spaces off), the project and activity axes.
|
|
1027
|
-
*/
|
|
1028
|
-
export function filterDirectorySessions<S extends SidebarListSession>(
|
|
1029
|
-
sessions: readonly S[],
|
|
1030
|
-
filter: {
|
|
1031
|
-
inSpace: ((session: S) => boolean) | null;
|
|
1032
|
-
project: string | null;
|
|
1033
|
-
activity: SessionActivityFilter;
|
|
1034
|
-
now?: number;
|
|
1035
|
-
},
|
|
1036
|
-
): readonly S[] {
|
|
1037
|
-
const { inSpace, project, activity } = filter;
|
|
1038
|
-
if (project === null && activity === 'all' && inSpace === null) return sessions;
|
|
1039
|
-
const cutoff = activity === 'all' ? 0 : (filter.now ?? Date.now()) - ACTIVITY_FILTER_MS[activity];
|
|
1040
|
-
return sessions.filter((s) => {
|
|
1041
|
-
if (inSpace && !inSpace(s) && !(s.hostId && !s.spaceId)) return false;
|
|
1042
|
-
if (project !== null && projectKeyOf(s) !== project) return false;
|
|
1043
|
-
if (cutoff > 0 && s.updatedAt < cutoff) return false;
|
|
1044
|
-
return true;
|
|
1045
|
-
});
|
|
1046
|
-
}
|