@brimveyn/aimux 1.20.4 → 1.22.0
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 +305 -1589
- package/src/app-runtime/snippet-actions.ts +3 -2
- package/src/app-runtime/split-drag-controller.ts +4 -8
- 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 +28 -42
- 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 +28 -33
- 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 +102 -85
- 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 +149 -101
- 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-merge.ts +64 -0
- package/src/git/pr-status-poller.ts +57 -0
- package/src/git/pr-status.ts +227 -0
- 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 +11 -6
- 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/open-url.ts +39 -0
- 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 +3 -1
- 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 +75 -0
- package/src/state/dispatch-ref.ts +1 -1
- package/src/state/git-pane-sizing.ts +0 -9
- package/src/state/layout-resize.ts +2 -2
- package/src/state/pr-status-store.ts +39 -0
- 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} +77 -73
- 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 -53
- 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 +86 -15
- package/src/state/selectors.ts +49 -37
- package/src/state/store.ts +83 -57
- package/src/state/types.ts +261 -417
- 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/diff-renderer/pierre-diff.tsx +2 -1
- 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-header.tsx +105 -39
- package/src/ui/components/git/pane/git-pane-widget.tsx +37 -23
- package/src/ui/components/git/pane/pr-checks-panel.tsx +197 -0
- package/src/ui/components/git/pane/pr-state-row.tsx +103 -0
- package/src/ui/components/layout/bar.tsx +191 -0
- 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 +48 -37
- 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 +164 -230
- 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 +21 -0
- package/src/ui/widgets/widget-context-menu.ts +85 -0
- 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 -45
- package/src/ui/components/git/pane/git-pane-context-menu.ts +0 -26
- package/src/ui/components/layout/sidebar/sidebar.tsx +0 -163
- 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,21 +235,58 @@ 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'
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export type BarSide = 'left' | 'right'
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* One widget slot in a bar. `grow` is the flex weight opentui consumes
|
|
274
|
+
* directly; hidden widgets keep their weight but are excluded from the layout.
|
|
275
|
+
*/
|
|
276
|
+
export interface BarWidget {
|
|
277
|
+
id: string
|
|
278
|
+
grow: number
|
|
279
|
+
visible: boolean
|
|
212
280
|
}
|
|
213
281
|
|
|
214
|
-
export interface
|
|
282
|
+
export interface BarState {
|
|
215
283
|
visible: boolean
|
|
216
284
|
width: number
|
|
217
|
-
|
|
218
|
-
|
|
285
|
+
/** Ordered top → bottom. */
|
|
286
|
+
widgets: BarWidget[]
|
|
219
287
|
}
|
|
220
288
|
|
|
221
|
-
export type
|
|
222
|
-
export type GitPanePosition = 'top' | 'bottom' | 'left' | 'right'
|
|
289
|
+
export type BarsState = Record<BarSide, BarState>
|
|
223
290
|
|
|
224
291
|
export type GitPanePathConfig =
|
|
225
292
|
| { enabled: false }
|
|
@@ -230,11 +297,6 @@ export interface GitPaneDiffCountConfig {
|
|
|
230
297
|
}
|
|
231
298
|
|
|
232
299
|
export interface GitPaneState {
|
|
233
|
-
visible: boolean
|
|
234
|
-
mode: GitPaneMode
|
|
235
|
-
position: GitPanePosition
|
|
236
|
-
paneRatio: number
|
|
237
|
-
embeddedRatio: number
|
|
238
300
|
diffModeRatio: number
|
|
239
301
|
fileListMode: GitFileListMode
|
|
240
302
|
treeCompaction: boolean
|
|
@@ -345,59 +407,89 @@ export interface GitModeState {
|
|
|
345
407
|
folds: Record<string, Record<string, FoldState>>
|
|
346
408
|
/** Working-tree-vs-HEAD~N offset. 0 = working tree vs HEAD (default). */
|
|
347
409
|
headOffset: number
|
|
348
|
-
/** When true, diff the active
|
|
410
|
+
/** When true, diff the active workspace's working tree against its fork point. */
|
|
349
411
|
reviewBase: boolean
|
|
350
412
|
}
|
|
351
413
|
|
|
352
414
|
interface ModalBase {
|
|
353
415
|
selectedIndex: number
|
|
354
416
|
editBuffer: string | null
|
|
355
|
-
|
|
417
|
+
projectTargetId: string | null
|
|
356
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
|
|
357
426
|
}
|
|
358
427
|
|
|
359
428
|
export interface ModalClosed extends ModalBase {
|
|
360
429
|
type: null
|
|
361
430
|
editBuffer: null
|
|
362
|
-
|
|
431
|
+
projectTargetId: null
|
|
363
432
|
}
|
|
364
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
|
+
*/
|
|
365
438
|
export interface ModalNewTab extends ModalBase {
|
|
366
439
|
type: 'new-tab'
|
|
367
440
|
editingCommand: AssistantId | null
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
baseBranches: string[]
|
|
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
|
|
383
455
|
}
|
|
384
456
|
|
|
385
|
-
export interface
|
|
386
|
-
|
|
457
|
+
export interface PendingWorkspaceLaunch {
|
|
458
|
+
projectId: string
|
|
459
|
+
workspaceId: string
|
|
460
|
+
prompt: string
|
|
387
461
|
}
|
|
388
462
|
|
|
389
|
-
export interface
|
|
390
|
-
type: '
|
|
391
|
-
|
|
463
|
+
export interface ModalProjectPicker extends ModalBase {
|
|
464
|
+
type: 'project-picker'
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export interface ModalProjectName extends ModalBase {
|
|
468
|
+
type: 'project-name'
|
|
469
|
+
returnToProjectPicker: boolean
|
|
392
470
|
}
|
|
393
471
|
|
|
394
472
|
export interface ModalRenameTab extends ModalBase {
|
|
395
473
|
type: 'rename-tab'
|
|
396
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
|
+
}
|
|
397
489
|
|
|
398
|
-
export interface
|
|
399
|
-
type: 'rename-
|
|
400
|
-
|
|
490
|
+
export interface ModalRenameWorkspace extends ModalBase {
|
|
491
|
+
type: 'rename-workspace'
|
|
492
|
+
workspaceProjectId: string
|
|
401
493
|
}
|
|
402
494
|
|
|
403
495
|
export interface ModalSnippetPicker extends ModalBase {
|
|
@@ -432,13 +524,35 @@ export interface ModalGitCommit extends ModalBase {
|
|
|
432
524
|
stage: 'edit' | 'generating' | 'confirm'
|
|
433
525
|
}
|
|
434
526
|
|
|
435
|
-
export interface
|
|
436
|
-
type: 'create-
|
|
527
|
+
export interface ModalCreateProject extends ModalBase {
|
|
528
|
+
type: 'create-project'
|
|
437
529
|
directoryResults: DirectoryResult[]
|
|
438
530
|
pendingProjectPath: string | null
|
|
439
531
|
activeField: 'directory' | 'name'
|
|
440
532
|
nameBuffer: string
|
|
441
|
-
|
|
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[]
|
|
442
556
|
}
|
|
443
557
|
|
|
444
558
|
export interface ModalSnippetEditor extends ModalBase {
|
|
@@ -462,68 +576,68 @@ export interface ModalAIUsage extends ModalBase {
|
|
|
462
576
|
type: 'ai-usage'
|
|
463
577
|
}
|
|
464
578
|
|
|
465
|
-
export interface
|
|
466
|
-
type: '
|
|
467
|
-
/** The
|
|
468
|
-
|
|
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
|
|
469
583
|
deleteSource: boolean
|
|
470
|
-
/** Per-
|
|
584
|
+
/** Per-workspace dirty file counts, loaded async when the modal opens. */
|
|
471
585
|
stats: { kind: 'loading' } | { kind: 'ready'; dirtyFiles: Record<string, number> }
|
|
472
586
|
}
|
|
473
587
|
|
|
474
588
|
/**
|
|
475
589
|
* Confirmation for a recoverable move failure: the target's dirty files
|
|
476
590
|
* overlap the incoming changes (stash-target) or the squash conflicts
|
|
477
|
-
* (keep-conflicts). Both
|
|
478
|
-
* move-
|
|
591
|
+
* (keep-conflicts). Both workspaces are already restored; confirming re-runs
|
|
592
|
+
* move-workspace with the matching flag.
|
|
479
593
|
*/
|
|
480
|
-
export interface
|
|
481
|
-
type: '
|
|
594
|
+
export interface ModalWorkspaceMoveConfirm extends ModalBase {
|
|
595
|
+
type: 'workspace-move-confirm'
|
|
482
596
|
variant: 'stash-target' | 'keep-conflicts'
|
|
483
597
|
files: string[]
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
598
|
+
projectId: string
|
|
599
|
+
sourceWorkspaceId: string
|
|
600
|
+
targetWorkspaceId: string
|
|
487
601
|
deleteSource: boolean
|
|
488
602
|
sourceLabel: string
|
|
489
603
|
targetLabel: string
|
|
490
604
|
}
|
|
491
605
|
|
|
492
606
|
/**
|
|
493
|
-
* Standalone confirmation for a recoverable
|
|
494
|
-
* 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
|
|
495
609
|
* params needed to re-run the delete with force once confirmed.
|
|
496
610
|
*/
|
|
497
|
-
export interface
|
|
498
|
-
type: '
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
611
|
+
export interface ModalWorkspaceDeleteConfirm extends ModalBase {
|
|
612
|
+
type: 'workspace-delete-confirm'
|
|
613
|
+
projectId: string
|
|
614
|
+
workspaceId: string
|
|
615
|
+
workspaceLabel: string
|
|
502
616
|
reason: string
|
|
503
617
|
closeTabs: boolean
|
|
504
618
|
/** Whether confirming force-deletes — true only after a recoverable failure. */
|
|
505
619
|
force: boolean
|
|
506
620
|
}
|
|
507
621
|
|
|
508
|
-
export type DirectoryResultType = 'git-repo' | '
|
|
622
|
+
export type DirectoryResultType = 'git-repo' | 'workspace' | 'project'
|
|
509
623
|
|
|
510
624
|
export interface DirectoryResult {
|
|
511
625
|
path: string
|
|
512
626
|
type: DirectoryResultType
|
|
513
627
|
}
|
|
514
628
|
|
|
515
|
-
export type FlashJumpTargetKind = '
|
|
629
|
+
export type FlashJumpTargetKind = 'project' | 'workspace' | 'tab'
|
|
516
630
|
|
|
517
631
|
export interface FlashJumpTarget {
|
|
518
632
|
kind: FlashJumpTargetKind
|
|
519
633
|
/**
|
|
520
|
-
* 1-based index of the
|
|
521
|
-
* 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.
|
|
522
636
|
*/
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
/** Set for kind '
|
|
526
|
-
|
|
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
|
|
527
641
|
/** Set for kind 'tab'. */
|
|
528
642
|
tabId?: string
|
|
529
643
|
}
|
|
@@ -551,23 +665,26 @@ export interface ModalFlashJump extends ModalBase {
|
|
|
551
665
|
export type ModalState =
|
|
552
666
|
| ModalClosed
|
|
553
667
|
| ModalNewTab
|
|
554
|
-
|
|
|
555
|
-
|
|
|
668
|
+
| ModalProjectPicker
|
|
669
|
+
| ModalProjectName
|
|
556
670
|
| ModalRenameTab
|
|
557
|
-
|
|
|
671
|
+
| ModalRenameWorkspace
|
|
558
672
|
| ModalSnippetPicker
|
|
559
673
|
| ModalThemePicker
|
|
560
674
|
| ModalHelp
|
|
561
675
|
| ModalSplitPicker
|
|
562
|
-
|
|
|
676
|
+
| ModalCreateProject
|
|
677
|
+
| ModalCreateWorkspace
|
|
563
678
|
| ModalSnippetEditor
|
|
564
679
|
| ModalGitCommit
|
|
565
680
|
| ModalUpdateAvailable
|
|
566
681
|
| ModalAIUsage
|
|
567
|
-
|
|
|
568
|
-
|
|
|
569
|
-
|
|
|
682
|
+
| ModalWorkspaceMove
|
|
683
|
+
| ModalWorkspaceMoveConfirm
|
|
684
|
+
| ModalWorkspaceDeleteConfirm
|
|
570
685
|
| ModalFlashJump
|
|
686
|
+
| ModalSettingText
|
|
687
|
+
| ModalSettingsSearch
|
|
571
688
|
|
|
572
689
|
export interface LayoutState {
|
|
573
690
|
terminalCols: number
|
|
@@ -585,9 +702,9 @@ export interface SnippetRecord {
|
|
|
585
702
|
export interface DiscoveredRepo {
|
|
586
703
|
/** Absolute path to the repo. */
|
|
587
704
|
path: string
|
|
588
|
-
/** Label shown in UI (relative to the
|
|
705
|
+
/** Label shown in UI (relative to the project root or repo basename). */
|
|
589
706
|
name: string
|
|
590
|
-
/** True when the repo is the
|
|
707
|
+
/** True when the repo is the project's projectPath itself. */
|
|
591
708
|
isRoot: boolean
|
|
592
709
|
}
|
|
593
710
|
|
|
@@ -600,18 +717,31 @@ export interface MultiRepoState {
|
|
|
600
717
|
|
|
601
718
|
export const EMPTY_MULTI_REPO_STATE: MultiRepoState = { prefixes: {}, repos: [] }
|
|
602
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
|
+
|
|
603
733
|
export interface AppState {
|
|
604
734
|
tabs: TabSession[]
|
|
605
735
|
activeTabId: string | null
|
|
606
736
|
layoutTrees: Record<string, LayoutNode>
|
|
607
737
|
tabGroupMap: Record<string, string>
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
738
|
+
projects: ProjectRecord[]
|
|
739
|
+
currentProjectId: string | null
|
|
740
|
+
projectStatuses: Record<string, ProjectStatus>
|
|
741
|
+
projectBar: ProjectBarState
|
|
612
742
|
snippets: SnippetRecord[]
|
|
613
743
|
focusMode: FocusMode
|
|
614
|
-
|
|
744
|
+
bars: BarsState
|
|
615
745
|
gitPane: GitPaneState
|
|
616
746
|
modal: ModalState
|
|
617
747
|
layout: LayoutState
|
|
@@ -620,204 +750,30 @@ export interface AppState {
|
|
|
620
750
|
gitMode: GitModeState
|
|
621
751
|
autoCommit: AutoCommitState
|
|
622
752
|
multiRepo: MultiRepoState
|
|
753
|
+
settings: SettingsUIState
|
|
754
|
+
/**
|
|
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.
|
|
757
|
+
*/
|
|
758
|
+
workspaceDivergence: Record<string, BranchDivergence>
|
|
623
759
|
/**
|
|
624
|
-
*
|
|
625
|
-
*
|
|
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.
|
|
626
764
|
*/
|
|
627
|
-
|
|
765
|
+
workspaceActivity: Record<string, WorkspaceActivity>
|
|
628
766
|
/**
|
|
629
|
-
* Last active tab a user viewed within each
|
|
630
|
-
* Lets switching back to a
|
|
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
|
|
631
769
|
* snapping to the first one. Ephemeral (in-memory); not persisted to the catalog.
|
|
632
770
|
*/
|
|
633
|
-
|
|
771
|
+
lastActiveTabByWorkspace: Record<string, string>
|
|
634
772
|
/** Chord prefix the sequence resolver is currently waiting on, or null when idle. */
|
|
635
773
|
pendingChords: string[] | null
|
|
636
|
-
/** User-defined templates applied at worktree creation. Loaded from aimux.json. */
|
|
637
|
-
worktreeTemplates: WorktreeTemplate[]
|
|
638
774
|
}
|
|
639
775
|
|
|
640
|
-
// --
|
|
641
|
-
export type ModalAction =
|
|
642
|
-
| { type: 'move-modal-cursor'; delta?: number; to?: 'home' | 'end' }
|
|
643
|
-
| { type: 'open-new-tab-modal' }
|
|
644
|
-
| { type: 'set-new-tab-branch-error'; message: string | null }
|
|
645
|
-
| {
|
|
646
|
-
type: 'set-new-tab-worktree-delete-prompt'
|
|
647
|
-
prompt: { worktreeId: string; reason: string } | null
|
|
648
|
-
}
|
|
649
|
-
| { type: 'set-new-tab-base-branches'; branches: string[] }
|
|
650
|
-
| { type: 'enter-new-tab-worktree-create' }
|
|
651
|
-
| { type: 'enter-new-tab-template-pick' }
|
|
652
|
-
| { type: 'enter-new-tab-template-shortcut' }
|
|
653
|
-
| { type: 'select-new-tab-assistant'; assistantId?: AssistantId }
|
|
654
|
-
| { type: 'toggle-new-tab-worktree'; assistantId?: AssistantId }
|
|
655
|
-
| { type: 'open-edit-custom-command'; assistantId: AssistantId }
|
|
656
|
-
| { type: 'open-help-modal'; scope?: ModeId }
|
|
657
|
-
| { type: 'open-split-picker'; direction: SplitDirection }
|
|
658
|
-
| { type: 'open-session-picker' }
|
|
659
|
-
| {
|
|
660
|
-
type: 'open-session-name-modal'
|
|
661
|
-
sessionTargetId?: string
|
|
662
|
-
initialName?: string
|
|
663
|
-
returnToSessionPicker?: boolean
|
|
664
|
-
}
|
|
665
|
-
| { type: 'close-modal' }
|
|
666
|
-
| { type: 'move-modal-selection'; delta: number }
|
|
667
|
-
| { type: 'update-command-edit'; char: string }
|
|
668
|
-
| { type: 'cancel-command-edit' }
|
|
669
|
-
| { type: 'open-create-session-modal'; returnToSessionPicker: boolean }
|
|
670
|
-
| { type: 'set-directory-results'; results: DirectoryResult[] }
|
|
671
|
-
| { type: 'switch-create-session-field' }
|
|
672
|
-
| { type: 'select-directory' }
|
|
673
|
-
| { type: 'open-rename-tab-modal' }
|
|
674
|
-
| {
|
|
675
|
-
type: 'open-rename-worktree-modal'
|
|
676
|
-
sessionId: string
|
|
677
|
-
worktreeId: string
|
|
678
|
-
initialName: string
|
|
679
|
-
}
|
|
680
|
-
| { type: 'open-snippet-picker' }
|
|
681
|
-
| { type: 'open-snippet-editor'; snippetId?: string }
|
|
682
|
-
| { type: 'set-help-entry-count'; count: number }
|
|
683
|
-
| { type: 'set-theme-entry-count'; count: number }
|
|
684
|
-
| { type: 'open-theme-picker' }
|
|
685
|
-
| { type: 'open-update-available-modal'; currentVersion: string; latestVersion: string }
|
|
686
|
-
| { type: 'set-modal-selection-index'; index: number }
|
|
687
|
-
| { type: 'open-ai-usage-modal' }
|
|
688
|
-
| { type: 'open-worktree-move-modal'; sourceWorktreeId: string }
|
|
689
|
-
| { type: 'toggle-worktree-move-delete' }
|
|
690
|
-
| { type: 'set-worktree-move-stats'; dirtyFiles: Record<string, number> }
|
|
691
|
-
| {
|
|
692
|
-
type: 'open-worktree-move-confirm'
|
|
693
|
-
variant: 'stash-target' | 'keep-conflicts'
|
|
694
|
-
files: string[]
|
|
695
|
-
sessionId: string
|
|
696
|
-
sourceWorktreeId: string
|
|
697
|
-
targetWorktreeId: string
|
|
698
|
-
deleteSource: boolean
|
|
699
|
-
sourceLabel: string
|
|
700
|
-
targetLabel: string
|
|
701
|
-
}
|
|
702
|
-
| {
|
|
703
|
-
type: 'open-worktree-delete-confirm'
|
|
704
|
-
sessionId: string
|
|
705
|
-
worktreeId: string
|
|
706
|
-
worktreeLabel: string
|
|
707
|
-
reason: string
|
|
708
|
-
closeTabs: boolean
|
|
709
|
-
force: boolean
|
|
710
|
-
}
|
|
711
|
-
| { type: 'open-flash-jump-modal' }
|
|
712
|
-
| { type: 'clear-flash-jump-pending' }
|
|
713
|
-
|
|
714
|
-
// -- Session actions --
|
|
715
|
-
export type SessionAction =
|
|
716
|
-
| {
|
|
717
|
-
type: 'load-session'
|
|
718
|
-
sessionId: string
|
|
719
|
-
workspaceSnapshot?: WorkspaceSnapshotV1
|
|
720
|
-
forceDisconnected?: boolean
|
|
721
|
-
}
|
|
722
|
-
| { type: 'set-sessions'; sessions: SessionRecord[] }
|
|
723
|
-
| { type: 'create-session-record'; session: SessionRecord }
|
|
724
|
-
| { type: 'rename-session-record'; sessionId: string; name: string }
|
|
725
|
-
| { type: 'delete-session-record'; sessionId: string; openSessionPicker?: boolean }
|
|
726
|
-
| { type: 'reorder-sessions'; orderedIds: string[] }
|
|
727
|
-
| { type: 'reorder-active-session'; delta: number }
|
|
728
|
-
| { type: 'set-session-status'; sessionId: string; status: SessionStatus }
|
|
729
|
-
| { type: 'add-worktree-record'; sessionId: string; worktree: WorktreeRecord; activate?: boolean }
|
|
730
|
-
| { type: 'set-active-worktree'; sessionId: string; worktreeId: string }
|
|
731
|
-
| {
|
|
732
|
-
type: 'update-worktree-record'
|
|
733
|
-
sessionId: string
|
|
734
|
-
worktreeId: string
|
|
735
|
-
patch: Partial<WorktreeRecord>
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
// -- Tab actions --
|
|
739
|
-
export type TabAction =
|
|
740
|
-
| { type: 'add-tab'; tab: TabSession }
|
|
741
|
-
| {
|
|
742
|
-
type: 'hydrate-workspace'
|
|
743
|
-
tabs: TabSession[]
|
|
744
|
-
activeTabId: string | null
|
|
745
|
-
layoutTree?: LayoutNode | null
|
|
746
|
-
layoutTrees?: Record<string, LayoutNode>
|
|
747
|
-
tabGroupMap?: Record<string, string>
|
|
748
|
-
}
|
|
749
|
-
| { type: 'close-tab'; tabId: string }
|
|
750
|
-
| { type: 'close-active-tab' }
|
|
751
|
-
| { type: 'set-active-tab'; tabId: string }
|
|
752
|
-
| { type: 'move-active-tab'; delta: number }
|
|
753
|
-
| { type: 'reorder-active-tab'; delta: number }
|
|
754
|
-
| { type: 'reorder-tabs'; orderedTabIds: string[] }
|
|
755
|
-
| { type: 'reset-tab-session'; tabId: string }
|
|
756
|
-
| {
|
|
757
|
-
type: 'rename-tab'
|
|
758
|
-
tabId: string
|
|
759
|
-
title: string
|
|
760
|
-
autoRenameStatus?: 'eligible' | 'attempted'
|
|
761
|
-
}
|
|
762
|
-
| {
|
|
763
|
-
type: 'update-tab-metadata'
|
|
764
|
-
tabId: string
|
|
765
|
-
title?: string
|
|
766
|
-
autoRenameStatus?: 'eligible' | 'attempted'
|
|
767
|
-
}
|
|
768
|
-
| { type: 'append-tab-buffer'; tabId: string; chunk: string }
|
|
769
|
-
| {
|
|
770
|
-
type: 'replace-tab-viewport'
|
|
771
|
-
tabId: string
|
|
772
|
-
viewport: TerminalSnapshot
|
|
773
|
-
terminalModes: TerminalModeState
|
|
774
|
-
source?: 'resize' | 'scroll' | 'data' | 'switch'
|
|
775
|
-
}
|
|
776
|
-
| { type: 'set-tab-activity'; tabId: string; activity?: TabActivity }
|
|
777
|
-
| { type: 'set-tab-error'; tabId: string; message: string }
|
|
778
|
-
|
|
779
|
-
// -- Layout actions --
|
|
780
|
-
export type LayoutAction =
|
|
781
|
-
| {
|
|
782
|
-
type: 'split-pane'
|
|
783
|
-
direction: SplitDirection
|
|
784
|
-
newTab: TabSession
|
|
785
|
-
}
|
|
786
|
-
| { type: 'close-pane'; tabId: string }
|
|
787
|
-
| {
|
|
788
|
-
type: 'focus-pane-direction'
|
|
789
|
-
direction: 'left' | 'right' | 'up' | 'down'
|
|
790
|
-
}
|
|
791
|
-
| {
|
|
792
|
-
type: 'resize-pane'
|
|
793
|
-
tabId: string
|
|
794
|
-
delta: number
|
|
795
|
-
axis?: SplitDirection
|
|
796
|
-
}
|
|
797
|
-
| {
|
|
798
|
-
type: 'set-split-ratio'
|
|
799
|
-
tabId: string
|
|
800
|
-
ratio: number
|
|
801
|
-
axis?: SplitDirection
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
// -- UI actions --
|
|
805
|
-
export type UIAction =
|
|
806
|
-
| { type: 'toggle-sidebar' }
|
|
807
|
-
| { type: 'resize-sidebar'; delta: number }
|
|
808
|
-
| { type: 'set-sidebar-width'; width: number }
|
|
809
|
-
| { type: 'set-focus-mode'; focusMode: FocusMode }
|
|
810
|
-
| { type: 'set-terminal-size'; cols: number; rows: number }
|
|
811
|
-
| { type: 'toggle-git-pane' }
|
|
812
|
-
| { type: 'resize-git-pane'; delta: number }
|
|
813
|
-
| { type: 'set-git-pane-ratio'; target: 'pane' | 'embedded'; ratio: number }
|
|
814
|
-
| { type: 'resize-git-diff-pane'; delta: number }
|
|
815
|
-
| { type: 'set-git-pane-mode'; mode: GitPaneMode }
|
|
816
|
-
| { type: 'set-git-pane-position'; position: GitPanePosition }
|
|
817
|
-
| { type: 'set-pending-chords'; chords: string[] | null }
|
|
818
|
-
| { type: 'toggle-session-bar' }
|
|
819
|
-
|
|
820
|
-
// -- Git panel actions --
|
|
776
|
+
// -- Git panel payloads --
|
|
821
777
|
export interface GitRefreshPayload {
|
|
822
778
|
branch: string | null
|
|
823
779
|
ahead: number
|
|
@@ -825,19 +781,16 @@ export interface GitRefreshPayload {
|
|
|
825
781
|
files: GitFileEntry[]
|
|
826
782
|
}
|
|
827
783
|
|
|
828
|
-
/** Commits a
|
|
784
|
+
/** Commits a workspace branch is ahead/behind the ref it forked from. */
|
|
829
785
|
export interface BranchDivergence {
|
|
830
786
|
ahead: number
|
|
831
787
|
behind: number
|
|
788
|
+
/** Lines changed since the fork point, working tree included. */
|
|
789
|
+
added?: number
|
|
790
|
+
removed?: number
|
|
832
791
|
}
|
|
833
792
|
|
|
834
|
-
|
|
835
|
-
| { type: 'git-refresh-success'; payload: GitRefreshPayload }
|
|
836
|
-
| { type: 'git-refresh-error'; kind: GitPanelError }
|
|
837
|
-
| { type: 'git-panel-reset' }
|
|
838
|
-
| { type: 'set-worktree-divergence'; divergence: Record<string, BranchDivergence> }
|
|
839
|
-
|
|
840
|
-
// -- Auto-commit state & actions --
|
|
793
|
+
// -- Auto-commit state --
|
|
841
794
|
export type AutoCommitSuggestion =
|
|
842
795
|
| { kind: 'idle' }
|
|
843
796
|
| {
|
|
@@ -857,116 +810,7 @@ export type AutoCommitSuggestion =
|
|
|
857
810
|
}
|
|
858
811
|
|
|
859
812
|
export interface AutoCommitState {
|
|
860
|
-
|
|
813
|
+
byProject: Record<string, AutoCommitSuggestion>
|
|
861
814
|
}
|
|
862
815
|
|
|
863
|
-
export const EMPTY_AUTO_COMMIT_STATE: AutoCommitState = {
|
|
864
|
-
|
|
865
|
-
export type AutoCommitAction =
|
|
866
|
-
| {
|
|
867
|
-
type: 'auto-commit-generation-started'
|
|
868
|
-
sessionId: string
|
|
869
|
-
tabId: string
|
|
870
|
-
workingTreeHash: string
|
|
871
|
-
abortController: AbortController
|
|
872
|
-
startedAt: number
|
|
873
|
-
}
|
|
874
|
-
| {
|
|
875
|
-
type: 'auto-commit-generation-ready'
|
|
876
|
-
sessionId: string
|
|
877
|
-
workingTreeHash: string
|
|
878
|
-
title: string
|
|
879
|
-
body: string
|
|
880
|
-
generatedAt: number
|
|
881
|
-
}
|
|
882
|
-
| { type: 'auto-commit-clear'; sessionId: string }
|
|
883
|
-
|
|
884
|
-
export type GitModeAction =
|
|
885
|
-
| { type: 'enter-git-mode' }
|
|
886
|
-
| { type: 'exit-git-mode' }
|
|
887
|
-
| { type: 'git-mode-move-selection'; delta: -1 | 1 }
|
|
888
|
-
| { type: 'git-mode-move-file-selection'; delta: -1 | 1 }
|
|
889
|
-
| { type: 'git-mode-select-entry-by-key'; key: string }
|
|
890
|
-
| { type: 'git-mode-toggle-folder'; key: string }
|
|
891
|
-
| { type: 'git-mode-toggle-selected-folder' }
|
|
892
|
-
| { type: 'git-mode-collapse-selection' }
|
|
893
|
-
| { type: 'git-mode-expand-selection' }
|
|
894
|
-
| { type: 'git-mode-toggle-file-list-mode' }
|
|
895
|
-
| { type: 'git-mode-toggle-tree-compaction' }
|
|
896
|
-
| { type: 'git-mode-set-diff'; key: string; diff: DiffData; hash: string }
|
|
897
|
-
| {
|
|
898
|
-
type: 'git-mode-set-parsed'
|
|
899
|
-
key: string
|
|
900
|
-
hash: string
|
|
901
|
-
file: unknown
|
|
902
|
-
}
|
|
903
|
-
| {
|
|
904
|
-
type: 'git-mode-set-highlights'
|
|
905
|
-
key: string
|
|
906
|
-
hash: string
|
|
907
|
-
themeId: string
|
|
908
|
-
add: unknown
|
|
909
|
-
del: unknown
|
|
910
|
-
}
|
|
911
|
-
| {
|
|
912
|
-
type: 'git-mode-merge-highlights'
|
|
913
|
-
key: string
|
|
914
|
-
hash: string
|
|
915
|
-
themeId: string
|
|
916
|
-
add: { start: number; tokens: unknown }[]
|
|
917
|
-
del: { start: number; tokens: unknown }[]
|
|
918
|
-
}
|
|
919
|
-
| { type: 'git-mode-invalidate-diffs'; paths: string[] }
|
|
920
|
-
| { type: 'git-mode-set-loading'; key: string; loading: boolean }
|
|
921
|
-
| { type: 'git-mode-set-pending-delete'; path: string | null }
|
|
922
|
-
| { type: 'git-mode-clear-diff-cache'; path: string }
|
|
923
|
-
| { type: 'git-mode-set-message'; message: string | null }
|
|
924
|
-
| { type: 'snippet-picker-set-message'; message: string | null }
|
|
925
|
-
| { type: 'git-mode-toggle-diff-view' }
|
|
926
|
-
| { type: 'git-mode-toggle-review-base' }
|
|
927
|
-
| { type: 'git-mode-shift-head-offset'; delta: number }
|
|
928
|
-
| { type: 'git-mode-set-head-offset'; offset: number }
|
|
929
|
-
| {
|
|
930
|
-
type: 'git-mode-fold-adjust'
|
|
931
|
-
key: string
|
|
932
|
-
foldId: string
|
|
933
|
-
side: 'top' | 'bottom'
|
|
934
|
-
delta: number
|
|
935
|
-
}
|
|
936
|
-
| { type: 'git-mode-fold-set'; key: string; foldId: string; top: number; bottom: number }
|
|
937
|
-
| { type: 'git-mode-fold-toggle-all'; key: string }
|
|
938
|
-
| {
|
|
939
|
-
type: 'git-mode-optimistic-move'
|
|
940
|
-
path: string
|
|
941
|
-
fromSection: GitFileSection
|
|
942
|
-
toSection: GitFileSection | null
|
|
943
|
-
}
|
|
944
|
-
| { type: 'open-git-commit-modal'; sessionId?: string }
|
|
945
|
-
| { type: 'git-commit-enter-confirm' }
|
|
946
|
-
| { type: 'git-commit-leave-confirm' }
|
|
947
|
-
| { type: 'git-commit-enter-generating'; sessionId: string }
|
|
948
|
-
| { type: 'git-commit-leave-generating' }
|
|
949
|
-
| { type: 'git-commit-use-background-suggestion'; sessionId: string }
|
|
950
|
-
|
|
951
|
-
// -- Data actions --
|
|
952
|
-
export type DataAction =
|
|
953
|
-
| { type: 'set-snippets'; snippets: SnippetRecord[] }
|
|
954
|
-
| { type: 'delete-snippet'; snippetId: string }
|
|
955
|
-
| { type: 'set-custom-commands'; customCommands: Record<AssistantId, string> }
|
|
956
|
-
|
|
957
|
-
// -- Multi-repo actions --
|
|
958
|
-
export type MultiRepoAction =
|
|
959
|
-
| { type: 'multi-repo-set-repos'; repos: DiscoveredRepo[] }
|
|
960
|
-
| { type: 'multi-repo-clear' }
|
|
961
|
-
|
|
962
|
-
export type AppAction =
|
|
963
|
-
| ModalAction
|
|
964
|
-
| SessionAction
|
|
965
|
-
| TabAction
|
|
966
|
-
| LayoutAction
|
|
967
|
-
| UIAction
|
|
968
|
-
| DataAction
|
|
969
|
-
| GitPanelAction
|
|
970
|
-
| GitModeAction
|
|
971
|
-
| AutoCommitAction
|
|
972
|
-
| MultiRepoAction
|
|
816
|
+
export const EMPTY_AUTO_COMMIT_STATE: AutoCommitState = { byProject: {} }
|