@brimveyn/aimux-config 0.6.9 → 0.6.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brimveyn/aimux-config",
3
- "version": "0.6.9",
3
+ "version": "0.6.10",
4
4
  "description": "TypeScript configuration API for aimux — keymaps, themes, and backends with a fluent builder.",
5
5
  "keywords": [
6
6
  "aimux",
package/src/actions.ts CHANGED
@@ -195,7 +195,7 @@ export const launchSelectedAssistant: ActionFn = (ctx: ModeContext) => {
195
195
  ctx.state.modal.step === 'worktree' &&
196
196
  ctx.state.modal.createWorktree
197
197
  ) {
198
- return r([{ type: 'enter-new-tab-worktree-create' }])
198
+ return r([{ type: 'enter-new-tab-worktree-create' }], [{ type: 'load-new-tab-base-branches' }])
199
199
  }
200
200
  return r([], [{ type: 'launch-selected-assistant' }])
201
201
  }
@@ -210,19 +210,49 @@ export const deleteSelectedWorktree: ActionFn = (ctx: ModeContext) => {
210
210
  const session = ctx.state.sessions.find((entry) => entry.id === sessionId)
211
211
  const worktree = session?.worktrees?.[modal.selectedIndex]
212
212
  if (!worktree) return null
213
+ // First attempt is never forced — a recoverable failure opens the confirm
214
+ // dialog (see set-new-tab-worktree-delete-prompt), where confirmDeleteWorktree
215
+ // retries with force.
213
216
  return r(
214
- [
215
- { index: modal.selectedIndex, type: 'set-modal-selection-index' },
216
- { message: null, type: 'set-new-tab-worktree-delete-state' },
217
- ],
217
+ [{ index: modal.selectedIndex, type: 'set-modal-selection-index' }],
218
+ [{ force: false, sessionId, type: 'delete-worktree', worktreeId: worktree.id }]
219
+ )
220
+ }
221
+
222
+ export const confirmDeleteWorktree: ActionFn = (ctx: ModeContext) => {
223
+ const modal = ctx.state.modal
224
+ const sessionId = ctx.state.currentSessionId
225
+ if (modal.type !== 'new-tab' || modal.worktreeDeletePrompt == null) return null
226
+ if (!(sessionId != null && sessionId !== '')) return null
227
+ const { worktreeId } = modal.worktreeDeletePrompt
228
+ return r(
229
+ [{ prompt: null, type: 'set-new-tab-worktree-delete-prompt' }],
230
+ [{ force: true, sessionId, type: 'delete-worktree', worktreeId }],
231
+ 'modal.new-tab.command-edit'
232
+ )
233
+ }
234
+
235
+ export const cancelDeleteWorktree: KeyResult = r(
236
+ [{ prompt: null, type: 'set-new-tab-worktree-delete-prompt' }],
237
+ [],
238
+ 'modal.new-tab.command-edit'
239
+ )
240
+
241
+ export const confirmWorktreeDeleteModal: ActionFn = (ctx: ModeContext) => {
242
+ const modal = ctx.state.modal
243
+ if (modal.type !== 'worktree-delete-confirm') return null
244
+ return r(
245
+ [{ type: 'close-modal' }],
218
246
  [
219
247
  {
220
- force: modal.worktreeDeleteConfirmId === worktree.id,
221
- sessionId,
248
+ closeTabs: modal.closeTabs,
249
+ force: modal.force,
250
+ sessionId: modal.sessionId,
222
251
  type: 'delete-worktree',
223
- worktreeId: worktree.id,
252
+ worktreeId: modal.worktreeId,
224
253
  },
225
- ]
254
+ ],
255
+ 'navigation'
226
256
  )
227
257
  }
228
258
 
package/src/defaults.ts CHANGED
@@ -204,6 +204,17 @@ export function getDefaultKeymapConfig(): ResolvedKeymapConfig {
204
204
  .map('<CR>', actions.confirmWorktreeMove, 'Move')
205
205
  )
206
206
 
207
+ // -----------------------------------------------------------------------
208
+ // Modal: standalone worktree delete confirmation (sidebar "Remove worktree")
209
+ // -----------------------------------------------------------------------
210
+ .mode('modal.worktree-delete-confirm', (m) =>
211
+ m
212
+ .map('<Esc>', actions.closeModal, 'Cancel')
213
+ .map('n', actions.closeModal, 'Cancel')
214
+ .map('<CR>', actions.confirmWorktreeDeleteModal, 'Delete worktree')
215
+ .map('y', actions.confirmWorktreeDeleteModal, 'Delete worktree')
216
+ )
217
+
207
218
  // -----------------------------------------------------------------------
208
219
  // Modal: rename-tab
209
220
  // -----------------------------------------------------------------------
@@ -239,6 +250,17 @@ export function getDefaultKeymapConfig(): ResolvedKeymapConfig {
239
250
  .passthrough()
240
251
  )
241
252
 
253
+ // -----------------------------------------------------------------------
254
+ // Modal: new-tab worktree delete confirmation dialog
255
+ // -----------------------------------------------------------------------
256
+ .mode('modal.new-tab.worktree-delete-confirm', (m) =>
257
+ m
258
+ .map('<Esc>', actions.cancelDeleteWorktree, 'Cancel')
259
+ .map('n', actions.cancelDeleteWorktree, 'Cancel')
260
+ .map('<CR>', actions.confirmDeleteWorktree, 'Delete worktree')
261
+ .map('y', actions.confirmDeleteWorktree, 'Delete worktree')
262
+ )
263
+
242
264
  // -----------------------------------------------------------------------
243
265
  // Modal: session-picker (always in filter mode via Picker)
244
266
  // -----------------------------------------------------------------------
package/src/types.ts CHANGED
@@ -14,6 +14,8 @@ export type ModeId =
14
14
  | 'git-mode'
15
15
  | 'modal.new-tab.command-edit'
16
16
  | 'modal.new-tab.editing-command'
17
+ | 'modal.new-tab.worktree-delete-confirm'
18
+ | 'modal.worktree-delete-confirm'
17
19
  | 'modal.session-picker.filtering'
18
20
  | 'modal.session-name'
19
21
  | 'modal.create-session'
@@ -296,16 +298,21 @@ export interface ModalClosed extends ModalBase {
296
298
  export interface ModalNewTab extends ModalBase {
297
299
  type: 'new-tab'
298
300
  editingCommand: AssistantId | null
299
- activeField: 'assistant' | 'branch-name' | 'target-worktree' | 'worktree-name'
301
+ activeField: 'assistant' | 'branch-name' | 'target-worktree' | 'worktree-name' | 'base'
300
302
  branchError: string | null
301
303
  branchName: string
302
304
  createWorktree: boolean
303
305
  selectedAssistantId: AssistantId | null
304
306
  step: 'assistant' | 'worktree' | 'worktree-create' | 'template'
305
307
  targetWorktreeIndex: number
306
- worktreeDeleteConfirmId: string | null
307
- worktreeDeleteMessage: string | null
308
+ worktreeDeletePrompt: { worktreeId: string; reason: string } | null
308
309
  worktreeName: string
310
+ /** Filter text typed into the "Base" picker on the worktree-create step. */
311
+ baseQuery: string
312
+ /** Resolved base ref the new worktree is forked from (branch of a worktree or a local branch). */
313
+ baseRef: string
314
+ /** Local branches available as base refs, loaded when the create step opens. */
315
+ baseBranches: string[]
309
316
  }
310
317
  export interface ModalSessionPicker extends ModalBase {
311
318
  type: 'session-picker'
@@ -373,6 +380,22 @@ export interface ModalWorktreeMove extends ModalBase {
373
380
  deleteSource: boolean
374
381
  }
375
382
 
383
+ /**
384
+ * Standalone confirmation for a recoverable worktree delete failure triggered
385
+ * outside the new-tab picker (e.g. the sidebar's "Remove worktree"). Carries the
386
+ * params needed to re-run the delete with force once confirmed.
387
+ */
388
+ export interface ModalWorktreeDeleteConfirm extends ModalBase {
389
+ type: 'worktree-delete-confirm'
390
+ sessionId: string
391
+ worktreeId: string
392
+ worktreeLabel: string
393
+ reason: string
394
+ closeTabs: boolean
395
+ /** Whether confirming force-deletes — true only after a recoverable failure. */
396
+ force: boolean
397
+ }
398
+
376
399
  export type ModalState =
377
400
  | ModalClosed
378
401
  | ModalNewTab
@@ -389,6 +412,7 @@ export type ModalState =
389
412
  | ModalUpdateAvailable
390
413
  | ModalAIUsage
391
414
  | ModalWorktreeMove
415
+ | ModalWorktreeDeleteConfirm
392
416
 
393
417
  export interface LayoutState {
394
418
  terminalCols: number
@@ -464,10 +488,10 @@ export type ModalAction =
464
488
  | { type: 'open-new-tab-modal' }
465
489
  | { type: 'set-new-tab-branch-error'; message: string | null }
466
490
  | {
467
- type: 'set-new-tab-worktree-delete-state'
468
- confirmWorktreeId?: string | null
469
- message: string | null
491
+ type: 'set-new-tab-worktree-delete-prompt'
492
+ prompt: { worktreeId: string; reason: string } | null
470
493
  }
494
+ | { type: 'set-new-tab-base-branches'; branches: string[] }
471
495
  | { type: 'enter-new-tab-worktree-create' }
472
496
  | { type: 'enter-new-tab-template-pick' }
473
497
  | { type: 'enter-new-tab-template-shortcut' }
@@ -502,6 +526,15 @@ export type ModalAction =
502
526
  | { type: 'open-edit-custom-command'; assistantId: AssistantId }
503
527
  | { type: 'open-worktree-move-modal'; sourceWorktreeId: string }
504
528
  | { type: 'toggle-worktree-move-delete' }
529
+ | {
530
+ type: 'open-worktree-delete-confirm'
531
+ sessionId: string
532
+ worktreeId: string
533
+ worktreeLabel: string
534
+ reason: string
535
+ closeTabs: boolean
536
+ force: boolean
537
+ }
505
538
 
506
539
  export type SessionAction =
507
540
  | { type: 'load-session'; sessionId: string; workspaceSnapshot?: WorkspaceSnapshotV1 }
@@ -513,7 +546,6 @@ export type SessionAction =
513
546
  | { type: 'reorder-active-session'; delta: number }
514
547
  | { type: 'set-session-status'; sessionId: string; status: SessionStatus }
515
548
  | { type: 'add-worktree-record'; sessionId: string; worktree: WorktreeRecord; activate?: boolean }
516
- | { type: 'remove-worktree-record'; sessionId: string; worktreeId: string }
517
549
  | { type: 'set-active-worktree'; sessionId: string; worktreeId: string }
518
550
  | {
519
551
  type: 'update-worktree-record'
@@ -709,6 +741,7 @@ export type AppAction =
709
741
  export type SideEffect =
710
742
  | { type: 'quit'; state: AppState }
711
743
  | { type: 'launch-selected-assistant' }
744
+ | { type: 'load-new-tab-base-branches' }
712
745
  | { type: 'edit-selected-assistant' }
713
746
  | { type: 'confirm-selected-session' }
714
747
  | { type: 'delete-selected-session' }
@@ -748,7 +781,18 @@ export type SideEffect =
748
781
  | { type: 'cycle-sidebar-item'; direction: 1 | -1 }
749
782
  | { type: 'switch-tab-by-index'; index: number }
750
783
  | { type: 'delete-session'; sessionId: string }
751
- | { type: 'delete-worktree'; sessionId: string; worktreeId: string; force?: boolean }
784
+ | {
785
+ type: 'delete-worktree'
786
+ sessionId: string
787
+ worktreeId: string
788
+ // Force the git worktree removal (discards uncommitted changes in the
789
+ // worktree). Also implies closing the worktree's tabs.
790
+ force?: boolean
791
+ // Close the worktree's tabs without forcing the git removal. Lets the
792
+ // sidebar "Remove worktree" clean up tabs (avoiding orphans) while still
793
+ // refusing to discard uncommitted work in a temp worktree.
794
+ closeTabs?: boolean
795
+ }
752
796
  | {
753
797
  type: 'move-worktree'
754
798
  sessionId: string