@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
|
@@ -4,7 +4,7 @@ interface ScreenLike {
|
|
|
4
4
|
markDirty(): void;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
interface RuntimeRenderLifecycleOptions {
|
|
7
|
+
export interface RuntimeRenderLifecycleOptions {
|
|
8
8
|
readonly screen: ScreenLike;
|
|
9
9
|
readonly render: () => void;
|
|
10
10
|
readonly isShuttingDown: () => boolean;
|
|
@@ -21,84 +21,85 @@ interface RuntimeRenderLifecycleOptions {
|
|
|
21
21
|
|
|
22
22
|
const FATAL_EXIT_DELAY_MS = 1200;
|
|
23
23
|
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
private runtimeFatal: { origin: string; error: unknown } | null = null;
|
|
33
|
-
private runtimeFatalExitTimer: ReturnType<typeof setTimeout> | null = null;
|
|
34
|
-
|
|
35
|
-
constructor(private readonly options: RuntimeRenderLifecycleOptions) {
|
|
36
|
-
this.setImmediateFn = options.setImmediateFn ?? setImmediate;
|
|
37
|
-
this.setTimeoutFn = options.setTimeoutFn ?? setTimeout;
|
|
38
|
-
this.clearTimeoutFn = options.clearTimeoutFn ?? clearTimeout;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
hasFatal(): boolean {
|
|
42
|
-
return this.runtimeFatal !== null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
clearRenderScheduled(): void {
|
|
46
|
-
this.renderScheduled = false;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
clearRuntimeFatalExitTimer(): void {
|
|
50
|
-
if (this.runtimeFatalExitTimer === null) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
this.clearTimeoutFn(this.runtimeFatalExitTimer);
|
|
54
|
-
this.runtimeFatalExitTimer = null;
|
|
55
|
-
}
|
|
24
|
+
export interface RuntimeRenderLifecycle {
|
|
25
|
+
hasFatal(): boolean;
|
|
26
|
+
clearRenderScheduled(): void;
|
|
27
|
+
clearRuntimeFatalExitTimer(): void;
|
|
28
|
+
markDirty(): void;
|
|
29
|
+
scheduleRender(): void;
|
|
30
|
+
handleRuntimeFatal(origin: string, error: unknown): void;
|
|
31
|
+
}
|
|
56
32
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
33
|
+
export function createRuntimeRenderLifecycle(
|
|
34
|
+
options: RuntimeRenderLifecycleOptions,
|
|
35
|
+
): RuntimeRenderLifecycle {
|
|
36
|
+
const setImmediateFn = options.setImmediateFn ?? setImmediate;
|
|
37
|
+
const setTimeoutFn = options.setTimeoutFn ?? setTimeout;
|
|
38
|
+
const clearTimeoutFn = options.clearTimeoutFn ?? clearTimeout;
|
|
39
|
+
let renderScheduled = false;
|
|
40
|
+
let runtimeFatal: { origin: string; error: unknown } | null = null;
|
|
41
|
+
let runtimeFatalExitTimer: ReturnType<typeof setTimeout> | null = null;
|
|
64
42
|
|
|
65
|
-
scheduleRender(): void {
|
|
66
|
-
if (
|
|
43
|
+
const scheduleRender = (): void => {
|
|
44
|
+
if (options.isShuttingDown() || renderScheduled) {
|
|
67
45
|
return;
|
|
68
46
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
47
|
+
renderScheduled = true;
|
|
48
|
+
setImmediateFn(() => {
|
|
49
|
+
renderScheduled = false;
|
|
72
50
|
try {
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
|
|
51
|
+
options.render();
|
|
52
|
+
if (options.screen.isDirty()) {
|
|
53
|
+
scheduleRender();
|
|
76
54
|
}
|
|
77
55
|
} catch (error: unknown) {
|
|
78
|
-
|
|
56
|
+
handleRuntimeFatal('render', error);
|
|
79
57
|
}
|
|
80
58
|
});
|
|
81
|
-
}
|
|
59
|
+
};
|
|
82
60
|
|
|
83
|
-
handleRuntimeFatal(origin: string, error: unknown): void {
|
|
84
|
-
if (
|
|
61
|
+
const handleRuntimeFatal = (origin: string, error: unknown): void => {
|
|
62
|
+
if (runtimeFatal !== null) {
|
|
85
63
|
return;
|
|
86
64
|
}
|
|
87
|
-
|
|
65
|
+
runtimeFatal = {
|
|
88
66
|
origin,
|
|
89
67
|
error,
|
|
90
68
|
};
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`[mux] fatal runtime error (${origin}): ${
|
|
69
|
+
options.setShuttingDown(true);
|
|
70
|
+
options.setStop(true);
|
|
71
|
+
options.screen.clearDirty();
|
|
72
|
+
options.writeStderr(
|
|
73
|
+
`[mux] fatal runtime error (${origin}): ${options.formatErrorMessage(error)}\n`,
|
|
96
74
|
);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
75
|
+
options.restoreTerminalState();
|
|
76
|
+
runtimeFatalExitTimer = setTimeoutFn(() => {
|
|
77
|
+
options.writeStderr('[mux] fatal runtime error forced exit\n');
|
|
78
|
+
options.exitProcess(1);
|
|
101
79
|
}, FATAL_EXIT_DELAY_MS);
|
|
102
|
-
|
|
103
|
-
}
|
|
80
|
+
runtimeFatalExitTimer.unref?.();
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
hasFatal: (): boolean => runtimeFatal !== null,
|
|
85
|
+
clearRenderScheduled: (): void => {
|
|
86
|
+
renderScheduled = false;
|
|
87
|
+
},
|
|
88
|
+
clearRuntimeFatalExitTimer: (): void => {
|
|
89
|
+
if (runtimeFatalExitTimer === null) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
clearTimeoutFn(runtimeFatalExitTimer);
|
|
93
|
+
runtimeFatalExitTimer = null;
|
|
94
|
+
},
|
|
95
|
+
markDirty: (): void => {
|
|
96
|
+
if (options.isShuttingDown()) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
options.screen.markDirty();
|
|
100
|
+
scheduleRender();
|
|
101
|
+
},
|
|
102
|
+
scheduleRender,
|
|
103
|
+
handleRuntimeFatal,
|
|
104
|
+
};
|
|
104
105
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
interface RuntimeRenderStateResult<TConversation, TFrame, TSelection> {
|
|
2
2
|
readonly projectPaneActive: boolean;
|
|
3
3
|
readonly homePaneActive: boolean;
|
|
4
|
+
readonly nimPaneActive: boolean;
|
|
4
5
|
readonly activeConversation: TConversation | null;
|
|
5
6
|
readonly rightFrame: TFrame | null;
|
|
6
7
|
readonly renderSelection: TSelection | null;
|
|
@@ -12,28 +13,35 @@ interface RuntimeLeftRailRenderResult<TRailViewRows> {
|
|
|
12
13
|
readonly viewRows: TRailViewRows;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
interface RuntimeRenderOrchestratorOptions<
|
|
16
|
+
export interface RuntimeRenderOrchestratorOptions<
|
|
16
17
|
TLayout,
|
|
17
18
|
TConversation,
|
|
18
19
|
TFrame,
|
|
19
20
|
TSelection,
|
|
20
21
|
TSelectionDrag,
|
|
21
22
|
TRailViewRows,
|
|
23
|
+
TRenderSnapshot,
|
|
22
24
|
> {
|
|
23
25
|
readonly isScreenDirty: () => boolean;
|
|
24
26
|
readonly clearDirty: () => void;
|
|
27
|
+
readonly readRenderSnapshot: () => TRenderSnapshot;
|
|
25
28
|
readonly prepareRenderState: (
|
|
26
29
|
selection: TSelection | null,
|
|
27
30
|
selectionDrag: TSelectionDrag | null,
|
|
28
31
|
) => RuntimeRenderStateResult<TConversation, TFrame, TSelection> | null;
|
|
29
|
-
readonly renderLeftRail: (
|
|
32
|
+
readonly renderLeftRail: (
|
|
33
|
+
layout: TLayout,
|
|
34
|
+
snapshot: TRenderSnapshot,
|
|
35
|
+
) => RuntimeLeftRailRenderResult<TRailViewRows>;
|
|
30
36
|
readonly setLatestRailViewRows: (rows: TRailViewRows) => void;
|
|
31
37
|
readonly renderRightRows: (input: {
|
|
32
38
|
layout: TLayout;
|
|
33
39
|
rightFrame: TFrame | null;
|
|
34
40
|
homePaneActive: boolean;
|
|
41
|
+
nimPaneActive: boolean;
|
|
35
42
|
projectPaneActive: boolean;
|
|
36
43
|
activeDirectoryId: string | null;
|
|
44
|
+
snapshot: TRenderSnapshot;
|
|
37
45
|
}) => readonly string[];
|
|
38
46
|
readonly flushRender: (input: {
|
|
39
47
|
layout: TLayout;
|
|
@@ -49,60 +57,62 @@ interface RuntimeRenderOrchestratorOptions<
|
|
|
49
57
|
readonly activeDirectoryId: () => string | null;
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
interface RuntimeRenderOrchestratorInput<TLayout, TSelection, TSelectionDrag> {
|
|
60
|
+
export interface RuntimeRenderOrchestratorInput<TLayout, TSelection, TSelectionDrag> {
|
|
53
61
|
readonly shuttingDown: boolean;
|
|
54
62
|
readonly layout: TLayout;
|
|
55
63
|
readonly selection: TSelection | null;
|
|
56
64
|
readonly selectionDrag: TSelectionDrag | null;
|
|
57
65
|
}
|
|
58
66
|
|
|
59
|
-
export
|
|
67
|
+
export function orchestrateRuntimeRender<
|
|
60
68
|
TLayout,
|
|
61
69
|
TConversation,
|
|
62
70
|
TFrame,
|
|
63
71
|
TSelection,
|
|
64
72
|
TSelectionDrag,
|
|
65
73
|
TRailViewRows,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
const rail = this.options.renderLeftRail(input.layout);
|
|
88
|
-
this.options.setLatestRailViewRows(rail.viewRows);
|
|
89
|
-
const rightRows = this.options.renderRightRows({
|
|
90
|
-
layout: input.layout,
|
|
91
|
-
rightFrame: renderState.rightFrame,
|
|
92
|
-
homePaneActive: renderState.homePaneActive,
|
|
93
|
-
projectPaneActive: renderState.projectPaneActive,
|
|
94
|
-
activeDirectoryId: this.options.activeDirectoryId(),
|
|
95
|
-
});
|
|
96
|
-
this.options.flushRender({
|
|
97
|
-
layout: input.layout,
|
|
98
|
-
projectPaneActive: renderState.projectPaneActive,
|
|
99
|
-
homePaneActive: renderState.homePaneActive,
|
|
100
|
-
activeConversation: renderState.activeConversation,
|
|
101
|
-
rightFrame: renderState.rightFrame,
|
|
102
|
-
renderSelection: renderState.renderSelection,
|
|
103
|
-
selectionRows: renderState.selectionRows,
|
|
104
|
-
railAnsiRows: rail.ansiRows,
|
|
105
|
-
rightRows,
|
|
106
|
-
});
|
|
74
|
+
TRenderSnapshot,
|
|
75
|
+
>(
|
|
76
|
+
options: RuntimeRenderOrchestratorOptions<
|
|
77
|
+
TLayout,
|
|
78
|
+
TConversation,
|
|
79
|
+
TFrame,
|
|
80
|
+
TSelection,
|
|
81
|
+
TSelectionDrag,
|
|
82
|
+
TRailViewRows,
|
|
83
|
+
TRenderSnapshot
|
|
84
|
+
>,
|
|
85
|
+
input: RuntimeRenderOrchestratorInput<TLayout, TSelection, TSelectionDrag>,
|
|
86
|
+
): void {
|
|
87
|
+
if (input.shuttingDown || !options.isScreenDirty()) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const renderState = options.prepareRenderState(input.selection, input.selectionDrag);
|
|
91
|
+
if (renderState === null) {
|
|
92
|
+
options.clearDirty();
|
|
93
|
+
return;
|
|
107
94
|
}
|
|
95
|
+
const snapshot = options.readRenderSnapshot();
|
|
96
|
+
const rail = options.renderLeftRail(input.layout, snapshot);
|
|
97
|
+
options.setLatestRailViewRows(rail.viewRows);
|
|
98
|
+
const rightRows = options.renderRightRows({
|
|
99
|
+
layout: input.layout,
|
|
100
|
+
rightFrame: renderState.rightFrame,
|
|
101
|
+
homePaneActive: renderState.homePaneActive,
|
|
102
|
+
nimPaneActive: renderState.nimPaneActive,
|
|
103
|
+
projectPaneActive: renderState.projectPaneActive,
|
|
104
|
+
activeDirectoryId: options.activeDirectoryId(),
|
|
105
|
+
snapshot,
|
|
106
|
+
});
|
|
107
|
+
options.flushRender({
|
|
108
|
+
layout: input.layout,
|
|
109
|
+
projectPaneActive: renderState.projectPaneActive,
|
|
110
|
+
homePaneActive: renderState.homePaneActive,
|
|
111
|
+
activeConversation: renderState.activeConversation,
|
|
112
|
+
rightFrame: renderState.rightFrame,
|
|
113
|
+
renderSelection: renderState.renderSelection,
|
|
114
|
+
selectionRows: renderState.selectionRows,
|
|
115
|
+
railAnsiRows: rail.ansiRows,
|
|
116
|
+
rightRows,
|
|
117
|
+
});
|
|
108
118
|
}
|
|
@@ -5,57 +5,46 @@ import type {
|
|
|
5
5
|
TaskFocusedPaneTaskRecord,
|
|
6
6
|
} from '../mux/task-focused-pane.ts';
|
|
7
7
|
import type { TerminalSnapshotFrameCore } from '../terminal/snapshot-oracle.ts';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
import {
|
|
9
|
+
renderRuntimeLeftRail,
|
|
10
|
+
type RuntimeLeftRailRenderOptions,
|
|
11
|
+
type RuntimeLeftRailRenderSnapshot,
|
|
12
|
+
} from './runtime-left-rail-render.ts';
|
|
13
|
+
import { flushRuntimeRender, type RuntimeRenderFlushOptions } from './runtime-render-flush.ts';
|
|
14
|
+
import {
|
|
15
|
+
orchestrateRuntimeRender,
|
|
16
|
+
type RuntimeRenderOrchestratorInput,
|
|
17
|
+
type RuntimeRenderOrchestratorOptions,
|
|
18
|
+
} from './runtime-render-orchestrator.ts';
|
|
19
|
+
import {
|
|
20
|
+
prepareRuntimeRenderState,
|
|
21
|
+
type RuntimeRenderStateOptions,
|
|
22
|
+
} from './runtime-render-state.ts';
|
|
23
|
+
import {
|
|
24
|
+
renderRuntimeRightPaneRows,
|
|
25
|
+
type RuntimeRightPaneRenderOptions,
|
|
26
|
+
type RuntimeRightPaneRenderSnapshot,
|
|
27
|
+
} from './runtime-right-pane-render.ts';
|
|
13
28
|
|
|
14
29
|
type RuntimeLayout = ReturnType<typeof computeDualPaneLayout>;
|
|
15
30
|
|
|
16
|
-
|
|
17
|
-
typeof RuntimeRenderFlush<
|
|
18
|
-
TConversation,
|
|
19
|
-
TerminalSnapshotFrameCore,
|
|
20
|
-
PaneSelection,
|
|
21
|
-
RuntimeLayout,
|
|
22
|
-
TModalOverlay,
|
|
23
|
-
TStatusRow
|
|
24
|
-
>
|
|
25
|
-
>[0];
|
|
26
|
-
|
|
27
|
-
type RuntimeRightPaneRenderOptions<
|
|
28
|
-
TRepositoryRecord extends TaskFocusedPaneRepositoryRecord,
|
|
29
|
-
TTaskRecord extends TaskFocusedPaneTaskRecord,
|
|
30
|
-
> = ConstructorParameters<typeof RuntimeRightPaneRender<TRepositoryRecord, TTaskRecord>>[0];
|
|
31
|
-
|
|
32
|
-
type RuntimeLeftRailRenderOptions<
|
|
31
|
+
export interface RuntimeRenderPipelineSnapshot<
|
|
33
32
|
TDirectoryRecord,
|
|
34
33
|
TConversation,
|
|
35
|
-
TRepositoryRecord,
|
|
36
|
-
|
|
37
|
-
TGitSummary,
|
|
34
|
+
TRepositoryRecord extends TaskFocusedPaneRepositoryRecord,
|
|
35
|
+
TTaskRecord extends TaskFocusedPaneTaskRecord,
|
|
38
36
|
TProcessUsage,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
> = ConstructorParameters<
|
|
42
|
-
typeof RuntimeLeftRailRender<
|
|
37
|
+
> {
|
|
38
|
+
readonly leftRail: RuntimeLeftRailRenderSnapshot<
|
|
43
39
|
TDirectoryRecord,
|
|
44
40
|
TConversation,
|
|
45
41
|
TRepositoryRecord,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
TRailViewRows
|
|
51
|
-
>
|
|
52
|
-
>[0];
|
|
53
|
-
|
|
54
|
-
type RuntimeRenderStateOptions<TConversation> = ConstructorParameters<
|
|
55
|
-
typeof RuntimeRenderState<TConversation, TerminalSnapshotFrameCore>
|
|
56
|
-
>[0];
|
|
42
|
+
TProcessUsage
|
|
43
|
+
>;
|
|
44
|
+
readonly rightPane: RuntimeRightPaneRenderSnapshot<TRepositoryRecord, TTaskRecord>;
|
|
45
|
+
}
|
|
57
46
|
|
|
58
|
-
interface RuntimeRenderPipelineOptions<
|
|
47
|
+
export interface RuntimeRenderPipelineOptions<
|
|
59
48
|
TConversation,
|
|
60
49
|
TRepositoryRecord extends TaskFocusedPaneRepositoryRecord,
|
|
61
50
|
TTaskRecord extends TaskFocusedPaneTaskRecord,
|
|
@@ -63,12 +52,18 @@ interface RuntimeRenderPipelineOptions<
|
|
|
63
52
|
TRepositorySnapshot,
|
|
64
53
|
TGitSummary,
|
|
65
54
|
TProcessUsage,
|
|
66
|
-
TShortcutBindings,
|
|
67
55
|
TRailViewRows,
|
|
68
56
|
TModalOverlay,
|
|
69
57
|
TStatusRow,
|
|
70
58
|
> {
|
|
71
|
-
readonly renderFlush: RuntimeRenderFlushOptions<
|
|
59
|
+
readonly renderFlush: RuntimeRenderFlushOptions<
|
|
60
|
+
TConversation,
|
|
61
|
+
TerminalSnapshotFrameCore,
|
|
62
|
+
PaneSelection,
|
|
63
|
+
RuntimeLayout,
|
|
64
|
+
TModalOverlay,
|
|
65
|
+
TStatusRow
|
|
66
|
+
>;
|
|
72
67
|
readonly rightPaneRender: RuntimeRightPaneRenderOptions<TRepositoryRecord, TTaskRecord>;
|
|
73
68
|
readonly leftRailRender: RuntimeLeftRailRenderOptions<
|
|
74
69
|
TDirectoryRecord,
|
|
@@ -77,28 +72,30 @@ interface RuntimeRenderPipelineOptions<
|
|
|
77
72
|
TRepositorySnapshot,
|
|
78
73
|
TGitSummary,
|
|
79
74
|
TProcessUsage,
|
|
80
|
-
TShortcutBindings,
|
|
81
75
|
TRailViewRows
|
|
82
76
|
>;
|
|
83
|
-
readonly renderState: RuntimeRenderStateOptions<TConversation>;
|
|
77
|
+
readonly renderState: RuntimeRenderStateOptions<TConversation, TerminalSnapshotFrameCore>;
|
|
84
78
|
readonly isScreenDirty: () => boolean;
|
|
85
79
|
readonly clearDirty: () => void;
|
|
80
|
+
// Frame-local TUI snapshot read. React/web adapters should consume store selectors directly.
|
|
81
|
+
readonly readRenderSnapshot: () => RuntimeRenderPipelineSnapshot<
|
|
82
|
+
TDirectoryRecord,
|
|
83
|
+
TConversation,
|
|
84
|
+
TRepositoryRecord,
|
|
85
|
+
TTaskRecord,
|
|
86
|
+
TProcessUsage
|
|
87
|
+
>;
|
|
86
88
|
readonly setLatestRailViewRows: (rows: TRailViewRows) => void;
|
|
87
89
|
readonly activeDirectoryId: () => string | null;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
type RuntimeRenderPipelineInput =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
PaneSelection,
|
|
96
|
-
PaneSelectionDrag,
|
|
97
|
-
unknown
|
|
98
|
-
>['render']
|
|
99
|
-
>[0];
|
|
92
|
+
type RuntimeRenderPipelineInput = RuntimeRenderOrchestratorInput<
|
|
93
|
+
RuntimeLayout,
|
|
94
|
+
PaneSelection,
|
|
95
|
+
PaneSelectionDrag
|
|
96
|
+
>;
|
|
100
97
|
|
|
101
|
-
export
|
|
98
|
+
export function createRuntimeRenderPipeline<
|
|
102
99
|
TConversation,
|
|
103
100
|
TRepositoryRecord extends TaskFocusedPaneRepositoryRecord,
|
|
104
101
|
TTaskRecord extends TaskFocusedPaneTaskRecord,
|
|
@@ -106,62 +103,68 @@ export class RuntimeRenderPipeline<
|
|
|
106
103
|
TRepositorySnapshot,
|
|
107
104
|
TGitSummary,
|
|
108
105
|
TProcessUsage,
|
|
109
|
-
TShortcutBindings,
|
|
110
106
|
TRailViewRows,
|
|
111
107
|
TModalOverlay,
|
|
112
108
|
TStatusRow,
|
|
113
|
-
>
|
|
114
|
-
|
|
109
|
+
>(
|
|
110
|
+
options: RuntimeRenderPipelineOptions<
|
|
111
|
+
TConversation,
|
|
112
|
+
TRepositoryRecord,
|
|
113
|
+
TTaskRecord,
|
|
114
|
+
TDirectoryRecord,
|
|
115
|
+
TRepositorySnapshot,
|
|
116
|
+
TGitSummary,
|
|
117
|
+
TProcessUsage,
|
|
118
|
+
TRailViewRows,
|
|
119
|
+
TModalOverlay,
|
|
120
|
+
TStatusRow
|
|
121
|
+
>,
|
|
122
|
+
): (input: RuntimeRenderPipelineInput) => void {
|
|
123
|
+
const renderOrchestratorOptions: RuntimeRenderOrchestratorOptions<
|
|
115
124
|
RuntimeLayout,
|
|
116
125
|
TConversation,
|
|
117
126
|
TerminalSnapshotFrameCore,
|
|
118
127
|
PaneSelection,
|
|
119
128
|
PaneSelectionDrag,
|
|
120
|
-
TRailViewRows
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
constructor(
|
|
124
|
-
options: RuntimeRenderPipelineOptions<
|
|
129
|
+
TRailViewRows,
|
|
130
|
+
RuntimeRenderPipelineSnapshot<
|
|
131
|
+
TDirectoryRecord,
|
|
125
132
|
TConversation,
|
|
126
133
|
TRepositoryRecord,
|
|
127
134
|
TTaskRecord,
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
render(input: RuntimeRenderPipelineInput): void {
|
|
165
|
-
this.renderOrchestrator.render(input);
|
|
166
|
-
}
|
|
135
|
+
TProcessUsage
|
|
136
|
+
>
|
|
137
|
+
> = {
|
|
138
|
+
isScreenDirty: options.isScreenDirty,
|
|
139
|
+
clearDirty: options.clearDirty,
|
|
140
|
+
readRenderSnapshot: options.readRenderSnapshot,
|
|
141
|
+
prepareRenderState: (selection, selectionDrag) => {
|
|
142
|
+
return prepareRuntimeRenderState(options.renderState, selection, selectionDrag);
|
|
143
|
+
},
|
|
144
|
+
renderLeftRail: (layout, snapshot) => {
|
|
145
|
+
return renderRuntimeLeftRail(options.leftRailRender, {
|
|
146
|
+
layout,
|
|
147
|
+
snapshot: snapshot.leftRail,
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
setLatestRailViewRows: options.setLatestRailViewRows,
|
|
151
|
+
renderRightRows: (input) => {
|
|
152
|
+
return renderRuntimeRightPaneRows(options.rightPaneRender, {
|
|
153
|
+
layout: input.layout,
|
|
154
|
+
rightFrame: input.rightFrame,
|
|
155
|
+
homePaneActive: input.homePaneActive,
|
|
156
|
+
nimPaneActive: input.nimPaneActive,
|
|
157
|
+
projectPaneActive: input.projectPaneActive,
|
|
158
|
+
activeDirectoryId: input.activeDirectoryId,
|
|
159
|
+
snapshot: input.snapshot.rightPane,
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
flushRender: (input) => {
|
|
163
|
+
flushRuntimeRender(options.renderFlush, input);
|
|
164
|
+
},
|
|
165
|
+
activeDirectoryId: options.activeDirectoryId,
|
|
166
|
+
};
|
|
167
|
+
return (input: RuntimeRenderPipelineInput): void => {
|
|
168
|
+
orchestrateRuntimeRender(renderOrchestratorOptions, input);
|
|
169
|
+
};
|
|
167
170
|
}
|