@brimveyn/aimux 1.21.0 → 1.22.2
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 +27 -25
- package/package.json +2 -2
- package/src/app-runtime/auto-commit-driver.ts +22 -27
- package/src/app-runtime/backend-attach-runtime.ts +43 -36
- package/src/app-runtime/backend-runtime-events.ts +107 -88
- package/src/app-runtime/editor-actions.ts +201 -0
- package/src/app-runtime/git-actions.ts +197 -0
- package/src/app-runtime/measure-ref.ts +19 -0
- package/src/app-runtime/navigation-actions.ts +213 -0
- package/src/app-runtime/project-actions.ts +188 -0
- package/src/app-runtime/prompt-injection.ts +123 -0
- package/src/app-runtime/selection.ts +29 -0
- package/src/app-runtime/settings-actions.ts +156 -0
- package/src/app-runtime/setup-actions.ts +237 -0
- package/src/app-runtime/side-effect-context.ts +33 -0
- package/src/app-runtime/side-effects.ts +302 -1541
- package/src/app-runtime/snippet-actions.ts +3 -2
- package/src/app-runtime/tab-actions.ts +218 -0
- package/src/app-runtime/tab-runtime-timeouts.ts +1 -1
- package/src/app-runtime/use-auto-commit-driver.ts +14 -13
- package/src/app-runtime/use-backend-runtime.ts +12 -11
- package/src/app-runtime/use-directory-search.ts +5 -4
- package/src/app-runtime/use-mouse-handlers.ts +2 -1
- package/src/app-runtime/{use-workspace-autosave.ts → use-project-autosave.ts} +4 -4
- package/src/app-runtime/use-renderer-bindings.ts +2 -1
- package/src/app-runtime/use-setup-runner.ts +96 -0
- package/src/app-runtime/use-terminal-resize.ts +18 -14
- package/src/app-runtime/workspace-actions.ts +366 -0
- package/src/app-runtime/workspace-activity.ts +138 -0
- package/src/app-runtime/workspace-naming.ts +90 -0
- package/src/app.tsx +93 -48
- package/src/assets/sounds/bell.wav +0 -0
- package/src/assets/sounds/ding.wav +0 -0
- package/src/assets/sounds/plane.wav +0 -0
- package/src/cli/client/daemon-client.ts +2 -2
- package/src/cli/client/project-resolver.ts +112 -0
- package/src/cli/commands/project/close.ts +32 -0
- package/src/cli/commands/project/create.ts +93 -0
- package/src/cli/commands/project/list.ts +25 -0
- package/src/cli/commands/project/show.ts +32 -0
- package/src/cli/commands/{workspace → project}/switch.ts +19 -19
- package/src/cli/commands/tab/await.ts +2 -2
- package/src/cli/commands/tab/close.ts +3 -3
- package/src/cli/commands/tab/create.ts +74 -73
- package/src/cli/commands/tab/focus.ts +3 -3
- package/src/cli/commands/tab/list.ts +6 -6
- package/src/cli/commands/tab/run.ts +2 -2
- package/src/cli/commands/tab/send.ts +2 -2
- package/src/cli/commands/tab/snapshot.ts +2 -2
- package/src/cli/commands/tab/tail.ts +2 -2
- package/src/cli/commands/tab/wait.ts +2 -2
- package/src/cli/commands/worker/await.ts +3 -3
- package/src/cli/commands/worker/doctor.ts +30 -30
- package/src/cli/commands/worker/list.ts +15 -15
- package/src/cli/commands/worker/prompt.ts +3 -3
- package/src/cli/commands/worker/run.ts +23 -23
- package/src/cli/commands/worker/shared.ts +53 -59
- package/src/cli/commands/worker/stop.ts +29 -29
- package/src/cli/commands/worker/submit.ts +3 -3
- package/src/cli/commands/{worktree → workspace}/create-core.ts +26 -26
- package/src/cli/commands/workspace/create.ts +30 -68
- package/src/cli/commands/workspace/list.ts +52 -9
- package/src/cli/commands/workspace/remove.ts +81 -0
- package/src/cli/completion/plan.ts +2 -2
- package/src/cli/completion/sources.ts +18 -18
- package/src/cli/context.ts +13 -13
- package/src/cli/flags.ts +30 -10
- package/src/cli/index.ts +26 -16
- package/src/cli/output.ts +1 -1
- package/src/cli/registry.ts +12 -12
- package/src/config/loader.ts +16 -5
- package/src/config.ts +70 -112
- package/src/daemon/catalog-writer.ts +67 -67
- package/src/daemon/daemon.ts +205 -201
- package/src/daemon/session-manager.ts +39 -39
- package/src/daemon/session-registry.ts +14 -14
- package/src/git/divergence.ts +33 -2
- package/src/git/git-poller.ts +1 -1
- package/src/git/git-status.ts +2 -2
- package/src/git/{move-worktree.ts → move-workspace.ts} +5 -5
- package/src/git/pr-status.ts +1 -1
- package/src/git/repo-discovery.ts +1 -1
- package/src/git/use-repo-discovery.ts +1 -1
- package/src/git/workspace-branch-poller.ts +54 -0
- package/src/git/workspace-divergence-poller.ts +65 -0
- package/src/git/worktree.ts +29 -0
- package/src/index.tsx +4 -4
- package/src/input/keymap/help-entries.ts +7 -5
- package/src/input/modes/bridge.ts +13 -12
- package/src/input/modes/handlers/shared.ts +1 -1
- package/src/input/modes/transitions.ts +34 -21
- package/src/input/modes/types.ts +48 -31
- package/src/ipc/manager-protocol.ts +44 -44
- package/src/ipc/protocol.ts +192 -166
- package/src/platform/play-sound.ts +184 -0
- package/src/platform/project-search.ts +8 -8
- package/src/platform/worktree-paths.ts +8 -6
- package/src/pty/assistant-question-extractor.ts +1 -1
- package/src/pty/assistant-status-detection-loop.ts +79 -55
- package/src/pty/assistant-status-detector.ts +40 -15
- package/src/pty/command-registry.ts +81 -1
- package/src/restart-terminal-manager.ts +1 -1
- package/src/services/ai-usage/provider.ts +9 -2
- package/src/services/ai-usage/spawn.ts +19 -6
- package/src/session-backend/bootstrap.ts +4 -4
- package/src/session-backend/local-session-backend.ts +78 -75
- package/src/session-backend/remote-session-backend.ts +64 -52
- package/src/session-backend/types.ts +43 -32
- package/src/settings/live.ts +90 -0
- package/src/settings/search.ts +43 -0
- package/src/settings/sections/about.ts +49 -0
- package/src/settings/sections/appearance.ts +54 -0
- package/src/settings/sections/automation.ts +105 -0
- package/src/settings/sections/commands.ts +72 -0
- package/src/settings/sections/editor.ts +56 -0
- package/src/settings/sections/experimental.ts +57 -0
- package/src/settings/sections/git.ts +112 -0
- package/src/settings/sections/index.ts +95 -0
- package/src/settings/sections/integrations.ts +23 -0
- package/src/settings/sections/layout.ts +72 -0
- package/src/settings/sections/notifications.ts +99 -0
- package/src/settings/sections/setup.ts +54 -0
- package/src/settings/sections/status-bar.ts +63 -0
- package/src/settings/settings-store.ts +207 -0
- package/src/settings/types.ts +108 -0
- package/src/snippets/run-shell-var.ts +48 -22
- package/src/state/actions.ts +342 -0
- package/src/state/app-store.ts +2 -1
- package/src/state/bars.ts +1 -1
- package/src/state/dispatch-ref.ts +1 -1
- package/src/state/layout-resize.ts +2 -2
- package/src/state/project-catalog.ts +275 -0
- package/src/state/project-data.ts +143 -0
- package/src/state/{session-persistence.ts → project-persistence.ts} +74 -68
- package/src/state/project-save.ts +46 -0
- package/src/state/project-workspaces.ts +392 -0
- package/src/state/reducers/auto-commit-state.ts +11 -10
- package/src/state/reducers/git-commit-modal-state.ts +122 -0
- package/src/state/reducers/git-mode-state.ts +1 -1
- package/src/state/reducers/git-panel-state.ts +10 -6
- package/src/state/reducers/modal-state.ts +290 -681
- package/src/state/reducers/multi-repo-state.ts +3 -6
- package/src/state/reducers/project-state.ts +312 -0
- package/src/state/reducers/settings-state.ts +80 -0
- package/src/state/reducers/tab-state.ts +107 -60
- package/src/state/reducers/ui-state.ts +4 -3
- package/src/state/selectors.ts +49 -37
- package/src/state/store.ts +57 -24
- package/src/state/types.ts +244 -405
- package/src/state/validation.ts +14 -12
- package/src/terminal-manager/manager-client.ts +32 -32
- package/src/terminal-manager/terminal-manager.ts +24 -24
- package/src/ui/components/git/git-panel.tsx +2 -2
- package/src/ui/components/git/git-view.tsx +12 -12
- package/src/ui/components/git/image-diff/image-diff-view.tsx +1 -1
- package/src/ui/components/git/pane/git-pane-widget.tsx +7 -7
- package/src/ui/components/layout/sidebar/project-list.tsx +444 -0
- package/src/ui/components/layout/sidebar/tab-item.tsx +27 -12
- package/src/ui/components/layout/sidebar/use-sidebar-auto-scroll.ts +1 -1
- package/src/ui/components/layout/sidebar/workspace-row.tsx +253 -0
- package/src/ui/components/layout/status-bar.tsx +6 -2
- package/src/ui/components/layout/terminal-pane.tsx +34 -29
- package/src/ui/components/layout/top-tab-bar.tsx +46 -36
- package/src/ui/components/modals/git/git-commit-modal.tsx +8 -8
- package/src/ui/components/modals/{sessions/create-session-modal.tsx → projects/create-project-modal.tsx} +12 -12
- package/src/ui/components/modals/{sessions/session-name-modal.tsx → projects/project-name-modal.tsx} +2 -2
- package/src/ui/components/modals/{sessions/session-picker-modal.tsx → projects/project-picker-modal.tsx} +33 -35
- package/src/ui/components/modals/settings/settings-search-modal.tsx +70 -0
- package/src/ui/components/modals/shared/form.tsx +34 -22
- package/src/ui/components/modals/shared/picker.tsx +10 -10
- package/src/ui/components/modals/shared/{worktree-delete-confirm.tsx → workspace-delete-confirm.tsx} +9 -9
- package/src/ui/components/modals/tabs/new-tab-modal.tsx +30 -324
- package/src/ui/components/modals/workspace/create-workspace-modal.tsx +101 -0
- package/src/ui/components/modals/{worktree/worktree-move-confirm-modal.tsx → workspace/workspace-move-confirm-modal.tsx} +5 -5
- package/src/ui/components/modals/{worktree/worktree-move-modal.tsx → workspace/workspace-move-modal.tsx} +29 -27
- package/src/ui/components/primitives/input-field.tsx +7 -3
- package/src/ui/components/primitives/surface.tsx +3 -0
- package/src/ui/components/settings/row-value.tsx +74 -0
- package/src/ui/components/settings/settings-row.tsx +78 -0
- package/src/ui/components/settings/settings-view.tsx +169 -0
- package/src/ui/components/setup/setup-widget.tsx +152 -0
- package/src/ui/flash/build-labels.ts +27 -27
- package/src/ui/hooks/use-activity-sprite.ts +73 -0
- package/src/ui/hooks/use-scroll-active-into-view.ts +26 -0
- package/src/ui/{session-ordering.ts → project-ordering.ts} +4 -4
- package/src/ui/root.tsx +139 -121
- package/src/ui/status-bar-model.ts +48 -34
- package/src/ui/terminal-graphics/kitty.ts +28 -2
- package/src/ui/terminal-graphics/sprites/done@330/0.png +0 -0
- package/src/ui/terminal-graphics/sprites/done@330/1.png +0 -0
- package/src/ui/terminal-graphics/sprites/idle@1000/0.png +0 -0
- package/src/ui/terminal-graphics/sprites/idle@1000/1.png +0 -0
- package/src/ui/terminal-graphics/sprites/waiting@170/0.png +0 -0
- package/src/ui/terminal-graphics/sprites/waiting@170/1.png +0 -0
- package/src/ui/terminal-graphics/sprites/working@150/0.png +0 -0
- package/src/ui/terminal-graphics/sprites/working@150/1.png +0 -0
- package/src/ui/terminal-graphics/sprites/working@150/2.png +0 -0
- package/src/ui/terminal-graphics/sprites/working@150/3.png +0 -0
- package/src/ui/terminal-graphics/sprites.ts +246 -0
- package/src/ui/truncate.ts +7 -0
- package/src/ui/widgets/registry.tsx +6 -3
- package/src/ui/widgets/widget-context-menu.ts +26 -10
- package/src/update.ts +2 -2
- package/src/app-runtime/session-actions.ts +0 -187
- package/src/cli/client/workspace-resolver.ts +0 -110
- package/src/cli/commands/workspace/close.ts +0 -32
- package/src/cli/commands/workspace/show.ts +0 -32
- package/src/cli/commands/worktree/create.ts +0 -55
- package/src/cli/commands/worktree/list.ts +0 -68
- package/src/cli/commands/worktree/remove.ts +0 -81
- package/src/git/worktree-branch-poller.ts +0 -54
- package/src/git/worktree-divergence-poller.ts +0 -59
- package/src/state/reducers/session-state.ts +0 -262
- package/src/state/session-catalog.ts +0 -143
- package/src/state/session-worktrees.ts +0 -260
- package/src/state/workspace-save.ts +0 -43
- package/src/ui/components/layout/sidebar/use-top-tab-bar-auto-scroll.ts +0 -30
- package/src/ui/components/layout/sidebar/workspace-list.tsx +0 -418
- package/src/ui/components/layout/sidebar/worktree-row.tsx +0 -149
- /package/src/ui/{components/git/image-diff → terminal-graphics}/dimensions.ts +0 -0
package/src/state/types.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ModeId, SnippetVar } from '@brimveyn/aimux-config'
|
|
2
2
|
import type { ThemedToken } from 'shiki'
|
|
3
3
|
|
|
4
|
-
import type { WorktreeTemplate } from '../config'
|
|
5
4
|
import type { LayoutNode, SplitDirection } from './layout-tree'
|
|
6
5
|
|
|
7
6
|
export type BuiltinAssistantId =
|
|
@@ -18,7 +17,7 @@ export type AssistantId = BuiltinAssistantId | (string & {})
|
|
|
18
17
|
export type TabStatus = 'starting' | 'running' | 'disconnected' | 'error'
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
|
-
* Status values that may appear in legacy on-disk
|
|
20
|
+
* Status values that may appear in legacy on-disk project snapshots but are
|
|
22
21
|
* not produced by the running app anymore. Filtered at restore time.
|
|
23
22
|
*/
|
|
24
23
|
export type LegacyPersistedTabStatus = TabStatus | 'exited'
|
|
@@ -34,26 +33,51 @@ export type TabActivity = 'working' | 'waiting-input' | 'idle'
|
|
|
34
33
|
export type QuestionKind = 'question' | 'permission'
|
|
35
34
|
|
|
36
35
|
/**
|
|
37
|
-
* Per-
|
|
36
|
+
* Per-project status flags. Both can be true at once (e.g. one tab working,
|
|
38
37
|
* another waiting for user input) so we keep them as independent booleans
|
|
39
38
|
* rather than a single priority enum.
|
|
40
39
|
*/
|
|
41
|
-
export interface
|
|
40
|
+
export interface ProjectStatus {
|
|
42
41
|
working: boolean
|
|
43
42
|
waiting: boolean
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
export const
|
|
45
|
+
export const IDLE_PROJECT_STATUS: ProjectStatus = { waiting: false, working: false }
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
/**
|
|
48
|
+
* A workspace's status, as the sidebar draws it. `working`/`waiting` mirror
|
|
49
|
+
* `ProjectStatus` one level down; `done` is a latch — an assistant here
|
|
50
|
+
* finished a turn and nobody has looked yet — cleared when the workspace is
|
|
51
|
+
* entered or when it goes back to work.
|
|
52
|
+
*/
|
|
53
|
+
export interface WorkspaceActivity {
|
|
54
|
+
working: boolean
|
|
55
|
+
waiting: boolean
|
|
56
|
+
done: boolean
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const IDLE_WORKSPACE_ACTIVITY: WorkspaceActivity = {
|
|
60
|
+
done: false,
|
|
61
|
+
waiting: false,
|
|
62
|
+
working: false,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type FocusMode =
|
|
66
|
+
| 'navigation'
|
|
67
|
+
| 'terminal-input'
|
|
68
|
+
| 'modal'
|
|
69
|
+
| 'command-edit'
|
|
70
|
+
| 'git'
|
|
71
|
+
| 'settings'
|
|
49
72
|
|
|
50
73
|
export type ModalType =
|
|
51
74
|
| 'new-tab'
|
|
52
|
-
| '
|
|
53
|
-
| '
|
|
54
|
-
| 'create-
|
|
75
|
+
| 'project-picker'
|
|
76
|
+
| 'project-name'
|
|
77
|
+
| 'create-project'
|
|
78
|
+
| 'create-workspace'
|
|
55
79
|
| 'rename-tab'
|
|
56
|
-
| 'rename-
|
|
80
|
+
| 'rename-workspace'
|
|
57
81
|
| 'snippet-picker'
|
|
58
82
|
| 'snippet-editor'
|
|
59
83
|
| 'theme-picker'
|
|
@@ -62,10 +86,12 @@ export type ModalType =
|
|
|
62
86
|
| 'git-commit'
|
|
63
87
|
| 'update-available'
|
|
64
88
|
| 'ai-usage'
|
|
65
|
-
| '
|
|
66
|
-
| '
|
|
67
|
-
| '
|
|
89
|
+
| 'workspace-move'
|
|
90
|
+
| 'workspace-move-confirm'
|
|
91
|
+
| 'workspace-delete-confirm'
|
|
68
92
|
| 'flash-jump'
|
|
93
|
+
| 'setting-text'
|
|
94
|
+
| 'settings-search'
|
|
69
95
|
| null
|
|
70
96
|
|
|
71
97
|
export interface TerminalSpan {
|
|
@@ -132,13 +158,13 @@ export interface PersistedTabSnapshot {
|
|
|
132
158
|
terminalModes: TerminalModeState
|
|
133
159
|
errorMessage?: string
|
|
134
160
|
exitCode?: number
|
|
135
|
-
|
|
136
|
-
/** Stable
|
|
161
|
+
workspaceId?: string
|
|
162
|
+
/** Stable project-scoped name assigned by the headless worker facade. */
|
|
137
163
|
workerName?: string
|
|
138
164
|
autoRenameStatus?: 'eligible' | 'attempted'
|
|
139
165
|
}
|
|
140
166
|
|
|
141
|
-
export interface
|
|
167
|
+
export interface ProjectSnapshotV1 {
|
|
142
168
|
version: 1
|
|
143
169
|
savedAt: string
|
|
144
170
|
activeTabId: string | null
|
|
@@ -151,17 +177,17 @@ export interface WorkspaceSnapshotV1 {
|
|
|
151
177
|
layoutTrees?: Record<string, LayoutNode>
|
|
152
178
|
tabGroupMap?: Record<string, string>
|
|
153
179
|
/**
|
|
154
|
-
* Last viewed tab per
|
|
180
|
+
* Last viewed tab per workspace, keyed by workspace id. Optional and additive
|
|
155
181
|
* (no version bump): older builds ignore it, newer builds tolerate its
|
|
156
182
|
* absence. Written now so the data accrues, but restoring it at startup is
|
|
157
|
-
* gated off until a future change flips
|
|
183
|
+
* gated off until a future change flips RESTORE_LAST_ACTIVE_TAB_BY_WORKSPACE.
|
|
158
184
|
*/
|
|
159
|
-
|
|
185
|
+
lastActiveTabByWorkspace?: Record<string, string>
|
|
160
186
|
}
|
|
161
187
|
|
|
162
|
-
export type
|
|
188
|
+
export type WorkspaceSource = 'primary' | 'aimux-temp' | 'external'
|
|
163
189
|
|
|
164
|
-
export interface
|
|
190
|
+
export interface WorkspaceRecord {
|
|
165
191
|
id: string
|
|
166
192
|
name: string
|
|
167
193
|
path: string
|
|
@@ -169,14 +195,18 @@ export interface WorktreeRecord {
|
|
|
169
195
|
branch?: string
|
|
170
196
|
baseRef?: string
|
|
171
197
|
commitSha?: string
|
|
172
|
-
source:
|
|
198
|
+
source: WorkspaceSource
|
|
173
199
|
createdByAimux: boolean
|
|
174
200
|
color?: string
|
|
175
201
|
createdAt: string
|
|
176
202
|
updatedAt: string
|
|
203
|
+
/** Last setup-script run for this workspace. Display only — the auto-run gate
|
|
204
|
+
* is "this session has not seen this workspace id before". */
|
|
205
|
+
setupRanAt?: string
|
|
206
|
+
setupExitCode?: number
|
|
177
207
|
}
|
|
178
208
|
|
|
179
|
-
export interface
|
|
209
|
+
export interface ProjectRecord {
|
|
180
210
|
id: string
|
|
181
211
|
name: string
|
|
182
212
|
projectPath?: string
|
|
@@ -184,12 +214,12 @@ export interface SessionRecord {
|
|
|
184
214
|
updatedAt: string
|
|
185
215
|
lastOpenedAt: string
|
|
186
216
|
order?: number
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
217
|
+
projectSnapshot?: ProjectSnapshotV1
|
|
218
|
+
workspaces?: WorkspaceRecord[]
|
|
219
|
+
activeWorkspaceId?: string
|
|
190
220
|
}
|
|
191
221
|
|
|
192
|
-
export interface
|
|
222
|
+
export interface ProjectBarState {
|
|
193
223
|
visible: boolean
|
|
194
224
|
}
|
|
195
225
|
|
|
@@ -205,10 +235,36 @@ export interface TabSession {
|
|
|
205
235
|
command: string
|
|
206
236
|
errorMessage?: string
|
|
207
237
|
exitCode?: number
|
|
208
|
-
|
|
209
|
-
/**
|
|
238
|
+
workspaceId?: string
|
|
239
|
+
/**
|
|
240
|
+
* This tab is the one that rang: it finished a turn while you were looking
|
|
241
|
+
* elsewhere. Set alongside the workspace's own tick and cleared the moment
|
|
242
|
+
* the tab is opened or goes back to work, so the notification points at
|
|
243
|
+
* something rather than just happening. Ephemeral — never persisted, never
|
|
244
|
+
* on the wire.
|
|
245
|
+
*/
|
|
246
|
+
unseen?: boolean
|
|
247
|
+
/** Stable project-scoped name assigned by the headless worker facade. */
|
|
210
248
|
workerName?: string
|
|
211
249
|
autoRenameStatus?: 'eligible' | 'attempted'
|
|
250
|
+
/**
|
|
251
|
+
* A real PTY tab that no chrome enumerates: absent from the top tab bar, from
|
|
252
|
+
* tab navigation, from `activeTabId` picks, and from the persisted snapshot.
|
|
253
|
+
* Rendered by whatever created it — today only the setup widget.
|
|
254
|
+
* `filterTabsForActiveWorkspace` is the single guard the UI paths share.
|
|
255
|
+
*/
|
|
256
|
+
hidden?: boolean
|
|
257
|
+
/**
|
|
258
|
+
* Who owns this tab. Separate from `hidden` on purpose: promoting a setup tab
|
|
259
|
+
* into the main pane clears `hidden` but must not turn it back into an
|
|
260
|
+
* ordinary tab, or the PTY exit would close it and take the failure output
|
|
261
|
+
* with it — which is the one thing the promotion exists to read.
|
|
262
|
+
*
|
|
263
|
+
* ponytail: not on the ipc wire nor in the snapshot, so a promoted setup tab
|
|
264
|
+
* comes back from a restart as a plain tab running `bash …/setup.sh`. Add it
|
|
265
|
+
* to `TabSessionSummary` if that ever matters.
|
|
266
|
+
*/
|
|
267
|
+
role?: 'setup'
|
|
212
268
|
}
|
|
213
269
|
|
|
214
270
|
export type BarSide = 'left' | 'right'
|
|
@@ -351,59 +407,89 @@ export interface GitModeState {
|
|
|
351
407
|
folds: Record<string, Record<string, FoldState>>
|
|
352
408
|
/** Working-tree-vs-HEAD~N offset. 0 = working tree vs HEAD (default). */
|
|
353
409
|
headOffset: number
|
|
354
|
-
/** When true, diff the active
|
|
410
|
+
/** When true, diff the active workspace's working tree against its fork point. */
|
|
355
411
|
reviewBase: boolean
|
|
356
412
|
}
|
|
357
413
|
|
|
358
414
|
interface ModalBase {
|
|
359
415
|
selectedIndex: number
|
|
360
416
|
editBuffer: string | null
|
|
361
|
-
|
|
417
|
+
projectTargetId: string | null
|
|
362
418
|
cursorPos?: number
|
|
419
|
+
/**
|
|
420
|
+
* Where the focus goes when this modal closes, when it is not back to the
|
|
421
|
+
* panes. Set by whoever opened it, because that is who knows what is behind it
|
|
422
|
+
* — the settings screen opens five different modals, and none of them should
|
|
423
|
+
* have to grow a case in the reducer to find their way home.
|
|
424
|
+
*/
|
|
425
|
+
returnTo?: FocusMode
|
|
363
426
|
}
|
|
364
427
|
|
|
365
428
|
export interface ModalClosed extends ModalBase {
|
|
366
429
|
type: null
|
|
367
430
|
editBuffer: null
|
|
368
|
-
|
|
431
|
+
projectTargetId: null
|
|
369
432
|
}
|
|
370
433
|
|
|
434
|
+
/**
|
|
435
|
+
* Picking an assistant for a new tab, and nothing else. The tab lands in the
|
|
436
|
+
* project's active workspace; creating a workspace is `create-workspace`'s job.
|
|
437
|
+
*/
|
|
371
438
|
export interface ModalNewTab extends ModalBase {
|
|
372
439
|
type: 'new-tab'
|
|
373
440
|
editingCommand: AssistantId | null
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
441
|
+
/**
|
|
442
|
+
* Set when `create-workspace` chained into this picker. The prompt the user
|
|
443
|
+
* typed there is sent to the assistant and drives the workspace's real name,
|
|
444
|
+
* and the tab is pinned to the freshly created workspace rather than the
|
|
445
|
+
* project's active one. Living on the modal means `close-modal` clears it, so
|
|
446
|
+
* escaping the picker cannot leak a stale prompt into a later tab.
|
|
447
|
+
*/
|
|
448
|
+
pendingWorkspace?: PendingWorkspaceLaunch
|
|
449
|
+
/**
|
|
450
|
+
* A prompt to hand the picked assistant, with none of `pendingWorkspace`'s
|
|
451
|
+
* other behaviour: no workspace pinning, no rename. Used by "Ask an agent" in
|
|
452
|
+
* the setup widget.
|
|
453
|
+
*/
|
|
454
|
+
pendingPrompt?: string
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export interface PendingWorkspaceLaunch {
|
|
458
|
+
projectId: string
|
|
459
|
+
workspaceId: string
|
|
460
|
+
prompt: string
|
|
389
461
|
}
|
|
390
462
|
|
|
391
|
-
export interface
|
|
392
|
-
type: '
|
|
463
|
+
export interface ModalProjectPicker extends ModalBase {
|
|
464
|
+
type: 'project-picker'
|
|
393
465
|
}
|
|
394
466
|
|
|
395
|
-
export interface
|
|
396
|
-
type: '
|
|
397
|
-
|
|
467
|
+
export interface ModalProjectName extends ModalBase {
|
|
468
|
+
type: 'project-name'
|
|
469
|
+
returnToProjectPicker: boolean
|
|
398
470
|
}
|
|
399
471
|
|
|
400
472
|
export interface ModalRenameTab extends ModalBase {
|
|
401
473
|
type: 'rename-tab'
|
|
402
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* One text field over a settings row. Carries the row it belongs to so confirming
|
|
477
|
+
* writes back to the right one, and closing returns to the settings screen rather
|
|
478
|
+
* than to the panes.
|
|
479
|
+
*/
|
|
480
|
+
/** Fuzzy-ish search across every setting, from inside the settings screen. */
|
|
481
|
+
export interface ModalSettingsSearch extends ModalBase {
|
|
482
|
+
type: 'settings-search'
|
|
483
|
+
}
|
|
484
|
+
export interface ModalSettingText extends ModalBase {
|
|
485
|
+
type: 'setting-text'
|
|
486
|
+
settingId: string
|
|
487
|
+
settingLabel: string
|
|
488
|
+
}
|
|
403
489
|
|
|
404
|
-
export interface
|
|
405
|
-
type: 'rename-
|
|
406
|
-
|
|
490
|
+
export interface ModalRenameWorkspace extends ModalBase {
|
|
491
|
+
type: 'rename-workspace'
|
|
492
|
+
workspaceProjectId: string
|
|
407
493
|
}
|
|
408
494
|
|
|
409
495
|
export interface ModalSnippetPicker extends ModalBase {
|
|
@@ -438,13 +524,35 @@ export interface ModalGitCommit extends ModalBase {
|
|
|
438
524
|
stage: 'edit' | 'generating' | 'confirm'
|
|
439
525
|
}
|
|
440
526
|
|
|
441
|
-
export interface
|
|
442
|
-
type: 'create-
|
|
527
|
+
export interface ModalCreateProject extends ModalBase {
|
|
528
|
+
type: 'create-project'
|
|
443
529
|
directoryResults: DirectoryResult[]
|
|
444
530
|
pendingProjectPath: string | null
|
|
445
531
|
activeField: 'directory' | 'name'
|
|
446
532
|
nameBuffer: string
|
|
447
|
-
|
|
533
|
+
returnToProjectPicker: boolean
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Creating a workspace inside the current project — the second of the three
|
|
538
|
+
* creation actions (project / workspace / tab). Deliberately carries no
|
|
539
|
+
* assistant: once the workspace exists the effect chains into the new-tab modal.
|
|
540
|
+
*/
|
|
541
|
+
export interface ModalCreateWorkspace extends ModalBase {
|
|
542
|
+
type: 'create-workspace'
|
|
543
|
+
activeField: 'prompt' | 'base'
|
|
544
|
+
/**
|
|
545
|
+
* "What do you want to work on?" — the only thing the user types. It is sent
|
|
546
|
+
* to the assistant, and it names both the workspace and its branch.
|
|
547
|
+
*/
|
|
548
|
+
prompt: string
|
|
549
|
+
branchError: string | null
|
|
550
|
+
/** Filter text typed into the "Base" picker. */
|
|
551
|
+
baseQuery: string
|
|
552
|
+
/** Resolved base ref the new workspace is forked from (a workspace's branch or a local branch). */
|
|
553
|
+
baseRef: string
|
|
554
|
+
/** Local branches available as base refs, loaded when the modal opens. */
|
|
555
|
+
baseBranches: string[]
|
|
448
556
|
}
|
|
449
557
|
|
|
450
558
|
export interface ModalSnippetEditor extends ModalBase {
|
|
@@ -468,68 +576,68 @@ export interface ModalAIUsage extends ModalBase {
|
|
|
468
576
|
type: 'ai-usage'
|
|
469
577
|
}
|
|
470
578
|
|
|
471
|
-
export interface
|
|
472
|
-
type: '
|
|
473
|
-
/** The
|
|
474
|
-
|
|
579
|
+
export interface ModalWorkspaceMove extends ModalBase {
|
|
580
|
+
type: 'workspace-move'
|
|
581
|
+
/** The workspace being moved (may differ from the active one, e.g. a tab menu). */
|
|
582
|
+
sourceWorkspaceId: string
|
|
475
583
|
deleteSource: boolean
|
|
476
|
-
/** Per-
|
|
584
|
+
/** Per-workspace dirty file counts, loaded async when the modal opens. */
|
|
477
585
|
stats: { kind: 'loading' } | { kind: 'ready'; dirtyFiles: Record<string, number> }
|
|
478
586
|
}
|
|
479
587
|
|
|
480
588
|
/**
|
|
481
589
|
* Confirmation for a recoverable move failure: the target's dirty files
|
|
482
590
|
* overlap the incoming changes (stash-target) or the squash conflicts
|
|
483
|
-
* (keep-conflicts). Both
|
|
484
|
-
* move-
|
|
591
|
+
* (keep-conflicts). Both workspaces are already restored; confirming re-runs
|
|
592
|
+
* move-workspace with the matching flag.
|
|
485
593
|
*/
|
|
486
|
-
export interface
|
|
487
|
-
type: '
|
|
594
|
+
export interface ModalWorkspaceMoveConfirm extends ModalBase {
|
|
595
|
+
type: 'workspace-move-confirm'
|
|
488
596
|
variant: 'stash-target' | 'keep-conflicts'
|
|
489
597
|
files: string[]
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
598
|
+
projectId: string
|
|
599
|
+
sourceWorkspaceId: string
|
|
600
|
+
targetWorkspaceId: string
|
|
493
601
|
deleteSource: boolean
|
|
494
602
|
sourceLabel: string
|
|
495
603
|
targetLabel: string
|
|
496
604
|
}
|
|
497
605
|
|
|
498
606
|
/**
|
|
499
|
-
* Standalone confirmation for a recoverable
|
|
500
|
-
* outside the new-tab picker (e.g. the sidebar's "Remove
|
|
607
|
+
* Standalone confirmation for a recoverable workspace delete failure triggered
|
|
608
|
+
* outside the new-tab picker (e.g. the sidebar's "Remove workspace"). Carries the
|
|
501
609
|
* params needed to re-run the delete with force once confirmed.
|
|
502
610
|
*/
|
|
503
|
-
export interface
|
|
504
|
-
type: '
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
611
|
+
export interface ModalWorkspaceDeleteConfirm extends ModalBase {
|
|
612
|
+
type: 'workspace-delete-confirm'
|
|
613
|
+
projectId: string
|
|
614
|
+
workspaceId: string
|
|
615
|
+
workspaceLabel: string
|
|
508
616
|
reason: string
|
|
509
617
|
closeTabs: boolean
|
|
510
618
|
/** Whether confirming force-deletes — true only after a recoverable failure. */
|
|
511
619
|
force: boolean
|
|
512
620
|
}
|
|
513
621
|
|
|
514
|
-
export type DirectoryResultType = 'git-repo' | '
|
|
622
|
+
export type DirectoryResultType = 'git-repo' | 'workspace' | 'project'
|
|
515
623
|
|
|
516
624
|
export interface DirectoryResult {
|
|
517
625
|
path: string
|
|
518
626
|
type: DirectoryResultType
|
|
519
627
|
}
|
|
520
628
|
|
|
521
|
-
export type FlashJumpTargetKind = '
|
|
629
|
+
export type FlashJumpTargetKind = 'project' | 'workspace' | 'tab'
|
|
522
630
|
|
|
523
631
|
export interface FlashJumpTarget {
|
|
524
632
|
kind: FlashJumpTargetKind
|
|
525
633
|
/**
|
|
526
|
-
* 1-based index of the
|
|
527
|
-
* the existing `switch-
|
|
634
|
+
* 1-based index of the project in the visible project ordering — fed to
|
|
635
|
+
* the existing `switch-project-by-index` side effect when jumping.
|
|
528
636
|
*/
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
/** Set for kind '
|
|
532
|
-
|
|
637
|
+
projectIndex: number
|
|
638
|
+
projectId: string
|
|
639
|
+
/** Set for kind 'workspace' (the non-primary target) and kind 'tab' (the tab's workspace). */
|
|
640
|
+
workspaceId?: string
|
|
533
641
|
/** Set for kind 'tab'. */
|
|
534
642
|
tabId?: string
|
|
535
643
|
}
|
|
@@ -557,23 +665,26 @@ export interface ModalFlashJump extends ModalBase {
|
|
|
557
665
|
export type ModalState =
|
|
558
666
|
| ModalClosed
|
|
559
667
|
| ModalNewTab
|
|
560
|
-
|
|
|
561
|
-
|
|
|
668
|
+
| ModalProjectPicker
|
|
669
|
+
| ModalProjectName
|
|
562
670
|
| ModalRenameTab
|
|
563
|
-
|
|
|
671
|
+
| ModalRenameWorkspace
|
|
564
672
|
| ModalSnippetPicker
|
|
565
673
|
| ModalThemePicker
|
|
566
674
|
| ModalHelp
|
|
567
675
|
| ModalSplitPicker
|
|
568
|
-
|
|
|
676
|
+
| ModalCreateProject
|
|
677
|
+
| ModalCreateWorkspace
|
|
569
678
|
| ModalSnippetEditor
|
|
570
679
|
| ModalGitCommit
|
|
571
680
|
| ModalUpdateAvailable
|
|
572
681
|
| ModalAIUsage
|
|
573
|
-
|
|
|
574
|
-
|
|
|
575
|
-
|
|
|
682
|
+
| ModalWorkspaceMove
|
|
683
|
+
| ModalWorkspaceMoveConfirm
|
|
684
|
+
| ModalWorkspaceDeleteConfirm
|
|
576
685
|
| ModalFlashJump
|
|
686
|
+
| ModalSettingText
|
|
687
|
+
| ModalSettingsSearch
|
|
577
688
|
|
|
578
689
|
export interface LayoutState {
|
|
579
690
|
terminalCols: number
|
|
@@ -591,9 +702,9 @@ export interface SnippetRecord {
|
|
|
591
702
|
export interface DiscoveredRepo {
|
|
592
703
|
/** Absolute path to the repo. */
|
|
593
704
|
path: string
|
|
594
|
-
/** Label shown in UI (relative to the
|
|
705
|
+
/** Label shown in UI (relative to the project root or repo basename). */
|
|
595
706
|
name: string
|
|
596
|
-
/** True when the repo is the
|
|
707
|
+
/** True when the repo is the project's projectPath itself. */
|
|
597
708
|
isRoot: boolean
|
|
598
709
|
}
|
|
599
710
|
|
|
@@ -606,15 +717,28 @@ export interface MultiRepoState {
|
|
|
606
717
|
|
|
607
718
|
export const EMPTY_MULTI_REPO_STATE: MultiRepoState = { prefixes: {}, repos: [] }
|
|
608
719
|
|
|
720
|
+
/**
|
|
721
|
+
* Where the cursor is in the settings screen. Only the cursor: the values being
|
|
722
|
+
* edited live in `src/settings/settings-store.ts`, or already have a home in
|
|
723
|
+
* this state (`gitPane`, `customCommands`, …). Duplicating them here would make
|
|
724
|
+
* two of them.
|
|
725
|
+
*/
|
|
726
|
+
export interface SettingsUIState {
|
|
727
|
+
sectionId: string
|
|
728
|
+
/** Which of the two columns has the keyboard: the section list, or its rows. */
|
|
729
|
+
pane: 'nav' | 'rows'
|
|
730
|
+
rowIndex: number
|
|
731
|
+
}
|
|
732
|
+
|
|
609
733
|
export interface AppState {
|
|
610
734
|
tabs: TabSession[]
|
|
611
735
|
activeTabId: string | null
|
|
612
736
|
layoutTrees: Record<string, LayoutNode>
|
|
613
737
|
tabGroupMap: Record<string, string>
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
738
|
+
projects: ProjectRecord[]
|
|
739
|
+
currentProjectId: string | null
|
|
740
|
+
projectStatuses: Record<string, ProjectStatus>
|
|
741
|
+
projectBar: ProjectBarState
|
|
618
742
|
snippets: SnippetRecord[]
|
|
619
743
|
focusMode: FocusMode
|
|
620
744
|
bars: BarsState
|
|
@@ -626,203 +750,30 @@ export interface AppState {
|
|
|
626
750
|
gitMode: GitModeState
|
|
627
751
|
autoCommit: AutoCommitState
|
|
628
752
|
multiRepo: MultiRepoState
|
|
753
|
+
settings: SettingsUIState
|
|
629
754
|
/**
|
|
630
|
-
* Commits each
|
|
631
|
-
* keyed by
|
|
755
|
+
* Commits each workspace's branch is ahead/behind the ref it forked from,
|
|
756
|
+
* keyed by workspace id. Ephemeral (polled); not persisted to the catalog.
|
|
632
757
|
*/
|
|
633
|
-
|
|
758
|
+
workspaceDivergence: Record<string, BranchDivergence>
|
|
634
759
|
/**
|
|
635
|
-
*
|
|
636
|
-
*
|
|
760
|
+
* What each workspace's assistants are doing, keyed by workspace id. Covers
|
|
761
|
+
* every project the daemon knows, not just the current one — see
|
|
762
|
+
* `src/app-runtime/workspace-activity.ts`, which owns the aggregation.
|
|
763
|
+
* Ephemeral; not persisted to the catalog.
|
|
764
|
+
*/
|
|
765
|
+
workspaceActivity: Record<string, WorkspaceActivity>
|
|
766
|
+
/**
|
|
767
|
+
* Last active tab a user viewed within each workspace, keyed by workspace id.
|
|
768
|
+
* Lets switching back to a workspace restore its last-viewed tab instead of
|
|
637
769
|
* snapping to the first one. Ephemeral (in-memory); not persisted to the catalog.
|
|
638
770
|
*/
|
|
639
|
-
|
|
771
|
+
lastActiveTabByWorkspace: Record<string, string>
|
|
640
772
|
/** Chord prefix the sequence resolver is currently waiting on, or null when idle. */
|
|
641
773
|
pendingChords: string[] | null
|
|
642
|
-
/** User-defined templates applied at worktree creation. Loaded from aimux.json. */
|
|
643
|
-
worktreeTemplates: WorktreeTemplate[]
|
|
644
774
|
}
|
|
645
775
|
|
|
646
|
-
// --
|
|
647
|
-
export type ModalAction =
|
|
648
|
-
| { type: 'move-modal-cursor'; delta?: number; to?: 'home' | 'end' }
|
|
649
|
-
| { type: 'open-new-tab-modal' }
|
|
650
|
-
| { type: 'set-new-tab-branch-error'; message: string | null }
|
|
651
|
-
| {
|
|
652
|
-
type: 'set-new-tab-worktree-delete-prompt'
|
|
653
|
-
prompt: { worktreeId: string; reason: string } | null
|
|
654
|
-
}
|
|
655
|
-
| { type: 'set-new-tab-base-branches'; branches: string[] }
|
|
656
|
-
| { type: 'enter-new-tab-worktree-create' }
|
|
657
|
-
| { type: 'enter-new-tab-template-pick' }
|
|
658
|
-
| { type: 'enter-new-tab-template-shortcut' }
|
|
659
|
-
| { type: 'select-new-tab-assistant'; assistantId?: AssistantId }
|
|
660
|
-
| { type: 'toggle-new-tab-worktree'; assistantId?: AssistantId }
|
|
661
|
-
| { type: 'open-edit-custom-command'; assistantId: AssistantId }
|
|
662
|
-
| { type: 'open-help-modal'; scope?: ModeId }
|
|
663
|
-
| { type: 'open-split-picker'; direction: SplitDirection }
|
|
664
|
-
| { type: 'open-session-picker' }
|
|
665
|
-
| {
|
|
666
|
-
type: 'open-session-name-modal'
|
|
667
|
-
sessionTargetId?: string
|
|
668
|
-
initialName?: string
|
|
669
|
-
returnToSessionPicker?: boolean
|
|
670
|
-
}
|
|
671
|
-
| { type: 'close-modal' }
|
|
672
|
-
| { type: 'move-modal-selection'; delta: number }
|
|
673
|
-
| { type: 'update-command-edit'; char: string }
|
|
674
|
-
| { type: 'cancel-command-edit' }
|
|
675
|
-
| { type: 'open-create-session-modal'; returnToSessionPicker: boolean }
|
|
676
|
-
| { type: 'set-directory-results'; results: DirectoryResult[] }
|
|
677
|
-
| { type: 'switch-create-session-field' }
|
|
678
|
-
| { type: 'select-directory' }
|
|
679
|
-
| { type: 'open-rename-tab-modal' }
|
|
680
|
-
| {
|
|
681
|
-
type: 'open-rename-worktree-modal'
|
|
682
|
-
sessionId: string
|
|
683
|
-
worktreeId: string
|
|
684
|
-
initialName: string
|
|
685
|
-
}
|
|
686
|
-
| { type: 'open-snippet-picker' }
|
|
687
|
-
| { type: 'open-snippet-editor'; snippetId?: string }
|
|
688
|
-
| { type: 'set-help-entry-count'; count: number }
|
|
689
|
-
| { type: 'set-theme-entry-count'; count: number }
|
|
690
|
-
| { type: 'open-theme-picker' }
|
|
691
|
-
| { type: 'open-update-available-modal'; currentVersion: string; latestVersion: string }
|
|
692
|
-
| { type: 'set-modal-selection-index'; index: number }
|
|
693
|
-
| { type: 'open-ai-usage-modal' }
|
|
694
|
-
| { type: 'open-worktree-move-modal'; sourceWorktreeId: string }
|
|
695
|
-
| { type: 'toggle-worktree-move-delete' }
|
|
696
|
-
| { type: 'set-worktree-move-stats'; dirtyFiles: Record<string, number> }
|
|
697
|
-
| {
|
|
698
|
-
type: 'open-worktree-move-confirm'
|
|
699
|
-
variant: 'stash-target' | 'keep-conflicts'
|
|
700
|
-
files: string[]
|
|
701
|
-
sessionId: string
|
|
702
|
-
sourceWorktreeId: string
|
|
703
|
-
targetWorktreeId: string
|
|
704
|
-
deleteSource: boolean
|
|
705
|
-
sourceLabel: string
|
|
706
|
-
targetLabel: string
|
|
707
|
-
}
|
|
708
|
-
| {
|
|
709
|
-
type: 'open-worktree-delete-confirm'
|
|
710
|
-
sessionId: string
|
|
711
|
-
worktreeId: string
|
|
712
|
-
worktreeLabel: string
|
|
713
|
-
reason: string
|
|
714
|
-
closeTabs: boolean
|
|
715
|
-
force: boolean
|
|
716
|
-
}
|
|
717
|
-
| { type: 'open-flash-jump-modal' }
|
|
718
|
-
| { type: 'clear-flash-jump-pending' }
|
|
719
|
-
|
|
720
|
-
// -- Session actions --
|
|
721
|
-
export type SessionAction =
|
|
722
|
-
| {
|
|
723
|
-
type: 'load-session'
|
|
724
|
-
sessionId: string
|
|
725
|
-
workspaceSnapshot?: WorkspaceSnapshotV1
|
|
726
|
-
forceDisconnected?: boolean
|
|
727
|
-
}
|
|
728
|
-
| { type: 'set-sessions'; sessions: SessionRecord[] }
|
|
729
|
-
| { type: 'create-session-record'; session: SessionRecord }
|
|
730
|
-
| { type: 'rename-session-record'; sessionId: string; name: string }
|
|
731
|
-
| { type: 'delete-session-record'; sessionId: string; openSessionPicker?: boolean }
|
|
732
|
-
| { type: 'reorder-sessions'; orderedIds: string[] }
|
|
733
|
-
| { type: 'reorder-active-session'; delta: number }
|
|
734
|
-
| { type: 'set-session-status'; sessionId: string; status: SessionStatus }
|
|
735
|
-
| { type: 'add-worktree-record'; sessionId: string; worktree: WorktreeRecord; activate?: boolean }
|
|
736
|
-
| { type: 'set-active-worktree'; sessionId: string; worktreeId: string }
|
|
737
|
-
| {
|
|
738
|
-
type: 'update-worktree-record'
|
|
739
|
-
sessionId: string
|
|
740
|
-
worktreeId: string
|
|
741
|
-
patch: Partial<WorktreeRecord>
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
// -- Tab actions --
|
|
745
|
-
export type TabAction =
|
|
746
|
-
| { type: 'add-tab'; tab: TabSession }
|
|
747
|
-
| {
|
|
748
|
-
type: 'hydrate-workspace'
|
|
749
|
-
tabs: TabSession[]
|
|
750
|
-
activeTabId: string | null
|
|
751
|
-
layoutTree?: LayoutNode | null
|
|
752
|
-
layoutTrees?: Record<string, LayoutNode>
|
|
753
|
-
tabGroupMap?: Record<string, string>
|
|
754
|
-
}
|
|
755
|
-
| { type: 'close-tab'; tabId: string }
|
|
756
|
-
| { type: 'close-active-tab' }
|
|
757
|
-
| { type: 'set-active-tab'; tabId: string }
|
|
758
|
-
| { type: 'move-active-tab'; delta: number }
|
|
759
|
-
| { type: 'reorder-active-tab'; delta: number }
|
|
760
|
-
| { type: 'reorder-tabs'; orderedTabIds: string[] }
|
|
761
|
-
| { type: 'reset-tab-session'; tabId: string }
|
|
762
|
-
| {
|
|
763
|
-
type: 'rename-tab'
|
|
764
|
-
tabId: string
|
|
765
|
-
title: string
|
|
766
|
-
autoRenameStatus?: 'eligible' | 'attempted'
|
|
767
|
-
}
|
|
768
|
-
| {
|
|
769
|
-
type: 'update-tab-metadata'
|
|
770
|
-
tabId: string
|
|
771
|
-
title?: string
|
|
772
|
-
autoRenameStatus?: 'eligible' | 'attempted'
|
|
773
|
-
}
|
|
774
|
-
| { type: 'append-tab-buffer'; tabId: string; chunk: string }
|
|
775
|
-
| {
|
|
776
|
-
type: 'replace-tab-viewport'
|
|
777
|
-
tabId: string
|
|
778
|
-
viewport: TerminalSnapshot
|
|
779
|
-
terminalModes: TerminalModeState
|
|
780
|
-
source?: 'resize' | 'scroll' | 'data' | 'switch'
|
|
781
|
-
}
|
|
782
|
-
| { type: 'set-tab-activity'; tabId: string; activity?: TabActivity }
|
|
783
|
-
| { type: 'set-tab-error'; tabId: string; message: string }
|
|
784
|
-
|
|
785
|
-
// -- Layout actions --
|
|
786
|
-
export type LayoutAction =
|
|
787
|
-
| {
|
|
788
|
-
type: 'split-pane'
|
|
789
|
-
direction: SplitDirection
|
|
790
|
-
newTab: TabSession
|
|
791
|
-
}
|
|
792
|
-
| { type: 'close-pane'; tabId: string }
|
|
793
|
-
| {
|
|
794
|
-
type: 'focus-pane-direction'
|
|
795
|
-
direction: 'left' | 'right' | 'up' | 'down'
|
|
796
|
-
}
|
|
797
|
-
| {
|
|
798
|
-
type: 'resize-pane'
|
|
799
|
-
tabId: string
|
|
800
|
-
delta: number
|
|
801
|
-
axis?: SplitDirection
|
|
802
|
-
}
|
|
803
|
-
| {
|
|
804
|
-
type: 'set-split-ratio'
|
|
805
|
-
tabId: string
|
|
806
|
-
ratio: number
|
|
807
|
-
axis?: SplitDirection
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
// -- UI actions --
|
|
811
|
-
export type UIAction =
|
|
812
|
-
| { type: 'toggle-bar'; side: BarSide }
|
|
813
|
-
| { type: 'resize-bar'; side: BarSide; delta: number }
|
|
814
|
-
| { type: 'set-bar-width'; side: BarSide; width: number }
|
|
815
|
-
| { type: 'toggle-widget'; widgetId: string }
|
|
816
|
-
| { type: 'move-widget'; widgetId: string; side: BarSide; index: number }
|
|
817
|
-
| { type: 'set-bar-boundary'; side: BarSide; index: number; ratio: number }
|
|
818
|
-
| { type: 'resize-widget'; widgetId: string; delta: number }
|
|
819
|
-
| { type: 'set-focus-mode'; focusMode: FocusMode }
|
|
820
|
-
| { type: 'set-terminal-size'; cols: number; rows: number }
|
|
821
|
-
| { type: 'resize-git-diff-pane'; delta: number }
|
|
822
|
-
| { type: 'set-pending-chords'; chords: string[] | null }
|
|
823
|
-
| { type: 'toggle-session-bar' }
|
|
824
|
-
|
|
825
|
-
// -- Git panel actions --
|
|
776
|
+
// -- Git panel payloads --
|
|
826
777
|
export interface GitRefreshPayload {
|
|
827
778
|
branch: string | null
|
|
828
779
|
ahead: number
|
|
@@ -830,19 +781,16 @@ export interface GitRefreshPayload {
|
|
|
830
781
|
files: GitFileEntry[]
|
|
831
782
|
}
|
|
832
783
|
|
|
833
|
-
/** Commits a
|
|
784
|
+
/** Commits a workspace branch is ahead/behind the ref it forked from. */
|
|
834
785
|
export interface BranchDivergence {
|
|
835
786
|
ahead: number
|
|
836
787
|
behind: number
|
|
788
|
+
/** Lines changed since the fork point, working tree included. */
|
|
789
|
+
added?: number
|
|
790
|
+
removed?: number
|
|
837
791
|
}
|
|
838
792
|
|
|
839
|
-
|
|
840
|
-
| { type: 'git-refresh-success'; payload: GitRefreshPayload }
|
|
841
|
-
| { type: 'git-refresh-error'; kind: GitPanelError }
|
|
842
|
-
| { type: 'git-panel-reset' }
|
|
843
|
-
| { type: 'set-worktree-divergence'; divergence: Record<string, BranchDivergence> }
|
|
844
|
-
|
|
845
|
-
// -- Auto-commit state & actions --
|
|
793
|
+
// -- Auto-commit state --
|
|
846
794
|
export type AutoCommitSuggestion =
|
|
847
795
|
| { kind: 'idle' }
|
|
848
796
|
| {
|
|
@@ -862,116 +810,7 @@ export type AutoCommitSuggestion =
|
|
|
862
810
|
}
|
|
863
811
|
|
|
864
812
|
export interface AutoCommitState {
|
|
865
|
-
|
|
813
|
+
byProject: Record<string, AutoCommitSuggestion>
|
|
866
814
|
}
|
|
867
815
|
|
|
868
|
-
export const EMPTY_AUTO_COMMIT_STATE: AutoCommitState = {
|
|
869
|
-
|
|
870
|
-
export type AutoCommitAction =
|
|
871
|
-
| {
|
|
872
|
-
type: 'auto-commit-generation-started'
|
|
873
|
-
sessionId: string
|
|
874
|
-
tabId: string
|
|
875
|
-
workingTreeHash: string
|
|
876
|
-
abortController: AbortController
|
|
877
|
-
startedAt: number
|
|
878
|
-
}
|
|
879
|
-
| {
|
|
880
|
-
type: 'auto-commit-generation-ready'
|
|
881
|
-
sessionId: string
|
|
882
|
-
workingTreeHash: string
|
|
883
|
-
title: string
|
|
884
|
-
body: string
|
|
885
|
-
generatedAt: number
|
|
886
|
-
}
|
|
887
|
-
| { type: 'auto-commit-clear'; sessionId: string }
|
|
888
|
-
|
|
889
|
-
export type GitModeAction =
|
|
890
|
-
| { type: 'enter-git-mode' }
|
|
891
|
-
| { type: 'exit-git-mode' }
|
|
892
|
-
| { type: 'git-mode-move-selection'; delta: -1 | 1 }
|
|
893
|
-
| { type: 'git-mode-move-file-selection'; delta: -1 | 1 }
|
|
894
|
-
| { type: 'git-mode-select-entry-by-key'; key: string }
|
|
895
|
-
| { type: 'git-mode-toggle-folder'; key: string }
|
|
896
|
-
| { type: 'git-mode-toggle-selected-folder' }
|
|
897
|
-
| { type: 'git-mode-collapse-selection' }
|
|
898
|
-
| { type: 'git-mode-expand-selection' }
|
|
899
|
-
| { type: 'git-mode-toggle-file-list-mode' }
|
|
900
|
-
| { type: 'git-mode-toggle-tree-compaction' }
|
|
901
|
-
| { type: 'git-mode-set-diff'; key: string; diff: DiffData; hash: string }
|
|
902
|
-
| {
|
|
903
|
-
type: 'git-mode-set-parsed'
|
|
904
|
-
key: string
|
|
905
|
-
hash: string
|
|
906
|
-
file: unknown
|
|
907
|
-
}
|
|
908
|
-
| {
|
|
909
|
-
type: 'git-mode-set-highlights'
|
|
910
|
-
key: string
|
|
911
|
-
hash: string
|
|
912
|
-
themeId: string
|
|
913
|
-
add: unknown
|
|
914
|
-
del: unknown
|
|
915
|
-
}
|
|
916
|
-
| {
|
|
917
|
-
type: 'git-mode-merge-highlights'
|
|
918
|
-
key: string
|
|
919
|
-
hash: string
|
|
920
|
-
themeId: string
|
|
921
|
-
add: { start: number; tokens: unknown }[]
|
|
922
|
-
del: { start: number; tokens: unknown }[]
|
|
923
|
-
}
|
|
924
|
-
| { type: 'git-mode-invalidate-diffs'; paths: string[] }
|
|
925
|
-
| { type: 'git-mode-set-loading'; key: string; loading: boolean }
|
|
926
|
-
| { type: 'git-mode-set-pending-delete'; path: string | null }
|
|
927
|
-
| { type: 'git-mode-clear-diff-cache'; path: string }
|
|
928
|
-
| { type: 'git-mode-set-message'; message: string | null }
|
|
929
|
-
| { type: 'snippet-picker-set-message'; message: string | null }
|
|
930
|
-
| { type: 'git-mode-toggle-diff-view' }
|
|
931
|
-
| { type: 'git-mode-toggle-review-base' }
|
|
932
|
-
| { type: 'git-mode-shift-head-offset'; delta: number }
|
|
933
|
-
| { type: 'git-mode-set-head-offset'; offset: number }
|
|
934
|
-
| {
|
|
935
|
-
type: 'git-mode-fold-adjust'
|
|
936
|
-
key: string
|
|
937
|
-
foldId: string
|
|
938
|
-
side: 'top' | 'bottom'
|
|
939
|
-
delta: number
|
|
940
|
-
}
|
|
941
|
-
| { type: 'git-mode-fold-set'; key: string; foldId: string; top: number; bottom: number }
|
|
942
|
-
| { type: 'git-mode-fold-toggle-all'; key: string }
|
|
943
|
-
| {
|
|
944
|
-
type: 'git-mode-optimistic-move'
|
|
945
|
-
path: string
|
|
946
|
-
fromSection: GitFileSection
|
|
947
|
-
toSection: GitFileSection | null
|
|
948
|
-
}
|
|
949
|
-
| { type: 'open-git-commit-modal'; sessionId?: string }
|
|
950
|
-
| { type: 'git-commit-enter-confirm' }
|
|
951
|
-
| { type: 'git-commit-leave-confirm' }
|
|
952
|
-
| { type: 'git-commit-enter-generating'; sessionId: string }
|
|
953
|
-
| { type: 'git-commit-leave-generating' }
|
|
954
|
-
| { type: 'git-commit-use-background-suggestion'; sessionId: string }
|
|
955
|
-
|
|
956
|
-
// -- Data actions --
|
|
957
|
-
export type DataAction =
|
|
958
|
-
| { type: 'set-snippets'; snippets: SnippetRecord[] }
|
|
959
|
-
| { type: 'delete-snippet'; snippetId: string }
|
|
960
|
-
| { type: 'set-custom-commands'; customCommands: Record<AssistantId, string> }
|
|
961
|
-
|
|
962
|
-
// -- Multi-repo actions --
|
|
963
|
-
export type MultiRepoAction =
|
|
964
|
-
| { type: 'multi-repo-set-repos'; repos: DiscoveredRepo[] }
|
|
965
|
-
| { type: 'multi-repo-clear' }
|
|
966
|
-
|
|
967
|
-
export type AppAction =
|
|
968
|
-
| ModalAction
|
|
969
|
-
| SessionAction
|
|
970
|
-
| TabAction
|
|
971
|
-
| LayoutAction
|
|
972
|
-
| UIAction
|
|
973
|
-
| DataAction
|
|
974
|
-
| GitPanelAction
|
|
975
|
-
| GitModeAction
|
|
976
|
-
| AutoCommitAction
|
|
977
|
-
| MultiRepoAction
|
|
816
|
+
export const EMPTY_AUTO_COMMIT_STATE: AutoCommitState = { byProject: {} }
|