@jmoyers/harness 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/native/ptyd/Cargo.lock +16 -0
- package/native/ptyd/Cargo.toml +7 -0
- package/native/ptyd/src/main.rs +257 -0
- package/package.json +90 -0
- package/scripts/build-ptyd.sh +73 -0
- package/scripts/control-plane-daemon.ts +277 -0
- package/scripts/cursor-hook-relay.ts +82 -0
- package/scripts/harness-animate.ts +469 -0
- package/scripts/harness-bin.js +77 -0
- package/scripts/harness-core.ts +1 -0
- package/scripts/harness-inspector.ts +439 -0
- package/scripts/harness.ts +2493 -0
- package/src/adapters/agent-session-state.ts +390 -0
- package/src/cli/gateway-record.ts +173 -0
- package/src/codex/live-session.ts +872 -0
- package/src/config/config-core.ts +1359 -0
- package/src/config/secrets-core.ts +170 -0
- package/src/control-plane/agent-realtime-api.ts +2441 -0
- package/src/control-plane/codex-session-stream.ts +392 -0
- package/src/control-plane/codex-telemetry.ts +1325 -0
- package/src/control-plane/lifecycle-hooks.ts +706 -0
- package/src/control-plane/session-summary.ts +380 -0
- package/src/control-plane/status/agent-status-reducer.ts +21 -0
- package/src/control-plane/status/reducer-base.ts +170 -0
- package/src/control-plane/status/reducers/claude-status-reducer.ts +37 -0
- package/src/control-plane/status/reducers/codex-status-reducer.ts +48 -0
- package/src/control-plane/status/reducers/critique-status-reducer.ts +15 -0
- package/src/control-plane/status/reducers/cursor-status-reducer.ts +37 -0
- package/src/control-plane/status/reducers/terminal-status-reducer.ts +15 -0
- package/src/control-plane/status/session-status-engine.ts +76 -0
- package/src/control-plane/stream-client.ts +396 -0
- package/src/control-plane/stream-command-parser.ts +1673 -0
- package/src/control-plane/stream-protocol.ts +1808 -0
- package/src/control-plane/stream-server-background.ts +486 -0
- package/src/control-plane/stream-server-command.ts +2557 -0
- package/src/control-plane/stream-server-connection.ts +234 -0
- package/src/control-plane/stream-server-observed-filter.ts +112 -0
- package/src/control-plane/stream-server-session-runtime.ts +566 -0
- package/src/control-plane/stream-server-state-store.ts +15 -0
- package/src/control-plane/stream-server.ts +3192 -0
- package/src/cursor/managed-hooks.ts +282 -0
- package/src/domain/conversations.ts +414 -0
- package/src/domain/directories.ts +78 -0
- package/src/domain/repositories.ts +123 -0
- package/src/domain/tasks.ts +148 -0
- package/src/domain/workspace.ts +156 -0
- package/src/events/normalized-events.ts +124 -0
- package/src/mux/ansi-integrity.ts +103 -0
- package/src/mux/control-plane-op-queue.ts +212 -0
- package/src/mux/conversation-rail.ts +339 -0
- package/src/mux/double-click.ts +78 -0
- package/src/mux/dual-pane-core.ts +435 -0
- package/src/mux/harness-core-ui.ts +817 -0
- package/src/mux/input-shortcuts.ts +667 -0
- package/src/mux/live-mux/actions-conversation.ts +344 -0
- package/src/mux/live-mux/actions-repository.ts +246 -0
- package/src/mux/live-mux/actions-task.ts +115 -0
- package/src/mux/live-mux/args.ts +142 -0
- package/src/mux/live-mux/command-menu.ts +298 -0
- package/src/mux/live-mux/control-plane-records.ts +546 -0
- package/src/mux/live-mux/conversation-state.ts +188 -0
- package/src/mux/live-mux/directory-resolution.ts +34 -0
- package/src/mux/live-mux/event-mapping.ts +96 -0
- package/src/mux/live-mux/gateway-profiler.ts +152 -0
- package/src/mux/live-mux/gateway-render-trace.ts +177 -0
- package/src/mux/live-mux/gateway-status-timeline.ts +166 -0
- package/src/mux/live-mux/git-parsing.ts +131 -0
- package/src/mux/live-mux/git-snapshot.ts +263 -0
- package/src/mux/live-mux/git-state.ts +136 -0
- package/src/mux/live-mux/global-shortcut-handlers.ts +143 -0
- package/src/mux/live-mux/home-pane-actions.ts +58 -0
- package/src/mux/live-mux/home-pane-drop.ts +44 -0
- package/src/mux/live-mux/home-pane-entity-click.ts +96 -0
- package/src/mux/live-mux/home-pane-pointer.ts +96 -0
- package/src/mux/live-mux/input-forwarding.ts +112 -0
- package/src/mux/live-mux/layout.ts +30 -0
- package/src/mux/live-mux/left-nav-activation.ts +103 -0
- package/src/mux/live-mux/left-nav.ts +85 -0
- package/src/mux/live-mux/left-rail-actions.ts +118 -0
- package/src/mux/live-mux/left-rail-conversation-click.ts +82 -0
- package/src/mux/live-mux/left-rail-pointer.ts +74 -0
- package/src/mux/live-mux/modal-command-menu-handler.ts +101 -0
- package/src/mux/live-mux/modal-conversation-handlers.ts +217 -0
- package/src/mux/live-mux/modal-input-reducers.ts +94 -0
- package/src/mux/live-mux/modal-overlays.ts +287 -0
- package/src/mux/live-mux/modal-pointer.ts +70 -0
- package/src/mux/live-mux/modal-prompt-handlers.ts +187 -0
- package/src/mux/live-mux/modal-task-editor-handler.ts +156 -0
- package/src/mux/live-mux/observed-stream.ts +87 -0
- package/src/mux/live-mux/palette-parsing.ts +128 -0
- package/src/mux/live-mux/pointer-routing.ts +108 -0
- package/src/mux/live-mux/process-usage.ts +53 -0
- package/src/mux/live-mux/project-pane-pointer.ts +44 -0
- package/src/mux/live-mux/rail-layout.ts +244 -0
- package/src/mux/live-mux/render-trace-analysis.ts +213 -0
- package/src/mux/live-mux/render-trace-state.ts +84 -0
- package/src/mux/live-mux/repository-folding.ts +207 -0
- package/src/mux/live-mux/runtime-shutdown.ts +51 -0
- package/src/mux/live-mux/selection.ts +411 -0
- package/src/mux/live-mux/startup-utils.ts +187 -0
- package/src/mux/live-mux/status-timeline-state.ts +82 -0
- package/src/mux/live-mux/task-pane-shortcuts.ts +206 -0
- package/src/mux/live-mux/terminal-palette.ts +79 -0
- package/src/mux/new-thread-prompt.ts +165 -0
- package/src/mux/project-tree.ts +295 -0
- package/src/mux/render-frame.ts +113 -0
- package/src/mux/runtime-wiring.ts +185 -0
- package/src/mux/selector-index.ts +160 -0
- package/src/mux/startup-sequencer.ts +238 -0
- package/src/mux/task-composer.ts +289 -0
- package/src/mux/task-focused-pane.ts +417 -0
- package/src/mux/task-screen-keybindings.ts +539 -0
- package/src/mux/terminal-input-modes.ts +35 -0
- package/src/mux/workspace-path.ts +55 -0
- package/src/mux/workspace-rail-model.ts +701 -0
- package/src/mux/workspace-rail.ts +247 -0
- package/src/perf/perf-core.ts +307 -0
- package/src/pty/pty_host.ts +217 -0
- package/src/pty/session-broker.ts +158 -0
- package/src/recording/terminal-recording.ts +383 -0
- package/src/services/control-plane.ts +567 -0
- package/src/services/conversation-lifecycle.ts +176 -0
- package/src/services/conversation-startup-hydration.ts +47 -0
- package/src/services/directory-hydration.ts +49 -0
- package/src/services/event-persistence.ts +104 -0
- package/src/services/mux-ui-state-persistence.ts +82 -0
- package/src/services/output-load-sampler.ts +231 -0
- package/src/services/process-usage-refresh.ts +88 -0
- package/src/services/recording.ts +75 -0
- package/src/services/render-trace-recorder.ts +177 -0
- package/src/services/runtime-control-actions.ts +123 -0
- package/src/services/runtime-control-plane-ops.ts +131 -0
- package/src/services/runtime-conversation-actions.ts +113 -0
- package/src/services/runtime-conversation-activation.ts +78 -0
- package/src/services/runtime-conversation-starter.ts +171 -0
- package/src/services/runtime-conversation-title-edit.ts +149 -0
- package/src/services/runtime-directory-actions.ts +164 -0
- package/src/services/runtime-envelope-handler.ts +198 -0
- package/src/services/runtime-git-state.ts +92 -0
- package/src/services/runtime-input-pipeline.ts +50 -0
- package/src/services/runtime-input-router.ts +202 -0
- package/src/services/runtime-layout-resize.ts +236 -0
- package/src/services/runtime-left-rail-render.ts +159 -0
- package/src/services/runtime-main-pane-input.ts +230 -0
- package/src/services/runtime-modal-input.ts +119 -0
- package/src/services/runtime-navigation-input.ts +207 -0
- package/src/services/runtime-process-wiring.ts +68 -0
- package/src/services/runtime-rail-input.ts +287 -0
- package/src/services/runtime-render-flush.ts +146 -0
- package/src/services/runtime-render-lifecycle.ts +104 -0
- package/src/services/runtime-render-orchestrator.ts +108 -0
- package/src/services/runtime-render-pipeline.ts +167 -0
- package/src/services/runtime-render-state.ts +72 -0
- package/src/services/runtime-repository-actions.ts +197 -0
- package/src/services/runtime-right-pane-render.ts +132 -0
- package/src/services/runtime-shutdown.ts +79 -0
- package/src/services/runtime-stream-subscriptions.ts +56 -0
- package/src/services/runtime-task-composer-persistence.ts +139 -0
- package/src/services/runtime-task-editor-actions.ts +83 -0
- package/src/services/runtime-task-pane-actions.ts +198 -0
- package/src/services/runtime-task-pane-shortcuts.ts +189 -0
- package/src/services/runtime-task-pane.ts +62 -0
- package/src/services/runtime-workspace-actions.ts +153 -0
- package/src/services/runtime-workspace-observed-events.ts +190 -0
- package/src/services/session-projection-instrumentation.ts +190 -0
- package/src/services/startup-background-probe.ts +91 -0
- package/src/services/startup-background-resume.ts +65 -0
- package/src/services/startup-orchestrator.ts +166 -0
- package/src/services/startup-output-tracker.ts +54 -0
- package/src/services/startup-paint-tracker.ts +115 -0
- package/src/services/startup-persisted-conversation-queue.ts +45 -0
- package/src/services/startup-settled-gate.ts +67 -0
- package/src/services/startup-shutdown.ts +53 -0
- package/src/services/startup-span-tracker.ts +77 -0
- package/src/services/startup-state-hydration.ts +94 -0
- package/src/services/startup-visibility.ts +35 -0
- package/src/services/status-timeline-recorder.ts +144 -0
- package/src/services/task-pane-selection-actions.ts +153 -0
- package/src/services/task-planning-hydration.ts +58 -0
- package/src/services/task-planning-observed-events.ts +89 -0
- package/src/services/workspace-observed-events.ts +113 -0
- package/src/store/control-plane-store-normalize.ts +760 -0
- package/src/store/control-plane-store-types.ts +224 -0
- package/src/store/control-plane-store.ts +2951 -0
- package/src/store/event-store.ts +253 -0
- package/src/store/sqlite.ts +81 -0
- package/src/terminal/compat-matrix.ts +345 -0
- package/src/terminal/differential-checkpoints.ts +132 -0
- package/src/terminal/parity-suite.ts +441 -0
- package/src/terminal/snapshot-oracle.ts +1840 -0
- package/src/ui/conversation-input-forwarder.ts +114 -0
- package/src/ui/conversation-selection-input.ts +103 -0
- package/src/ui/debug-footer-notice.ts +39 -0
- package/src/ui/global-shortcut-input.ts +126 -0
- package/src/ui/input-preflight.ts +68 -0
- package/src/ui/input-token-router.ts +312 -0
- package/src/ui/input.ts +238 -0
- package/src/ui/kit.ts +509 -0
- package/src/ui/left-nav-input.ts +80 -0
- package/src/ui/left-rail-pointer-input.ts +148 -0
- package/src/ui/main-pane-pointer-input.ts +150 -0
- package/src/ui/modals/manager.ts +192 -0
- package/src/ui/mux-theme.ts +529 -0
- package/src/ui/panes/conversation.ts +19 -0
- package/src/ui/panes/home-gridfire.ts +302 -0
- package/src/ui/panes/home.ts +109 -0
- package/src/ui/panes/left-rail.ts +12 -0
- package/src/ui/panes/project.ts +44 -0
- package/src/ui/pointer-routing-input.ts +158 -0
- package/src/ui/repository-fold-input.ts +91 -0
- package/src/ui/screen.ts +210 -0
- package/src/ui/surface.ts +224 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
StreamObservedEvent,
|
|
3
|
+
StreamServerEnvelope,
|
|
4
|
+
} from '../control-plane/stream-protocol.ts';
|
|
5
|
+
import type { PtyExit } from '../pty/pty_host.ts';
|
|
6
|
+
|
|
7
|
+
interface RuntimeEnvelopeConversationLike {
|
|
8
|
+
directoryId: string | null;
|
|
9
|
+
agentType: string;
|
|
10
|
+
adapterState: Record<string, unknown>;
|
|
11
|
+
scope: unknown;
|
|
12
|
+
lastEventAt: string | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface RuntimeEnvelopeOutputIngestResult<TConversation extends RuntimeEnvelopeConversationLike> {
|
|
16
|
+
readonly conversation: TConversation;
|
|
17
|
+
readonly cursorRegressed: boolean;
|
|
18
|
+
readonly previousCursor: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface RuntimeEnvelopeHandlerOptions<
|
|
22
|
+
TConversation extends RuntimeEnvelopeConversationLike,
|
|
23
|
+
TNormalizedEvent extends { ts: string },
|
|
24
|
+
> {
|
|
25
|
+
readonly perfNowNs: () => bigint;
|
|
26
|
+
readonly isRemoved: (sessionId: string) => boolean;
|
|
27
|
+
readonly ensureConversation: (sessionId: string) => TConversation;
|
|
28
|
+
readonly ingestOutputChunk: (input: {
|
|
29
|
+
sessionId: string;
|
|
30
|
+
cursor: number;
|
|
31
|
+
chunk: Buffer;
|
|
32
|
+
ensureConversation: (sessionId: string) => TConversation;
|
|
33
|
+
}) => RuntimeEnvelopeOutputIngestResult<TConversation>;
|
|
34
|
+
readonly noteGitActivity: (directoryId: string | null) => void;
|
|
35
|
+
readonly recordOutputChunk: (input: {
|
|
36
|
+
sessionId: string;
|
|
37
|
+
chunkLength: number;
|
|
38
|
+
active: boolean;
|
|
39
|
+
}) => void;
|
|
40
|
+
readonly startupOutputChunk: (sessionId: string, chunkLength: number) => void;
|
|
41
|
+
readonly startupPaintOutputChunk: (sessionId: string) => void;
|
|
42
|
+
readonly recordPerfEvent: (
|
|
43
|
+
name: string,
|
|
44
|
+
attrs: Record<string, string | number | boolean>,
|
|
45
|
+
) => void;
|
|
46
|
+
readonly mapTerminalOutputToNormalizedEvent: (
|
|
47
|
+
chunk: Buffer,
|
|
48
|
+
scope: unknown,
|
|
49
|
+
idFactory: () => string,
|
|
50
|
+
) => TNormalizedEvent;
|
|
51
|
+
readonly mapSessionEventToNormalizedEvent: (
|
|
52
|
+
event: unknown,
|
|
53
|
+
scope: unknown,
|
|
54
|
+
idFactory: () => string,
|
|
55
|
+
) => TNormalizedEvent | null;
|
|
56
|
+
readonly observedAtFromSessionEvent: (event: unknown) => string;
|
|
57
|
+
readonly mergeAdapterStateFromSessionEvent: (
|
|
58
|
+
agentType: string,
|
|
59
|
+
adapterState: Record<string, unknown>,
|
|
60
|
+
event: unknown,
|
|
61
|
+
observedAt: string,
|
|
62
|
+
) => Record<string, unknown> | null;
|
|
63
|
+
readonly enqueueEvent: (event: TNormalizedEvent) => void;
|
|
64
|
+
readonly activeConversationId: () => string | null;
|
|
65
|
+
readonly markSessionExited: (input: {
|
|
66
|
+
sessionId: string;
|
|
67
|
+
exit: PtyExit;
|
|
68
|
+
exitedAt: string;
|
|
69
|
+
}) => void;
|
|
70
|
+
readonly deletePtySize: (sessionId: string) => void;
|
|
71
|
+
readonly setExit: (exit: PtyExit) => void;
|
|
72
|
+
readonly markDirty: () => void;
|
|
73
|
+
readonly nowIso: () => string;
|
|
74
|
+
readonly recordOutputHandled: (durationMs: number) => void;
|
|
75
|
+
readonly conversationById: (sessionId: string) => TConversation | undefined;
|
|
76
|
+
readonly applyObservedWorkspaceEvent: (event: StreamObservedEvent) => void;
|
|
77
|
+
readonly applyObservedGitStatusEvent: (event: StreamObservedEvent) => void;
|
|
78
|
+
readonly applyObservedTaskPlanningEvent: (event: StreamObservedEvent) => void;
|
|
79
|
+
readonly idFactory: () => string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export class RuntimeEnvelopeHandler<
|
|
83
|
+
TConversation extends RuntimeEnvelopeConversationLike,
|
|
84
|
+
TNormalizedEvent extends { ts: string },
|
|
85
|
+
> {
|
|
86
|
+
constructor(
|
|
87
|
+
private readonly options: RuntimeEnvelopeHandlerOptions<TConversation, TNormalizedEvent>,
|
|
88
|
+
) {}
|
|
89
|
+
|
|
90
|
+
handleEnvelope(envelope: StreamServerEnvelope): void {
|
|
91
|
+
if (envelope.kind === 'pty.output') {
|
|
92
|
+
const outputHandledStartedAtNs = this.options.perfNowNs();
|
|
93
|
+
if (this.options.isRemoved(envelope.sessionId)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const chunk = Buffer.from(envelope.chunkBase64, 'base64');
|
|
97
|
+
const outputIngest = this.options.ingestOutputChunk({
|
|
98
|
+
sessionId: envelope.sessionId,
|
|
99
|
+
cursor: envelope.cursor,
|
|
100
|
+
chunk,
|
|
101
|
+
ensureConversation: this.options.ensureConversation,
|
|
102
|
+
});
|
|
103
|
+
const conversation = outputIngest.conversation;
|
|
104
|
+
this.options.noteGitActivity(conversation.directoryId);
|
|
105
|
+
this.options.recordOutputChunk({
|
|
106
|
+
sessionId: envelope.sessionId,
|
|
107
|
+
chunkLength: chunk.length,
|
|
108
|
+
active: this.options.activeConversationId() === envelope.sessionId,
|
|
109
|
+
});
|
|
110
|
+
this.options.startupOutputChunk(envelope.sessionId, chunk.length);
|
|
111
|
+
this.options.startupPaintOutputChunk(envelope.sessionId);
|
|
112
|
+
if (outputIngest.cursorRegressed) {
|
|
113
|
+
this.options.recordPerfEvent('mux.output.cursor-regression', {
|
|
114
|
+
sessionId: envelope.sessionId,
|
|
115
|
+
previousCursor: outputIngest.previousCursor,
|
|
116
|
+
cursor: envelope.cursor,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const normalized = this.options.mapTerminalOutputToNormalizedEvent(
|
|
121
|
+
chunk,
|
|
122
|
+
conversation.scope,
|
|
123
|
+
this.options.idFactory,
|
|
124
|
+
);
|
|
125
|
+
this.options.enqueueEvent(normalized);
|
|
126
|
+
conversation.lastEventAt = normalized.ts;
|
|
127
|
+
if (this.options.activeConversationId() === envelope.sessionId) {
|
|
128
|
+
this.options.markDirty();
|
|
129
|
+
}
|
|
130
|
+
const outputHandledDurationMs =
|
|
131
|
+
Number(this.options.perfNowNs() - outputHandledStartedAtNs) / 1e6;
|
|
132
|
+
this.options.recordOutputHandled(outputHandledDurationMs);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (envelope.kind === 'pty.event') {
|
|
137
|
+
if (this.options.isRemoved(envelope.sessionId)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const conversation = this.options.ensureConversation(envelope.sessionId);
|
|
141
|
+
this.options.noteGitActivity(conversation.directoryId);
|
|
142
|
+
const observedAt = this.options.observedAtFromSessionEvent(envelope.event);
|
|
143
|
+
const updatedAdapterState = this.options.mergeAdapterStateFromSessionEvent(
|
|
144
|
+
conversation.agentType,
|
|
145
|
+
conversation.adapterState,
|
|
146
|
+
envelope.event,
|
|
147
|
+
observedAt,
|
|
148
|
+
);
|
|
149
|
+
if (updatedAdapterState !== null) {
|
|
150
|
+
conversation.adapterState = updatedAdapterState;
|
|
151
|
+
}
|
|
152
|
+
const normalized = this.options.mapSessionEventToNormalizedEvent(
|
|
153
|
+
envelope.event,
|
|
154
|
+
conversation.scope,
|
|
155
|
+
this.options.idFactory,
|
|
156
|
+
);
|
|
157
|
+
if (normalized !== null) {
|
|
158
|
+
this.options.enqueueEvent(normalized);
|
|
159
|
+
}
|
|
160
|
+
if (envelope.event.type === 'session-exit') {
|
|
161
|
+
this.options.setExit(envelope.event.exit);
|
|
162
|
+
this.options.markSessionExited({
|
|
163
|
+
sessionId: envelope.sessionId,
|
|
164
|
+
exit: envelope.event.exit,
|
|
165
|
+
exitedAt: this.options.nowIso(),
|
|
166
|
+
});
|
|
167
|
+
this.options.deletePtySize(envelope.sessionId);
|
|
168
|
+
}
|
|
169
|
+
this.options.markDirty();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (envelope.kind === 'pty.exit') {
|
|
174
|
+
if (this.options.isRemoved(envelope.sessionId)) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const conversation = this.options.conversationById(envelope.sessionId);
|
|
178
|
+
if (conversation !== undefined) {
|
|
179
|
+
this.options.noteGitActivity(conversation.directoryId);
|
|
180
|
+
this.options.setExit(envelope.exit);
|
|
181
|
+
this.options.markSessionExited({
|
|
182
|
+
sessionId: envelope.sessionId,
|
|
183
|
+
exit: envelope.exit,
|
|
184
|
+
exitedAt: this.options.nowIso(),
|
|
185
|
+
});
|
|
186
|
+
this.options.deletePtySize(envelope.sessionId);
|
|
187
|
+
}
|
|
188
|
+
this.options.markDirty();
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (envelope.kind === 'stream.event') {
|
|
193
|
+
this.options.applyObservedWorkspaceEvent(envelope.event);
|
|
194
|
+
this.options.applyObservedGitStatusEvent(envelope.event);
|
|
195
|
+
this.options.applyObservedTaskPlanningEvent(envelope.event);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { StreamObservedEvent } from '../control-plane/stream-protocol.ts';
|
|
2
|
+
import {
|
|
3
|
+
applyObservedGitStatusEvent as applyObservedGitStatusEventFn,
|
|
4
|
+
deleteDirectoryGitState as deleteDirectoryGitStateFn,
|
|
5
|
+
type GitRepositorySnapshot,
|
|
6
|
+
type GitSummary,
|
|
7
|
+
} from '../mux/live-mux/git-state.ts';
|
|
8
|
+
|
|
9
|
+
interface RepositoryRecordShape {
|
|
10
|
+
readonly repositoryId: string;
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly remoteUrl: string;
|
|
13
|
+
readonly defaultBranch: string;
|
|
14
|
+
readonly archivedAt: string | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface RuntimeGitStateDirectoryManager {
|
|
18
|
+
hasDirectory(directoryId: string): boolean;
|
|
19
|
+
ensureGitSummary(directoryId: string, loadingSummary: GitSummary): void;
|
|
20
|
+
syncGitSummariesWithDirectories(loadingSummary: GitSummary): void;
|
|
21
|
+
mutableGitSummaries(): Map<string, GitSummary>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface RuntimeGitStateOptions<TRepositoryRecord extends RepositoryRecordShape> {
|
|
25
|
+
readonly enabled: boolean;
|
|
26
|
+
readonly directoryManager: RuntimeGitStateDirectoryManager;
|
|
27
|
+
readonly directoryRepositorySnapshotByDirectoryId: Map<string, GitRepositorySnapshot>;
|
|
28
|
+
readonly repositoryAssociationByDirectoryId: Map<string, string>;
|
|
29
|
+
readonly repositories: Map<string, TRepositoryRecord>;
|
|
30
|
+
readonly parseRepositoryRecord: (input: unknown) => TRepositoryRecord | null;
|
|
31
|
+
readonly loadingSummary: GitSummary;
|
|
32
|
+
readonly emptyRepositorySnapshot: GitRepositorySnapshot;
|
|
33
|
+
readonly syncRepositoryAssociationsWithDirectorySnapshots: () => void;
|
|
34
|
+
readonly syncTaskPaneRepositorySelection: () => void;
|
|
35
|
+
readonly markDirty: () => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class RuntimeGitState<TRepositoryRecord extends RepositoryRecordShape> {
|
|
39
|
+
constructor(private readonly options: RuntimeGitStateOptions<TRepositoryRecord>) {}
|
|
40
|
+
|
|
41
|
+
deleteDirectoryGitState(directoryId: string): void {
|
|
42
|
+
deleteDirectoryGitStateFn(
|
|
43
|
+
directoryId,
|
|
44
|
+
this.options.directoryManager.mutableGitSummaries(),
|
|
45
|
+
this.options.directoryRepositorySnapshotByDirectoryId,
|
|
46
|
+
this.options.repositoryAssociationByDirectoryId,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
syncGitStateWithDirectories(): void {
|
|
51
|
+
this.options.directoryManager.syncGitSummariesWithDirectories(this.options.loadingSummary);
|
|
52
|
+
this.options.syncRepositoryAssociationsWithDirectorySnapshots();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
noteGitActivity(directoryId: string | null): void {
|
|
56
|
+
if (directoryId === null || !this.options.directoryManager.hasDirectory(directoryId)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.options.directoryManager.ensureGitSummary(directoryId, this.options.loadingSummary);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
applyObservedGitStatusEvent(observed: StreamObservedEvent): void {
|
|
63
|
+
const reduced = applyObservedGitStatusEventFn({
|
|
64
|
+
enabled: this.options.enabled,
|
|
65
|
+
observed,
|
|
66
|
+
gitSummaryByDirectoryId: this.options.directoryManager.mutableGitSummaries(),
|
|
67
|
+
loadingSummary: this.options.loadingSummary,
|
|
68
|
+
directoryRepositorySnapshotByDirectoryId:
|
|
69
|
+
this.options.directoryRepositorySnapshotByDirectoryId,
|
|
70
|
+
emptyRepositorySnapshot: this.options.emptyRepositorySnapshot,
|
|
71
|
+
repositoryAssociationByDirectoryId: this.options.repositoryAssociationByDirectoryId,
|
|
72
|
+
repositories: this.options.repositories,
|
|
73
|
+
parseRepositoryRecord: this.options.parseRepositoryRecord,
|
|
74
|
+
repositoryRecordChanged: (previous, repository) =>
|
|
75
|
+
previous === undefined ||
|
|
76
|
+
previous.name !== repository.name ||
|
|
77
|
+
previous.remoteUrl !== repository.remoteUrl ||
|
|
78
|
+
previous.defaultBranch !== repository.defaultBranch ||
|
|
79
|
+
previous.archivedAt !== repository.archivedAt,
|
|
80
|
+
});
|
|
81
|
+
if (!reduced.handled) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (reduced.repositoryRecordChanged) {
|
|
85
|
+
this.options.syncRepositoryAssociationsWithDirectorySnapshots();
|
|
86
|
+
this.options.syncTaskPaneRepositorySelection();
|
|
87
|
+
}
|
|
88
|
+
if (reduced.changed) {
|
|
89
|
+
this.options.markDirty();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ConversationInputForwarder } from '../ui/conversation-input-forwarder.ts';
|
|
2
|
+
import { InputPreflight } from '../ui/input-preflight.ts';
|
|
3
|
+
|
|
4
|
+
type InputPreflightOptions = ConstructorParameters<typeof InputPreflight>[0];
|
|
5
|
+
type ConversationInputForwarderOptions = ConstructorParameters<
|
|
6
|
+
typeof ConversationInputForwarder
|
|
7
|
+
>[0];
|
|
8
|
+
|
|
9
|
+
interface RuntimeInputPipelineOptions {
|
|
10
|
+
readonly preflight: InputPreflightOptions;
|
|
11
|
+
readonly forwarder: ConversationInputForwarderOptions;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface RuntimeInputPipelineDependencies {
|
|
15
|
+
readonly createInputPreflight?: (
|
|
16
|
+
options: InputPreflightOptions,
|
|
17
|
+
) => Pick<InputPreflight, 'nextInput'>;
|
|
18
|
+
readonly createConversationInputForwarder?: (
|
|
19
|
+
options: ConversationInputForwarderOptions,
|
|
20
|
+
) => Pick<ConversationInputForwarder, 'handleInput'>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class RuntimeInputPipeline {
|
|
24
|
+
private readonly inputPreflight: Pick<InputPreflight, 'nextInput'>;
|
|
25
|
+
private readonly conversationInputForwarder: Pick<ConversationInputForwarder, 'handleInput'>;
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
options: RuntimeInputPipelineOptions,
|
|
29
|
+
dependencies: RuntimeInputPipelineDependencies = {},
|
|
30
|
+
) {
|
|
31
|
+
const createInputPreflight =
|
|
32
|
+
dependencies.createInputPreflight ??
|
|
33
|
+
((preflightOptions: InputPreflightOptions) => new InputPreflight(preflightOptions));
|
|
34
|
+
const createConversationInputForwarder =
|
|
35
|
+
dependencies.createConversationInputForwarder ??
|
|
36
|
+
((forwarderOptions: ConversationInputForwarderOptions) =>
|
|
37
|
+
new ConversationInputForwarder(forwarderOptions));
|
|
38
|
+
|
|
39
|
+
this.inputPreflight = createInputPreflight(options.preflight);
|
|
40
|
+
this.conversationInputForwarder = createConversationInputForwarder(options.forwarder);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
handleInput(input: Buffer): void {
|
|
44
|
+
const sanitized = this.inputPreflight.nextInput(input);
|
|
45
|
+
if (sanitized === null) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.conversationInputForwarder.handleInput(sanitized);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { RuntimeMainPaneInput } from './runtime-main-pane-input.ts';
|
|
2
|
+
import { RuntimeModalInput } from './runtime-modal-input.ts';
|
|
3
|
+
import { RuntimeRailInput } from './runtime-rail-input.ts';
|
|
4
|
+
import type { CommandMenuActionDescriptor } from '../mux/live-mux/command-menu.ts';
|
|
5
|
+
|
|
6
|
+
type RuntimeModalInputOptions = ConstructorParameters<typeof RuntimeModalInput>[0];
|
|
7
|
+
type RuntimeRailInputOptions = ConstructorParameters<typeof RuntimeRailInput>[0];
|
|
8
|
+
type RuntimeMainPaneInputOptions = ConstructorParameters<typeof RuntimeMainPaneInput>[0];
|
|
9
|
+
type RuntimeMainPaneInputWithoutLeftRail = Omit<
|
|
10
|
+
RuntimeMainPaneInputOptions,
|
|
11
|
+
'leftRailPointerInput'
|
|
12
|
+
>;
|
|
13
|
+
type RuntimeWorkspaceActions = RuntimeModalInputOptions['workspaceActions'] &
|
|
14
|
+
RuntimeRailInputOptions['runtimeWorkspaceActions'] &
|
|
15
|
+
RuntimeMainPaneInputWithoutLeftRail['workspaceActions'];
|
|
16
|
+
type RuntimeTaskEditorActions = RuntimeModalInputOptions['taskEditorActions'];
|
|
17
|
+
type RuntimeShortcutBindings = RuntimeRailInputOptions['shortcutBindings'];
|
|
18
|
+
type RuntimeConversationRecord = {
|
|
19
|
+
title: string;
|
|
20
|
+
directoryId: string | null;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
interface RuntimeInputRouterOptions {
|
|
24
|
+
readonly workspace: RuntimeModalInputOptions['workspace'];
|
|
25
|
+
readonly conversations: ReadonlyMap<string, RuntimeConversationRecord>;
|
|
26
|
+
readonly runtimeWorkspaceActions: RuntimeWorkspaceActions;
|
|
27
|
+
readonly runtimeTaskEditorActions: RuntimeTaskEditorActions;
|
|
28
|
+
readonly detectShortcut: (input: Buffer, bindings: RuntimeShortcutBindings) => string | null;
|
|
29
|
+
readonly modalDismissShortcutBindings: RuntimeShortcutBindings;
|
|
30
|
+
readonly shortcutBindings: RuntimeShortcutBindings;
|
|
31
|
+
readonly dismissOnOutsideClick: RuntimeModalInputOptions['dismissOnOutsideClick'];
|
|
32
|
+
readonly buildCommandMenuModalOverlay: RuntimeModalInputOptions['buildCommandMenuModalOverlay'];
|
|
33
|
+
readonly buildConversationTitleModalOverlay: RuntimeModalInputOptions['buildConversationTitleModalOverlay'];
|
|
34
|
+
readonly buildNewThreadModalOverlay: RuntimeModalInputOptions['buildNewThreadModalOverlay'];
|
|
35
|
+
readonly resolveNewThreadPromptAgentByRow: RuntimeModalInputOptions['resolveNewThreadPromptAgentByRow'];
|
|
36
|
+
readonly stopConversationTitleEdit: (persistPending: boolean) => void;
|
|
37
|
+
readonly queueControlPlaneOp: RuntimeModalInputOptions['queueControlPlaneOp'];
|
|
38
|
+
readonly normalizeGitHubRemoteUrl: RuntimeModalInputOptions['normalizeGitHubRemoteUrl'];
|
|
39
|
+
readonly repositoriesHas: (repositoryId: string) => boolean;
|
|
40
|
+
readonly markDirty: () => void;
|
|
41
|
+
readonly scheduleConversationTitlePersist: () => void;
|
|
42
|
+
readonly resolveCommandMenuActions: () => readonly CommandMenuActionDescriptor[];
|
|
43
|
+
readonly executeCommandMenuAction: (actionId: string) => void;
|
|
44
|
+
readonly requestStop: RuntimeRailInputOptions['requestStop'];
|
|
45
|
+
readonly resolveDirectoryForAction: RuntimeRailInputOptions['resolveDirectoryForAction'];
|
|
46
|
+
readonly toggleCommandMenu: RuntimeRailInputOptions['toggleCommandMenu'];
|
|
47
|
+
readonly openNewThreadPrompt: RuntimeRailInputOptions['openNewThreadPrompt'];
|
|
48
|
+
readonly firstDirectoryForRepositoryGroup: RuntimeRailInputOptions['firstDirectoryForRepositoryGroup'];
|
|
49
|
+
readonly enterHomePane: RuntimeRailInputOptions['enterHomePane'];
|
|
50
|
+
readonly enterProjectPane: RuntimeRailInputOptions['enterProjectPane'];
|
|
51
|
+
readonly queuePersistMuxUiState: RuntimeRailInputOptions['queuePersistMuxUiState'];
|
|
52
|
+
readonly repositoryGroupIdForDirectory: RuntimeRailInputOptions['repositoryGroupIdForDirectory'];
|
|
53
|
+
readonly toggleRepositoryGroup: RuntimeRailInputOptions['toggleRepositoryGroup'];
|
|
54
|
+
readonly collapseRepositoryGroup: RuntimeRailInputOptions['collapseRepositoryGroup'];
|
|
55
|
+
readonly expandRepositoryGroup: RuntimeRailInputOptions['expandRepositoryGroup'];
|
|
56
|
+
readonly collapseAllRepositoryGroups: RuntimeRailInputOptions['collapseAllRepositoryGroups'];
|
|
57
|
+
readonly expandAllRepositoryGroups: RuntimeRailInputOptions['expandAllRepositoryGroups'];
|
|
58
|
+
readonly directoriesHas: RuntimeRailInputOptions['directoriesHas'];
|
|
59
|
+
readonly conversationDirectoryId: RuntimeRailInputOptions['conversationDirectoryId'];
|
|
60
|
+
readonly conversationsHas: RuntimeRailInputOptions['conversationsHas'];
|
|
61
|
+
readonly getMainPaneMode: RuntimeRailInputOptions['getMainPaneMode'];
|
|
62
|
+
readonly getActiveConversationId: RuntimeRailInputOptions['getActiveConversationId'];
|
|
63
|
+
readonly getActiveDirectoryId: RuntimeRailInputOptions['getActiveDirectoryId'];
|
|
64
|
+
readonly forwardInterruptAllToActiveConversation?: RuntimeRailInputOptions['forwardInterruptAllToActiveConversation'];
|
|
65
|
+
readonly interruptAllDoubleTapWindowMs?: RuntimeRailInputOptions['interruptAllDoubleTapWindowMs'];
|
|
66
|
+
readonly chordTimeoutMs: RuntimeRailInputOptions['chordTimeoutMs'];
|
|
67
|
+
readonly collapseAllChordPrefix: RuntimeRailInputOptions['collapseAllChordPrefix'];
|
|
68
|
+
readonly releaseViewportPinForSelection: RuntimeRailInputOptions['releaseViewportPinForSelection'];
|
|
69
|
+
readonly beginConversationTitleEdit: RuntimeRailInputOptions['beginConversationTitleEdit'];
|
|
70
|
+
readonly resetConversationPaneFrameCache: RuntimeRailInputOptions['resetConversationPaneFrameCache'];
|
|
71
|
+
readonly conversationTitleEditDoubleClickWindowMs: RuntimeRailInputOptions['conversationTitleEditDoubleClickWindowMs'];
|
|
72
|
+
readonly projectPaneActionAtRow: RuntimeMainPaneInputWithoutLeftRail['projectPaneActionAtRow'];
|
|
73
|
+
readonly queueCloseDirectory: RuntimeMainPaneInputWithoutLeftRail['queueCloseDirectory'];
|
|
74
|
+
readonly selectTaskById: RuntimeMainPaneInputWithoutLeftRail['selectTaskById'];
|
|
75
|
+
readonly selectRepositoryById: RuntimeMainPaneInputWithoutLeftRail['selectRepositoryById'];
|
|
76
|
+
readonly taskPaneActionAtCell: RuntimeMainPaneInputWithoutLeftRail['taskPaneActionAtCell'];
|
|
77
|
+
readonly taskPaneActionAtRow: RuntimeMainPaneInputWithoutLeftRail['taskPaneActionAtRow'];
|
|
78
|
+
readonly taskPaneTaskIdAtRow: RuntimeMainPaneInputWithoutLeftRail['taskPaneTaskIdAtRow'];
|
|
79
|
+
readonly taskPaneRepositoryIdAtRow: RuntimeMainPaneInputWithoutLeftRail['taskPaneRepositoryIdAtRow'];
|
|
80
|
+
readonly applyPaneDividerAtCol: RuntimeMainPaneInputWithoutLeftRail['applyPaneDividerAtCol'];
|
|
81
|
+
readonly pinViewportForSelection: RuntimeMainPaneInputWithoutLeftRail['pinViewportForSelection'];
|
|
82
|
+
readonly homePaneEditDoubleClickWindowMs: RuntimeMainPaneInputWithoutLeftRail['homePaneEditDoubleClickWindowMs'];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export class RuntimeInputRouter {
|
|
86
|
+
private readonly modalInput: RuntimeModalInput;
|
|
87
|
+
private readonly railInput: RuntimeRailInput;
|
|
88
|
+
private readonly mainPaneInput: RuntimeMainPaneInput;
|
|
89
|
+
|
|
90
|
+
constructor(options: RuntimeInputRouterOptions) {
|
|
91
|
+
this.modalInput = new RuntimeModalInput({
|
|
92
|
+
workspace: options.workspace,
|
|
93
|
+
conversations: options.conversations,
|
|
94
|
+
workspaceActions: options.runtimeWorkspaceActions,
|
|
95
|
+
taskEditorActions: options.runtimeTaskEditorActions,
|
|
96
|
+
isModalDismissShortcut: (input) =>
|
|
97
|
+
options.detectShortcut(input, options.modalDismissShortcutBindings) === 'mux.app.quit',
|
|
98
|
+
isCommandMenuToggleShortcut: (input) =>
|
|
99
|
+
options.detectShortcut(input, options.shortcutBindings) === 'mux.command-menu.toggle',
|
|
100
|
+
isArchiveConversationShortcut: (input) => {
|
|
101
|
+
const action = options.detectShortcut(input, options.shortcutBindings);
|
|
102
|
+
return action === 'mux.conversation.archive' || action === 'mux.conversation.delete';
|
|
103
|
+
},
|
|
104
|
+
dismissOnOutsideClick: options.dismissOnOutsideClick,
|
|
105
|
+
buildCommandMenuModalOverlay: options.buildCommandMenuModalOverlay,
|
|
106
|
+
buildConversationTitleModalOverlay: options.buildConversationTitleModalOverlay,
|
|
107
|
+
buildNewThreadModalOverlay: options.buildNewThreadModalOverlay,
|
|
108
|
+
resolveNewThreadPromptAgentByRow: options.resolveNewThreadPromptAgentByRow,
|
|
109
|
+
stopConversationTitleEdit: options.stopConversationTitleEdit,
|
|
110
|
+
queueControlPlaneOp: options.queueControlPlaneOp,
|
|
111
|
+
normalizeGitHubRemoteUrl: options.normalizeGitHubRemoteUrl,
|
|
112
|
+
repositoriesHas: options.repositoriesHas,
|
|
113
|
+
markDirty: options.markDirty,
|
|
114
|
+
scheduleConversationTitlePersist: options.scheduleConversationTitlePersist,
|
|
115
|
+
resolveCommandMenuActions: options.resolveCommandMenuActions,
|
|
116
|
+
executeCommandMenuAction: options.executeCommandMenuAction,
|
|
117
|
+
});
|
|
118
|
+
const runtimeRailOptions: RuntimeRailInputOptions = {
|
|
119
|
+
workspace: options.workspace,
|
|
120
|
+
shortcutBindings: options.shortcutBindings,
|
|
121
|
+
queueControlPlaneOp: options.queueControlPlaneOp,
|
|
122
|
+
runtimeWorkspaceActions: options.runtimeWorkspaceActions,
|
|
123
|
+
requestStop: options.requestStop,
|
|
124
|
+
resolveDirectoryForAction: options.resolveDirectoryForAction,
|
|
125
|
+
openNewThreadPrompt: options.openNewThreadPrompt,
|
|
126
|
+
toggleCommandMenu: options.toggleCommandMenu,
|
|
127
|
+
firstDirectoryForRepositoryGroup: options.firstDirectoryForRepositoryGroup,
|
|
128
|
+
enterHomePane: options.enterHomePane,
|
|
129
|
+
enterProjectPane: options.enterProjectPane,
|
|
130
|
+
markDirty: options.markDirty,
|
|
131
|
+
queuePersistMuxUiState: options.queuePersistMuxUiState,
|
|
132
|
+
conversations: options.conversations,
|
|
133
|
+
repositoryGroupIdForDirectory: options.repositoryGroupIdForDirectory,
|
|
134
|
+
toggleRepositoryGroup: options.toggleRepositoryGroup,
|
|
135
|
+
collapseRepositoryGroup: options.collapseRepositoryGroup,
|
|
136
|
+
expandRepositoryGroup: options.expandRepositoryGroup,
|
|
137
|
+
collapseAllRepositoryGroups: options.collapseAllRepositoryGroups,
|
|
138
|
+
expandAllRepositoryGroups: options.expandAllRepositoryGroups,
|
|
139
|
+
directoriesHas: options.directoriesHas,
|
|
140
|
+
conversationDirectoryId: options.conversationDirectoryId,
|
|
141
|
+
conversationsHas: options.conversationsHas,
|
|
142
|
+
getMainPaneMode: options.getMainPaneMode,
|
|
143
|
+
getActiveConversationId: options.getActiveConversationId,
|
|
144
|
+
getActiveDirectoryId: options.getActiveDirectoryId,
|
|
145
|
+
repositoriesHas: options.repositoriesHas,
|
|
146
|
+
chordTimeoutMs: options.chordTimeoutMs,
|
|
147
|
+
collapseAllChordPrefix: options.collapseAllChordPrefix,
|
|
148
|
+
stopConversationTitleEdit: options.stopConversationTitleEdit,
|
|
149
|
+
releaseViewportPinForSelection: options.releaseViewportPinForSelection,
|
|
150
|
+
beginConversationTitleEdit: options.beginConversationTitleEdit,
|
|
151
|
+
resetConversationPaneFrameCache: options.resetConversationPaneFrameCache,
|
|
152
|
+
conversationTitleEditDoubleClickWindowMs: options.conversationTitleEditDoubleClickWindowMs,
|
|
153
|
+
...(options.forwardInterruptAllToActiveConversation === undefined
|
|
154
|
+
? {}
|
|
155
|
+
: {
|
|
156
|
+
forwardInterruptAllToActiveConversation:
|
|
157
|
+
options.forwardInterruptAllToActiveConversation,
|
|
158
|
+
}),
|
|
159
|
+
...(options.interruptAllDoubleTapWindowMs === undefined
|
|
160
|
+
? {}
|
|
161
|
+
: {
|
|
162
|
+
interruptAllDoubleTapWindowMs: options.interruptAllDoubleTapWindowMs,
|
|
163
|
+
}),
|
|
164
|
+
};
|
|
165
|
+
this.railInput = new RuntimeRailInput(runtimeRailOptions);
|
|
166
|
+
this.mainPaneInput = new RuntimeMainPaneInput({
|
|
167
|
+
workspace: options.workspace,
|
|
168
|
+
workspaceActions: options.runtimeWorkspaceActions,
|
|
169
|
+
projectPaneActionAtRow: options.projectPaneActionAtRow,
|
|
170
|
+
openNewThreadPrompt: options.openNewThreadPrompt,
|
|
171
|
+
queueCloseDirectory: options.queueCloseDirectory,
|
|
172
|
+
selectTaskById: options.selectTaskById,
|
|
173
|
+
selectRepositoryById: options.selectRepositoryById,
|
|
174
|
+
taskPaneActionAtCell: options.taskPaneActionAtCell,
|
|
175
|
+
taskPaneActionAtRow: options.taskPaneActionAtRow,
|
|
176
|
+
taskPaneTaskIdAtRow: options.taskPaneTaskIdAtRow,
|
|
177
|
+
taskPaneRepositoryIdAtRow: options.taskPaneRepositoryIdAtRow,
|
|
178
|
+
applyPaneDividerAtCol: options.applyPaneDividerAtCol,
|
|
179
|
+
pinViewportForSelection: options.pinViewportForSelection,
|
|
180
|
+
releaseViewportPinForSelection: options.releaseViewportPinForSelection,
|
|
181
|
+
markDirty: options.markDirty,
|
|
182
|
+
homePaneEditDoubleClickWindowMs: options.homePaneEditDoubleClickWindowMs,
|
|
183
|
+
leftRailPointerInput: this.railInput,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
routeModalInput(input: Buffer): boolean {
|
|
188
|
+
return this.modalInput.routeModalInput(input);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
handleRepositoryFoldInput(input: Buffer): boolean {
|
|
192
|
+
return this.railInput.handleRepositoryFoldInput(input);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
handleGlobalShortcutInput(input: Buffer): boolean {
|
|
196
|
+
return this.railInput.handleGlobalShortcutInput(input);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
inputTokenRouter(): Pick<RuntimeMainPaneInput, 'routeTokens'> {
|
|
200
|
+
return this.mainPaneInput;
|
|
201
|
+
}
|
|
202
|
+
}
|