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
|
@@ -8,12 +8,7 @@ import { SessionRuntime } from "../session-runtime.js";
|
|
|
8
8
|
import { TmuxSessionTransport } from "../tmux/session-transport.js";
|
|
9
9
|
import { loadMetadataState } from "../metadata-store.js";
|
|
10
10
|
import { parseAgentOutput } from "../agent-output-parser.js";
|
|
11
|
-
import { serializeAgentInput } from "../agent-message-parts.js";
|
|
12
|
-
import { resolveAttachmentPath } from "../attachment-store.js";
|
|
13
|
-
import { appendSessionMessage, readSessionMessages } from "../session-message-history.js";
|
|
14
|
-
import { createSessionInputOperation, saveSessionInputOperation, } from "../session-input-operations.js";
|
|
15
11
|
import { captureGitContext } from "../context/context-bridge.js";
|
|
16
|
-
import { normalizeSubmittedPrompt, paneStillContainsPromptDraft, scheduleTmuxPromptSubmit, } from "../agent-prompt-delivery.js";
|
|
17
12
|
export function getSessionLabel(host, sessionId) {
|
|
18
13
|
return (host.sessionLabels.get(sessionId) ?? host.offlineSessions.find((session) => session.id === sessionId)?.label);
|
|
19
14
|
}
|
|
@@ -99,9 +94,6 @@ export function readStatusHeadline(_host, sessionId) {
|
|
|
99
94
|
}
|
|
100
95
|
}
|
|
101
96
|
export function deriveHeadline(host, sessionId) {
|
|
102
|
-
const taskDescription = host.taskDispatcher?.getSessionTask(sessionId);
|
|
103
|
-
if (taskDescription)
|
|
104
|
-
return taskDescription.slice(0, 80);
|
|
105
97
|
const statusHeadline = readStatusHeadline(host, sessionId);
|
|
106
98
|
if (statusHeadline)
|
|
107
99
|
return statusHeadline;
|
|
@@ -153,124 +145,6 @@ export function resolveLiveSessionTmuxTarget(host, sessionId, fallback) {
|
|
|
153
145
|
catch { }
|
|
154
146
|
return undefined;
|
|
155
147
|
}
|
|
156
|
-
export function writeTmuxAgentInput(host, sessionId, transport, data) {
|
|
157
|
-
const target = resolveLiveSessionTmuxTarget(host, sessionId, transport.tmuxTarget);
|
|
158
|
-
if (!target) {
|
|
159
|
-
throw new Error(`Session "${sessionId}" does not have a live tmux target`);
|
|
160
|
-
}
|
|
161
|
-
transport.retarget(target);
|
|
162
|
-
let textBuffer = "";
|
|
163
|
-
const flushText = () => {
|
|
164
|
-
if (!textBuffer)
|
|
165
|
-
return;
|
|
166
|
-
host.tmuxRuntimeManager.sendText(target, textBuffer);
|
|
167
|
-
textBuffer = "";
|
|
168
|
-
};
|
|
169
|
-
for (const ch of data) {
|
|
170
|
-
if (ch === "\r") {
|
|
171
|
-
flushText();
|
|
172
|
-
host.tmuxRuntimeManager.sendEnter(target);
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
if (ch === "\n") {
|
|
176
|
-
flushText();
|
|
177
|
-
host.tmuxRuntimeManager.sendKey(target, "C-j");
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
textBuffer += ch;
|
|
181
|
-
}
|
|
182
|
-
flushText();
|
|
183
|
-
}
|
|
184
|
-
export function normalizeAgentInput(host, data, submit, sessionId) {
|
|
185
|
-
const tool = sessionId ? host.sessionToolKeys?.get(sessionId) : undefined;
|
|
186
|
-
return normalizeSubmittedPrompt(tool, data, submit);
|
|
187
|
-
}
|
|
188
|
-
export function paneStillContainsAgentDraft(host, target, draft) {
|
|
189
|
-
return paneStillContainsPromptDraft(host.tmuxRuntimeManager, target, draft);
|
|
190
|
-
}
|
|
191
|
-
export function scheduleTmuxAgentSubmit(host, sessionId, target, draft) {
|
|
192
|
-
const isTargetCurrent = () => {
|
|
193
|
-
const currentTarget = resolveLiveSessionTmuxTarget(host, sessionId);
|
|
194
|
-
return Boolean(currentTarget && currentTarget.windowId === target.windowId);
|
|
195
|
-
};
|
|
196
|
-
scheduleTmuxPromptSubmit({
|
|
197
|
-
tmuxRuntimeManager: host.tmuxRuntimeManager,
|
|
198
|
-
target,
|
|
199
|
-
draft,
|
|
200
|
-
isTargetCurrent,
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
export async function writeAgentInput(host, sessionId, data = "", parts, clientMessageId, submit = false) {
|
|
204
|
-
const session = resolveRunningSession(host, sessionId);
|
|
205
|
-
const serializedData = serializeAgentInput({ data, parts }, {
|
|
206
|
-
tool: host.sessionToolKeys.get(sessionId),
|
|
207
|
-
resolveAttachmentPath,
|
|
208
|
-
});
|
|
209
|
-
const normalizedData = normalizeAgentInput(host, serializedData, submit, sessionId);
|
|
210
|
-
if (!normalizedData && !submit) {
|
|
211
|
-
throw new Error("input data is required");
|
|
212
|
-
}
|
|
213
|
-
let operation = createSessionInputOperation({ sessionId, clientMessageId, submit });
|
|
214
|
-
try {
|
|
215
|
-
const message = appendSessionMessage(sessionId, { data, parts, clientMessageId });
|
|
216
|
-
if (message?.id) {
|
|
217
|
-
operation = saveSessionInputOperation({
|
|
218
|
-
...operation,
|
|
219
|
-
messageId: message.id,
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
if (session.transport instanceof TmuxSessionTransport) {
|
|
223
|
-
if (normalizedData) {
|
|
224
|
-
writeTmuxAgentInput(host, sessionId, session.transport, normalizedData);
|
|
225
|
-
}
|
|
226
|
-
operation = saveSessionInputOperation({
|
|
227
|
-
...operation,
|
|
228
|
-
state: submit ? "submitted" : "applied",
|
|
229
|
-
});
|
|
230
|
-
if (submit) {
|
|
231
|
-
const target = resolveLiveSessionTmuxTarget(host, sessionId, session.transport.tmuxTarget);
|
|
232
|
-
if (!target)
|
|
233
|
-
throw new Error(`Session "${sessionId}" does not have a live tmux target`);
|
|
234
|
-
scheduleTmuxAgentSubmit(host, sessionId, target, normalizedData);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
session.write(submit ? `${normalizedData}\r` : normalizedData);
|
|
239
|
-
operation = saveSessionInputOperation({
|
|
240
|
-
...operation,
|
|
241
|
-
state: submit ? "submitted" : "applied",
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
sessionId,
|
|
246
|
-
accepted: true,
|
|
247
|
-
operation,
|
|
248
|
-
messageId: message?.id,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
operation = saveSessionInputOperation({
|
|
253
|
-
...operation,
|
|
254
|
-
state: "failed",
|
|
255
|
-
error: error instanceof Error ? error.message : String(error),
|
|
256
|
-
});
|
|
257
|
-
return {
|
|
258
|
-
sessionId,
|
|
259
|
-
accepted: false,
|
|
260
|
-
operation,
|
|
261
|
-
messageId: operation.messageId,
|
|
262
|
-
error: operation.error,
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
export async function readAgentHistory(host, sessionId, lastN) {
|
|
267
|
-
resolveRunningSession(host, sessionId);
|
|
268
|
-
return {
|
|
269
|
-
sessionId,
|
|
270
|
-
messages: readSessionMessages(sessionId, { lastN: lastN ?? 20 }),
|
|
271
|
-
lastN: lastN ?? 20,
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
148
|
export async function interruptAgent(host, sessionId) {
|
|
275
149
|
const session = resolveRunningSession(host, sessionId);
|
|
276
150
|
if (session.transport instanceof TmuxSessionTransport) {
|
|
@@ -285,6 +159,22 @@ export async function interruptAgent(host, sessionId) {
|
|
|
285
159
|
}
|
|
286
160
|
return { sessionId };
|
|
287
161
|
}
|
|
162
|
+
export async function sendAgentInput(host, sessionId, text) {
|
|
163
|
+
const session = resolveRunningSession(host, sessionId);
|
|
164
|
+
if (session.transport instanceof TmuxSessionTransport) {
|
|
165
|
+
const target = resolveLiveSessionTmuxTarget(host, sessionId, session.transport.tmuxTarget);
|
|
166
|
+
if (!target)
|
|
167
|
+
throw new Error(`Session "${sessionId}" does not have a live tmux target`);
|
|
168
|
+
session.transport.retarget(target);
|
|
169
|
+
session.transport.write(text);
|
|
170
|
+
session.transport.write("\r");
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
session.write(text);
|
|
174
|
+
session.write("\r");
|
|
175
|
+
}
|
|
176
|
+
return { sessionId, accepted: true };
|
|
177
|
+
}
|
|
288
178
|
export async function readAgentOutput(host, sessionId, startLine) {
|
|
289
179
|
resolveRunningSession(host, sessionId);
|
|
290
180
|
const target = resolveLiveSessionTmuxTarget(host, sessionId);
|
|
@@ -303,13 +193,14 @@ export async function readAgentOutput(host, sessionId, startLine) {
|
|
|
303
193
|
}),
|
|
304
194
|
};
|
|
305
195
|
}
|
|
306
|
-
export function registerManagedSession(host, session, args, toolConfigKey, worktreePath, role, startTime) {
|
|
196
|
+
export function registerManagedSession(host, session, args, toolConfigKey, worktreePath, role, startTime, team) {
|
|
307
197
|
const existing = host.sessions.find((runtime) => runtime.transport === session);
|
|
308
198
|
if (existing)
|
|
309
199
|
return existing;
|
|
310
200
|
const runtime = new SessionRuntime(session, startTime, {
|
|
311
201
|
onEvent: (event) => host.handleSessionRuntimeEvent(runtime, event),
|
|
312
202
|
});
|
|
203
|
+
runtime.team = team;
|
|
313
204
|
if (toolConfigKey) {
|
|
314
205
|
host.sessionToolKeys.set(runtime.id, toolConfigKey);
|
|
315
206
|
}
|
|
@@ -317,7 +208,10 @@ export function registerManagedSession(host, session, args, toolConfigKey, workt
|
|
|
317
208
|
if (worktreePath) {
|
|
318
209
|
host.sessionWorktreePaths.set(runtime.id, worktreePath);
|
|
319
210
|
}
|
|
320
|
-
if (
|
|
211
|
+
if (team) {
|
|
212
|
+
host.sessionRoles.delete(runtime.id);
|
|
213
|
+
}
|
|
214
|
+
else if (role) {
|
|
321
215
|
host.sessionRoles.set(runtime.id, role);
|
|
322
216
|
}
|
|
323
217
|
else if (!host.sessionRoles.has(runtime.id)) {
|
|
@@ -332,7 +226,6 @@ export function registerManagedSession(host, session, args, toolConfigKey, workt
|
|
|
332
226
|
host.sessionLabels.set(runtime.id, label);
|
|
333
227
|
}
|
|
334
228
|
host.sessions.push(runtime);
|
|
335
|
-
host.writeSessionsFile();
|
|
336
229
|
host.updateContextWatcherSessions();
|
|
337
230
|
if (host.sessions.length === 1)
|
|
338
231
|
host.contextWatcher.start();
|
|
@@ -389,7 +282,9 @@ export function handleSessionRuntimeEvent(host, runtime, event) {
|
|
|
389
282
|
if (idx === -1)
|
|
390
283
|
return;
|
|
391
284
|
const explicitStop = host.stoppingSessionIds.has(runtime.id);
|
|
392
|
-
const
|
|
285
|
+
const graveyardAfterStop = host.graveyardAfterStopSessionIds?.has?.(runtime.id) ?? false;
|
|
286
|
+
const backendSessionId = runtime.backendSessionId;
|
|
287
|
+
const shouldPreserveOffline = !graveyardAfterStop && (explicitStop || Boolean(backendSessionId) || uptime >= 10_000);
|
|
393
288
|
if (shouldPreserveOffline && !host.offlineSessions.some((entry) => entry.id === runtime.id)) {
|
|
394
289
|
host.offlineSessions.push({
|
|
395
290
|
id: runtime.id,
|
|
@@ -399,15 +294,23 @@ export function handleSessionRuntimeEvent(host, runtime, event) {
|
|
|
399
294
|
args: host.sessionOriginalArgs.get(runtime.id) ?? [],
|
|
400
295
|
lifecycle: "offline",
|
|
401
296
|
createdAt: runtime.startTime ? new Date(runtime.startTime).toISOString() : undefined,
|
|
402
|
-
backendSessionId
|
|
297
|
+
backendSessionId,
|
|
298
|
+
team: runtime.team,
|
|
403
299
|
worktreePath: host.sessionWorktreePaths.get(runtime.id),
|
|
404
300
|
label: host.getSessionLabel(runtime.id),
|
|
405
301
|
headline: host.deriveHeadline(runtime.id),
|
|
406
302
|
});
|
|
407
303
|
}
|
|
304
|
+
else if (!shouldPreserveOffline) {
|
|
305
|
+
host.unpreservedExitedSessionIds ??= new Set();
|
|
306
|
+
host.unpreservedExitedSessionIds.add(runtime.id);
|
|
307
|
+
}
|
|
408
308
|
host.sessions.splice(idx, 1);
|
|
409
309
|
host.stoppingSessionIds.delete(runtime.id);
|
|
410
|
-
host.
|
|
310
|
+
host.graveyardAfterStopSessionIds?.delete?.(runtime.id);
|
|
311
|
+
if (graveyardAfterStop) {
|
|
312
|
+
host.offlineSessions = host.offlineSessions.filter((entry) => entry.id !== runtime.id);
|
|
313
|
+
}
|
|
411
314
|
host.updateContextWatcherSessions();
|
|
412
315
|
const mappedTarget = host.sessionTmuxTargets.get(runtime.id);
|
|
413
316
|
const runtimeTarget = runtime.transport instanceof TmuxSessionTransport ? runtime.transport.tmuxTarget : undefined;
|
|
@@ -428,15 +331,17 @@ export function handleSessionRuntimeEvent(host, runtime, event) {
|
|
|
428
331
|
}
|
|
429
332
|
host.renderDashboard();
|
|
430
333
|
}
|
|
431
|
-
export function buildTmuxWindowMetadata(host, sessionId, command) {
|
|
334
|
+
export function buildTmuxWindowMetadata(host, sessionId, command, existing) {
|
|
432
335
|
const sessionMetadata = loadMetadataState().sessions[sessionId];
|
|
336
|
+
const runtime = host.sessions.find((session) => session.id === sessionId);
|
|
433
337
|
return {
|
|
434
338
|
kind: "agent",
|
|
435
339
|
sessionId,
|
|
436
340
|
command,
|
|
437
341
|
args: host.sessionOriginalArgs.get(sessionId) ?? [],
|
|
438
342
|
toolConfigKey: host.sessionToolKeys.get(sessionId) ?? command,
|
|
439
|
-
backendSessionId:
|
|
343
|
+
backendSessionId: runtime?.backendSessionId,
|
|
344
|
+
team: runtime?.team ?? existing?.team,
|
|
440
345
|
worktreePath: host.sessionWorktreePaths.get(sessionId),
|
|
441
346
|
label: getSessionLabel(host, sessionId),
|
|
442
347
|
role: host.sessionRoles.get(sessionId),
|
|
@@ -458,7 +363,7 @@ export function syncTmuxWindowMetadata(host, sessionId) {
|
|
|
458
363
|
return;
|
|
459
364
|
}
|
|
460
365
|
const existing = host.tmuxRuntimeManager.getWindowMetadata(target);
|
|
461
|
-
const metadata = buildTmuxWindowMetadata(host, sessionId, runtime.command);
|
|
366
|
+
const metadata = buildTmuxWindowMetadata(host, sessionId, runtime.command, existing);
|
|
462
367
|
metadata.createdAt =
|
|
463
368
|
existing?.createdAt ??
|
|
464
369
|
(runtime.startTime ? new Date(runtime.startTime).toISOString() : undefined) ??
|
|
@@ -479,4 +384,3 @@ export function updateContextWatcherSessions(host) {
|
|
|
479
384
|
};
|
|
480
385
|
}));
|
|
481
386
|
}
|
|
482
|
-
//# sourceMappingURL=session-runtime-core.js.map
|
|
@@ -5,6 +5,10 @@ import { buildThreadEntries, buildWorkflowEntries, filterWorkflowEntries, } from
|
|
|
5
5
|
import { renderActivityScreen, renderThreadDetails, renderThreadsScreen, renderWorkflowDetails, renderWorkflowScreen, } from "../tui/screens/subscreen-renderers.js";
|
|
6
6
|
import { handleNotificationsKey as handleNotificationsKeyImpl, notificationTargetLabel as notificationTargetLabelImpl, renderNotifications as renderNotificationsImpl, showNotifications as showNotificationsImpl, } from "./notifications.js";
|
|
7
7
|
import { navigationUrgencyScore } from "../fast-control.js";
|
|
8
|
+
function findDashboardSessionOrTeammate(host, sessionId) {
|
|
9
|
+
return (host.getDashboardSessions?.().find((session) => session.id === sessionId) ??
|
|
10
|
+
(host.dashboardTeammatesCache ?? []).find((session) => session.id === sessionId));
|
|
11
|
+
}
|
|
8
12
|
export function attentionScore(host, entry) {
|
|
9
13
|
return navigationUrgencyScore(entry);
|
|
10
14
|
}
|
|
@@ -409,9 +413,12 @@ export function handleThreadsKey(host, data) {
|
|
|
409
413
|
const targetSessionId = entry.thread.owner ?? entry.thread.waitingOn?.[0] ?? entry.thread.participants[0];
|
|
410
414
|
if (targetSessionId) {
|
|
411
415
|
markThreadSeen(entry.thread.id, targetSessionId);
|
|
412
|
-
const dashEntry = host
|
|
413
|
-
if (dashEntry)
|
|
414
|
-
void host.activateDashboardEntry(dashEntry
|
|
416
|
+
const dashEntry = findDashboardSessionOrTeammate(host, targetSessionId);
|
|
417
|
+
if (dashEntry) {
|
|
418
|
+
void host.activateDashboardEntry(dashEntry, {
|
|
419
|
+
preserveDashboardSelection: Boolean(dashEntry.team),
|
|
420
|
+
});
|
|
421
|
+
}
|
|
415
422
|
}
|
|
416
423
|
}
|
|
417
424
|
}
|
|
@@ -700,4 +707,3 @@ export async function activateNextAttentionEntry(host) {
|
|
|
700
707
|
const next = ordered[currentIdx >= 0 ? (currentIdx + 1) % ordered.length : 0];
|
|
701
708
|
await host.activateDashboardEntryByNumber(next.index);
|
|
702
709
|
}
|
|
703
|
-
//# sourceMappingURL=subscreens.js.map
|
|
@@ -9,5 +9,4 @@ export interface WorktreeGraveyardEntry {
|
|
|
9
9
|
services?: ServiceState[];
|
|
10
10
|
}
|
|
11
11
|
export declare function listWorktreeGraveyardEntries(): WorktreeGraveyardEntry[];
|
|
12
|
-
export declare function writeWorktreeGraveyardEntries(entries: WorktreeGraveyardEntry[]): void;
|
|
13
12
|
export declare function listWorktreeGraveyardPaths(): Set<string>;
|
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
import { listTopologySessionStates } from "../runtime-core/topology-sessions.js";
|
|
3
|
+
import { listTopologyServiceStates } from "../runtime-core/topology-services.js";
|
|
4
|
+
import { listTopologyWorktreeGraveyard, listTopologyWorktreeGraveyardPaths, } from "../runtime-core/topology-worktrees.js";
|
|
3
5
|
export function listWorktreeGraveyardEntries() {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
export function writeWorktreeGraveyardEntries(entries) {
|
|
16
|
-
writeFileSync(getWorktreeGraveyardPath(), JSON.stringify(entries, null, 2) + "\n");
|
|
6
|
+
const sessions = listTopologySessionStates();
|
|
7
|
+
const services = listTopologyServiceStates();
|
|
8
|
+
return listTopologyWorktreeGraveyard().map((entry) => ({
|
|
9
|
+
name: entry.name ?? (basename(entry.path) || entry.path),
|
|
10
|
+
path: entry.path,
|
|
11
|
+
branch: entry.branch ?? "",
|
|
12
|
+
graveyardedAt: entry.graveyardedAt,
|
|
13
|
+
agents: sessions.filter((session) => session.worktreePath === entry.path),
|
|
14
|
+
services: services.filter((service) => service.worktreePath === entry.path),
|
|
15
|
+
}));
|
|
17
16
|
}
|
|
18
17
|
export function listWorktreeGraveyardPaths() {
|
|
19
|
-
return
|
|
18
|
+
return listTopologyWorktreeGraveyardPaths();
|
|
20
19
|
}
|
|
21
|
-
//# sourceMappingURL=worktree-graveyard.js.map
|
|
@@ -4,18 +4,25 @@ import { parseKeys } from "../key-parser.js";
|
|
|
4
4
|
import { addDashboardOperationFailure } from "../dashboard/operation-failures.js";
|
|
5
5
|
import { buildWorktreeListOverlayOutput, buildWorktreeRemoveConfirmOverlayOutput, } from "../tui/screens/overlay-renderers.js";
|
|
6
6
|
import { postToProjectService } from "./dashboard-control.js";
|
|
7
|
-
import { DashboardPendingActions } from "../dashboard/pending-actions.js";
|
|
8
7
|
import { dashboardCreatedSortKey } from "../dashboard/sort.js";
|
|
9
8
|
function assertDashboardWorktreeMutationSettled(settled, action) {
|
|
10
9
|
if (!settled) {
|
|
11
10
|
throw new Error(`worktree ${action} did not settle before timing out`);
|
|
12
11
|
}
|
|
13
12
|
}
|
|
13
|
+
function findRenderedWorktreeForSettlement(host, path) {
|
|
14
|
+
const raw = Array.isArray(host.dashboardRawWorktreeGroupsCache)
|
|
15
|
+
? host.dashboardRawWorktreeGroupsCache.find((entry) => entry.path === path)
|
|
16
|
+
: undefined;
|
|
17
|
+
if (raw)
|
|
18
|
+
return raw;
|
|
19
|
+
return host.dashboardWorktreeGroupsCache.find((entry) => entry.path === path);
|
|
20
|
+
}
|
|
14
21
|
async function waitForRenderedDashboardWorktreeState(host, path, predicate, timeoutMs = 10_000) {
|
|
15
22
|
const deadline = Date.now() + timeoutMs;
|
|
16
23
|
while (Date.now() < deadline) {
|
|
17
24
|
await host.refreshDashboardModelFromService(true);
|
|
18
|
-
const group = host
|
|
25
|
+
const group = findRenderedWorktreeForSettlement(host, path);
|
|
19
26
|
if (predicate(group))
|
|
20
27
|
return true;
|
|
21
28
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -23,16 +30,19 @@ async function waitForRenderedDashboardWorktreeState(host, path, predicate, time
|
|
|
23
30
|
return false;
|
|
24
31
|
}
|
|
25
32
|
async function runDashboardWorktreeMutation(host, opts) {
|
|
26
|
-
host.dashboardPendingActions.
|
|
33
|
+
host.dashboardPendingActions.setWorktreeAction(opts.pendingPath, opts.pendingAction);
|
|
34
|
+
host.reapplyDashboardPendingActions?.();
|
|
27
35
|
host.renderDashboard();
|
|
28
36
|
try {
|
|
29
37
|
await opts.request();
|
|
30
38
|
assertDashboardWorktreeMutationSettled(await opts.settle(), opts.pendingAction);
|
|
31
|
-
host.dashboardPendingActions.
|
|
39
|
+
host.dashboardPendingActions.clearWorktreeAction(opts.pendingPath);
|
|
40
|
+
host.reapplyDashboardPendingActions?.();
|
|
32
41
|
opts.onSuccess?.();
|
|
33
42
|
}
|
|
34
43
|
catch (error) {
|
|
35
|
-
host.dashboardPendingActions.
|
|
44
|
+
host.dashboardPendingActions.clearWorktreeAction(opts.pendingPath);
|
|
45
|
+
host.reapplyDashboardPendingActions?.();
|
|
36
46
|
opts.onError?.(error);
|
|
37
47
|
}
|
|
38
48
|
}
|
|
@@ -45,32 +55,34 @@ function sortDashboardWorktrees(worktrees) {
|
|
|
45
55
|
return dashboardCreatedSortKey(b) - dashboardCreatedSortKey(a);
|
|
46
56
|
});
|
|
47
57
|
}
|
|
58
|
+
function getOptimisticWorktreeCreatedAt(host, path) {
|
|
59
|
+
const existing = host.dashboardWorktreeGroupsCache.find((group) => group.path === path);
|
|
60
|
+
if (typeof existing?.createdAt === "string")
|
|
61
|
+
return existing.createdAt;
|
|
62
|
+
host.dashboardOptimisticWorktreeCreatedAt ??= new Map();
|
|
63
|
+
const cached = host.dashboardOptimisticWorktreeCreatedAt.get(path);
|
|
64
|
+
if (cached)
|
|
65
|
+
return cached;
|
|
66
|
+
const createdAt = new Date().toISOString();
|
|
67
|
+
host.dashboardOptimisticWorktreeCreatedAt.set(path, createdAt);
|
|
68
|
+
return createdAt;
|
|
69
|
+
}
|
|
48
70
|
function showOptimisticDashboardWorktreeCreate(host, name) {
|
|
49
71
|
const targetPath = getWorktreeCreatePath(name);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
services: [],
|
|
65
|
-
},
|
|
66
|
-
];
|
|
67
|
-
sortDashboardWorktrees(host.dashboardWorktreeGroupsCache);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
existing.pending = true;
|
|
71
|
-
existing.pendingAction = "creating";
|
|
72
|
-
existing.optimistic = true;
|
|
73
|
-
}
|
|
72
|
+
host.dashboardPendingActions.setWorktreeAction(targetPath, "creating", {
|
|
73
|
+
worktreeSeed: {
|
|
74
|
+
name,
|
|
75
|
+
branch: name,
|
|
76
|
+
path: targetPath,
|
|
77
|
+
createdAt: getOptimisticWorktreeCreatedAt(host, targetPath),
|
|
78
|
+
status: "offline",
|
|
79
|
+
isBare: false,
|
|
80
|
+
sessions: [],
|
|
81
|
+
services: [],
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
host.reapplyDashboardPendingActions?.();
|
|
85
|
+
sortDashboardWorktrees(host.dashboardWorktreeGroupsCache);
|
|
74
86
|
host.dashboardState.focusedWorktreePath = targetPath;
|
|
75
87
|
host.dashboardUiStateStore.markSelectionDirty();
|
|
76
88
|
host.dashboardState.worktreeNavOrder = host.dashboardWorktreeGroupsCache.map((wt) => wt.path);
|
|
@@ -94,6 +106,8 @@ function showDashboardWorktreeCreateFailure(host, name, path, error) {
|
|
|
94
106
|
worktreePath: path,
|
|
95
107
|
worktreeName: name,
|
|
96
108
|
});
|
|
109
|
+
host.dashboardPendingActions.clearWorktreeAction(path);
|
|
110
|
+
host.dashboardOptimisticWorktreeCreatedAt?.delete?.(path);
|
|
97
111
|
removeOptimisticDashboardWorktree(host, path);
|
|
98
112
|
host.dashboardWorktreeGroupsCache = [
|
|
99
113
|
...host.dashboardWorktreeGroupsCache,
|
|
@@ -119,6 +133,40 @@ function showDashboardWorktreeCreateFailure(host, name, path, error) {
|
|
|
119
133
|
host.dashboardUiStateStore.markSelectionDirty();
|
|
120
134
|
host.showDashboardError(`Failed to create "${name}"`, [`Path: ${path}`, `Error: ${message}`]);
|
|
121
135
|
}
|
|
136
|
+
function findDashboardWorktreeCreateFailure(host, path) {
|
|
137
|
+
const groupFailure = host.dashboardWorktreeGroupsCache?.find((group) => group.path === path)?.operationFailure;
|
|
138
|
+
if (groupFailure)
|
|
139
|
+
return groupFailure;
|
|
140
|
+
return (host.dashboardOperationFailuresCache ?? []).find((failure) => failure.targetKind === "worktree" && failure.operation === "create" && failure.worktreePath === path);
|
|
141
|
+
}
|
|
142
|
+
function isDashboardWorktreeCreateSettled(group) {
|
|
143
|
+
if (!group)
|
|
144
|
+
return false;
|
|
145
|
+
if (group.operationFailure)
|
|
146
|
+
return false;
|
|
147
|
+
return group.pending !== true && group.pendingAction !== "creating";
|
|
148
|
+
}
|
|
149
|
+
async function waitForRenderedDashboardWorktreeCreate(host, name, path, timeoutMs = 180_000) {
|
|
150
|
+
const deadline = Date.now() + timeoutMs;
|
|
151
|
+
while (Date.now() < deadline) {
|
|
152
|
+
if (typeof host.refreshDashboardModelFromService === "function") {
|
|
153
|
+
await host.refreshDashboardModelFromService(true);
|
|
154
|
+
}
|
|
155
|
+
const failure = findDashboardWorktreeCreateFailure(host, path);
|
|
156
|
+
if (failure) {
|
|
157
|
+
const message = typeof failure.message === "string" ? failure.message : "worktree create failed";
|
|
158
|
+
return { ok: false, error: new Error(message) };
|
|
159
|
+
}
|
|
160
|
+
const group = findRenderedWorktreeForSettlement(host, path);
|
|
161
|
+
if (isDashboardWorktreeCreateSettled(group)) {
|
|
162
|
+
return { ok: true };
|
|
163
|
+
}
|
|
164
|
+
showOptimisticDashboardWorktreeCreate(host, name);
|
|
165
|
+
host.renderDashboard?.();
|
|
166
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
167
|
+
}
|
|
168
|
+
return { ok: false, error: new Error("worktree creating did not settle before timing out") };
|
|
169
|
+
}
|
|
122
170
|
export function showWorktreeCreatePrompt(host) {
|
|
123
171
|
host.openDashboardOverlay("worktree-input");
|
|
124
172
|
host.worktreeInputBuffer = "";
|
|
@@ -170,17 +218,27 @@ export function handleWorktreeInputKey(host, data) {
|
|
|
170
218
|
if (name) {
|
|
171
219
|
if (host.mode === "dashboard") {
|
|
172
220
|
const targetPath = showOptimisticDashboardWorktreeCreate(host, name);
|
|
173
|
-
const pendingKey = DashboardPendingActions.worktreeKey(targetPath);
|
|
174
221
|
host.renderDashboard();
|
|
175
222
|
void (async () => {
|
|
176
223
|
try {
|
|
177
224
|
await postToProjectService(host, "/worktrees/create", { name }, { timeoutMs: 180_000 });
|
|
178
|
-
await host
|
|
225
|
+
const result = await waitForRenderedDashboardWorktreeCreate(host, name, targetPath);
|
|
226
|
+
if (!result.ok) {
|
|
227
|
+
throw result.error;
|
|
228
|
+
}
|
|
179
229
|
debug(`worktree created from UI: ${name}`, "worktree");
|
|
180
|
-
host.
|
|
230
|
+
host.dashboardPendingActions.clearWorktreeAction(targetPath);
|
|
231
|
+
host.reapplyDashboardPendingActions?.();
|
|
232
|
+
host.dashboardOptimisticWorktreeCreatedAt?.delete?.(targetPath);
|
|
233
|
+
await host.refreshDashboardModelFromService?.(true);
|
|
234
|
+
host.dashboardState.focusedWorktreePath = targetPath;
|
|
235
|
+
host.dashboardUiStateStore.markSelectionDirty();
|
|
236
|
+
host.renderDashboard();
|
|
181
237
|
}
|
|
182
238
|
catch (err) {
|
|
183
|
-
host.dashboardPendingActions.
|
|
239
|
+
host.dashboardPendingActions.clearWorktreeAction(targetPath);
|
|
240
|
+
host.reapplyDashboardPendingActions?.();
|
|
241
|
+
host.dashboardOptimisticWorktreeCreatedAt?.delete?.(targetPath);
|
|
184
242
|
debug(`worktree create failed: ${err instanceof Error ? err.message : String(err)}`, "worktree");
|
|
185
243
|
showDashboardWorktreeCreateFailure(host, name, targetPath, err);
|
|
186
244
|
}
|
|
@@ -241,8 +299,6 @@ export function beginWorktreeRemoval(host, path, name, oldIdx) {
|
|
|
241
299
|
host.renderDashboard();
|
|
242
300
|
return;
|
|
243
301
|
}
|
|
244
|
-
if (host.pendingWorktreeRemovals?.has?.(path))
|
|
245
|
-
return;
|
|
246
302
|
debug(`begin worktree graveyard: name=${name} path=${path}`, "worktree");
|
|
247
303
|
host.worktreeRemovalJob = {
|
|
248
304
|
path,
|
|
@@ -251,15 +307,12 @@ export function beginWorktreeRemoval(host, path, name, oldIdx) {
|
|
|
251
307
|
oldIdx,
|
|
252
308
|
stderr: "",
|
|
253
309
|
};
|
|
254
|
-
host.refreshLocalDashboardModel();
|
|
255
|
-
host.renderDashboard();
|
|
256
310
|
if (host.mode === "dashboard") {
|
|
257
|
-
const pendingKey = DashboardPendingActions.worktreeKey(path);
|
|
258
311
|
void runDashboardWorktreeMutation(host, {
|
|
259
|
-
|
|
312
|
+
pendingPath: path,
|
|
260
313
|
pendingAction: "graveyarding",
|
|
261
314
|
request: async () => {
|
|
262
|
-
await postToProjectService(host, "/worktrees/graveyard", { path }, { timeoutMs:
|
|
315
|
+
await postToProjectService(host, "/worktrees/graveyard", { path }, { timeoutMs: 180_000 });
|
|
263
316
|
},
|
|
264
317
|
settle: () => waitForRenderedDashboardWorktreeState(host, path, (group) => !group),
|
|
265
318
|
onSuccess: () => {
|
|
@@ -276,6 +329,8 @@ export function beginWorktreeRemoval(host, path, name, oldIdx) {
|
|
|
276
329
|
});
|
|
277
330
|
return;
|
|
278
331
|
}
|
|
332
|
+
host.refreshLocalDashboardModel();
|
|
333
|
+
host.renderDashboard();
|
|
279
334
|
void (async () => {
|
|
280
335
|
try {
|
|
281
336
|
await host.graveyardDesktopWorktree(path);
|
|
@@ -326,6 +381,7 @@ export function finishWorktreeRemoval(host, code) {
|
|
|
326
381
|
`Error: ${message}`,
|
|
327
382
|
...details,
|
|
328
383
|
]);
|
|
384
|
+
host.renderDashboard();
|
|
329
385
|
return;
|
|
330
386
|
}
|
|
331
387
|
host.renderDashboard();
|
|
@@ -362,4 +418,3 @@ export function handleWorktreeListKey(host, data) {
|
|
|
362
418
|
host.restoreDashboardAfterOverlayDismiss();
|
|
363
419
|
}
|
|
364
420
|
}
|
|
365
|
-
//# sourceMappingURL=worktrees.js.map
|
|
@@ -35,12 +35,16 @@ function isDirectSessionFocus(entry, sessionId) {
|
|
|
35
35
|
}
|
|
36
36
|
export function updateNotificationContext(source, patch) {
|
|
37
37
|
const state = loadState();
|
|
38
|
+
const previous = state.contexts[source];
|
|
39
|
+
const has = (key) => Object.prototype.hasOwnProperty.call(patch, key);
|
|
40
|
+
const nextSessionId = has("sessionId") ? patch.sessionId : previous?.sessionId;
|
|
41
|
+
const nextScreen = has("screen") ? patch.screen : has("sessionId") && nextSessionId ? "session" : previous?.screen;
|
|
38
42
|
const next = {
|
|
39
43
|
source,
|
|
40
|
-
focused: patch.focused ??
|
|
41
|
-
screen:
|
|
42
|
-
sessionId:
|
|
43
|
-
panelOpen: patch.panelOpen ??
|
|
44
|
+
focused: has("focused") ? (patch.focused ?? false) : (previous?.focused ?? false),
|
|
45
|
+
screen: nextScreen,
|
|
46
|
+
sessionId: nextSessionId,
|
|
47
|
+
panelOpen: has("panelOpen") ? (patch.panelOpen ?? false) : (previous?.panelOpen ?? false),
|
|
44
48
|
updatedAt: new Date().toISOString(),
|
|
45
49
|
};
|
|
46
50
|
state.contexts[source] = next;
|
|
@@ -76,4 +80,3 @@ export function shouldSuppressNotification(event) {
|
|
|
76
80
|
}
|
|
77
81
|
return false;
|
|
78
82
|
}
|
|
79
|
-
//# sourceMappingURL=notification-context.js.map
|