@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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ControlPlaneConversationRecord,
|
|
3
|
+
ControlPlaneDirectoryRecord,
|
|
4
|
+
ControlPlaneTaskRecord,
|
|
5
|
+
} from '../../core/contracts/records.ts';
|
|
6
|
+
import type {
|
|
7
|
+
HarnessSyncedStore,
|
|
8
|
+
HarnessSyncedStoreState,
|
|
9
|
+
} from '../../core/store/harness-synced-store.ts';
|
|
10
|
+
|
|
11
|
+
export interface WebConversationListItem {
|
|
12
|
+
readonly conversationId: string;
|
|
13
|
+
readonly directoryId: string;
|
|
14
|
+
readonly title: string;
|
|
15
|
+
readonly agentType: string;
|
|
16
|
+
readonly runtimeStatus: ControlPlaneConversationRecord['runtimeStatus'];
|
|
17
|
+
readonly phase: NonNullable<ControlPlaneConversationRecord['runtimeStatusModel']>['phase'] | null;
|
|
18
|
+
readonly activityHint:
|
|
19
|
+
| NonNullable<ControlPlaneConversationRecord['runtimeStatusModel']>['activityHint']
|
|
20
|
+
| null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface WebTaskListItem {
|
|
24
|
+
readonly taskId: string;
|
|
25
|
+
readonly repositoryId: string | null;
|
|
26
|
+
readonly title: string;
|
|
27
|
+
readonly status: ControlPlaneTaskRecord['status'];
|
|
28
|
+
readonly orderIndex: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface MemoizedProjection<TResult> {
|
|
32
|
+
readonly read: (state: HarnessSyncedStoreState) => TResult;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function createMemoizedProjection<TById extends Readonly<Record<string, unknown>>, TResult>(
|
|
36
|
+
selectById: (state: HarnessSyncedStoreState) => TById,
|
|
37
|
+
project: (byId: TById) => TResult,
|
|
38
|
+
): MemoizedProjection<TResult> {
|
|
39
|
+
let previousById: TById | null = null;
|
|
40
|
+
let previousResult: TResult | null = null;
|
|
41
|
+
return {
|
|
42
|
+
read: (state) => {
|
|
43
|
+
const currentById = selectById(state);
|
|
44
|
+
if (previousById === currentById && previousResult !== null) {
|
|
45
|
+
return previousResult;
|
|
46
|
+
}
|
|
47
|
+
const nextResult = project(currentById);
|
|
48
|
+
previousById = currentById;
|
|
49
|
+
previousResult = nextResult;
|
|
50
|
+
return nextResult;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function createWebConversationListSelector(): (
|
|
56
|
+
state: HarnessSyncedStoreState,
|
|
57
|
+
) => readonly WebConversationListItem[] {
|
|
58
|
+
const memoized = createMemoizedProjection(
|
|
59
|
+
(state) => state.synced.conversationsById,
|
|
60
|
+
(conversationsById) =>
|
|
61
|
+
Object.values(conversationsById)
|
|
62
|
+
.sort((left, right) => left.conversationId.localeCompare(right.conversationId))
|
|
63
|
+
.map((conversation) => ({
|
|
64
|
+
conversationId: conversation.conversationId,
|
|
65
|
+
directoryId: conversation.directoryId,
|
|
66
|
+
title: conversation.title,
|
|
67
|
+
agentType: conversation.agentType,
|
|
68
|
+
runtimeStatus: conversation.runtimeStatus,
|
|
69
|
+
phase: conversation.runtimeStatusModel?.phase ?? null,
|
|
70
|
+
activityHint: conversation.runtimeStatusModel?.activityHint ?? null,
|
|
71
|
+
})),
|
|
72
|
+
);
|
|
73
|
+
return (state) => memoized.read(state);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function createWebTaskListSelector(): (
|
|
77
|
+
state: HarnessSyncedStoreState,
|
|
78
|
+
) => readonly WebTaskListItem[] {
|
|
79
|
+
const memoized = createMemoizedProjection(
|
|
80
|
+
(state) => state.synced.tasksById,
|
|
81
|
+
(tasksById) =>
|
|
82
|
+
Object.values(tasksById)
|
|
83
|
+
.sort((left, right) => left.taskId.localeCompare(right.taskId))
|
|
84
|
+
.sort((left, right) => {
|
|
85
|
+
if (left.orderIndex !== right.orderIndex) {
|
|
86
|
+
return left.orderIndex - right.orderIndex;
|
|
87
|
+
}
|
|
88
|
+
return left.taskId.localeCompare(right.taskId);
|
|
89
|
+
})
|
|
90
|
+
.map((task) => ({
|
|
91
|
+
taskId: task.taskId,
|
|
92
|
+
repositoryId: task.repositoryId,
|
|
93
|
+
title: task.title,
|
|
94
|
+
status: task.status,
|
|
95
|
+
orderIndex: task.orderIndex,
|
|
96
|
+
})),
|
|
97
|
+
);
|
|
98
|
+
return (state) => memoized.read(state);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function selectWebDirectoryList(
|
|
102
|
+
state: HarnessSyncedStoreState,
|
|
103
|
+
): readonly ControlPlaneDirectoryRecord[] {
|
|
104
|
+
return Object.values(state.synced.directoriesById).sort((left, right) =>
|
|
105
|
+
left.directoryId.localeCompare(right.directoryId),
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function selectWebConversationById(
|
|
110
|
+
state: HarnessSyncedStoreState,
|
|
111
|
+
conversationId: string,
|
|
112
|
+
): ControlPlaneConversationRecord | null {
|
|
113
|
+
return state.synced.conversationsById[conversationId] ?? null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function subscribeStoreSelector<TSelected>(
|
|
117
|
+
store: HarnessSyncedStore,
|
|
118
|
+
select: (state: HarnessSyncedStoreState) => TSelected,
|
|
119
|
+
onChange: (selected: TSelected, previous: TSelected) => void,
|
|
120
|
+
equals: (left: TSelected, right: TSelected) => boolean = Object.is,
|
|
121
|
+
): () => void {
|
|
122
|
+
let previousSelected = select(store.getState());
|
|
123
|
+
return store.subscribe((state) => {
|
|
124
|
+
const nextSelected = select(state);
|
|
125
|
+
if (equals(nextSelected, previousSelected)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const before = previousSelected;
|
|
129
|
+
previousSelected = nextSelected;
|
|
130
|
+
onChange(nextSelected, before);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
@@ -172,6 +172,68 @@ const DEFAULT_DA2_REPLY = '\u001b[>1;10;0c';
|
|
|
172
172
|
const CELL_PIXEL_HEIGHT = 16;
|
|
173
173
|
const CELL_PIXEL_WIDTH = 8;
|
|
174
174
|
|
|
175
|
+
function isAsciiDigits(value: string, allowEmpty = false): boolean {
|
|
176
|
+
if (!allowEmpty && value.length === 0) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
180
|
+
const code = value.charCodeAt(index);
|
|
181
|
+
if (code < 0x30 || code > 0x39) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function isAsciiDigitsOrSemicolons(value: string): boolean {
|
|
189
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
190
|
+
const code = value.charCodeAt(index);
|
|
191
|
+
if (code === 0x3b) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (code < 0x30 || code > 0x39) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function parseAsciiInt(value: string): number | null {
|
|
202
|
+
if (!isAsciiDigits(value, false)) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
let parsed = 0;
|
|
206
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
207
|
+
parsed = parsed * 10 + (value.charCodeAt(index) - 0x30);
|
|
208
|
+
}
|
|
209
|
+
return parsed;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function parseKittyKeyboardFlags(payload: string): number | null {
|
|
213
|
+
if (!payload.startsWith('>') || !payload.endsWith('u')) {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
return parseAsciiInt(payload.slice(1, -1));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function parseModifyOtherKeysLevel(payload: string): number | null {
|
|
220
|
+
if (payload === '>4m') {
|
|
221
|
+
return 0;
|
|
222
|
+
}
|
|
223
|
+
if (!payload.startsWith('>4;') || !payload.endsWith('m')) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const rawLevel = payload.slice(3, -1);
|
|
227
|
+
if (!isAsciiDigits(rawLevel, false)) {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
const parsedLevel = parseAsciiInt(rawLevel);
|
|
231
|
+
if (parsedLevel === null) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
return Math.max(0, Math.min(2, parsedLevel));
|
|
235
|
+
}
|
|
236
|
+
|
|
175
237
|
function tsRuntimeArgs(scriptPath: string, args: readonly string[] = []): string[] {
|
|
176
238
|
return [scriptPath, ...args];
|
|
177
239
|
}
|
|
@@ -381,8 +443,7 @@ class TerminalQueryResponder {
|
|
|
381
443
|
};
|
|
382
444
|
let handled = false;
|
|
383
445
|
|
|
384
|
-
|
|
385
|
-
if (!handled && modifyOtherKeysQueryMatch !== null) {
|
|
446
|
+
if (!handled && payload === '>4;?m') {
|
|
386
447
|
this.writeReply(`\u001b[>4;${String(this.modifyOtherKeysLevel)}m`);
|
|
387
448
|
handled = true;
|
|
388
449
|
}
|
|
@@ -446,29 +507,15 @@ class TerminalQueryResponder {
|
|
|
446
507
|
}
|
|
447
508
|
|
|
448
509
|
private observeCsiCommand(payload: string): void {
|
|
449
|
-
const
|
|
450
|
-
if (
|
|
451
|
-
|
|
452
|
-
if (Number.isFinite(nextFlags)) {
|
|
453
|
-
this.kittyKeyboardFlags = Math.max(0, nextFlags);
|
|
454
|
-
}
|
|
510
|
+
const nextFlags = parseKittyKeyboardFlags(payload);
|
|
511
|
+
if (nextFlags !== null) {
|
|
512
|
+
this.kittyKeyboardFlags = Math.max(0, nextFlags);
|
|
455
513
|
return;
|
|
456
514
|
}
|
|
457
515
|
|
|
458
|
-
const
|
|
459
|
-
if (
|
|
460
|
-
|
|
461
|
-
if (rawLevel === undefined) {
|
|
462
|
-
this.modifyOtherKeysLevel = 0;
|
|
463
|
-
return;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
const parsedLevel = Number.parseInt(rawLevel, 10);
|
|
467
|
-
if (!Number.isFinite(parsedLevel)) {
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
this.modifyOtherKeysLevel = Math.max(0, Math.min(2, parsedLevel));
|
|
516
|
+
const modifyOtherKeysLevel = parseModifyOtherKeysLevel(payload);
|
|
517
|
+
if (modifyOtherKeysLevel !== null) {
|
|
518
|
+
this.modifyOtherKeysLevel = modifyOtherKeysLevel;
|
|
472
519
|
}
|
|
473
520
|
}
|
|
474
521
|
|
|
@@ -491,22 +538,28 @@ class TerminalQueryResponder {
|
|
|
491
538
|
}
|
|
492
539
|
|
|
493
540
|
private isLikelyCsiQueryPayload(payload: string): boolean {
|
|
494
|
-
if (
|
|
541
|
+
if (payload === 'c' || payload === '0c' || payload === '>c' || payload === '>0c') {
|
|
495
542
|
return true;
|
|
496
543
|
}
|
|
497
|
-
if (
|
|
544
|
+
if (payload.endsWith('n') && isAsciiDigits(payload.slice(0, -1), true)) {
|
|
498
545
|
return true;
|
|
499
546
|
}
|
|
500
|
-
if (
|
|
547
|
+
if (payload === '14t' || payload === '16t' || payload === '18t') {
|
|
501
548
|
return true;
|
|
502
549
|
}
|
|
503
|
-
if (
|
|
550
|
+
if (payload === '>0q') {
|
|
504
551
|
return true;
|
|
505
552
|
}
|
|
506
|
-
if (
|
|
553
|
+
if (payload === '>4;?m') {
|
|
507
554
|
return true;
|
|
508
555
|
}
|
|
509
|
-
if (
|
|
556
|
+
if (
|
|
557
|
+
payload.length >= 3 &&
|
|
558
|
+
payload.startsWith('?') &&
|
|
559
|
+
payload.endsWith('p') &&
|
|
560
|
+
payload.charCodeAt(payload.length - 2) === 0x24 &&
|
|
561
|
+
isAsciiDigitsOrSemicolons(payload.slice(1, -2))
|
|
562
|
+
) {
|
|
510
563
|
return true;
|
|
511
564
|
}
|
|
512
565
|
if (payload === '?u') {
|
|
@@ -616,7 +669,7 @@ class CodexLiveSession {
|
|
|
616
669
|
this.emit({
|
|
617
670
|
type: 'terminal-output',
|
|
618
671
|
cursor: event.cursor,
|
|
619
|
-
chunk:
|
|
672
|
+
chunk: event.chunk,
|
|
620
673
|
});
|
|
621
674
|
},
|
|
622
675
|
onExit: (exit: PtyExit) => {
|