@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
|
@@ -7,8 +7,13 @@ import {
|
|
|
7
7
|
unlinkSync,
|
|
8
8
|
writeFileSync,
|
|
9
9
|
} from 'node:fs';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
10
11
|
import { dirname, resolve } from 'node:path';
|
|
11
12
|
import { fileURLToPath } from 'node:url';
|
|
13
|
+
import {
|
|
14
|
+
DEFAULT_STORAGE_LIFECYCLE_POLICY,
|
|
15
|
+
type StorageLifecyclePolicy,
|
|
16
|
+
} from '../storage/storage-lifecycle-core.ts';
|
|
12
17
|
|
|
13
18
|
export const HARNESS_CONFIG_FILE_NAME = 'harness.config.jsonc';
|
|
14
19
|
export const HARNESS_CONFIG_VERSION = 1;
|
|
@@ -40,13 +45,46 @@ const HARNESS_LIFECYCLE_EVENT_TYPES = [
|
|
|
40
45
|
|
|
41
46
|
export type HarnessLifecycleEventType = (typeof HARNESS_LIFECYCLE_EVENT_TYPES)[number];
|
|
42
47
|
|
|
48
|
+
export const HARNESS_MUX_OPEN_IN_TARGET_IDS = [
|
|
49
|
+
'iterm2',
|
|
50
|
+
'ghostty',
|
|
51
|
+
'zed',
|
|
52
|
+
'cursor',
|
|
53
|
+
'vscode',
|
|
54
|
+
'warp',
|
|
55
|
+
'finder',
|
|
56
|
+
] as const;
|
|
57
|
+
|
|
58
|
+
export type HarnessMuxOpenInTargetId = (typeof HARNESS_MUX_OPEN_IN_TARGET_IDS)[number];
|
|
59
|
+
|
|
60
|
+
export interface HarnessMuxOpenInTargetOverrideConfig {
|
|
61
|
+
readonly enabled?: boolean;
|
|
62
|
+
readonly appName?: string;
|
|
63
|
+
readonly detectCommand?: string | null;
|
|
64
|
+
readonly launchCommand?: readonly string[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface HarnessMuxOpenInLinkConfig {
|
|
68
|
+
readonly browserCommand: readonly string[] | null;
|
|
69
|
+
readonly fileCommand: readonly string[] | null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface HarnessMuxOpenInConfig {
|
|
73
|
+
readonly targets: Readonly<
|
|
74
|
+
Partial<Record<HarnessMuxOpenInTargetId, HarnessMuxOpenInTargetOverrideConfig>>
|
|
75
|
+
>;
|
|
76
|
+
readonly links: HarnessMuxOpenInLinkConfig;
|
|
77
|
+
}
|
|
78
|
+
|
|
43
79
|
interface HarnessMuxConfig {
|
|
44
80
|
readonly keybindings: Readonly<Record<string, readonly string[]>>;
|
|
45
81
|
readonly ui: HarnessMuxUiConfig;
|
|
46
82
|
readonly git: HarnessMuxGitConfig;
|
|
83
|
+
readonly openIn: HarnessMuxOpenInConfig;
|
|
47
84
|
}
|
|
48
85
|
|
|
49
86
|
type HarnessMuxThemeMode = 'dark' | 'light';
|
|
87
|
+
type HarnessMuxStartupPane = 'home' | 'nim';
|
|
50
88
|
|
|
51
89
|
export interface HarnessMuxThemeConfig {
|
|
52
90
|
readonly preset: string;
|
|
@@ -58,6 +96,9 @@ interface HarnessMuxUiConfig {
|
|
|
58
96
|
readonly paneWidthPercent: number | null;
|
|
59
97
|
readonly repositoriesCollapsed: boolean;
|
|
60
98
|
readonly shortcutsCollapsed: boolean;
|
|
99
|
+
readonly startupPane: HarnessMuxStartupPane;
|
|
100
|
+
readonly showTasks: boolean;
|
|
101
|
+
readonly showDebugBar: boolean;
|
|
61
102
|
readonly theme: HarnessMuxThemeConfig | null;
|
|
62
103
|
}
|
|
63
104
|
|
|
@@ -83,6 +124,16 @@ interface HarnessGitHubConfig {
|
|
|
83
124
|
readonly viewerLogin: string | null;
|
|
84
125
|
}
|
|
85
126
|
|
|
127
|
+
interface HarnessLinearConfig {
|
|
128
|
+
readonly enabled: boolean;
|
|
129
|
+
readonly apiBaseUrl: string;
|
|
130
|
+
readonly tokenEnvVar: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
interface HarnessGatewayConfig {
|
|
134
|
+
readonly host: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
86
137
|
interface HarnessPerfConfig {
|
|
87
138
|
readonly enabled: boolean;
|
|
88
139
|
readonly filePath: string;
|
|
@@ -215,15 +266,24 @@ interface HarnessHooksConfig {
|
|
|
215
266
|
readonly lifecycle: HarnessLifecycleHooksConfig;
|
|
216
267
|
}
|
|
217
268
|
|
|
269
|
+
export type HarnessStorageLifecycleConfig = StorageLifecyclePolicy;
|
|
270
|
+
|
|
271
|
+
interface HarnessStorageConfig {
|
|
272
|
+
readonly lifecycle: HarnessStorageLifecycleConfig;
|
|
273
|
+
}
|
|
274
|
+
|
|
218
275
|
interface HarnessConfig {
|
|
219
276
|
readonly configVersion: number;
|
|
220
277
|
readonly mux: HarnessMuxConfig;
|
|
221
278
|
readonly github: HarnessGitHubConfig;
|
|
279
|
+
readonly gateway: HarnessGatewayConfig;
|
|
280
|
+
readonly linear: HarnessLinearConfig;
|
|
222
281
|
readonly debug: HarnessDebugConfig;
|
|
223
282
|
readonly codex: HarnessCodexConfig;
|
|
224
283
|
readonly claude: HarnessClaudeConfig;
|
|
225
284
|
readonly cursor: HarnessCursorConfig;
|
|
226
285
|
readonly critique: HarnessCritiqueConfig;
|
|
286
|
+
readonly storage: HarnessStorageConfig;
|
|
227
287
|
readonly hooks: HarnessHooksConfig;
|
|
228
288
|
}
|
|
229
289
|
|
|
@@ -242,6 +302,9 @@ export const DEFAULT_HARNESS_CONFIG: HarnessConfig = {
|
|
|
242
302
|
paneWidthPercent: null,
|
|
243
303
|
repositoriesCollapsed: false,
|
|
244
304
|
shortcutsCollapsed: false,
|
|
305
|
+
startupPane: 'home',
|
|
306
|
+
showTasks: false,
|
|
307
|
+
showDebugBar: false,
|
|
245
308
|
theme: null,
|
|
246
309
|
},
|
|
247
310
|
git: {
|
|
@@ -253,6 +316,13 @@ export const DEFAULT_HARNESS_CONFIG: HarnessConfig = {
|
|
|
253
316
|
triggerDebounceMs: 180,
|
|
254
317
|
maxConcurrency: 1,
|
|
255
318
|
},
|
|
319
|
+
openIn: {
|
|
320
|
+
targets: {},
|
|
321
|
+
links: {
|
|
322
|
+
browserCommand: null,
|
|
323
|
+
fileCommand: null,
|
|
324
|
+
},
|
|
325
|
+
},
|
|
256
326
|
},
|
|
257
327
|
github: {
|
|
258
328
|
enabled: true,
|
|
@@ -263,6 +333,14 @@ export const DEFAULT_HARNESS_CONFIG: HarnessConfig = {
|
|
|
263
333
|
branchStrategy: 'pinned-then-current',
|
|
264
334
|
viewerLogin: null,
|
|
265
335
|
},
|
|
336
|
+
gateway: {
|
|
337
|
+
host: '127.0.0.1',
|
|
338
|
+
},
|
|
339
|
+
linear: {
|
|
340
|
+
enabled: true,
|
|
341
|
+
apiBaseUrl: 'https://api.linear.app/graphql',
|
|
342
|
+
tokenEnvVar: 'LINEAR_API_KEY',
|
|
343
|
+
},
|
|
266
344
|
debug: {
|
|
267
345
|
enabled: true,
|
|
268
346
|
overwriteArtifactsOnStart: true,
|
|
@@ -335,6 +413,11 @@ export const DEFAULT_HARNESS_CONFIG: HarnessConfig = {
|
|
|
335
413
|
command: 'bun add --global critique@latest',
|
|
336
414
|
},
|
|
337
415
|
},
|
|
416
|
+
storage: {
|
|
417
|
+
lifecycle: {
|
|
418
|
+
...DEFAULT_STORAGE_LIFECYCLE_POLICY,
|
|
419
|
+
},
|
|
420
|
+
},
|
|
338
421
|
hooks: {
|
|
339
422
|
lifecycle: {
|
|
340
423
|
enabled: false,
|
|
@@ -538,6 +621,16 @@ function normalizeMuxThemeMode(value: unknown, fallback: HarnessMuxThemeMode): H
|
|
|
538
621
|
return fallback;
|
|
539
622
|
}
|
|
540
623
|
|
|
624
|
+
function normalizeMuxStartupPane(
|
|
625
|
+
value: unknown,
|
|
626
|
+
fallback: HarnessMuxStartupPane,
|
|
627
|
+
): HarnessMuxStartupPane {
|
|
628
|
+
if (value === 'home' || value === 'nim') {
|
|
629
|
+
return value;
|
|
630
|
+
}
|
|
631
|
+
return fallback;
|
|
632
|
+
}
|
|
633
|
+
|
|
541
634
|
function normalizeMuxThemeConfig(input: unknown): HarnessMuxThemeConfig | null {
|
|
542
635
|
if (input === null || input === false) {
|
|
543
636
|
return null;
|
|
@@ -573,18 +666,33 @@ function normalizeMuxUiConfig(input: unknown): HarnessMuxUiConfig {
|
|
|
573
666
|
record['paneWidthPercent'],
|
|
574
667
|
DEFAULT_HARNESS_CONFIG.mux.ui.paneWidthPercent,
|
|
575
668
|
);
|
|
576
|
-
const shortcutsCollapsed =
|
|
577
|
-
typeof record['shortcutsCollapsed'] === 'boolean'
|
|
578
|
-
? record['shortcutsCollapsed']
|
|
579
|
-
: DEFAULT_HARNESS_CONFIG.mux.ui.shortcutsCollapsed;
|
|
580
669
|
const repositoriesCollapsed =
|
|
581
670
|
typeof record['repositoriesCollapsed'] === 'boolean'
|
|
582
671
|
? record['repositoriesCollapsed']
|
|
583
672
|
: DEFAULT_HARNESS_CONFIG.mux.ui.repositoriesCollapsed;
|
|
673
|
+
const shortcutsCollapsed =
|
|
674
|
+
typeof record['shortcutsCollapsed'] === 'boolean'
|
|
675
|
+
? record['shortcutsCollapsed']
|
|
676
|
+
: DEFAULT_HARNESS_CONFIG.mux.ui.shortcutsCollapsed;
|
|
677
|
+
const startupPane = normalizeMuxStartupPane(
|
|
678
|
+
record['startupPane'],
|
|
679
|
+
DEFAULT_HARNESS_CONFIG.mux.ui.startupPane,
|
|
680
|
+
);
|
|
681
|
+
const showTasks =
|
|
682
|
+
typeof record['showTasks'] === 'boolean'
|
|
683
|
+
? record['showTasks']
|
|
684
|
+
: DEFAULT_HARNESS_CONFIG.mux.ui.showTasks;
|
|
685
|
+
const showDebugBar =
|
|
686
|
+
typeof record['showDebugBar'] === 'boolean'
|
|
687
|
+
? record['showDebugBar']
|
|
688
|
+
: DEFAULT_HARNESS_CONFIG.mux.ui.showDebugBar;
|
|
584
689
|
return {
|
|
585
690
|
paneWidthPercent,
|
|
586
691
|
repositoriesCollapsed,
|
|
587
692
|
shortcutsCollapsed,
|
|
693
|
+
startupPane,
|
|
694
|
+
showTasks,
|
|
695
|
+
showDebugBar,
|
|
588
696
|
theme: normalizeMuxThemeConfig(record['theme']),
|
|
589
697
|
};
|
|
590
698
|
}
|
|
@@ -629,6 +737,113 @@ function normalizeMuxGitConfig(input: unknown): HarnessMuxGitConfig {
|
|
|
629
737
|
};
|
|
630
738
|
}
|
|
631
739
|
|
|
740
|
+
function normalizeMuxOpenInTargetOverride(
|
|
741
|
+
input: unknown,
|
|
742
|
+
): HarnessMuxOpenInTargetOverrideConfig | null {
|
|
743
|
+
const record = asRecord(input);
|
|
744
|
+
if (record === null) {
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
const enabled = typeof record['enabled'] === 'boolean' ? record['enabled'] : undefined;
|
|
748
|
+
const appName =
|
|
749
|
+
typeof record['appName'] === 'string' && record['appName'].trim().length > 0
|
|
750
|
+
? record['appName'].trim()
|
|
751
|
+
: undefined;
|
|
752
|
+
const detectCommand =
|
|
753
|
+
record['detectCommand'] === null
|
|
754
|
+
? null
|
|
755
|
+
: typeof record['detectCommand'] === 'string' && record['detectCommand'].trim().length > 0
|
|
756
|
+
? record['detectCommand'].trim()
|
|
757
|
+
: undefined;
|
|
758
|
+
const launchCommandFromArray = Array.isArray(record['launchCommand'])
|
|
759
|
+
? record['launchCommand']
|
|
760
|
+
.flatMap((entry) => (typeof entry === 'string' ? [entry.trim()] : []))
|
|
761
|
+
.filter((entry) => entry.length > 0)
|
|
762
|
+
: null;
|
|
763
|
+
const launchCommand =
|
|
764
|
+
launchCommandFromArray !== null
|
|
765
|
+
? launchCommandFromArray.length > 0
|
|
766
|
+
? launchCommandFromArray
|
|
767
|
+
: undefined
|
|
768
|
+
: typeof record['launchCommand'] === 'string' && record['launchCommand'].trim().length > 0
|
|
769
|
+
? [record['launchCommand'].trim()]
|
|
770
|
+
: undefined;
|
|
771
|
+
if (
|
|
772
|
+
enabled === undefined &&
|
|
773
|
+
appName === undefined &&
|
|
774
|
+
detectCommand === undefined &&
|
|
775
|
+
launchCommand === undefined
|
|
776
|
+
) {
|
|
777
|
+
return null;
|
|
778
|
+
}
|
|
779
|
+
return {
|
|
780
|
+
...(enabled === undefined ? {} : { enabled }),
|
|
781
|
+
...(appName === undefined ? {} : { appName }),
|
|
782
|
+
...(detectCommand === undefined ? {} : { detectCommand }),
|
|
783
|
+
...(launchCommand === undefined ? {} : { launchCommand }),
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
function normalizeOpenInLinkCommand(
|
|
788
|
+
input: unknown,
|
|
789
|
+
fallback: readonly string[] | null,
|
|
790
|
+
): readonly string[] | null {
|
|
791
|
+
if (input === null) {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
if (Array.isArray(input)) {
|
|
795
|
+
const normalized = input
|
|
796
|
+
.flatMap((entry) => (typeof entry === 'string' ? [entry.trim()] : []))
|
|
797
|
+
.filter((entry) => entry.length > 0);
|
|
798
|
+
return normalized.length > 0 ? normalized : null;
|
|
799
|
+
}
|
|
800
|
+
if (typeof input === 'string' && input.trim().length > 0) {
|
|
801
|
+
return [input.trim()];
|
|
802
|
+
}
|
|
803
|
+
return fallback;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
function normalizeMuxOpenInLinksConfig(input: unknown): HarnessMuxOpenInLinkConfig {
|
|
807
|
+
const record = asRecord(input);
|
|
808
|
+
if (record === null) {
|
|
809
|
+
return DEFAULT_HARNESS_CONFIG.mux.openIn.links;
|
|
810
|
+
}
|
|
811
|
+
return {
|
|
812
|
+
browserCommand: normalizeOpenInLinkCommand(
|
|
813
|
+
record['browserCommand'],
|
|
814
|
+
DEFAULT_HARNESS_CONFIG.mux.openIn.links.browserCommand,
|
|
815
|
+
),
|
|
816
|
+
fileCommand: normalizeOpenInLinkCommand(
|
|
817
|
+
record['fileCommand'],
|
|
818
|
+
DEFAULT_HARNESS_CONFIG.mux.openIn.links.fileCommand,
|
|
819
|
+
),
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
function normalizeMuxOpenInConfig(input: unknown): HarnessMuxOpenInConfig {
|
|
824
|
+
const record = asRecord(input);
|
|
825
|
+
if (record === null) {
|
|
826
|
+
return DEFAULT_HARNESS_CONFIG.mux.openIn;
|
|
827
|
+
}
|
|
828
|
+
const targetsRecord = asRecord(record['targets']);
|
|
829
|
+
const normalizedTargets: Partial<
|
|
830
|
+
Record<HarnessMuxOpenInTargetId, HarnessMuxOpenInTargetOverrideConfig>
|
|
831
|
+
> = {};
|
|
832
|
+
if (targetsRecord !== null) {
|
|
833
|
+
for (const targetId of HARNESS_MUX_OPEN_IN_TARGET_IDS) {
|
|
834
|
+
const raw = targetsRecord[targetId];
|
|
835
|
+
const normalized = normalizeMuxOpenInTargetOverride(raw);
|
|
836
|
+
if (normalized !== null) {
|
|
837
|
+
normalizedTargets[targetId] = normalized;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return {
|
|
842
|
+
targets: normalizedTargets,
|
|
843
|
+
links: normalizeMuxOpenInLinksConfig(record['links']),
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
|
|
632
847
|
function normalizeGitHubBranchStrategy(value: unknown): HarnessGitHubBranchStrategy {
|
|
633
848
|
if (value === 'current-only' || value === 'pinned-only' || value === 'pinned-then-current') {
|
|
634
849
|
return value;
|
|
@@ -679,6 +894,41 @@ function normalizeGitHubConfig(input: unknown): HarnessGitHubConfig {
|
|
|
679
894
|
};
|
|
680
895
|
}
|
|
681
896
|
|
|
897
|
+
function normalizeGatewayConfig(input: unknown): HarnessGatewayConfig {
|
|
898
|
+
const record = asRecord(input);
|
|
899
|
+
if (record === null) {
|
|
900
|
+
return DEFAULT_HARNESS_CONFIG.gateway;
|
|
901
|
+
}
|
|
902
|
+
return {
|
|
903
|
+
host: normalizeHost(record['host'], DEFAULT_HARNESS_CONFIG.gateway.host),
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
function normalizeLinearConfig(input: unknown): HarnessLinearConfig {
|
|
908
|
+
const record = asRecord(input);
|
|
909
|
+
if (record === null) {
|
|
910
|
+
return DEFAULT_HARNESS_CONFIG.linear;
|
|
911
|
+
}
|
|
912
|
+
const tokenEnvVarRaw = record['tokenEnvVar'];
|
|
913
|
+
const tokenEnvVar =
|
|
914
|
+
typeof tokenEnvVarRaw === 'string' && tokenEnvVarRaw.trim().length > 0
|
|
915
|
+
? tokenEnvVarRaw.trim()
|
|
916
|
+
: DEFAULT_HARNESS_CONFIG.linear.tokenEnvVar;
|
|
917
|
+
const apiBaseUrlRaw = record['apiBaseUrl'];
|
|
918
|
+
const apiBaseUrl =
|
|
919
|
+
typeof apiBaseUrlRaw === 'string' && apiBaseUrlRaw.trim().length > 0
|
|
920
|
+
? apiBaseUrlRaw.trim().replace(/\/+$/u, '')
|
|
921
|
+
: DEFAULT_HARNESS_CONFIG.linear.apiBaseUrl;
|
|
922
|
+
return {
|
|
923
|
+
enabled:
|
|
924
|
+
typeof record['enabled'] === 'boolean'
|
|
925
|
+
? record['enabled']
|
|
926
|
+
: DEFAULT_HARNESS_CONFIG.linear.enabled,
|
|
927
|
+
apiBaseUrl,
|
|
928
|
+
tokenEnvVar,
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
|
|
682
932
|
function normalizePerfConfig(input: unknown): HarnessPerfConfig {
|
|
683
933
|
const record = asRecord(input);
|
|
684
934
|
if (record === null) {
|
|
@@ -709,6 +959,14 @@ function normalizeNonNegativeInt(value: unknown, fallback: number): number {
|
|
|
709
959
|
return normalized;
|
|
710
960
|
}
|
|
711
961
|
|
|
962
|
+
function normalizePositiveInt(value: unknown, fallback: number): number {
|
|
963
|
+
const normalized = normalizeNonNegativeInt(value, fallback);
|
|
964
|
+
if (normalized < 1) {
|
|
965
|
+
return fallback;
|
|
966
|
+
}
|
|
967
|
+
return normalized;
|
|
968
|
+
}
|
|
969
|
+
|
|
712
970
|
function normalizeDebugMuxConfig(input: unknown): HarnessDebugMuxConfig {
|
|
713
971
|
const record = asRecord(input);
|
|
714
972
|
if (record === null) {
|
|
@@ -1304,6 +1562,69 @@ function normalizeLifecycleWebhookConfig(
|
|
|
1304
1562
|
};
|
|
1305
1563
|
}
|
|
1306
1564
|
|
|
1565
|
+
function normalizeStorageLifecycleConfig(input: unknown): HarnessStorageLifecycleConfig {
|
|
1566
|
+
const record = asRecord(input);
|
|
1567
|
+
if (record === null) {
|
|
1568
|
+
return DEFAULT_HARNESS_CONFIG.storage.lifecycle;
|
|
1569
|
+
}
|
|
1570
|
+
return {
|
|
1571
|
+
eventRetentionMs: normalizePositiveInt(
|
|
1572
|
+
record['eventRetentionMs'],
|
|
1573
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.eventRetentionMs,
|
|
1574
|
+
),
|
|
1575
|
+
telemetryRetentionMs: normalizePositiveInt(
|
|
1576
|
+
record['telemetryRetentionMs'],
|
|
1577
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.telemetryRetentionMs,
|
|
1578
|
+
),
|
|
1579
|
+
maintenanceIntervalMs: normalizePositiveInt(
|
|
1580
|
+
record['maintenanceIntervalMs'],
|
|
1581
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.maintenanceIntervalMs,
|
|
1582
|
+
),
|
|
1583
|
+
pruneBatchSize: normalizePositiveInt(
|
|
1584
|
+
record['pruneBatchSize'],
|
|
1585
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.pruneBatchSize,
|
|
1586
|
+
),
|
|
1587
|
+
compactFreelistPages: normalizePositiveInt(
|
|
1588
|
+
record['compactFreelistPages'],
|
|
1589
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.compactFreelistPages,
|
|
1590
|
+
),
|
|
1591
|
+
copyForwardBatchSize: normalizePositiveInt(
|
|
1592
|
+
record['copyForwardBatchSize'],
|
|
1593
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.copyForwardBatchSize,
|
|
1594
|
+
),
|
|
1595
|
+
copyForwardFinalizeTailRows: normalizePositiveInt(
|
|
1596
|
+
record['copyForwardFinalizeTailRows'],
|
|
1597
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.copyForwardFinalizeTailRows,
|
|
1598
|
+
),
|
|
1599
|
+
telemetryPayloadMaxBytes: normalizePositiveInt(
|
|
1600
|
+
record['telemetryPayloadMaxBytes'],
|
|
1601
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.telemetryPayloadMaxBytes,
|
|
1602
|
+
),
|
|
1603
|
+
textDeltaPayloadMaxBytes: normalizePositiveInt(
|
|
1604
|
+
record['textDeltaPayloadMaxBytes'],
|
|
1605
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.textDeltaPayloadMaxBytes,
|
|
1606
|
+
),
|
|
1607
|
+
textDeltaCoalesceWindowMs: normalizePositiveInt(
|
|
1608
|
+
record['textDeltaCoalesceWindowMs'],
|
|
1609
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.textDeltaCoalesceWindowMs,
|
|
1610
|
+
),
|
|
1611
|
+
busyTimeoutMs: normalizePositiveInt(
|
|
1612
|
+
record['busyTimeoutMs'],
|
|
1613
|
+
DEFAULT_HARNESS_CONFIG.storage.lifecycle.busyTimeoutMs,
|
|
1614
|
+
),
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
function normalizeStorageConfig(input: unknown): HarnessStorageConfig {
|
|
1619
|
+
const record = asRecord(input);
|
|
1620
|
+
if (record === null) {
|
|
1621
|
+
return DEFAULT_HARNESS_CONFIG.storage;
|
|
1622
|
+
}
|
|
1623
|
+
return {
|
|
1624
|
+
lifecycle: normalizeStorageLifecycleConfig(record['lifecycle']),
|
|
1625
|
+
};
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1307
1628
|
function normalizeLifecycleHooksConfig(input: unknown): HarnessLifecycleHooksConfig {
|
|
1308
1629
|
const record = asRecord(input);
|
|
1309
1630
|
if (record === null) {
|
|
@@ -1371,12 +1692,15 @@ export function parseHarnessConfigText(text: string): HarnessConfig {
|
|
|
1371
1692
|
|
|
1372
1693
|
const mux = asRecord(migratedRoot['mux']);
|
|
1373
1694
|
const github = normalizeGitHubConfig(migratedRoot['github']);
|
|
1695
|
+
const gateway = normalizeGatewayConfig(migratedRoot['gateway']);
|
|
1696
|
+
const linear = normalizeLinearConfig(migratedRoot['linear']);
|
|
1374
1697
|
const legacyPerf = normalizePerfConfig(migratedRoot['perf']);
|
|
1375
1698
|
const debug = normalizeDebugConfig(migratedRoot['debug'], legacyPerf);
|
|
1376
1699
|
const codex = normalizeCodexConfig(migratedRoot['codex']);
|
|
1377
1700
|
const claude = normalizeClaudeConfig(migratedRoot['claude']);
|
|
1378
1701
|
const cursor = normalizeCursorConfig(migratedRoot['cursor']);
|
|
1379
1702
|
const critique = normalizeCritiqueConfig(migratedRoot['critique']);
|
|
1703
|
+
const storage = normalizeStorageConfig(migratedRoot['storage']);
|
|
1380
1704
|
const hooks = normalizeLifecycleHooksConfig(asRecord(migratedRoot['hooks'])?.['lifecycle']);
|
|
1381
1705
|
|
|
1382
1706
|
return {
|
|
@@ -1385,13 +1709,18 @@ export function parseHarnessConfigText(text: string): HarnessConfig {
|
|
|
1385
1709
|
keybindings: mux === null ? {} : normalizeKeybindings(mux['keybindings']),
|
|
1386
1710
|
ui: mux === null ? DEFAULT_HARNESS_CONFIG.mux.ui : normalizeMuxUiConfig(mux['ui']),
|
|
1387
1711
|
git: mux === null ? DEFAULT_HARNESS_CONFIG.mux.git : normalizeMuxGitConfig(mux['git']),
|
|
1712
|
+
openIn:
|
|
1713
|
+
mux === null ? DEFAULT_HARNESS_CONFIG.mux.openIn : normalizeMuxOpenInConfig(mux['openIn']),
|
|
1388
1714
|
},
|
|
1389
1715
|
github,
|
|
1716
|
+
gateway,
|
|
1717
|
+
linear,
|
|
1390
1718
|
debug,
|
|
1391
1719
|
codex,
|
|
1392
1720
|
claude,
|
|
1393
1721
|
cursor,
|
|
1394
1722
|
critique,
|
|
1723
|
+
storage,
|
|
1395
1724
|
hooks: {
|
|
1396
1725
|
lifecycle: hooks,
|
|
1397
1726
|
},
|
|
@@ -1435,14 +1764,24 @@ export function resolveHarnessConfigDirectory(
|
|
|
1435
1764
|
env: NodeJS.ProcessEnv = process.env,
|
|
1436
1765
|
): string {
|
|
1437
1766
|
const xdgConfigHome = readNonEmptyEnvPath(env.XDG_CONFIG_HOME);
|
|
1767
|
+
const homeDirectory = readNonEmptyEnvPath(env.HOME) ?? readNonEmptyEnvPath(homedir());
|
|
1768
|
+
return resolveHarnessConfigDirectoryFromRoots(cwd, xdgConfigHome, homeDirectory);
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
export function resolveHarnessConfigDirectoryFromRoots(
|
|
1772
|
+
cwd: string,
|
|
1773
|
+
xdgConfigHome: string | null,
|
|
1774
|
+
homeDirectory: string | null,
|
|
1775
|
+
): string {
|
|
1438
1776
|
if (xdgConfigHome !== null) {
|
|
1439
1777
|
return resolve(xdgConfigHome, HARNESS_CONFIG_XDG_DIRECTORY_NAME);
|
|
1440
1778
|
}
|
|
1441
|
-
const homeDirectory = readNonEmptyEnvPath(env.HOME);
|
|
1442
1779
|
if (homeDirectory !== null) {
|
|
1443
1780
|
return resolve(homeDirectory, HARNESS_CONFIG_HOME_DIRECTORY_NAME);
|
|
1444
1781
|
}
|
|
1445
|
-
|
|
1782
|
+
throw new Error(
|
|
1783
|
+
`unable to resolve harness config directory: HOME and XDG_CONFIG_HOME are unset (cwd=${cwd})`,
|
|
1784
|
+
);
|
|
1446
1785
|
}
|
|
1447
1786
|
|
|
1448
1787
|
export function resolveHarnessConfigPath(
|
|
@@ -1544,6 +1883,9 @@ export function updateHarnessMuxUiConfig(
|
|
|
1544
1883
|
paneWidthPercent: number | null;
|
|
1545
1884
|
repositoriesCollapsed: boolean;
|
|
1546
1885
|
shortcutsCollapsed: boolean;
|
|
1886
|
+
startupPane: HarnessMuxStartupPane;
|
|
1887
|
+
showTasks: boolean;
|
|
1888
|
+
showDebugBar: boolean;
|
|
1547
1889
|
}>,
|
|
1548
1890
|
options?: {
|
|
1549
1891
|
cwd?: string;
|
|
@@ -1562,14 +1904,20 @@ export function updateHarnessMuxUiConfig(
|
|
|
1562
1904
|
update.paneWidthPercent === undefined
|
|
1563
1905
|
? current.mux.ui.paneWidthPercent
|
|
1564
1906
|
: normalizePaneWidthPercent(update.paneWidthPercent, null);
|
|
1565
|
-
const nextShortcutsCollapsed =
|
|
1566
|
-
update.shortcutsCollapsed === undefined
|
|
1567
|
-
? current.mux.ui.shortcutsCollapsed
|
|
1568
|
-
: update.shortcutsCollapsed;
|
|
1569
1907
|
const nextRepositoriesCollapsed =
|
|
1570
1908
|
update.repositoriesCollapsed === undefined
|
|
1571
1909
|
? current.mux.ui.repositoriesCollapsed
|
|
1572
1910
|
: update.repositoriesCollapsed;
|
|
1911
|
+
const nextShortcutsCollapsed =
|
|
1912
|
+
update.shortcutsCollapsed === undefined
|
|
1913
|
+
? current.mux.ui.shortcutsCollapsed
|
|
1914
|
+
: update.shortcutsCollapsed;
|
|
1915
|
+
const nextStartupPane =
|
|
1916
|
+
update.startupPane === undefined ? current.mux.ui.startupPane : update.startupPane;
|
|
1917
|
+
const nextShowTasks =
|
|
1918
|
+
update.showTasks === undefined ? current.mux.ui.showTasks : update.showTasks;
|
|
1919
|
+
const nextShowDebugBar =
|
|
1920
|
+
update.showDebugBar === undefined ? current.mux.ui.showDebugBar : update.showDebugBar;
|
|
1573
1921
|
return {
|
|
1574
1922
|
...current,
|
|
1575
1923
|
mux: {
|
|
@@ -1579,6 +1927,9 @@ export function updateHarnessMuxUiConfig(
|
|
|
1579
1927
|
nextPaneWidthPercent === null ? null : roundUiPercent(nextPaneWidthPercent),
|
|
1580
1928
|
repositoriesCollapsed: nextRepositoriesCollapsed,
|
|
1581
1929
|
shortcutsCollapsed: nextShortcutsCollapsed,
|
|
1930
|
+
startupPane: nextStartupPane,
|
|
1931
|
+
showTasks: nextShowTasks,
|
|
1932
|
+
showDebugBar: nextShowDebugBar,
|
|
1582
1933
|
theme: current.mux.ui.theme,
|
|
1583
1934
|
},
|
|
1584
1935
|
},
|
|
@@ -39,11 +39,7 @@ export function resolveHarnessWorkspaceDirectory(
|
|
|
39
39
|
invocationDirectory: string,
|
|
40
40
|
env: NodeJS.ProcessEnv = process.env,
|
|
41
41
|
): string {
|
|
42
|
-
const legacyWorkspaceDirectory = resolveLegacyHarnessDirectory(invocationDirectory);
|
|
43
42
|
const configDirectory = resolveHarnessConfigDirectory(invocationDirectory, env);
|
|
44
|
-
if (resolve(configDirectory) === legacyWorkspaceDirectory) {
|
|
45
|
-
return legacyWorkspaceDirectory;
|
|
46
|
-
}
|
|
47
43
|
return resolve(
|
|
48
44
|
configDirectory,
|
|
49
45
|
HARNESS_WORKSPACES_DIRECTORY,
|
|
@@ -74,13 +70,14 @@ export function resolveHarnessRuntimePath(
|
|
|
74
70
|
pathValue: string,
|
|
75
71
|
env: NodeJS.ProcessEnv = process.env,
|
|
76
72
|
): string {
|
|
73
|
+
const workspaceRuntimeDirectory = resolveHarnessWorkspaceDirectory(invocationDirectory, env);
|
|
77
74
|
const normalizedPath = pathValue.trim();
|
|
78
75
|
if (normalizedPath.length === 0 || normalizedPath === HARNESS_LEGACY_RELATIVE_ROOT) {
|
|
79
|
-
return
|
|
76
|
+
return workspaceRuntimeDirectory;
|
|
80
77
|
}
|
|
81
78
|
if (normalizedPath.startsWith(`${HARNESS_LEGACY_RELATIVE_ROOT}/`)) {
|
|
82
79
|
return resolve(
|
|
83
|
-
|
|
80
|
+
workspaceRuntimeDirectory,
|
|
84
81
|
normalizedPath.slice(`${HARNESS_LEGACY_RELATIVE_ROOT}/`.length),
|
|
85
82
|
);
|
|
86
83
|
}
|
|
@@ -88,5 +85,5 @@ export function resolveHarnessRuntimePath(
|
|
|
88
85
|
if (expandedHomePath !== null) {
|
|
89
86
|
return expandedHomePath;
|
|
90
87
|
}
|
|
91
|
-
return resolve(
|
|
88
|
+
return resolve(workspaceRuntimeDirectory, normalizedPath);
|
|
92
89
|
}
|