aimux-cli 0.1.16 → 0.1.19
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 +184 -67
- package/bin/aimux-dev +10 -0
- package/dist/agent-events.js +0 -1
- package/dist/agent-output-parser.js +0 -1
- package/dist/agent-prompt-delivery.js +0 -1
- package/dist/agent-tracker.js +0 -1
- package/dist/agent-watcher.js +0 -1
- package/dist/alert-display.d.ts +21 -0
- package/dist/alert-display.js +85 -0
- package/dist/atomic-write.js +0 -1
- package/dist/attachment-store.d.ts +0 -7
- package/dist/attachment-store.js +2 -87
- package/dist/builtin-metadata-watchers.js +4 -5
- package/dist/claude-hooks.d.ts +1 -0
- package/dist/claude-hooks.js +25 -1
- package/dist/config.d.ts +19 -13
- package/dist/config.js +28 -15
- package/dist/connection-targets.d.ts +8 -0
- package/dist/connection-targets.js +27 -0
- package/dist/context/compactor.js +0 -1
- package/dist/context/context-bridge.js +0 -1
- package/dist/context/context-file.js +0 -1
- package/dist/context/history.js +0 -1
- package/dist/credentials.d.ts +12 -0
- package/dist/credentials.js +48 -0
- package/dist/daemon.d.ts +23 -0
- package/dist/daemon.js +391 -67
- package/dist/dashboard/command-spec.js +0 -1
- package/dist/dashboard/feedback.js +0 -1
- package/dist/dashboard/index.d.ts +13 -10
- package/dist/dashboard/index.js +3 -27
- package/dist/dashboard/operation-failures.js +0 -1
- package/dist/dashboard/order.d.ts +22 -0
- package/dist/dashboard/order.js +54 -0
- package/dist/dashboard/pending-actions.d.ts +39 -10
- package/dist/dashboard/pending-actions.js +166 -37
- package/dist/dashboard/quick-jump.d.ts +2 -1
- package/dist/dashboard/quick-jump.js +7 -5
- package/dist/dashboard/runtime-evidence.js +0 -1
- package/dist/dashboard/session-actions.d.ts +4 -4
- package/dist/dashboard/session-actions.js +1 -2
- package/dist/dashboard/session-registry.d.ts +4 -3
- package/dist/dashboard/session-registry.js +16 -51
- package/dist/dashboard/sort.js +0 -1
- package/dist/dashboard/state.d.ts +1 -1
- package/dist/dashboard/state.js +0 -1
- package/dist/dashboard/targets.js +0 -1
- package/dist/dashboard/ui-state-store.d.ts +16 -1
- package/dist/dashboard/ui-state-store.js +73 -3
- package/dist/debug-state.d.ts +97 -0
- package/dist/debug-state.js +540 -0
- package/dist/debug.d.ts +38 -0
- package/dist/debug.js +219 -16
- package/dist/default-plugins/gh-pr-context.d.ts +2 -1
- package/dist/default-plugins/gh-pr-context.js +17 -12
- package/dist/default-plugins/transcript-length.js +15 -3
- package/dist/fast-control.js +37 -20
- package/dist/hotkeys.js +0 -1
- package/dist/http-client.js +31 -3
- package/dist/key-parser.js +0 -1
- package/dist/last-used.js +0 -1
- package/dist/local-ui-server.d.ts +22 -0
- package/dist/local-ui-server.js +185 -0
- package/dist/login-flow.d.ts +7 -0
- package/dist/login-flow.js +119 -0
- package/dist/main.js +821 -152
- package/dist/managed-launch-env.js +14 -1
- package/dist/metadata-server.d.ts +36 -36
- package/dist/metadata-server.js +638 -138
- package/dist/metadata-store.d.ts +4 -1
- package/dist/metadata-store.js +30 -3
- package/dist/multiplexer/agent-io-methods.d.ts +2 -10
- package/dist/multiplexer/agent-io-methods.js +12 -44
- package/dist/multiplexer/archives.js +8 -10
- package/dist/multiplexer/dashboard-actions-methods.js +0 -1
- package/dist/multiplexer/dashboard-control.js +45 -14
- package/dist/multiplexer/dashboard-interaction.d.ts +8 -2
- package/dist/multiplexer/dashboard-interaction.js +187 -29
- package/dist/multiplexer/dashboard-model.d.ts +10 -3
- package/dist/multiplexer/dashboard-model.js +417 -36
- package/dist/multiplexer/dashboard-ops.d.ts +9 -7
- package/dist/multiplexer/dashboard-ops.js +178 -69
- package/dist/multiplexer/dashboard-state-methods.d.ts +2 -1
- package/dist/multiplexer/dashboard-state-methods.js +3 -3
- package/dist/multiplexer/dashboard-tail-methods.d.ts +22 -10
- package/dist/multiplexer/dashboard-tail-methods.js +164 -48
- package/dist/multiplexer/dashboard-view-methods.d.ts +1 -1
- package/dist/multiplexer/dashboard-view-methods.js +23 -9
- package/dist/multiplexer/graveyard-view-model.d.ts +9 -1
- package/dist/multiplexer/graveyard-view-model.js +39 -1
- package/dist/multiplexer/index.d.ts +15 -12
- package/dist/multiplexer/index.js +64 -44
- package/dist/multiplexer/navigation.js +0 -1
- package/dist/multiplexer/notifications.js +107 -25
- package/dist/multiplexer/persistence-methods.d.ts +31 -4
- package/dist/multiplexer/persistence-methods.js +304 -309
- package/dist/multiplexer/runtime-lifecycle-methods.d.ts +8 -10
- package/dist/multiplexer/runtime-lifecycle-methods.js +104 -87
- package/dist/multiplexer/runtime-state.d.ts +8 -10
- package/dist/multiplexer/runtime-state.js +82 -146
- package/dist/multiplexer/runtime-sync.d.ts +2 -10
- package/dist/multiplexer/runtime-sync.js +3 -19
- package/dist/multiplexer/service-state-snapshot.d.ts +2 -4
- package/dist/multiplexer/service-state-snapshot.js +4 -52
- package/dist/multiplexer/services.d.ts +1 -0
- package/dist/multiplexer/services.js +55 -6
- package/dist/multiplexer/session-capture.d.ts +1 -0
- package/dist/multiplexer/session-capture.js +23 -0
- package/dist/multiplexer/session-launch.d.ts +4 -1
- package/dist/multiplexer/session-launch.js +152 -64
- package/dist/multiplexer/session-runtime-core.d.ts +8 -20
- package/dist/multiplexer/session-runtime-core.js +40 -136
- package/dist/multiplexer/subscreens.js +10 -4
- package/dist/multiplexer/tool-picker.js +0 -1
- package/dist/multiplexer/worktree-graveyard.d.ts +0 -1
- package/dist/multiplexer/worktree-graveyard.js +15 -17
- package/dist/multiplexer/worktrees.js +96 -41
- package/dist/notification-context.js +8 -5
- package/dist/notifications.js +163 -102
- package/dist/notify.d.ts +4 -0
- package/dist/notify.js +14 -1
- package/dist/orchestration-actions.js +0 -1
- package/dist/orchestration-routing.js +0 -1
- package/dist/orchestration.js +0 -1
- package/dist/osc-notifications.js +0 -1
- package/dist/paths.d.ts +32 -7
- package/dist/paths.js +82 -59
- package/dist/pending-actions.d.ts +5 -0
- package/dist/pending-actions.js +13 -0
- package/dist/plugin-runtime.js +9 -3
- package/dist/project-events.d.ts +1 -10
- package/dist/project-events.js +0 -11
- package/dist/project-scanner.d.ts +2 -3
- package/dist/project-scanner.js +58 -130
- package/dist/project-service-manifest.d.ts +1 -3
- package/dist/project-service-manifest.js +1 -4
- package/dist/recency.js +0 -1
- package/dist/recorder.js +0 -1
- package/dist/relay-client.d.ts +30 -0
- package/dist/relay-client.js +190 -0
- package/dist/remote-access.d.ts +16 -0
- package/dist/remote-access.js +90 -0
- package/dist/runtime-core/exchange-derived.d.ts +2 -0
- package/dist/runtime-core/exchange-derived.js +153 -0
- package/dist/runtime-core/exchange-import.d.ts +24 -0
- package/dist/runtime-core/exchange-import.js +317 -0
- package/dist/runtime-core/exchange-store.d.ts +157 -0
- package/dist/runtime-core/exchange-store.js +452 -0
- package/dist/runtime-core/topology-services.d.ts +38 -0
- package/dist/runtime-core/topology-services.js +170 -0
- package/dist/runtime-core/topology-sessions.d.ts +52 -0
- package/dist/runtime-core/topology-sessions.js +238 -0
- package/dist/runtime-core/topology-store.d.ts +171 -0
- package/dist/runtime-core/topology-store.js +419 -0
- package/dist/runtime-core/topology-worktrees.d.ts +60 -0
- package/dist/runtime-core/topology-worktrees.js +199 -0
- package/dist/runtime-migration.d.ts +69 -0
- package/dist/runtime-migration.js +398 -0
- package/dist/session-bootstrap.d.ts +8 -6
- package/dist/session-bootstrap.js +51 -159
- package/dist/session-runtime.d.ts +2 -0
- package/dist/session-runtime.js +1 -1
- package/dist/session-semantics.d.ts +12 -4
- package/dist/session-semantics.js +14 -1
- package/dist/shell-args.js +0 -1
- package/dist/shell-hooks.js +32 -11
- package/dist/shell-state.d.ts +2 -0
- package/dist/shell-state.js +26 -2
- package/dist/status-detector.js +0 -1
- package/dist/statusline-model.d.ts +10 -2
- package/dist/statusline-model.js +106 -31
- package/dist/task-workflow.d.ts +6 -9
- package/dist/task-workflow.js +37 -85
- package/dist/tasks.d.ts +6 -33
- package/dist/tasks.js +46 -89
- package/dist/team.d.ts +29 -0
- package/dist/team.js +40 -1
- package/dist/terminal-host.js +0 -1
- package/dist/threads.d.ts +6 -35
- package/dist/threads.js +89 -99
- package/dist/tmux/doctor.js +0 -1
- package/dist/tmux/inbox-popup.js +37 -16
- package/dist/tmux/runtime-manager.d.ts +3 -0
- package/dist/tmux/runtime-manager.js +21 -5
- package/dist/tmux/session-transport.js +0 -1
- package/dist/tmux/statusline-cache.js +0 -1
- package/dist/tmux/statusline.js +49 -10
- package/dist/tmux/switcher.js +0 -1
- package/dist/tmux/window-open.js +1 -3
- package/dist/tool-output-watchers.d.ts +0 -18
- package/dist/tool-output-watchers.js +0 -323
- package/dist/tui/render/box.js +0 -1
- package/dist/tui/render/text.js +0 -1
- package/dist/tui/screens/dashboard-renderers.js +37 -26
- package/dist/tui/screens/overlay-renderers.d.ts +2 -0
- package/dist/tui/screens/overlay-renderers.js +37 -2
- package/dist/tui/screens/subscreen-renderers.js +7 -1
- package/dist/workflow.js +0 -1
- package/dist/worktree.js +17 -1
- package/dist-ui/_expo/static/css/web-30453ede1678c16acb08b97e83e8646d.css +1 -0
- package/dist-ui/_expo/static/js/web/entry-477c745b2adc79367a4380ecf07d9ff6.js +14620 -0
- package/dist-ui/assets/assets/images/icon.a5413dcd2e811c9f2317d01a28118d8a.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
- package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
- package/dist-ui/assets/node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
- package/dist-ui/assets/node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
- package/dist-ui/assets/node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
- package/dist-ui/assets/node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
- package/dist-ui/assets/node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
- package/dist-ui/assets/node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
- package/dist-ui/assets/node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
- package/dist-ui/favicon.ico +0 -0
- package/dist-ui/index.html +38 -0
- package/dist-ui/metadata.json +1 -0
- package/package.json +29 -12
- package/dist/agent-events.js.map +0 -1
- package/dist/agent-message-parts.d.ts +0 -17
- package/dist/agent-message-parts.js +0 -31
- package/dist/agent-message-parts.js.map +0 -1
- package/dist/agent-output-parser.js.map +0 -1
- package/dist/agent-prompt-delivery.js.map +0 -1
- package/dist/agent-tracker.js.map +0 -1
- package/dist/agent-watcher.js.map +0 -1
- package/dist/atomic-write.js.map +0 -1
- package/dist/attachment-store.js.map +0 -1
- package/dist/builtin-metadata-watchers.js.map +0 -1
- package/dist/claude-hooks.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/context/compactor.js.map +0 -1
- package/dist/context/context-bridge.js.map +0 -1
- package/dist/context/context-file.js.map +0 -1
- package/dist/context/history.js.map +0 -1
- package/dist/daemon.js.map +0 -1
- package/dist/dashboard/command-spec.js.map +0 -1
- package/dist/dashboard/feedback.js.map +0 -1
- package/dist/dashboard/index.js.map +0 -1
- package/dist/dashboard/operation-failures.js.map +0 -1
- package/dist/dashboard/pending-actions.js.map +0 -1
- package/dist/dashboard/quick-jump.js.map +0 -1
- package/dist/dashboard/runtime-evidence.js.map +0 -1
- package/dist/dashboard/session-actions.js.map +0 -1
- package/dist/dashboard/session-registry.js.map +0 -1
- package/dist/dashboard/sort.js.map +0 -1
- package/dist/dashboard/state.js.map +0 -1
- package/dist/dashboard/targets.js.map +0 -1
- package/dist/dashboard/ui-state-store.js.map +0 -1
- package/dist/debug.js.map +0 -1
- package/dist/default-plugins/gh-pr-context.js.map +0 -1
- package/dist/default-plugins/transcript-length.js.map +0 -1
- package/dist/fast-control.js.map +0 -1
- package/dist/hotkeys.js.map +0 -1
- package/dist/http-client.js.map +0 -1
- package/dist/instance-directory.d.ts +0 -32
- package/dist/instance-directory.js +0 -82
- package/dist/instance-directory.js.map +0 -1
- package/dist/instance-registry.d.ts +0 -39
- package/dist/instance-registry.js +0 -208
- package/dist/instance-registry.js.map +0 -1
- package/dist/key-parser.js.map +0 -1
- package/dist/last-used.js.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/managed-launch-env.js.map +0 -1
- package/dist/metadata-server.js.map +0 -1
- package/dist/metadata-store.js.map +0 -1
- package/dist/multiplexer/agent-io-methods.js.map +0 -1
- package/dist/multiplexer/archives.js.map +0 -1
- package/dist/multiplexer/dashboard-actions-methods.js.map +0 -1
- package/dist/multiplexer/dashboard-control.js.map +0 -1
- package/dist/multiplexer/dashboard-interaction.js.map +0 -1
- package/dist/multiplexer/dashboard-model.js.map +0 -1
- package/dist/multiplexer/dashboard-ops.js.map +0 -1
- package/dist/multiplexer/dashboard-state-methods.js.map +0 -1
- package/dist/multiplexer/dashboard-tail-methods.js.map +0 -1
- package/dist/multiplexer/dashboard-view-methods.js.map +0 -1
- package/dist/multiplexer/graveyard-view-model.js.map +0 -1
- package/dist/multiplexer/index.js.map +0 -1
- package/dist/multiplexer/navigation.js.map +0 -1
- package/dist/multiplexer/notifications.js.map +0 -1
- package/dist/multiplexer/persistence-methods.js.map +0 -1
- package/dist/multiplexer/runtime-lifecycle-methods.js.map +0 -1
- package/dist/multiplexer/runtime-state.js.map +0 -1
- package/dist/multiplexer/runtime-sync.js.map +0 -1
- package/dist/multiplexer/service-state-snapshot.js.map +0 -1
- package/dist/multiplexer/services.js.map +0 -1
- package/dist/multiplexer/session-actions.d.ts +0 -40
- package/dist/multiplexer/session-actions.js +0 -110
- package/dist/multiplexer/session-actions.js.map +0 -1
- package/dist/multiplexer/session-launch.js.map +0 -1
- package/dist/multiplexer/session-runtime-core.js.map +0 -1
- package/dist/multiplexer/subscreens.js.map +0 -1
- package/dist/multiplexer/tool-picker.js.map +0 -1
- package/dist/multiplexer/worktree-graveyard.js.map +0 -1
- package/dist/multiplexer/worktrees.js.map +0 -1
- package/dist/notification-context.js.map +0 -1
- package/dist/notifications.js.map +0 -1
- package/dist/notify.js.map +0 -1
- package/dist/orchestration-actions.js.map +0 -1
- package/dist/orchestration-dispatcher.d.ts +0 -25
- package/dist/orchestration-dispatcher.js +0 -59
- package/dist/orchestration-dispatcher.js.map +0 -1
- package/dist/orchestration-routing.js.map +0 -1
- package/dist/orchestration.js.map +0 -1
- package/dist/osc-notifications.js.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/plugin-runtime.js.map +0 -1
- package/dist/project-events.js.map +0 -1
- package/dist/project-scanner.js.map +0 -1
- package/dist/project-service-manifest.js.map +0 -1
- package/dist/recency.js.map +0 -1
- package/dist/recorder.js.map +0 -1
- package/dist/session-bootstrap.js.map +0 -1
- package/dist/session-input-operations.d.ts +0 -19
- package/dist/session-input-operations.js +0 -46
- package/dist/session-input-operations.js.map +0 -1
- package/dist/session-message-history.d.ts +0 -27
- package/dist/session-message-history.js +0 -105
- package/dist/session-message-history.js.map +0 -1
- package/dist/session-runtime.js.map +0 -1
- package/dist/session-semantics.js.map +0 -1
- package/dist/shell-args.js.map +0 -1
- package/dist/shell-hooks.js.map +0 -1
- package/dist/shell-state.js.map +0 -1
- package/dist/status-detector.js.map +0 -1
- package/dist/statusline-model.js.map +0 -1
- package/dist/task-dispatcher.d.ts +0 -64
- package/dist/task-dispatcher.js +0 -213
- package/dist/task-dispatcher.js.map +0 -1
- package/dist/task-workflow.js.map +0 -1
- package/dist/tasks.js.map +0 -1
- package/dist/team.js.map +0 -1
- package/dist/terminal-host.js.map +0 -1
- package/dist/threads.js.map +0 -1
- package/dist/tmux/doctor.js.map +0 -1
- package/dist/tmux/inbox-popup.js.map +0 -1
- package/dist/tmux/runtime-manager.js.map +0 -1
- package/dist/tmux/session-transport.js.map +0 -1
- package/dist/tmux/statusline-cache.js.map +0 -1
- package/dist/tmux/statusline.js.map +0 -1
- package/dist/tmux/switcher.js.map +0 -1
- package/dist/tmux/window-open.js.map +0 -1
- package/dist/tool-output-watchers.js.map +0 -1
- package/dist/tui/render/box.js.map +0 -1
- package/dist/tui/render/text.js.map +0 -1
- package/dist/tui/screens/dashboard-renderers.js.map +0 -1
- package/dist/tui/screens/overlay-renderers.js.map +0 -1
- package/dist/tui/screens/subscreen-renderers.js.map +0 -1
- package/dist/workflow.js.map +0 -1
- package/dist/worktree.js.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { SessionStatus } from "../status-detector.js";
|
|
2
1
|
import type { AgentActivityState, AgentAttentionState, AgentEvent } from "../agent-events.js";
|
|
3
2
|
import type { SessionServiceMetadata } from "../metadata-store.js";
|
|
4
|
-
import type {
|
|
3
|
+
import type { PendingDashboardActionKind, PendingWorktreeActionKind } from "../pending-actions.js";
|
|
4
|
+
import type { SessionPendingAction, SessionRawStatus, SessionSemanticState } from "../session-semantics.js";
|
|
5
|
+
import type { SessionTeamMetadata } from "../team.js";
|
|
5
6
|
import type { DashboardOperationFailure } from "./operation-failures.js";
|
|
6
|
-
export type DashboardSessionStatus =
|
|
7
|
+
export type DashboardSessionStatus = SessionRawStatus;
|
|
7
8
|
export interface DashboardSession {
|
|
8
9
|
index: number;
|
|
9
10
|
id: string;
|
|
@@ -13,15 +14,12 @@ export interface DashboardSession {
|
|
|
13
14
|
lastUsedAt?: string;
|
|
14
15
|
createdAt?: string;
|
|
15
16
|
backendSessionId?: string;
|
|
17
|
+
team?: SessionTeamMetadata;
|
|
16
18
|
status: DashboardSessionStatus;
|
|
17
19
|
active: boolean;
|
|
18
20
|
worktreePath?: string;
|
|
19
21
|
worktreeName?: string;
|
|
20
22
|
worktreeBranch?: string;
|
|
21
|
-
/** If set, this session belongs to another aimux instance */
|
|
22
|
-
remoteInstancePid?: number;
|
|
23
|
-
remoteInstanceId?: string;
|
|
24
|
-
remoteBackendSessionId?: string;
|
|
25
23
|
/** Active task description assigned to this session */
|
|
26
24
|
taskDescription?: string;
|
|
27
25
|
/** Auto-derived or user-set label for offline agents */
|
|
@@ -60,7 +58,8 @@ export interface DashboardSession {
|
|
|
60
58
|
notificationUnreadCount?: number;
|
|
61
59
|
latestNotificationText?: string;
|
|
62
60
|
semantic?: SessionSemanticState;
|
|
63
|
-
pendingAction?:
|
|
61
|
+
pendingAction?: SessionPendingAction;
|
|
62
|
+
pending?: boolean;
|
|
64
63
|
optimistic?: boolean;
|
|
65
64
|
}
|
|
66
65
|
export interface DashboardService {
|
|
@@ -79,9 +78,12 @@ export interface DashboardService {
|
|
|
79
78
|
label?: string;
|
|
80
79
|
cwd?: string;
|
|
81
80
|
foregroundCommand?: string;
|
|
81
|
+
shellCommand?: string;
|
|
82
|
+
shellCommandState?: "running" | "prompt";
|
|
82
83
|
pid?: number;
|
|
83
84
|
previewLine?: string;
|
|
84
|
-
pendingAction?:
|
|
85
|
+
pendingAction?: PendingDashboardActionKind;
|
|
86
|
+
pending?: boolean;
|
|
85
87
|
optimistic?: boolean;
|
|
86
88
|
}
|
|
87
89
|
export type DashboardWorktreeEntry = {
|
|
@@ -99,7 +101,7 @@ export interface WorktreeGroup {
|
|
|
99
101
|
status: "active" | "offline";
|
|
100
102
|
pending?: boolean;
|
|
101
103
|
removing?: boolean;
|
|
102
|
-
pendingAction?:
|
|
104
|
+
pendingAction?: PendingWorktreeActionKind;
|
|
103
105
|
operationFailure?: DashboardOperationFailure;
|
|
104
106
|
optimistic?: boolean;
|
|
105
107
|
sessions: DashboardSession[];
|
|
@@ -124,6 +126,7 @@ export interface DashboardViewModel {
|
|
|
124
126
|
navLevel: "worktrees" | "sessions";
|
|
125
127
|
selectedSessionId?: string;
|
|
126
128
|
selectedServiceId?: string;
|
|
129
|
+
selectedTeammates: DashboardSession[];
|
|
127
130
|
runtimeLabel?: string;
|
|
128
131
|
mainCheckout: MainCheckoutInfo;
|
|
129
132
|
worktreeRemoval?: DashboardWorktreeRemovalInfo;
|
package/dist/dashboard/index.js
CHANGED
|
@@ -1,31 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sessionDisplayStatusLabel } from "../session-semantics.js";
|
|
2
2
|
import { renderDashboardFrame } from "../tui/screens/dashboard-renderers.js";
|
|
3
|
-
const STATUS_LABELS = {
|
|
4
|
-
running: "running",
|
|
5
|
-
idle: "idle",
|
|
6
|
-
waiting: "thinking",
|
|
7
|
-
exited: "exited",
|
|
8
|
-
offline: "offline",
|
|
9
|
-
};
|
|
10
3
|
export function derivedStatusLabel(session) {
|
|
11
|
-
|
|
12
|
-
return "creating";
|
|
13
|
-
if (session.pendingAction === "forking")
|
|
14
|
-
return "forking";
|
|
15
|
-
if (session.pendingAction === "migrating")
|
|
16
|
-
return "migrating";
|
|
17
|
-
if (session.pendingAction === "starting")
|
|
18
|
-
return "starting";
|
|
19
|
-
if (session.pendingAction === "stopping")
|
|
20
|
-
return "stopping";
|
|
21
|
-
if (session.pendingAction === "graveyarding")
|
|
22
|
-
return "graveyarding";
|
|
23
|
-
if (session.pendingAction === "renaming")
|
|
24
|
-
return "renaming";
|
|
25
|
-
if (session.semantic) {
|
|
26
|
-
return sessionSemanticStatusLabel(session.semantic, session.status);
|
|
27
|
-
}
|
|
28
|
-
return STATUS_LABELS[session.status];
|
|
4
|
+
return sessionDisplayStatusLabel(session);
|
|
29
5
|
}
|
|
30
6
|
export class Dashboard {
|
|
31
7
|
viewModel = {
|
|
@@ -37,6 +13,7 @@ export class Dashboard {
|
|
|
37
13
|
navLevel: "sessions",
|
|
38
14
|
selectedSessionId: undefined,
|
|
39
15
|
selectedServiceId: undefined,
|
|
16
|
+
selectedTeammates: [],
|
|
40
17
|
runtimeLabel: undefined,
|
|
41
18
|
mainCheckout: { name: "Main Checkout", branch: "" },
|
|
42
19
|
worktreeRemoval: undefined,
|
|
@@ -69,4 +46,3 @@ export class Dashboard {
|
|
|
69
46
|
this.viewModel.detailsPaneVisible = this.detailsPaneVisible;
|
|
70
47
|
}
|
|
71
48
|
}
|
|
72
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { DashboardService, DashboardSession, WorktreeGroup } from "./index.js";
|
|
2
|
+
export declare const MAIN_CHECKOUT_ORDER_KEY = "__main__";
|
|
3
|
+
export interface DashboardOrderState {
|
|
4
|
+
agentOrderByWorktreeKey: Record<string, string[]>;
|
|
5
|
+
serviceOrderByWorktreeKey: Record<string, string[]>;
|
|
6
|
+
}
|
|
7
|
+
export type DashboardOrderKind = "session" | "service";
|
|
8
|
+
export type DashboardOrderDirection = "up" | "down";
|
|
9
|
+
export declare function dashboardOrderKey(worktreePath: string | undefined): string;
|
|
10
|
+
export declare function normalizeDashboardOrder(currentIds: string[], savedOrder: string[] | undefined): string[];
|
|
11
|
+
export declare function applyDashboardOrder<T extends {
|
|
12
|
+
id: string;
|
|
13
|
+
}>(items: T[], savedOrder: string[] | undefined): T[];
|
|
14
|
+
export declare function moveDashboardOrder<T extends {
|
|
15
|
+
id: string;
|
|
16
|
+
}>(items: T[], savedOrder: string[] | undefined, selectedId: string, direction: DashboardOrderDirection): {
|
|
17
|
+
moved: boolean;
|
|
18
|
+
order: string[];
|
|
19
|
+
};
|
|
20
|
+
export declare function orderDashboardWorktreeGroups(groups: WorktreeGroup[], orderState: DashboardOrderState): WorktreeGroup[];
|
|
21
|
+
export declare function orderDashboardSessionsForWorktree(sessions: DashboardSession[], worktreePath: string | undefined, orderState: DashboardOrderState): DashboardSession[];
|
|
22
|
+
export declare function orderDashboardServicesForWorktree(services: DashboardService[], worktreePath: string | undefined, orderState: DashboardOrderState): DashboardService[];
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const MAIN_CHECKOUT_ORDER_KEY = "__main__";
|
|
2
|
+
export function dashboardOrderKey(worktreePath) {
|
|
3
|
+
return worktreePath ?? MAIN_CHECKOUT_ORDER_KEY;
|
|
4
|
+
}
|
|
5
|
+
export function normalizeDashboardOrder(currentIds, savedOrder) {
|
|
6
|
+
const current = new Set(currentIds);
|
|
7
|
+
const normalized = [];
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
for (const id of savedOrder ?? []) {
|
|
10
|
+
if (!current.has(id) || seen.has(id))
|
|
11
|
+
continue;
|
|
12
|
+
normalized.push(id);
|
|
13
|
+
seen.add(id);
|
|
14
|
+
}
|
|
15
|
+
for (const id of currentIds) {
|
|
16
|
+
if (seen.has(id))
|
|
17
|
+
continue;
|
|
18
|
+
normalized.push(id);
|
|
19
|
+
seen.add(id);
|
|
20
|
+
}
|
|
21
|
+
return normalized;
|
|
22
|
+
}
|
|
23
|
+
export function applyDashboardOrder(items, savedOrder) {
|
|
24
|
+
const order = normalizeDashboardOrder(items.map((item) => item.id), savedOrder);
|
|
25
|
+
const byId = new Map(items.map((item) => [item.id, item]));
|
|
26
|
+
return order.map((id) => byId.get(id)).filter((item) => Boolean(item));
|
|
27
|
+
}
|
|
28
|
+
export function moveDashboardOrder(items, savedOrder, selectedId, direction) {
|
|
29
|
+
const order = normalizeDashboardOrder(items.map((item) => item.id), savedOrder);
|
|
30
|
+
const index = order.indexOf(selectedId);
|
|
31
|
+
if (index < 0)
|
|
32
|
+
return { moved: false, order };
|
|
33
|
+
const nextIndex = direction === "up" ? index - 1 : index + 1;
|
|
34
|
+
if (nextIndex < 0 || nextIndex >= order.length)
|
|
35
|
+
return { moved: false, order };
|
|
36
|
+
[order[index], order[nextIndex]] = [order[nextIndex], order[index]];
|
|
37
|
+
return { moved: true, order };
|
|
38
|
+
}
|
|
39
|
+
export function orderDashboardWorktreeGroups(groups, orderState) {
|
|
40
|
+
return groups.map((group) => {
|
|
41
|
+
const key = dashboardOrderKey(group.path);
|
|
42
|
+
return {
|
|
43
|
+
...group,
|
|
44
|
+
sessions: applyDashboardOrder(group.sessions, orderState.agentOrderByWorktreeKey[key]),
|
|
45
|
+
services: applyDashboardOrder(group.services, orderState.serviceOrderByWorktreeKey[key]),
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
export function orderDashboardSessionsForWorktree(sessions, worktreePath, orderState) {
|
|
50
|
+
return applyDashboardOrder(sessions, orderState.agentOrderByWorktreeKey[dashboardOrderKey(worktreePath)]);
|
|
51
|
+
}
|
|
52
|
+
export function orderDashboardServicesForWorktree(services, worktreePath, orderState) {
|
|
53
|
+
return applyDashboardOrder(services, orderState.serviceOrderByWorktreeKey[dashboardOrderKey(worktreePath)]);
|
|
54
|
+
}
|
|
@@ -1,24 +1,53 @@
|
|
|
1
1
|
import type { DashboardService, DashboardSession, WorktreeGroup } from "./index.js";
|
|
2
|
-
|
|
2
|
+
import type { PendingServiceActionKind, PendingSessionActionKind, PendingWorktreeActionKind } from "../pending-actions.js";
|
|
3
|
+
type PendingActionTarget = "session" | "service" | "worktree";
|
|
4
|
+
interface PendingActionOptions {
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
onTimeout?: () => void;
|
|
7
|
+
}
|
|
8
|
+
interface PendingSessionActionOptions extends PendingActionOptions {
|
|
9
|
+
sessionSeed?: DashboardSession;
|
|
10
|
+
}
|
|
11
|
+
interface PendingServiceActionOptions extends PendingActionOptions {
|
|
12
|
+
serviceSeed?: DashboardService;
|
|
13
|
+
}
|
|
14
|
+
interface PendingWorktreeActionOptions extends PendingActionOptions {
|
|
15
|
+
worktreeSeed?: WorktreeGroup;
|
|
16
|
+
}
|
|
17
|
+
interface ApplyPendingSessionOptions {
|
|
18
|
+
includeTeammates?: boolean;
|
|
19
|
+
}
|
|
3
20
|
export declare class DashboardPendingActions {
|
|
4
21
|
private readonly onChange;
|
|
5
22
|
private actions;
|
|
6
23
|
private version;
|
|
24
|
+
private nextEntryToken;
|
|
7
25
|
constructor(onChange: () => void);
|
|
8
26
|
static worktreeKey(path?: string): string;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
27
|
+
private static actionKey;
|
|
28
|
+
setSessionAction(sessionId: string, kind: PendingSessionActionKind, opts?: PendingSessionActionOptions): number;
|
|
29
|
+
clearSessionAction(sessionId: string): void;
|
|
30
|
+
clearSessionActionIfToken(sessionId: string, token: number): boolean;
|
|
31
|
+
setServiceAction(serviceId: string, kind: PendingServiceActionKind, opts?: PendingServiceActionOptions): number;
|
|
32
|
+
clearServiceAction(serviceId: string): void;
|
|
33
|
+
clearServiceActionIfToken(serviceId: string, token: number): boolean;
|
|
34
|
+
clearWorktreeActionIfToken(path: string | undefined, token: number): boolean;
|
|
35
|
+
setWorktreeAction(path: string | undefined, kind: PendingWorktreeActionKind, opts?: PendingWorktreeActionOptions): number;
|
|
36
|
+
clearWorktreeAction(path: string | undefined): void;
|
|
37
|
+
getSessionAction(sessionId: string): PendingSessionActionKind | undefined;
|
|
38
|
+
getServiceAction(serviceId: string): PendingServiceActionKind | undefined;
|
|
39
|
+
getWorktreeAction(path: string | undefined): PendingWorktreeActionKind | undefined;
|
|
40
|
+
private setEntry;
|
|
41
|
+
private clearEntry;
|
|
42
|
+
private clearEntryIfToken;
|
|
16
43
|
getVersion(): number;
|
|
17
|
-
applyToSessions(sessions: DashboardSession[]): DashboardSession[];
|
|
44
|
+
applyToSessions(sessions: DashboardSession[], opts?: ApplyPendingSessionOptions): DashboardSession[];
|
|
18
45
|
applyToServices(services: DashboardService[]): DashboardService[];
|
|
19
46
|
applyToWorktrees(worktrees: WorktreeGroup[]): WorktreeGroup[];
|
|
20
|
-
settleCreatePending(itemId: string, onSettled: () => void, opts?: {
|
|
47
|
+
settleCreatePending(target: PendingActionTarget, itemId: string, onSettled: () => void, opts?: {
|
|
21
48
|
isSettled?: () => boolean | Promise<boolean>;
|
|
22
49
|
timeoutMs?: number;
|
|
50
|
+
expectedToken?: number;
|
|
23
51
|
}): void;
|
|
24
52
|
}
|
|
53
|
+
export {};
|
|
@@ -1,76 +1,178 @@
|
|
|
1
|
+
function isTeammateSessionSeed(session) {
|
|
2
|
+
return Boolean(session?.team?.parentSessionId);
|
|
3
|
+
}
|
|
4
|
+
function visibleEntryKey(entry) {
|
|
5
|
+
if (!entry)
|
|
6
|
+
return "";
|
|
7
|
+
return JSON.stringify({
|
|
8
|
+
target: entry.target,
|
|
9
|
+
kind: entry.kind,
|
|
10
|
+
sessionSeed: entry.sessionSeed,
|
|
11
|
+
serviceSeed: entry.serviceSeed,
|
|
12
|
+
worktreeSeed: entry.worktreeSeed,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
1
15
|
function canSynthesizeMissingSession(kind) {
|
|
2
|
-
return
|
|
16
|
+
return kind === "creating" || kind === "forking";
|
|
3
17
|
}
|
|
4
18
|
function canSynthesizeMissingService(kind) {
|
|
5
19
|
return kind === "creating" || kind === "starting" || kind === "stopping";
|
|
6
20
|
}
|
|
21
|
+
function canSynthesizeMissingWorktree(kind) {
|
|
22
|
+
return kind === "creating";
|
|
23
|
+
}
|
|
7
24
|
export class DashboardPendingActions {
|
|
8
25
|
onChange;
|
|
9
26
|
actions = new Map();
|
|
10
27
|
version = 0;
|
|
28
|
+
nextEntryToken = 0;
|
|
11
29
|
constructor(onChange) {
|
|
12
30
|
this.onChange = onChange;
|
|
13
31
|
}
|
|
14
32
|
static worktreeKey(path) {
|
|
15
33
|
return `worktree:${path ?? "__main__"}`;
|
|
16
34
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
35
|
+
static actionKey(target, id) {
|
|
36
|
+
return `${target}:${id}`;
|
|
37
|
+
}
|
|
38
|
+
setSessionAction(sessionId, kind, opts) {
|
|
39
|
+
return this.setEntry("session", sessionId, kind, opts);
|
|
40
|
+
}
|
|
41
|
+
clearSessionAction(sessionId) {
|
|
42
|
+
this.clearEntry("session", sessionId);
|
|
43
|
+
}
|
|
44
|
+
clearSessionActionIfToken(sessionId, token) {
|
|
45
|
+
return this.clearEntryIfToken("session", sessionId, token);
|
|
46
|
+
}
|
|
47
|
+
setServiceAction(serviceId, kind, opts) {
|
|
48
|
+
return this.setEntry("service", serviceId, kind, opts);
|
|
49
|
+
}
|
|
50
|
+
clearServiceAction(serviceId) {
|
|
51
|
+
this.clearEntry("service", serviceId);
|
|
52
|
+
}
|
|
53
|
+
clearServiceActionIfToken(serviceId, token) {
|
|
54
|
+
return this.clearEntryIfToken("service", serviceId, token);
|
|
55
|
+
}
|
|
56
|
+
clearWorktreeActionIfToken(path, token) {
|
|
57
|
+
return this.clearEntryIfToken("worktree", DashboardPendingActions.worktreeKey(path), token);
|
|
58
|
+
}
|
|
59
|
+
setWorktreeAction(path, kind, opts) {
|
|
60
|
+
return this.setEntry("worktree", DashboardPendingActions.worktreeKey(path), kind, opts);
|
|
61
|
+
}
|
|
62
|
+
clearWorktreeAction(path) {
|
|
63
|
+
this.clearEntry("worktree", DashboardPendingActions.worktreeKey(path));
|
|
64
|
+
}
|
|
65
|
+
getSessionAction(sessionId) {
|
|
66
|
+
const entry = this.actions.get(DashboardPendingActions.actionKey("session", sessionId));
|
|
67
|
+
return entry?.target === "session" ? entry.kind : undefined;
|
|
68
|
+
}
|
|
69
|
+
getServiceAction(serviceId) {
|
|
70
|
+
const entry = this.actions.get(DashboardPendingActions.actionKey("service", serviceId));
|
|
71
|
+
return entry?.target === "service" ? entry.kind : undefined;
|
|
72
|
+
}
|
|
73
|
+
getWorktreeAction(path) {
|
|
74
|
+
const entry = this.actions.get(DashboardPendingActions.actionKey("worktree", DashboardPendingActions.worktreeKey(path)));
|
|
75
|
+
return entry?.target === "worktree" ? entry.kind : undefined;
|
|
76
|
+
}
|
|
77
|
+
setEntry(target, id, kind, opts) {
|
|
78
|
+
const key = DashboardPendingActions.actionKey(target, id);
|
|
79
|
+
const existing = this.actions.get(key);
|
|
80
|
+
const previousVisibleKey = visibleEntryKey(existing);
|
|
20
81
|
if (existing?.timeoutId) {
|
|
21
82
|
clearTimeout(existing.timeoutId);
|
|
22
83
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
84
|
+
const token = ++this.nextEntryToken;
|
|
85
|
+
let timeoutId;
|
|
86
|
+
if (opts?.timeoutMs && opts.timeoutMs > 0) {
|
|
87
|
+
timeoutId = setTimeout(() => {
|
|
88
|
+
const current = this.actions.get(key);
|
|
89
|
+
if (current?.target !== target || current.kind !== kind || current.token !== token)
|
|
90
|
+
return;
|
|
91
|
+
this.actions.delete(key);
|
|
92
|
+
this.version += 1;
|
|
93
|
+
try {
|
|
31
94
|
opts.onTimeout?.();
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
32
97
|
this.onChange();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
this.actions.set(sessionId, { kind, timeoutId, sessionSeed: opts?.sessionSeed, serviceSeed: opts?.serviceSeed });
|
|
98
|
+
}
|
|
99
|
+
}, opts.timeoutMs);
|
|
36
100
|
}
|
|
37
|
-
|
|
38
|
-
|
|
101
|
+
this.actions.set(key, {
|
|
102
|
+
target,
|
|
103
|
+
kind,
|
|
104
|
+
token,
|
|
105
|
+
timeoutId,
|
|
106
|
+
sessionSeed: opts?.sessionSeed,
|
|
107
|
+
serviceSeed: opts?.serviceSeed,
|
|
108
|
+
worktreeSeed: opts?.worktreeSeed,
|
|
109
|
+
});
|
|
110
|
+
const changed = previousVisibleKey !== visibleEntryKey(this.actions.get(key));
|
|
111
|
+
if (changed) {
|
|
112
|
+
this.version += 1;
|
|
113
|
+
this.onChange();
|
|
114
|
+
}
|
|
115
|
+
return token;
|
|
116
|
+
}
|
|
117
|
+
clearEntry(target, id) {
|
|
118
|
+
const key = DashboardPendingActions.actionKey(target, id);
|
|
119
|
+
const existing = this.actions.get(key);
|
|
120
|
+
const previousVisibleKey = visibleEntryKey(existing);
|
|
121
|
+
if (existing?.timeoutId) {
|
|
122
|
+
clearTimeout(existing.timeoutId);
|
|
39
123
|
}
|
|
40
|
-
|
|
124
|
+
this.actions.delete(key);
|
|
125
|
+
const changed = previousVisibleKey !== visibleEntryKey(this.actions.get(key));
|
|
126
|
+
if (changed) {
|
|
41
127
|
this.version += 1;
|
|
128
|
+
this.onChange();
|
|
42
129
|
}
|
|
43
|
-
this.onChange();
|
|
44
130
|
}
|
|
45
|
-
|
|
46
|
-
|
|
131
|
+
clearEntryIfToken(target, id, token) {
|
|
132
|
+
const key = DashboardPendingActions.actionKey(target, id);
|
|
133
|
+
const existing = this.actions.get(key);
|
|
134
|
+
if (!existing || existing.target !== target || existing.token !== token)
|
|
135
|
+
return false;
|
|
136
|
+
this.clearEntry(target, id);
|
|
137
|
+
return true;
|
|
47
138
|
}
|
|
48
139
|
getVersion() {
|
|
49
140
|
return this.version;
|
|
50
141
|
}
|
|
51
|
-
applyToSessions(sessions) {
|
|
142
|
+
applyToSessions(sessions, opts = {}) {
|
|
52
143
|
if (this.actions.size === 0)
|
|
53
144
|
return sessions;
|
|
54
145
|
const seen = new Set();
|
|
55
146
|
const applied = sessions.map((session) => {
|
|
56
147
|
seen.add(session.id);
|
|
57
|
-
const pendingAction = this.
|
|
58
|
-
if (pendingAction === "removing")
|
|
59
|
-
return session;
|
|
148
|
+
const pendingAction = this.getSessionAction(session.id);
|
|
60
149
|
if (!pendingAction)
|
|
61
150
|
return session;
|
|
62
|
-
return {
|
|
151
|
+
return {
|
|
152
|
+
...session,
|
|
153
|
+
pending: true,
|
|
154
|
+
pendingAction,
|
|
155
|
+
optimistic: true,
|
|
156
|
+
};
|
|
63
157
|
});
|
|
64
|
-
for (const [
|
|
158
|
+
for (const [entryKey, entry] of this.actions.entries()) {
|
|
159
|
+
if (entry.target !== "session")
|
|
160
|
+
continue;
|
|
161
|
+
const sessionId = entryKey.slice("session:".length);
|
|
65
162
|
if (seen.has(sessionId))
|
|
66
163
|
continue;
|
|
67
164
|
if (!entry.sessionSeed)
|
|
68
165
|
continue;
|
|
166
|
+
if (isTeammateSessionSeed(entry.sessionSeed) && !opts.includeTeammates)
|
|
167
|
+
continue;
|
|
168
|
+
if (!isTeammateSessionSeed(entry.sessionSeed) && opts.includeTeammates)
|
|
169
|
+
continue;
|
|
69
170
|
if (!canSynthesizeMissingSession(entry.kind))
|
|
70
171
|
continue;
|
|
71
172
|
applied.push({
|
|
72
173
|
...entry.sessionSeed,
|
|
73
174
|
id: sessionId,
|
|
175
|
+
pending: true,
|
|
74
176
|
pendingAction: entry.kind,
|
|
75
177
|
optimistic: true,
|
|
76
178
|
});
|
|
@@ -83,14 +185,15 @@ export class DashboardPendingActions {
|
|
|
83
185
|
const seen = new Set();
|
|
84
186
|
const applied = services.map((service) => {
|
|
85
187
|
seen.add(service.id);
|
|
86
|
-
const pendingAction = this.
|
|
87
|
-
if (pendingAction === "removing")
|
|
88
|
-
return service;
|
|
188
|
+
const pendingAction = this.getServiceAction(service.id);
|
|
89
189
|
if (!pendingAction)
|
|
90
190
|
return service;
|
|
91
|
-
return { ...service, pendingAction, optimistic: true };
|
|
191
|
+
return { ...service, pending: true, pendingAction, optimistic: true };
|
|
92
192
|
});
|
|
93
|
-
for (const [
|
|
193
|
+
for (const [entryKey, entry] of this.actions.entries()) {
|
|
194
|
+
if (entry.target !== "service")
|
|
195
|
+
continue;
|
|
196
|
+
const serviceId = entryKey.slice("service:".length);
|
|
94
197
|
if (seen.has(serviceId))
|
|
95
198
|
continue;
|
|
96
199
|
if (!entry.serviceSeed)
|
|
@@ -100,6 +203,7 @@ export class DashboardPendingActions {
|
|
|
100
203
|
applied.push({
|
|
101
204
|
...entry.serviceSeed,
|
|
102
205
|
id: serviceId,
|
|
206
|
+
pending: true,
|
|
103
207
|
pendingAction: entry.kind,
|
|
104
208
|
optimistic: true,
|
|
105
209
|
});
|
|
@@ -109,8 +213,10 @@ export class DashboardPendingActions {
|
|
|
109
213
|
applyToWorktrees(worktrees) {
|
|
110
214
|
if (this.actions.size === 0)
|
|
111
215
|
return worktrees;
|
|
112
|
-
|
|
113
|
-
|
|
216
|
+
const seen = new Set();
|
|
217
|
+
const applied = worktrees.map((worktree) => {
|
|
218
|
+
seen.add(DashboardPendingActions.worktreeKey(worktree.path));
|
|
219
|
+
const pendingAction = this.getWorktreeAction(worktree.path);
|
|
114
220
|
if (!pendingAction)
|
|
115
221
|
return worktree;
|
|
116
222
|
return {
|
|
@@ -123,11 +229,30 @@ export class DashboardPendingActions {
|
|
|
123
229
|
optimistic: true,
|
|
124
230
|
};
|
|
125
231
|
});
|
|
232
|
+
for (const [entryKey, entry] of this.actions.entries()) {
|
|
233
|
+
if (entry.target !== "worktree")
|
|
234
|
+
continue;
|
|
235
|
+
const worktreeKey = entryKey.slice("worktree:".length);
|
|
236
|
+
if (seen.has(worktreeKey))
|
|
237
|
+
continue;
|
|
238
|
+
if (!entry.worktreeSeed)
|
|
239
|
+
continue;
|
|
240
|
+
if (!canSynthesizeMissingWorktree(entry.kind))
|
|
241
|
+
continue;
|
|
242
|
+
applied.push({
|
|
243
|
+
...entry.worktreeSeed,
|
|
244
|
+
pending: true,
|
|
245
|
+
pendingAction: entry.kind,
|
|
246
|
+
optimistic: true,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
return applied;
|
|
126
250
|
}
|
|
127
|
-
settleCreatePending(itemId, onSettled, opts) {
|
|
251
|
+
settleCreatePending(target, itemId, onSettled, opts) {
|
|
128
252
|
const minVisibleMs = 250;
|
|
129
253
|
const timeoutMs = opts?.timeoutMs ?? 10_000;
|
|
130
254
|
const startedAt = Date.now();
|
|
255
|
+
const expectedToken = opts?.expectedToken ?? this.actions.get(DashboardPendingActions.actionKey(target, itemId))?.token;
|
|
131
256
|
void (async () => {
|
|
132
257
|
const remaining = minVisibleMs - (Date.now() - startedAt);
|
|
133
258
|
if (remaining > 0) {
|
|
@@ -141,9 +266,13 @@ export class DashboardPendingActions {
|
|
|
141
266
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
142
267
|
}
|
|
143
268
|
}
|
|
144
|
-
this.
|
|
269
|
+
if (expectedToken !== undefined && !this.clearEntryIfToken(target, itemId, expectedToken)) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (expectedToken === undefined) {
|
|
273
|
+
this.clearEntry(target, itemId);
|
|
274
|
+
}
|
|
145
275
|
onSettled();
|
|
146
276
|
})();
|
|
147
277
|
}
|
|
148
278
|
}
|
|
149
|
-
//# sourceMappingURL=pending-actions.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DashboardService, DashboardSession, MainCheckoutInfo, WorktreeGroup } from "./index.js";
|
|
2
2
|
import type { DashboardOperationFailure } from "./operation-failures.js";
|
|
3
|
+
import type { PendingWorktreeActionKind } from "../pending-actions.js";
|
|
3
4
|
export declare const DASHBOARD_QUICK_JUMP_TIMEOUT_MS = 1000;
|
|
4
5
|
export declare const DASHBOARD_QUICK_JUMP_LIMIT = 9;
|
|
5
6
|
export interface DashboardQuickJumpEntry {
|
|
@@ -14,7 +15,7 @@ export interface DashboardQuickJumpWorktree {
|
|
|
14
15
|
branch: string;
|
|
15
16
|
pending?: boolean;
|
|
16
17
|
removing?: boolean;
|
|
17
|
-
pendingAction?:
|
|
18
|
+
pendingAction?: PendingWorktreeActionKind;
|
|
18
19
|
operationFailure?: DashboardOperationFailure;
|
|
19
20
|
sessions: DashboardSession[];
|
|
20
21
|
services: DashboardService[];
|
|
@@ -20,6 +20,9 @@ function buildEntryList(sessions, services) {
|
|
|
20
20
|
}
|
|
21
21
|
return entries;
|
|
22
22
|
}
|
|
23
|
+
function entriesForGroup(orderedGroupEntries, fallbackEntries) {
|
|
24
|
+
return orderedGroupEntries.length > 0 ? orderedGroupEntries : (fallbackEntries ?? []);
|
|
25
|
+
}
|
|
23
26
|
export function buildDashboardQuickJumpWorktrees(input) {
|
|
24
27
|
const wtSessionMap = new Map();
|
|
25
28
|
const wtServiceMap = new Map();
|
|
@@ -70,8 +73,8 @@ export function buildDashboardQuickJumpWorktrees(input) {
|
|
|
70
73
|
removing: mainGroup.removing,
|
|
71
74
|
pendingAction: mainGroup.pendingAction,
|
|
72
75
|
operationFailure: mainGroup.operationFailure,
|
|
73
|
-
sessions: sortDashboardEntriesByCreatedAt(mainSessions),
|
|
74
|
-
services: sortDashboardEntriesByCreatedAt(mainServices),
|
|
76
|
+
sessions: entriesForGroup(mainGroup.sessions, sortDashboardEntriesByCreatedAt(mainSessions)),
|
|
77
|
+
services: entriesForGroup(mainGroup.services, sortDashboardEntriesByCreatedAt(mainServices)),
|
|
75
78
|
});
|
|
76
79
|
}
|
|
77
80
|
else {
|
|
@@ -95,8 +98,8 @@ export function buildDashboardQuickJumpWorktrees(input) {
|
|
|
95
98
|
removing: group.removing,
|
|
96
99
|
pendingAction: group.pendingAction,
|
|
97
100
|
operationFailure: group.operationFailure,
|
|
98
|
-
sessions: wtSessionMap.get(group.path)
|
|
99
|
-
services: wtServiceMap.get(group.path)
|
|
101
|
+
sessions: entriesForGroup(group.sessions, wtSessionMap.get(group.path)),
|
|
102
|
+
services: entriesForGroup(group.services, wtServiceMap.get(group.path)),
|
|
100
103
|
});
|
|
101
104
|
renderedPaths.add(group.path);
|
|
102
105
|
}
|
|
@@ -140,4 +143,3 @@ export function resolveDashboardQuickJumpTarget(worktrees, digits) {
|
|
|
140
143
|
}
|
|
141
144
|
return { kind: "entry", worktree, entry: worktree.entries[entryIndex], entryIndex };
|
|
142
145
|
}
|
|
143
|
-
//# sourceMappingURL=quick-jump.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PendingSessionActionKind } from "../pending-actions.js";
|
|
2
2
|
import type { SessionRuntime } from "../session-runtime.js";
|
|
3
3
|
export interface DashboardOfflineEntryLike {
|
|
4
4
|
id: string;
|
|
@@ -7,9 +7,9 @@ export interface DashboardOfflineEntryLike {
|
|
|
7
7
|
}
|
|
8
8
|
interface DashboardActionDeps {
|
|
9
9
|
getSessionLabel(sessionId: string): string | undefined;
|
|
10
|
-
getPendingAction(sessionId: string):
|
|
11
|
-
setPendingAction(sessionId: string, kind:
|
|
12
|
-
stopSessionToOffline(session: SessionRuntime): void
|
|
10
|
+
getPendingAction(sessionId: string): PendingSessionActionKind | undefined;
|
|
11
|
+
setPendingAction(sessionId: string, kind: PendingSessionActionKind | null): void;
|
|
12
|
+
stopSessionToOffline(session: SessionRuntime): void | Promise<void>;
|
|
13
13
|
isGraveyardAfterStop(sessionId: string): boolean;
|
|
14
14
|
sendAgentToGraveyard(sessionId: string): Promise<void>;
|
|
15
15
|
resumeOfflineSession(session: DashboardOfflineEntryLike): void | Promise<void>;
|
|
@@ -24,7 +24,7 @@ export async function stopSessionToOfflineWithFeedback(deps, session) {
|
|
|
24
24
|
const label = deps.getSessionLabel(session.id) ?? session.command;
|
|
25
25
|
deps.setPendingAction(session.id, "stopping");
|
|
26
26
|
try {
|
|
27
|
-
deps.stopSessionToOffline(session);
|
|
27
|
+
await deps.stopSessionToOffline(session);
|
|
28
28
|
await waitForSessionExit(session);
|
|
29
29
|
if (!deps.isGraveyardAfterStop(session.id)) {
|
|
30
30
|
deps.setPendingAction(session.id, null);
|
|
@@ -81,4 +81,3 @@ export async function resumeOfflineSessionWithFeedback(deps, session) {
|
|
|
81
81
|
deps.renderDashboard();
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
//# sourceMappingURL=session-actions.js.map
|