@jmoyers/harness 0.1.10 → 0.1.20
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 +31 -35
- package/package.json +31 -11
- package/packages/harness-ai/src/anthropic-protocol.ts +68 -68
- package/packages/harness-ai/src/stream-text.ts +13 -91
- package/packages/harness-ui/src/frame-primitives.ts +158 -0
- package/packages/harness-ui/src/index.ts +18 -0
- package/packages/harness-ui/src/interaction/conversation-input-forwarder.ts +221 -0
- package/packages/harness-ui/src/interaction/conversation-selection-input.ts +213 -0
- package/packages/harness-ui/src/interaction/global-shortcut-input.ts +172 -0
- package/{src/ui → packages/harness-ui/src/interaction}/input-preflight.ts +10 -12
- package/{src/ui → packages/harness-ui/src/interaction}/input-token-router.ts +120 -69
- package/packages/harness-ui/src/interaction/input.ts +420 -0
- package/packages/harness-ui/src/interaction/left-nav-input.ts +166 -0
- package/{src/ui → packages/harness-ui/src/interaction}/main-pane-pointer-input.ts +91 -23
- package/{src/ui → packages/harness-ui/src/interaction}/pointer-routing-input.ts +112 -48
- package/packages/harness-ui/src/interaction/rail-pointer-input.ts +62 -0
- package/packages/harness-ui/src/interaction/repository-fold-input.ts +118 -0
- package/packages/harness-ui/src/kit.ts +476 -0
- package/packages/harness-ui/src/layout.ts +238 -0
- package/{src/ui/modals/manager.ts → packages/harness-ui/src/modal-manager.ts} +94 -64
- package/{src/ui → packages/harness-ui/src}/screen.ts +53 -26
- package/packages/harness-ui/src/surface.ts +252 -0
- package/packages/harness-ui/src/text-layout.ts +210 -0
- package/packages/nim-core/src/contracts.ts +239 -0
- package/packages/nim-core/src/event-store.ts +299 -0
- package/packages/nim-core/src/events.ts +53 -0
- package/packages/nim-core/src/index.ts +9 -0
- package/packages/nim-core/src/provider-router.ts +129 -0
- package/packages/nim-core/src/providers/anthropic-driver.ts +291 -0
- package/packages/nim-core/src/runtime-factory.ts +49 -0
- package/packages/nim-core/src/runtime.ts +1797 -0
- package/packages/nim-core/src/session-store.ts +516 -0
- package/packages/nim-core/src/telemetry.ts +48 -0
- package/packages/nim-test-tui/src/index.ts +150 -0
- package/packages/nim-ui-core/src/index.ts +1 -0
- package/packages/nim-ui-core/src/projection.ts +87 -0
- package/scripts/codex-live-mux-runtime.ts +2 -3721
- package/scripts/control-plane-daemon.ts +24 -2
- package/scripts/harness-bin.js +5 -0
- package/scripts/harness-commands.ts +300 -0
- package/scripts/harness-runtime.ts +82 -0
- package/scripts/harness.ts +33 -3007
- package/scripts/nim-tui-smoke.ts +748 -0
- package/src/cli/auth/runtime.ts +948 -0
- package/src/cli/default-gateway-pointer.ts +193 -0
- package/src/cli/gateway/runtime.ts +1872 -0
- package/src/cli/parsing/flags.ts +23 -0
- package/src/cli/parsing/session.ts +42 -0
- package/src/cli/runtime/context.ts +193 -0
- package/src/cli/runtime-app/application.ts +392 -0
- package/src/cli/runtime-infra/gateway-control.ts +729 -0
- package/{scripts/harness-inspector.ts → src/cli/workflows/inspector.ts} +14 -11
- package/src/cli/workflows/runtime.ts +965 -0
- package/src/clients/tui/left-rail-interactions.ts +519 -0
- package/src/clients/tui/main-pane-interactions.ts +509 -0
- package/src/clients/tui/modal-input-routing.ts +71 -0
- package/src/clients/tui/render-snapshot-adapter.ts +88 -0
- package/src/clients/web/synced-selectors.ts +132 -0
- package/src/codex/live-session.ts +82 -29
- package/src/config/config-core.ts +361 -10
- package/src/config/harness-paths.ts +4 -7
- package/src/config/harness-runtime-migration.ts +142 -19
- package/src/config/harness.config.template.jsonc +33 -0
- package/src/config/secrets-core.ts +92 -4
- package/src/control-plane/agent-realtime-api.ts +82 -427
- package/src/control-plane/prompt/thread-title-namer.ts +49 -23
- package/src/control-plane/session-summary.ts +10 -81
- package/src/control-plane/status/reducer-base.ts +12 -12
- package/src/control-plane/status/reducers/claude-status-reducer.ts +3 -3
- package/src/control-plane/status/reducers/codex-status-reducer.ts +4 -4
- package/src/control-plane/status/reducers/cursor-status-reducer.ts +3 -3
- package/src/control-plane/stream-client.ts +12 -2
- package/src/control-plane/stream-command-parser.ts +83 -143
- package/src/control-plane/stream-protocol.ts +53 -37
- package/src/control-plane/stream-server-background.ts +18 -2
- package/src/control-plane/stream-server-command.ts +376 -69
- package/src/control-plane/stream-server-session-runtime.ts +3 -2
- package/src/control-plane/stream-server.ts +943 -80
- package/src/control-plane/stream-session-runtime-types.ts +41 -0
- package/src/{mux/live-mux/control-plane-records.ts → core/contracts/records.ts} +24 -97
- package/src/core/state/observed-stream-cursor.ts +43 -0
- package/src/core/state/synced-observed-state.ts +273 -0
- package/src/core/store/harness-synced-store.ts +81 -0
- package/src/diff/budget.ts +136 -0
- package/src/diff/build.ts +289 -0
- package/src/diff/chunker.ts +146 -0
- package/src/diff/git-invoke.ts +315 -0
- package/src/diff/git-parse.ts +472 -0
- package/src/diff/hash.ts +70 -0
- package/src/diff/index.ts +24 -0
- package/src/diff/normalize.ts +134 -0
- package/src/diff/types.ts +178 -0
- package/src/diff-ui/args.ts +346 -0
- package/src/diff-ui/commands.ts +123 -0
- package/src/diff-ui/finder.ts +94 -0
- package/src/diff-ui/highlight.ts +127 -0
- package/src/diff-ui/index.ts +2 -0
- package/src/diff-ui/model.ts +141 -0
- package/src/diff-ui/pager.ts +412 -0
- package/src/diff-ui/render.ts +337 -0
- package/src/diff-ui/runtime.ts +379 -0
- package/src/diff-ui/state.ts +224 -0
- package/src/diff-ui/types.ts +236 -0
- package/src/domain/conversations.ts +11 -7
- package/src/domain/workspace.ts +76 -4
- package/src/mux/control-plane-op-queue.ts +93 -7
- package/src/mux/conversation-rail.ts +28 -71
- package/src/mux/dual-pane-core.ts +13 -13
- package/src/mux/harness-core-ui.ts +313 -42
- package/src/mux/input-shortcuts.ts +22 -112
- package/src/mux/keybinding-catalog.ts +340 -0
- package/src/mux/keybinding-registry.ts +103 -0
- package/src/mux/live-mux/command-menu-open-in.ts +280 -0
- package/src/mux/live-mux/command-menu.ts +167 -4
- package/src/mux/live-mux/conversation-state.ts +13 -0
- package/src/mux/live-mux/directory-resolution.ts +1 -1
- package/src/mux/live-mux/git-parsing.ts +16 -0
- package/src/mux/live-mux/git-snapshot.ts +33 -2
- package/src/mux/live-mux/global-shortcut-handlers.ts +6 -0
- package/src/mux/live-mux/home-pane-drop.ts +1 -1
- package/src/mux/live-mux/home-pane-pointer.ts +10 -0
- package/src/mux/live-mux/input-forwarding.ts +59 -2
- package/src/mux/live-mux/left-nav-activation.ts +124 -7
- package/src/mux/live-mux/left-nav.ts +35 -0
- package/src/mux/live-mux/link-click.ts +292 -0
- package/src/mux/live-mux/modal-command-menu-handler.ts +46 -9
- package/src/mux/live-mux/modal-conversation-handlers.ts +5 -1
- package/src/mux/live-mux/modal-input-reducers.ts +106 -8
- package/src/mux/live-mux/modal-overlays.ts +210 -31
- package/src/mux/live-mux/modal-pointer.ts +3 -7
- package/src/mux/live-mux/modal-prompt-handlers.ts +107 -1
- package/src/mux/live-mux/modal-release-notes-handler.ts +111 -0
- package/src/mux/live-mux/modal-task-editor-handler.ts +16 -11
- package/src/mux/live-mux/pointer-routing.ts +5 -2
- package/src/mux/live-mux/project-pane-pointer.ts +8 -0
- package/src/mux/live-mux/rail-layout.ts +33 -30
- package/src/mux/live-mux/release-notes.ts +383 -0
- package/src/mux/live-mux/render-trace-analysis.ts +52 -7
- package/src/mux/live-mux/repository-folding.ts +3 -0
- package/src/mux/live-mux/selection.ts +0 -4
- package/src/mux/live-mux/session-diagnostics-paths.ts +21 -0
- package/src/mux/project-pane-github-review.ts +271 -0
- package/src/mux/render-frame.ts +4 -0
- package/src/mux/runtime-app/codex-live-mux-runtime.ts +5191 -0
- package/src/mux/task-composer.ts +21 -14
- package/src/mux/task-focused-pane.ts +118 -117
- package/src/mux/task-screen-keybindings.ts +19 -82
- package/src/mux/workspace-rail-model.ts +270 -104
- package/src/mux/workspace-rail.ts +45 -22
- package/src/pty/session-broker.ts +1 -1
- package/{scripts → src/recording}/terminal-recording-gif-lib.ts +2 -2
- package/src/services/control-plane.ts +50 -32
- package/src/services/conversation-lifecycle.ts +118 -87
- package/src/services/conversation-startup-hydration.ts +20 -12
- package/src/services/directory-hydration.ts +21 -16
- package/src/services/event-persistence.ts +7 -0
- package/src/services/left-rail-pointer-handler.ts +329 -0
- package/src/services/mux-ui-state-persistence.ts +5 -1
- package/src/services/recording.ts +34 -26
- package/src/services/runtime-command-menu-agent-tools.ts +1 -1
- package/src/services/runtime-control-actions.ts +79 -61
- package/src/services/runtime-control-plane-ops.ts +122 -83
- package/src/services/runtime-conversation-actions.ts +40 -26
- package/src/services/runtime-conversation-activation.ts +82 -30
- package/src/services/runtime-conversation-starter.ts +80 -48
- package/src/services/runtime-conversation-title-edit.ts +91 -80
- package/src/services/runtime-envelope-handler.ts +107 -105
- package/src/services/runtime-git-state.ts +42 -29
- package/src/services/runtime-layout-resize.ts +3 -1
- package/src/services/runtime-left-rail-render.ts +99 -63
- package/src/services/runtime-nim-cli-session.ts +438 -0
- package/src/services/runtime-nim-session.ts +705 -0
- package/src/services/runtime-nim-tool-bridge.ts +141 -0
- package/src/services/runtime-observed-event-projection-pipeline.ts +45 -0
- package/src/services/runtime-process-wiring.ts +29 -36
- package/src/services/runtime-project-pane-github-review-cache.ts +164 -0
- package/src/services/runtime-render-flush.ts +63 -70
- package/src/services/runtime-render-lifecycle.ts +65 -64
- package/src/services/runtime-render-orchestrator.ts +55 -45
- package/src/services/runtime-render-pipeline.ts +106 -103
- package/src/services/runtime-render-state.ts +62 -49
- package/src/services/runtime-repository-actions.ts +97 -70
- package/src/services/runtime-right-pane-render.ts +80 -53
- package/src/services/runtime-shutdown.ts +38 -35
- package/src/services/runtime-stream-subscriptions.ts +35 -27
- package/src/services/runtime-task-composer-persistence.ts +71 -59
- package/src/services/runtime-task-composer-snapshot.ts +14 -0
- package/src/services/runtime-task-editor-actions.ts +46 -29
- package/src/services/runtime-task-pane-actions.ts +220 -134
- package/src/services/runtime-task-pane-shortcuts.ts +323 -123
- package/src/services/runtime-workspace-observed-effect-queue.ts +25 -0
- package/src/services/runtime-workspace-observed-events.ts +33 -184
- package/src/services/runtime-workspace-observed-transition-policy.ts +228 -0
- package/src/services/session-diagnostics-store.ts +217 -0
- package/src/services/startup-background-resume.ts +26 -21
- package/src/services/startup-orchestrator.ts +16 -13
- package/src/services/startup-paint-tracker.ts +29 -21
- package/src/services/startup-persisted-conversation-queue.ts +19 -13
- package/src/services/startup-settled-gate.ts +25 -15
- package/src/services/startup-shutdown.ts +18 -22
- package/src/services/startup-state-hydration.ts +44 -34
- package/src/services/startup-visibility.ts +12 -4
- package/src/services/task-pane-selection-actions.ts +89 -72
- package/src/services/task-planning-hydration.ts +24 -18
- package/src/services/task-planning-observed-events.ts +50 -52
- package/src/services/workspace-observed-events.ts +66 -63
- package/src/storage/storage-lifecycle-core.ts +438 -0
- package/src/store/control-plane-store-normalize.ts +33 -242
- package/src/store/control-plane-store-types.ts +1 -35
- package/src/store/control-plane-store.ts +396 -56
- package/src/store/event-store.ts +397 -3
- package/src/terminal/snapshot-oracle.ts +207 -94
- package/src/ui/mux-theme.ts +112 -8
- package/src/ui/panes/home-gridfire.ts +40 -31
- package/src/ui/panes/home.ts +10 -2
- package/src/ui/panes/nim.ts +315 -0
- package/src/mux/live-mux/actions-task.ts +0 -115
- package/src/mux/live-mux/left-rail-actions.ts +0 -118
- package/src/mux/live-mux/left-rail-conversation-click.ts +0 -82
- package/src/mux/live-mux/left-rail-pointer.ts +0 -74
- package/src/mux/live-mux/task-pane-shortcuts.ts +0 -206
- package/src/services/runtime-directory-actions.ts +0 -164
- package/src/services/runtime-input-pipeline.ts +0 -50
- package/src/services/runtime-input-router.ts +0 -189
- package/src/services/runtime-main-pane-input.ts +0 -230
- package/src/services/runtime-modal-input.ts +0 -119
- package/src/services/runtime-navigation-input.ts +0 -197
- package/src/services/runtime-rail-input.ts +0 -278
- package/src/services/runtime-task-pane.ts +0 -62
- package/src/services/runtime-workspace-actions.ts +0 -158
- package/src/ui/conversation-input-forwarder.ts +0 -114
- package/src/ui/conversation-selection-input.ts +0 -103
- package/src/ui/global-shortcut-input.ts +0 -89
- package/src/ui/input.ts +0 -238
- package/src/ui/kit.ts +0 -509
- package/src/ui/left-nav-input.ts +0 -80
- package/src/ui/left-rail-pointer-input.ts +0 -148
- package/src/ui/repository-fold-input.ts +0 -91
- package/src/ui/surface.ts +0 -224
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import type { TaskPaneAction } from '../mux/harness-core-ui.ts';
|
|
2
|
-
|
|
3
|
-
interface RuntimeWorkspaceConversationActions {
|
|
4
|
-
activateConversation(sessionId: string): Promise<void>;
|
|
5
|
-
createAndActivateConversationInDirectory(directoryId: string, agentType: string): Promise<void>;
|
|
6
|
-
openOrCreateCritiqueConversationInDirectory(directoryId: string): Promise<void>;
|
|
7
|
-
takeoverConversation(sessionId: string): Promise<void>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface RuntimeWorkspaceDirectoryActions {
|
|
11
|
-
archiveConversation(sessionId: string): Promise<void>;
|
|
12
|
-
addDirectoryByPath(rawPath: string): Promise<void>;
|
|
13
|
-
closeDirectory(directoryId: string): Promise<void>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface RuntimeWorkspaceRepositoryActions {
|
|
17
|
-
openRepositoryPromptForCreate(): void;
|
|
18
|
-
openRepositoryPromptForEdit(repositoryId: string): void;
|
|
19
|
-
reorderRepositoryByDrop(
|
|
20
|
-
draggedRepositoryId: string,
|
|
21
|
-
targetRepositoryId: string,
|
|
22
|
-
orderedRepositoryIds: readonly string[],
|
|
23
|
-
): void;
|
|
24
|
-
upsertRepositoryByRemoteUrl(remoteUrl: string, existingRepositoryId?: string): Promise<void>;
|
|
25
|
-
archiveRepositoryById(repositoryId: string): Promise<void>;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface RuntimeWorkspaceControlActions {
|
|
29
|
-
interruptConversation(sessionId: string): Promise<void>;
|
|
30
|
-
toggleGatewayProfiler(): Promise<void>;
|
|
31
|
-
toggleGatewayStatusTimeline(): Promise<void>;
|
|
32
|
-
toggleGatewayRenderTrace(conversationId: string | null): Promise<void>;
|
|
33
|
-
refreshAllConversationTitles(): Promise<void>;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface RuntimeWorkspaceTaskPaneActions {
|
|
37
|
-
runTaskPaneAction(action: TaskPaneAction): void;
|
|
38
|
-
openTaskEditPrompt(taskId: string): void;
|
|
39
|
-
reorderTaskByDrop(draggedTaskId: string, targetTaskId: string): void;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
interface RuntimeWorkspaceTaskPaneShortcuts {
|
|
43
|
-
handleInput(input: Buffer): boolean;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface RuntimeWorkspaceActionsOptions {
|
|
47
|
-
readonly conversationActions: RuntimeWorkspaceConversationActions;
|
|
48
|
-
readonly directoryActions: RuntimeWorkspaceDirectoryActions;
|
|
49
|
-
readonly repositoryActions: RuntimeWorkspaceRepositoryActions;
|
|
50
|
-
readonly controlActions: RuntimeWorkspaceControlActions;
|
|
51
|
-
readonly taskPaneActions: RuntimeWorkspaceTaskPaneActions;
|
|
52
|
-
readonly taskPaneShortcuts: RuntimeWorkspaceTaskPaneShortcuts;
|
|
53
|
-
readonly orderedActiveRepositoryIds: () => readonly string[];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export class RuntimeWorkspaceActions {
|
|
57
|
-
constructor(private readonly options: RuntimeWorkspaceActionsOptions) {}
|
|
58
|
-
|
|
59
|
-
async activateConversation(sessionId: string): Promise<void> {
|
|
60
|
-
await this.options.conversationActions.activateConversation(sessionId);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async createAndActivateConversationInDirectory(
|
|
64
|
-
directoryId: string,
|
|
65
|
-
agentType: string,
|
|
66
|
-
): Promise<void> {
|
|
67
|
-
await this.options.conversationActions.createAndActivateConversationInDirectory(
|
|
68
|
-
directoryId,
|
|
69
|
-
agentType,
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async openOrCreateCritiqueConversationInDirectory(directoryId: string): Promise<void> {
|
|
74
|
-
await this.options.conversationActions.openOrCreateCritiqueConversationInDirectory(directoryId);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async takeoverConversation(sessionId: string): Promise<void> {
|
|
78
|
-
await this.options.conversationActions.takeoverConversation(sessionId);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
async archiveConversation(sessionId: string): Promise<void> {
|
|
82
|
-
await this.options.directoryActions.archiveConversation(sessionId);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async addDirectoryByPath(rawPath: string): Promise<void> {
|
|
86
|
-
await this.options.directoryActions.addDirectoryByPath(rawPath);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async closeDirectory(directoryId: string): Promise<void> {
|
|
90
|
-
await this.options.directoryActions.closeDirectory(directoryId);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
openRepositoryPromptForCreate(): void {
|
|
94
|
-
this.options.repositoryActions.openRepositoryPromptForCreate();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
openRepositoryPromptForEdit(repositoryId: string): void {
|
|
98
|
-
this.options.repositoryActions.openRepositoryPromptForEdit(repositoryId);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
reorderRepositoryByDrop(draggedRepositoryId: string, targetRepositoryId: string): void {
|
|
102
|
-
this.options.repositoryActions.reorderRepositoryByDrop(
|
|
103
|
-
draggedRepositoryId,
|
|
104
|
-
targetRepositoryId,
|
|
105
|
-
this.options.orderedActiveRepositoryIds(),
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async upsertRepositoryByRemoteUrl(
|
|
110
|
-
remoteUrl: string,
|
|
111
|
-
existingRepositoryId?: string,
|
|
112
|
-
): Promise<void> {
|
|
113
|
-
await this.options.repositoryActions.upsertRepositoryByRemoteUrl(
|
|
114
|
-
remoteUrl,
|
|
115
|
-
existingRepositoryId,
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async archiveRepositoryById(repositoryId: string): Promise<void> {
|
|
120
|
-
await this.options.repositoryActions.archiveRepositoryById(repositoryId);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
async interruptConversation(sessionId: string): Promise<void> {
|
|
124
|
-
await this.options.controlActions.interruptConversation(sessionId);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async toggleGatewayProfiler(): Promise<void> {
|
|
128
|
-
await this.options.controlActions.toggleGatewayProfiler();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async toggleGatewayStatusTimeline(): Promise<void> {
|
|
132
|
-
await this.options.controlActions.toggleGatewayStatusTimeline();
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async toggleGatewayRenderTrace(conversationId: string | null): Promise<void> {
|
|
136
|
-
await this.options.controlActions.toggleGatewayRenderTrace(conversationId);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async refreshAllConversationTitles(): Promise<void> {
|
|
140
|
-
await this.options.controlActions.refreshAllConversationTitles();
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
runTaskPaneAction(action: TaskPaneAction): void {
|
|
144
|
-
this.options.taskPaneActions.runTaskPaneAction(action);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
openTaskEditPrompt(taskId: string): void {
|
|
148
|
-
this.options.taskPaneActions.openTaskEditPrompt(taskId);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
reorderTaskByDrop(draggedTaskId: string, targetTaskId: string): void {
|
|
152
|
-
this.options.taskPaneActions.reorderTaskByDrop(draggedTaskId, targetTaskId);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
handleTaskPaneShortcutInput(input: Buffer): boolean {
|
|
156
|
-
return this.options.taskPaneShortcuts.handleInput(input);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
classifyPaneAt as classifyPaneAtFrame,
|
|
3
|
-
parseMuxInputChunk as parseMuxInputChunkFrame,
|
|
4
|
-
wheelDeltaRowsFromCode,
|
|
5
|
-
type computeDualPaneLayout,
|
|
6
|
-
} from '../mux/dual-pane-core.ts';
|
|
7
|
-
import { normalizeMuxKeyboardInputForPty as normalizeMuxKeyboardInputForPtyFrame } from '../mux/input-shortcuts.ts';
|
|
8
|
-
import { routeInputTokensForConversation as routeInputTokensForConversationFrame } from '../mux/live-mux/input-forwarding.ts';
|
|
9
|
-
import { hasShiftModifier } from '../mux/live-mux/selection.ts';
|
|
10
|
-
import type { ConversationState } from '../mux/live-mux/conversation-state.ts';
|
|
11
|
-
import type { InputTokenRouter } from './input-token-router.ts';
|
|
12
|
-
|
|
13
|
-
type MainPaneMode = 'conversation' | 'project' | 'home';
|
|
14
|
-
type DualPaneLayout = ReturnType<typeof computeDualPaneLayout>;
|
|
15
|
-
|
|
16
|
-
interface ConversationInputForwarderOptions {
|
|
17
|
-
readonly getInputRemainder: () => string;
|
|
18
|
-
readonly setInputRemainder: (next: string) => void;
|
|
19
|
-
readonly getMainPaneMode: () => MainPaneMode;
|
|
20
|
-
readonly getLayout: () => DualPaneLayout;
|
|
21
|
-
readonly inputTokenRouter: Pick<InputTokenRouter, 'routeTokens'>;
|
|
22
|
-
readonly getActiveConversation: () => ConversationState | null;
|
|
23
|
-
readonly markDirty: () => void;
|
|
24
|
-
readonly isControlledByLocalHuman: (input: {
|
|
25
|
-
readonly conversation: ConversationState;
|
|
26
|
-
readonly controllerId: string;
|
|
27
|
-
}) => boolean;
|
|
28
|
-
readonly controllerId: string;
|
|
29
|
-
readonly sendInputToSession: (sessionId: string, chunk: Buffer) => void;
|
|
30
|
-
readonly noteGitActivity: (directoryId: string | null) => void;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface ConversationInputForwarderDependencies {
|
|
34
|
-
readonly parseMuxInputChunk?: typeof parseMuxInputChunkFrame;
|
|
35
|
-
readonly routeInputTokensForConversation?: typeof routeInputTokensForConversationFrame;
|
|
36
|
-
readonly classifyPaneAt?: typeof classifyPaneAtFrame;
|
|
37
|
-
readonly normalizeMuxKeyboardInputForPty?: typeof normalizeMuxKeyboardInputForPtyFrame;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export class ConversationInputForwarder {
|
|
41
|
-
private readonly parseMuxInputChunk: typeof parseMuxInputChunkFrame;
|
|
42
|
-
private readonly routeInputTokensForConversation: typeof routeInputTokensForConversationFrame;
|
|
43
|
-
private readonly classifyPaneAt: typeof classifyPaneAtFrame;
|
|
44
|
-
private readonly normalizeMuxKeyboardInputForPty: typeof normalizeMuxKeyboardInputForPtyFrame;
|
|
45
|
-
|
|
46
|
-
constructor(
|
|
47
|
-
private readonly options: ConversationInputForwarderOptions,
|
|
48
|
-
dependencies: ConversationInputForwarderDependencies = {},
|
|
49
|
-
) {
|
|
50
|
-
this.parseMuxInputChunk = dependencies.parseMuxInputChunk ?? parseMuxInputChunkFrame;
|
|
51
|
-
this.routeInputTokensForConversation =
|
|
52
|
-
dependencies.routeInputTokensForConversation ?? routeInputTokensForConversationFrame;
|
|
53
|
-
this.classifyPaneAt = dependencies.classifyPaneAt ?? classifyPaneAtFrame;
|
|
54
|
-
this.normalizeMuxKeyboardInputForPty =
|
|
55
|
-
dependencies.normalizeMuxKeyboardInputForPty ?? normalizeMuxKeyboardInputForPtyFrame;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
handleInput(input: Buffer): void {
|
|
59
|
-
const parsed = this.parseMuxInputChunk(this.options.getInputRemainder(), input);
|
|
60
|
-
this.options.setInputRemainder(parsed.remainder);
|
|
61
|
-
|
|
62
|
-
const layout = this.options.getLayout();
|
|
63
|
-
const inputConversation = this.options.getActiveConversation();
|
|
64
|
-
const { routedTokens, snapshotForInput } = this.options.inputTokenRouter.routeTokens({
|
|
65
|
-
tokens: parsed.tokens,
|
|
66
|
-
layout,
|
|
67
|
-
conversation: inputConversation,
|
|
68
|
-
snapshotForInput:
|
|
69
|
-
inputConversation === null ? null : inputConversation.oracle.snapshotWithoutHash(),
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const { mainPaneScrollRows, forwardToSession } = this.routeInputTokensForConversation({
|
|
73
|
-
tokens: routedTokens,
|
|
74
|
-
mainPaneMode: this.options.getMainPaneMode(),
|
|
75
|
-
normalizeMuxKeyboardInputForPty: this.normalizeMuxKeyboardInputForPty,
|
|
76
|
-
classifyPaneAt: (col, row) => this.classifyPaneAt(layout, col, row),
|
|
77
|
-
wheelDeltaRowsFromCode,
|
|
78
|
-
hasShiftModifier,
|
|
79
|
-
layout: {
|
|
80
|
-
paneRows: layout.paneRows,
|
|
81
|
-
rightCols: layout.rightCols,
|
|
82
|
-
rightStartCol: layout.rightStartCol,
|
|
83
|
-
},
|
|
84
|
-
snapshotForInput,
|
|
85
|
-
appMouseTrackingEnabled:
|
|
86
|
-
inputConversation === null ? false : inputConversation.oracle.isMouseTrackingEnabled(),
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
if (mainPaneScrollRows !== 0 && inputConversation !== null) {
|
|
90
|
-
inputConversation.oracle.scrollViewport(mainPaneScrollRows);
|
|
91
|
-
this.options.markDirty();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (inputConversation === null) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (
|
|
98
|
-
inputConversation.controller !== null &&
|
|
99
|
-
!this.options.isControlledByLocalHuman({
|
|
100
|
-
conversation: inputConversation,
|
|
101
|
-
controllerId: this.options.controllerId,
|
|
102
|
-
})
|
|
103
|
-
) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
for (const forwardChunk of forwardToSession) {
|
|
108
|
-
this.options.sendInputToSession(inputConversation.sessionId, forwardChunk);
|
|
109
|
-
}
|
|
110
|
-
if (forwardToSession.length > 0) {
|
|
111
|
-
this.options.noteGitActivity(inputConversation.directoryId);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
hasAltModifier,
|
|
3
|
-
isLeftButtonPress,
|
|
4
|
-
isMouseRelease,
|
|
5
|
-
isSelectionDrag,
|
|
6
|
-
isWheelMouseCode,
|
|
7
|
-
pointFromMouseEvent as pointFromMouseEventFrame,
|
|
8
|
-
reduceConversationMouseSelection as reduceConversationMouseSelectionFrame,
|
|
9
|
-
selectionText as selectionTextFrame,
|
|
10
|
-
type PaneSelection,
|
|
11
|
-
type PaneSelectionDrag,
|
|
12
|
-
type SelectionLayout,
|
|
13
|
-
} from '../mux/live-mux/selection.ts';
|
|
14
|
-
import type { TerminalSnapshotFrameCore } from '../terminal/snapshot-oracle.ts';
|
|
15
|
-
|
|
16
|
-
interface ConversationSelectionInputOptions {
|
|
17
|
-
readonly getSelection: () => PaneSelection | null;
|
|
18
|
-
readonly setSelection: (next: PaneSelection | null) => void;
|
|
19
|
-
readonly getSelectionDrag: () => PaneSelectionDrag | null;
|
|
20
|
-
readonly setSelectionDrag: (next: PaneSelectionDrag | null) => void;
|
|
21
|
-
readonly pinViewportForSelection: () => void;
|
|
22
|
-
readonly releaseViewportPinForSelection: () => void;
|
|
23
|
-
readonly markDirty: () => void;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface ConversationSelectionInputDependencies {
|
|
27
|
-
readonly pointFromMouseEvent?: typeof pointFromMouseEventFrame;
|
|
28
|
-
readonly reduceConversationMouseSelection?: typeof reduceConversationMouseSelectionFrame;
|
|
29
|
-
readonly selectionText?: typeof selectionTextFrame;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface MouseSelectionInput {
|
|
33
|
-
readonly layout: SelectionLayout;
|
|
34
|
-
readonly frame: TerminalSnapshotFrameCore;
|
|
35
|
-
readonly isMainPaneTarget: boolean;
|
|
36
|
-
readonly resolveSelectionText?: (selection: PaneSelection) => string;
|
|
37
|
-
readonly event: {
|
|
38
|
-
readonly col: number;
|
|
39
|
-
readonly row: number;
|
|
40
|
-
readonly code: number;
|
|
41
|
-
readonly final: 'M' | 'm';
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export class ConversationSelectionInput {
|
|
46
|
-
private readonly pointFromMouseEvent: typeof pointFromMouseEventFrame;
|
|
47
|
-
private readonly reduceConversationMouseSelection: typeof reduceConversationMouseSelectionFrame;
|
|
48
|
-
private readonly selectionText: typeof selectionTextFrame;
|
|
49
|
-
|
|
50
|
-
constructor(
|
|
51
|
-
private readonly options: ConversationSelectionInputOptions,
|
|
52
|
-
dependencies: ConversationSelectionInputDependencies = {},
|
|
53
|
-
) {
|
|
54
|
-
this.pointFromMouseEvent = dependencies.pointFromMouseEvent ?? pointFromMouseEventFrame;
|
|
55
|
-
this.reduceConversationMouseSelection =
|
|
56
|
-
dependencies.reduceConversationMouseSelection ?? reduceConversationMouseSelectionFrame;
|
|
57
|
-
this.selectionText = dependencies.selectionText ?? selectionTextFrame;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
clearSelectionOnTextToken(textLength: number): boolean {
|
|
61
|
-
const hasSelection =
|
|
62
|
-
this.options.getSelection() !== null || this.options.getSelectionDrag() !== null;
|
|
63
|
-
if (textLength <= 0 || !hasSelection) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
this.options.setSelection(null);
|
|
67
|
-
this.options.setSelectionDrag(null);
|
|
68
|
-
this.options.releaseViewportPinForSelection();
|
|
69
|
-
this.options.markDirty();
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
handleMouseSelection(input: MouseSelectionInput): boolean {
|
|
74
|
-
const reduced = this.reduceConversationMouseSelection({
|
|
75
|
-
selection: this.options.getSelection(),
|
|
76
|
-
selectionDrag: this.options.getSelectionDrag(),
|
|
77
|
-
point: this.pointFromMouseEvent(input.layout, input.frame, input.event),
|
|
78
|
-
isMainPaneTarget: input.isMainPaneTarget,
|
|
79
|
-
isLeftButtonPress:
|
|
80
|
-
isLeftButtonPress(input.event.code, input.event.final) && !hasAltModifier(input.event.code),
|
|
81
|
-
isSelectionDrag:
|
|
82
|
-
isSelectionDrag(input.event.code, input.event.final) && !hasAltModifier(input.event.code),
|
|
83
|
-
isMouseRelease: isMouseRelease(input.event.final),
|
|
84
|
-
isWheelMouseCode: isWheelMouseCode(input.event.code),
|
|
85
|
-
selectionTextForPane: (nextSelection) =>
|
|
86
|
-
input.resolveSelectionText === undefined
|
|
87
|
-
? this.selectionText(input.frame, nextSelection)
|
|
88
|
-
: input.resolveSelectionText(nextSelection),
|
|
89
|
-
});
|
|
90
|
-
this.options.setSelection(reduced.selection);
|
|
91
|
-
this.options.setSelectionDrag(reduced.selectionDrag);
|
|
92
|
-
if (reduced.pinViewport) {
|
|
93
|
-
this.options.pinViewportForSelection();
|
|
94
|
-
}
|
|
95
|
-
if (reduced.releaseViewportPin) {
|
|
96
|
-
this.options.releaseViewportPinForSelection();
|
|
97
|
-
}
|
|
98
|
-
if (reduced.markDirty) {
|
|
99
|
-
this.options.markDirty();
|
|
100
|
-
}
|
|
101
|
-
return reduced.consumed;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
detectMuxGlobalShortcut as detectMuxGlobalShortcutFrame,
|
|
3
|
-
type resolveMuxShortcutBindings,
|
|
4
|
-
} from '../mux/input-shortcuts.ts';
|
|
5
|
-
import { handleGlobalShortcut as handleGlobalShortcutFrame } from '../mux/live-mux/global-shortcut-handlers.ts';
|
|
6
|
-
|
|
7
|
-
type ResolvedMuxShortcutBindings = ReturnType<typeof resolveMuxShortcutBindings>;
|
|
8
|
-
type ShortcutCycleDirection = 'next' | 'previous';
|
|
9
|
-
type MainPaneMode = 'conversation' | 'project' | 'home';
|
|
10
|
-
|
|
11
|
-
interface GlobalShortcutInputOptions {
|
|
12
|
-
readonly shortcutBindings: ResolvedMuxShortcutBindings;
|
|
13
|
-
readonly requestStop: () => void;
|
|
14
|
-
readonly resolveDirectoryForAction: () => string | null;
|
|
15
|
-
readonly openNewThreadPrompt: (directoryId: string) => void;
|
|
16
|
-
readonly toggleCommandMenu: () => void;
|
|
17
|
-
readonly openOrCreateCritiqueConversationInDirectory: (directoryId: string) => Promise<void>;
|
|
18
|
-
readonly toggleGatewayProfile: () => Promise<void>;
|
|
19
|
-
readonly toggleGatewayStatusTimeline: () => Promise<void>;
|
|
20
|
-
readonly toggleGatewayRenderTrace: (conversationId: string | null) => Promise<void>;
|
|
21
|
-
readonly getMainPaneMode: () => MainPaneMode;
|
|
22
|
-
readonly getActiveConversationId: () => string | null;
|
|
23
|
-
readonly conversationsHas: (sessionId: string) => boolean;
|
|
24
|
-
readonly queueControlPlaneOp: (task: () => Promise<void>, label: string) => void;
|
|
25
|
-
readonly archiveConversation: (sessionId: string) => Promise<void>;
|
|
26
|
-
readonly refreshAllConversationTitles: () => Promise<void>;
|
|
27
|
-
readonly interruptConversation: (sessionId: string) => Promise<void>;
|
|
28
|
-
readonly takeoverConversation: (sessionId: string) => Promise<void>;
|
|
29
|
-
readonly openAddDirectoryPrompt: () => void;
|
|
30
|
-
readonly getActiveDirectoryId: () => string | null;
|
|
31
|
-
readonly directoryExists: (directoryId: string) => boolean;
|
|
32
|
-
readonly closeDirectory: (directoryId: string) => Promise<void>;
|
|
33
|
-
readonly cycleLeftNavSelection: (direction: ShortcutCycleDirection) => void;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface GlobalShortcutInputDependencies {
|
|
37
|
-
readonly detectMuxGlobalShortcut?: typeof detectMuxGlobalShortcutFrame;
|
|
38
|
-
readonly handleGlobalShortcut?: typeof handleGlobalShortcutFrame;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export class GlobalShortcutInput {
|
|
42
|
-
private readonly detectMuxGlobalShortcut: typeof detectMuxGlobalShortcutFrame;
|
|
43
|
-
private readonly handleGlobalShortcut: typeof handleGlobalShortcutFrame;
|
|
44
|
-
|
|
45
|
-
constructor(
|
|
46
|
-
private readonly options: GlobalShortcutInputOptions,
|
|
47
|
-
dependencies: GlobalShortcutInputDependencies = {},
|
|
48
|
-
) {
|
|
49
|
-
this.detectMuxGlobalShortcut =
|
|
50
|
-
dependencies.detectMuxGlobalShortcut ?? detectMuxGlobalShortcutFrame;
|
|
51
|
-
this.handleGlobalShortcut = dependencies.handleGlobalShortcut ?? handleGlobalShortcutFrame;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
handleInput(input: Buffer): boolean {
|
|
55
|
-
const shortcut = this.detectMuxGlobalShortcut(input, this.options.shortcutBindings);
|
|
56
|
-
return this.handleGlobalShortcut({
|
|
57
|
-
shortcut,
|
|
58
|
-
requestStop: this.options.requestStop,
|
|
59
|
-
resolveDirectoryForAction: this.options.resolveDirectoryForAction,
|
|
60
|
-
openNewThreadPrompt: this.options.openNewThreadPrompt,
|
|
61
|
-
toggleCommandMenu: this.options.toggleCommandMenu,
|
|
62
|
-
openOrCreateCritiqueConversationInDirectory:
|
|
63
|
-
this.options.openOrCreateCritiqueConversationInDirectory,
|
|
64
|
-
toggleGatewayProfile: this.options.toggleGatewayProfile,
|
|
65
|
-
toggleGatewayStatusTimeline: this.options.toggleGatewayStatusTimeline,
|
|
66
|
-
toggleGatewayRenderTrace: this.options.toggleGatewayRenderTrace,
|
|
67
|
-
resolveConversationForAction: () =>
|
|
68
|
-
this.options.getMainPaneMode() === 'conversation'
|
|
69
|
-
? this.options.getActiveConversationId()
|
|
70
|
-
: null,
|
|
71
|
-
conversationsHas: this.options.conversationsHas,
|
|
72
|
-
queueControlPlaneOp: this.options.queueControlPlaneOp,
|
|
73
|
-
archiveConversation: this.options.archiveConversation,
|
|
74
|
-
refreshAllConversationTitles: this.options.refreshAllConversationTitles,
|
|
75
|
-
interruptConversation: this.options.interruptConversation,
|
|
76
|
-
takeoverConversation: this.options.takeoverConversation,
|
|
77
|
-
openAddDirectoryPrompt: this.options.openAddDirectoryPrompt,
|
|
78
|
-
resolveClosableDirectoryId: () => {
|
|
79
|
-
const activeDirectoryId = this.options.getActiveDirectoryId();
|
|
80
|
-
if (this.options.getMainPaneMode() !== 'project' || activeDirectoryId === null) {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
return this.options.directoryExists(activeDirectoryId) ? activeDirectoryId : null;
|
|
84
|
-
},
|
|
85
|
-
closeDirectory: this.options.closeDirectory,
|
|
86
|
-
cycleLeftNavSelection: this.options.cycleLeftNavSelection,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|