@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.
Files changed (239) hide show
  1. package/README.md +31 -35
  2. package/package.json +31 -11
  3. package/packages/harness-ai/src/anthropic-protocol.ts +68 -68
  4. package/packages/harness-ai/src/stream-text.ts +13 -91
  5. package/packages/harness-ui/src/frame-primitives.ts +158 -0
  6. package/packages/harness-ui/src/index.ts +18 -0
  7. package/packages/harness-ui/src/interaction/conversation-input-forwarder.ts +221 -0
  8. package/packages/harness-ui/src/interaction/conversation-selection-input.ts +213 -0
  9. package/packages/harness-ui/src/interaction/global-shortcut-input.ts +172 -0
  10. package/{src/ui → packages/harness-ui/src/interaction}/input-preflight.ts +10 -12
  11. package/{src/ui → packages/harness-ui/src/interaction}/input-token-router.ts +120 -69
  12. package/packages/harness-ui/src/interaction/input.ts +420 -0
  13. package/packages/harness-ui/src/interaction/left-nav-input.ts +166 -0
  14. package/{src/ui → packages/harness-ui/src/interaction}/main-pane-pointer-input.ts +91 -23
  15. package/{src/ui → packages/harness-ui/src/interaction}/pointer-routing-input.ts +112 -48
  16. package/packages/harness-ui/src/interaction/rail-pointer-input.ts +62 -0
  17. package/packages/harness-ui/src/interaction/repository-fold-input.ts +118 -0
  18. package/packages/harness-ui/src/kit.ts +476 -0
  19. package/packages/harness-ui/src/layout.ts +238 -0
  20. package/{src/ui/modals/manager.ts → packages/harness-ui/src/modal-manager.ts} +94 -64
  21. package/{src/ui → packages/harness-ui/src}/screen.ts +53 -26
  22. package/packages/harness-ui/src/surface.ts +252 -0
  23. package/packages/harness-ui/src/text-layout.ts +210 -0
  24. package/packages/nim-core/src/contracts.ts +239 -0
  25. package/packages/nim-core/src/event-store.ts +299 -0
  26. package/packages/nim-core/src/events.ts +53 -0
  27. package/packages/nim-core/src/index.ts +9 -0
  28. package/packages/nim-core/src/provider-router.ts +129 -0
  29. package/packages/nim-core/src/providers/anthropic-driver.ts +291 -0
  30. package/packages/nim-core/src/runtime-factory.ts +49 -0
  31. package/packages/nim-core/src/runtime.ts +1797 -0
  32. package/packages/nim-core/src/session-store.ts +516 -0
  33. package/packages/nim-core/src/telemetry.ts +48 -0
  34. package/packages/nim-test-tui/src/index.ts +150 -0
  35. package/packages/nim-ui-core/src/index.ts +1 -0
  36. package/packages/nim-ui-core/src/projection.ts +87 -0
  37. package/scripts/codex-live-mux-runtime.ts +2 -3721
  38. package/scripts/control-plane-daemon.ts +24 -2
  39. package/scripts/harness-bin.js +5 -0
  40. package/scripts/harness-commands.ts +300 -0
  41. package/scripts/harness-runtime.ts +82 -0
  42. package/scripts/harness.ts +33 -3007
  43. package/scripts/nim-tui-smoke.ts +748 -0
  44. package/src/cli/auth/runtime.ts +948 -0
  45. package/src/cli/default-gateway-pointer.ts +193 -0
  46. package/src/cli/gateway/runtime.ts +1872 -0
  47. package/src/cli/parsing/flags.ts +23 -0
  48. package/src/cli/parsing/session.ts +42 -0
  49. package/src/cli/runtime/context.ts +193 -0
  50. package/src/cli/runtime-app/application.ts +392 -0
  51. package/src/cli/runtime-infra/gateway-control.ts +729 -0
  52. package/{scripts/harness-inspector.ts → src/cli/workflows/inspector.ts} +14 -11
  53. package/src/cli/workflows/runtime.ts +965 -0
  54. package/src/clients/tui/left-rail-interactions.ts +519 -0
  55. package/src/clients/tui/main-pane-interactions.ts +509 -0
  56. package/src/clients/tui/modal-input-routing.ts +71 -0
  57. package/src/clients/tui/render-snapshot-adapter.ts +88 -0
  58. package/src/clients/web/synced-selectors.ts +132 -0
  59. package/src/codex/live-session.ts +82 -29
  60. package/src/config/config-core.ts +361 -10
  61. package/src/config/harness-paths.ts +4 -7
  62. package/src/config/harness-runtime-migration.ts +142 -19
  63. package/src/config/harness.config.template.jsonc +33 -0
  64. package/src/config/secrets-core.ts +92 -4
  65. package/src/control-plane/agent-realtime-api.ts +82 -427
  66. package/src/control-plane/prompt/thread-title-namer.ts +49 -23
  67. package/src/control-plane/session-summary.ts +10 -81
  68. package/src/control-plane/status/reducer-base.ts +12 -12
  69. package/src/control-plane/status/reducers/claude-status-reducer.ts +3 -3
  70. package/src/control-plane/status/reducers/codex-status-reducer.ts +4 -4
  71. package/src/control-plane/status/reducers/cursor-status-reducer.ts +3 -3
  72. package/src/control-plane/stream-client.ts +12 -2
  73. package/src/control-plane/stream-command-parser.ts +83 -143
  74. package/src/control-plane/stream-protocol.ts +53 -37
  75. package/src/control-plane/stream-server-background.ts +18 -2
  76. package/src/control-plane/stream-server-command.ts +376 -69
  77. package/src/control-plane/stream-server-session-runtime.ts +3 -2
  78. package/src/control-plane/stream-server.ts +943 -80
  79. package/src/control-plane/stream-session-runtime-types.ts +41 -0
  80. package/src/{mux/live-mux/control-plane-records.ts → core/contracts/records.ts} +24 -97
  81. package/src/core/state/observed-stream-cursor.ts +43 -0
  82. package/src/core/state/synced-observed-state.ts +273 -0
  83. package/src/core/store/harness-synced-store.ts +81 -0
  84. package/src/diff/budget.ts +136 -0
  85. package/src/diff/build.ts +289 -0
  86. package/src/diff/chunker.ts +146 -0
  87. package/src/diff/git-invoke.ts +315 -0
  88. package/src/diff/git-parse.ts +472 -0
  89. package/src/diff/hash.ts +70 -0
  90. package/src/diff/index.ts +24 -0
  91. package/src/diff/normalize.ts +134 -0
  92. package/src/diff/types.ts +178 -0
  93. package/src/diff-ui/args.ts +346 -0
  94. package/src/diff-ui/commands.ts +123 -0
  95. package/src/diff-ui/finder.ts +94 -0
  96. package/src/diff-ui/highlight.ts +127 -0
  97. package/src/diff-ui/index.ts +2 -0
  98. package/src/diff-ui/model.ts +141 -0
  99. package/src/diff-ui/pager.ts +412 -0
  100. package/src/diff-ui/render.ts +337 -0
  101. package/src/diff-ui/runtime.ts +379 -0
  102. package/src/diff-ui/state.ts +224 -0
  103. package/src/diff-ui/types.ts +236 -0
  104. package/src/domain/conversations.ts +11 -7
  105. package/src/domain/workspace.ts +76 -4
  106. package/src/mux/control-plane-op-queue.ts +93 -7
  107. package/src/mux/conversation-rail.ts +28 -71
  108. package/src/mux/dual-pane-core.ts +13 -13
  109. package/src/mux/harness-core-ui.ts +313 -42
  110. package/src/mux/input-shortcuts.ts +22 -112
  111. package/src/mux/keybinding-catalog.ts +340 -0
  112. package/src/mux/keybinding-registry.ts +103 -0
  113. package/src/mux/live-mux/command-menu-open-in.ts +280 -0
  114. package/src/mux/live-mux/command-menu.ts +167 -4
  115. package/src/mux/live-mux/conversation-state.ts +13 -0
  116. package/src/mux/live-mux/directory-resolution.ts +1 -1
  117. package/src/mux/live-mux/git-parsing.ts +16 -0
  118. package/src/mux/live-mux/git-snapshot.ts +33 -2
  119. package/src/mux/live-mux/global-shortcut-handlers.ts +6 -0
  120. package/src/mux/live-mux/home-pane-drop.ts +1 -1
  121. package/src/mux/live-mux/home-pane-pointer.ts +10 -0
  122. package/src/mux/live-mux/input-forwarding.ts +59 -2
  123. package/src/mux/live-mux/left-nav-activation.ts +124 -7
  124. package/src/mux/live-mux/left-nav.ts +35 -0
  125. package/src/mux/live-mux/link-click.ts +292 -0
  126. package/src/mux/live-mux/modal-command-menu-handler.ts +46 -9
  127. package/src/mux/live-mux/modal-conversation-handlers.ts +5 -1
  128. package/src/mux/live-mux/modal-input-reducers.ts +106 -8
  129. package/src/mux/live-mux/modal-overlays.ts +210 -31
  130. package/src/mux/live-mux/modal-pointer.ts +3 -7
  131. package/src/mux/live-mux/modal-prompt-handlers.ts +107 -1
  132. package/src/mux/live-mux/modal-release-notes-handler.ts +111 -0
  133. package/src/mux/live-mux/modal-task-editor-handler.ts +16 -11
  134. package/src/mux/live-mux/pointer-routing.ts +5 -2
  135. package/src/mux/live-mux/project-pane-pointer.ts +8 -0
  136. package/src/mux/live-mux/rail-layout.ts +33 -30
  137. package/src/mux/live-mux/release-notes.ts +383 -0
  138. package/src/mux/live-mux/render-trace-analysis.ts +52 -7
  139. package/src/mux/live-mux/repository-folding.ts +3 -0
  140. package/src/mux/live-mux/selection.ts +0 -4
  141. package/src/mux/live-mux/session-diagnostics-paths.ts +21 -0
  142. package/src/mux/project-pane-github-review.ts +271 -0
  143. package/src/mux/render-frame.ts +4 -0
  144. package/src/mux/runtime-app/codex-live-mux-runtime.ts +5191 -0
  145. package/src/mux/task-composer.ts +21 -14
  146. package/src/mux/task-focused-pane.ts +118 -117
  147. package/src/mux/task-screen-keybindings.ts +19 -82
  148. package/src/mux/workspace-rail-model.ts +270 -104
  149. package/src/mux/workspace-rail.ts +45 -22
  150. package/src/pty/session-broker.ts +1 -1
  151. package/{scripts → src/recording}/terminal-recording-gif-lib.ts +2 -2
  152. package/src/services/control-plane.ts +50 -32
  153. package/src/services/conversation-lifecycle.ts +118 -87
  154. package/src/services/conversation-startup-hydration.ts +20 -12
  155. package/src/services/directory-hydration.ts +21 -16
  156. package/src/services/event-persistence.ts +7 -0
  157. package/src/services/left-rail-pointer-handler.ts +329 -0
  158. package/src/services/mux-ui-state-persistence.ts +5 -1
  159. package/src/services/recording.ts +34 -26
  160. package/src/services/runtime-command-menu-agent-tools.ts +1 -1
  161. package/src/services/runtime-control-actions.ts +79 -61
  162. package/src/services/runtime-control-plane-ops.ts +122 -83
  163. package/src/services/runtime-conversation-actions.ts +40 -26
  164. package/src/services/runtime-conversation-activation.ts +82 -30
  165. package/src/services/runtime-conversation-starter.ts +80 -48
  166. package/src/services/runtime-conversation-title-edit.ts +91 -80
  167. package/src/services/runtime-envelope-handler.ts +107 -105
  168. package/src/services/runtime-git-state.ts +42 -29
  169. package/src/services/runtime-layout-resize.ts +3 -1
  170. package/src/services/runtime-left-rail-render.ts +99 -63
  171. package/src/services/runtime-nim-cli-session.ts +438 -0
  172. package/src/services/runtime-nim-session.ts +705 -0
  173. package/src/services/runtime-nim-tool-bridge.ts +141 -0
  174. package/src/services/runtime-observed-event-projection-pipeline.ts +45 -0
  175. package/src/services/runtime-process-wiring.ts +29 -36
  176. package/src/services/runtime-project-pane-github-review-cache.ts +164 -0
  177. package/src/services/runtime-render-flush.ts +63 -70
  178. package/src/services/runtime-render-lifecycle.ts +65 -64
  179. package/src/services/runtime-render-orchestrator.ts +55 -45
  180. package/src/services/runtime-render-pipeline.ts +106 -103
  181. package/src/services/runtime-render-state.ts +62 -49
  182. package/src/services/runtime-repository-actions.ts +97 -70
  183. package/src/services/runtime-right-pane-render.ts +80 -53
  184. package/src/services/runtime-shutdown.ts +38 -35
  185. package/src/services/runtime-stream-subscriptions.ts +35 -27
  186. package/src/services/runtime-task-composer-persistence.ts +71 -59
  187. package/src/services/runtime-task-composer-snapshot.ts +14 -0
  188. package/src/services/runtime-task-editor-actions.ts +46 -29
  189. package/src/services/runtime-task-pane-actions.ts +220 -134
  190. package/src/services/runtime-task-pane-shortcuts.ts +323 -123
  191. package/src/services/runtime-workspace-observed-effect-queue.ts +25 -0
  192. package/src/services/runtime-workspace-observed-events.ts +33 -184
  193. package/src/services/runtime-workspace-observed-transition-policy.ts +228 -0
  194. package/src/services/session-diagnostics-store.ts +217 -0
  195. package/src/services/startup-background-resume.ts +26 -21
  196. package/src/services/startup-orchestrator.ts +16 -13
  197. package/src/services/startup-paint-tracker.ts +29 -21
  198. package/src/services/startup-persisted-conversation-queue.ts +19 -13
  199. package/src/services/startup-settled-gate.ts +25 -15
  200. package/src/services/startup-shutdown.ts +18 -22
  201. package/src/services/startup-state-hydration.ts +44 -34
  202. package/src/services/startup-visibility.ts +12 -4
  203. package/src/services/task-pane-selection-actions.ts +89 -72
  204. package/src/services/task-planning-hydration.ts +24 -18
  205. package/src/services/task-planning-observed-events.ts +50 -52
  206. package/src/services/workspace-observed-events.ts +66 -63
  207. package/src/storage/storage-lifecycle-core.ts +438 -0
  208. package/src/store/control-plane-store-normalize.ts +33 -242
  209. package/src/store/control-plane-store-types.ts +1 -35
  210. package/src/store/control-plane-store.ts +396 -56
  211. package/src/store/event-store.ts +397 -3
  212. package/src/terminal/snapshot-oracle.ts +207 -94
  213. package/src/ui/mux-theme.ts +112 -8
  214. package/src/ui/panes/home-gridfire.ts +40 -31
  215. package/src/ui/panes/home.ts +10 -2
  216. package/src/ui/panes/nim.ts +315 -0
  217. package/src/mux/live-mux/actions-task.ts +0 -115
  218. package/src/mux/live-mux/left-rail-actions.ts +0 -118
  219. package/src/mux/live-mux/left-rail-conversation-click.ts +0 -82
  220. package/src/mux/live-mux/left-rail-pointer.ts +0 -74
  221. package/src/mux/live-mux/task-pane-shortcuts.ts +0 -206
  222. package/src/services/runtime-directory-actions.ts +0 -164
  223. package/src/services/runtime-input-pipeline.ts +0 -50
  224. package/src/services/runtime-input-router.ts +0 -189
  225. package/src/services/runtime-main-pane-input.ts +0 -230
  226. package/src/services/runtime-modal-input.ts +0 -119
  227. package/src/services/runtime-navigation-input.ts +0 -197
  228. package/src/services/runtime-rail-input.ts +0 -278
  229. package/src/services/runtime-task-pane.ts +0 -62
  230. package/src/services/runtime-workspace-actions.ts +0 -158
  231. package/src/ui/conversation-input-forwarder.ts +0 -114
  232. package/src/ui/conversation-selection-input.ts +0 -103
  233. package/src/ui/global-shortcut-input.ts +0 -89
  234. package/src/ui/input.ts +0 -238
  235. package/src/ui/kit.ts +0 -509
  236. package/src/ui/left-nav-input.ts +0 -80
  237. package/src/ui/left-rail-pointer-input.ts +0 -148
  238. package/src/ui/repository-fold-input.ts +0 -91
  239. package/src/ui/surface.ts +0 -224
@@ -1,7 +1,16 @@
1
1
  import type { PtyExit } from '../pty/pty_host.ts';
2
+ import {
3
+ parseDirectoryGitStatusRecord as parseContractDirectoryGitStatusRecord,
4
+ parseDirectoryRecord as parseContractDirectoryRecord,
5
+ parseRepositoryRecord as parseContractRepositoryRecord,
6
+ parseTaskRecord as parseContractTaskRecord,
7
+ type ControlPlaneRepositoryRecord,
8
+ } from '../core/contracts/records.ts';
2
9
  import { connectControlPlaneStreamClient, type ControlPlaneStreamClient } from './stream-client.ts';
3
10
  import { parseSessionSummaryList, parseSessionSummaryRecord } from './session-summary.ts';
4
11
  import {
12
+ parseStreamSessionRuntimeStatus,
13
+ parseStreamSessionStatusModel,
5
14
  type StreamCommand,
6
15
  type StreamObservedEvent,
7
16
  type StreamSessionController,
@@ -226,39 +235,6 @@ export interface AgentRepositoryUpdateInput {
226
235
  }
227
236
 
228
237
  export type AgentTaskStatus = 'draft' | 'ready' | 'in-progress' | 'completed';
229
- export type AgentTaskLinearPriority = 0 | 1 | 2 | 3 | 4;
230
-
231
- export interface AgentTaskLinearRecord {
232
- issueId: string | null;
233
- identifier: string | null;
234
- url: string | null;
235
- teamId: string | null;
236
- projectId: string | null;
237
- projectMilestoneId: string | null;
238
- cycleId: string | null;
239
- stateId: string | null;
240
- assigneeId: string | null;
241
- priority: AgentTaskLinearPriority | null;
242
- estimate: number | null;
243
- dueDate: string | null;
244
- labelIds: readonly string[];
245
- }
246
-
247
- export interface AgentTaskLinearInput {
248
- issueId?: string | null;
249
- identifier?: string | null;
250
- url?: string | null;
251
- teamId?: string | null;
252
- projectId?: string | null;
253
- projectMilestoneId?: string | null;
254
- cycleId?: string | null;
255
- stateId?: string | null;
256
- assigneeId?: string | null;
257
- priority?: AgentTaskLinearPriority | null;
258
- estimate?: number | null;
259
- dueDate?: string | null;
260
- labelIds?: readonly string[] | null;
261
- }
262
238
 
263
239
  export interface AgentTask {
264
240
  taskId: string;
@@ -269,7 +245,7 @@ export interface AgentTask {
269
245
  scopeKind: 'global' | 'repository' | 'project';
270
246
  projectId: string | null;
271
247
  title: string;
272
- description: string;
248
+ body: string;
273
249
  status: AgentTaskStatus;
274
250
  orderIndex: number;
275
251
  claimedByControllerId: string | null;
@@ -278,7 +254,6 @@ export interface AgentTask {
278
254
  baseBranch: string | null;
279
255
  claimedAt: string | null;
280
256
  completedAt: string | null;
281
- linear: AgentTaskLinearRecord;
282
257
  createdAt: string;
283
258
  updatedAt: string;
284
259
  }
@@ -287,9 +262,8 @@ export interface AgentTaskCreateInput extends AgentScopeQuery {
287
262
  taskId?: string;
288
263
  repositoryId?: string;
289
264
  projectId?: string;
290
- title: string;
291
- description?: string;
292
- linear?: AgentTaskLinearInput;
265
+ title?: string | null;
266
+ body: string;
293
267
  }
294
268
 
295
269
  export interface AgentTaskListQuery extends AgentScopeQuery {
@@ -301,11 +275,10 @@ export interface AgentTaskListQuery extends AgentScopeQuery {
301
275
  }
302
276
 
303
277
  export interface AgentTaskUpdateInput {
304
- title?: string;
305
- description?: string;
278
+ title?: string | null;
279
+ body?: string;
306
280
  repositoryId?: string | null;
307
281
  projectId?: string | null;
308
- linear?: AgentTaskLinearInput | null;
309
282
  }
310
283
 
311
284
  export interface AgentTaskClaimInput {
@@ -379,10 +352,6 @@ function readString(value: unknown): string | null {
379
352
  return typeof value === 'string' ? value : null;
380
353
  }
381
354
 
382
- function readNumber(value: unknown): number | null {
383
- return typeof value === 'number' && Number.isFinite(value) ? value : null;
384
- }
385
-
386
355
  function readBoolean(value: unknown): boolean | null {
387
356
  return typeof value === 'boolean' ? value : null;
388
357
  }
@@ -413,196 +382,6 @@ function readNullableNumber(value: unknown): number | null | undefined {
413
382
  return undefined;
414
383
  }
415
384
 
416
- function readStringArray(value: unknown): readonly string[] | undefined {
417
- if (!Array.isArray(value)) {
418
- return undefined;
419
- }
420
- if (!value.every((entry) => typeof entry === 'string')) {
421
- return undefined;
422
- }
423
- return [...value];
424
- }
425
-
426
- function defaultTaskLinearRecord(): AgentTaskLinearRecord {
427
- return {
428
- issueId: null,
429
- identifier: null,
430
- url: null,
431
- teamId: null,
432
- projectId: null,
433
- projectMilestoneId: null,
434
- cycleId: null,
435
- stateId: null,
436
- assigneeId: null,
437
- priority: null,
438
- estimate: null,
439
- dueDate: null,
440
- labelIds: [],
441
- };
442
- }
443
-
444
- function parseTaskLinearRecord(value: unknown): AgentTaskLinearRecord | null {
445
- if (value === undefined) {
446
- return defaultTaskLinearRecord();
447
- }
448
- const record = asRecord(value);
449
- if (record === null) {
450
- return null;
451
- }
452
-
453
- const issueId = readNullableString(record['issueId']);
454
- const identifier = readNullableString(record['identifier']);
455
- const url = readNullableString(record['url']);
456
- const teamId = readNullableString(record['teamId']);
457
- const projectId = readNullableString(record['projectId']);
458
- const projectMilestoneId = readNullableString(record['projectMilestoneId']);
459
- const cycleId = readNullableString(record['cycleId']);
460
- const stateId = readNullableString(record['stateId']);
461
- const assigneeId = readNullableString(record['assigneeId']);
462
- const priority = readNullableNumber(record['priority']);
463
- const estimate = readNullableNumber(record['estimate']);
464
- const dueDate = readNullableString(record['dueDate']);
465
- const labelIdsRaw = record['labelIds'];
466
- const labelIds = labelIdsRaw === undefined ? [] : readStringArray(labelIdsRaw);
467
- if (
468
- issueId === undefined ||
469
- identifier === undefined ||
470
- url === undefined ||
471
- teamId === undefined ||
472
- projectId === undefined ||
473
- projectMilestoneId === undefined ||
474
- cycleId === undefined ||
475
- stateId === undefined ||
476
- assigneeId === undefined ||
477
- priority === undefined ||
478
- estimate === undefined ||
479
- dueDate === undefined ||
480
- labelIds === undefined
481
- ) {
482
- return null;
483
- }
484
- if (priority !== null && !Number.isInteger(priority)) {
485
- return null;
486
- }
487
- if (priority !== null && (priority < 0 || priority > 4)) {
488
- return null;
489
- }
490
- if (estimate !== null && (!Number.isInteger(estimate) || estimate < 0)) {
491
- return null;
492
- }
493
- return {
494
- issueId,
495
- identifier,
496
- url,
497
- teamId,
498
- projectId,
499
- projectMilestoneId,
500
- cycleId,
501
- stateId,
502
- assigneeId,
503
- priority: priority as AgentTaskLinearPriority | null,
504
- estimate,
505
- dueDate,
506
- labelIds,
507
- };
508
- }
509
-
510
- function parseTaskStatus(value: unknown): AgentTaskStatus | null {
511
- if (value === 'draft' || value === 'ready' || value === 'in-progress' || value === 'completed') {
512
- return value;
513
- }
514
- return null;
515
- }
516
-
517
- function parseTaskScopeKind(
518
- value: unknown,
519
- repositoryId: string | null | undefined,
520
- projectId: string | null | undefined,
521
- ): 'global' | 'repository' | 'project' | null {
522
- if (value === 'global' || value === 'repository' || value === 'project') {
523
- return value;
524
- }
525
- if (projectId !== null) {
526
- return 'project';
527
- }
528
- if (repositoryId !== null) {
529
- return 'repository';
530
- }
531
- if (value === undefined || value === null) {
532
- return 'global';
533
- }
534
- return null;
535
- }
536
-
537
- function parseRuntimeStatus(value: unknown): StreamSessionRuntimeStatus | null {
538
- if (
539
- value === 'running' ||
540
- value === 'needs-input' ||
541
- value === 'completed' ||
542
- value === 'exited'
543
- ) {
544
- return value;
545
- }
546
- return null;
547
- }
548
-
549
- function parseRuntimeStatusModel(value: unknown): StreamSessionStatusModel | null | undefined {
550
- if (value === null) {
551
- return null;
552
- }
553
- const record = asRecord(value);
554
- if (record === null) {
555
- return undefined;
556
- }
557
- const runtimeStatus = parseRuntimeStatus(record['runtimeStatus']);
558
- const phase = readString(record['phase']);
559
- const glyph = readString(record['glyph']);
560
- const badge = readString(record['badge']);
561
- const detailText = readString(record['detailText']);
562
- const attentionReason = readNullableString(record['attentionReason']);
563
- const lastKnownWork = readNullableString(record['lastKnownWork']);
564
- const lastKnownWorkAt = readNullableString(record['lastKnownWorkAt']);
565
- const phaseHint = readNullableString(record['phaseHint']);
566
- const observedAt = readString(record['observedAt']);
567
- if (
568
- runtimeStatus === null ||
569
- phase === null ||
570
- (phase !== 'needs-action' &&
571
- phase !== 'starting' &&
572
- phase !== 'working' &&
573
- phase !== 'idle' &&
574
- phase !== 'exited') ||
575
- glyph === null ||
576
- (glyph !== '▲' && glyph !== '◔' && glyph !== '◆' && glyph !== '○' && glyph !== '■') ||
577
- badge === null ||
578
- (badge !== 'NEED' && badge !== 'RUN ' && badge !== 'DONE' && badge !== 'EXIT') ||
579
- detailText === null ||
580
- attentionReason === undefined ||
581
- lastKnownWork === undefined ||
582
- lastKnownWorkAt === undefined ||
583
- phaseHint === undefined ||
584
- (phaseHint !== null &&
585
- phaseHint !== 'needs-action' &&
586
- phaseHint !== 'working' &&
587
- phaseHint !== 'idle') ||
588
- observedAt === null
589
- ) {
590
- return undefined;
591
- }
592
- return {
593
- runtimeStatus,
594
- phase,
595
- glyph,
596
- badge,
597
- detailText,
598
- attentionReason,
599
- lastKnownWork,
600
- lastKnownWorkAt,
601
- phaseHint,
602
- observedAt,
603
- };
604
- }
605
-
606
385
  function parseSignal(value: unknown): NodeJS.Signals | null | undefined {
607
386
  if (value === undefined) {
608
387
  return undefined;
@@ -642,36 +421,18 @@ function parseExit(value: unknown): PtyExit | null | undefined {
642
421
  }
643
422
 
644
423
  function parseProjectRecord(value: unknown): AgentProject | null {
645
- const record = asRecord(value);
646
- if (record === null) {
647
- return null;
648
- }
649
- const projectId = readString(record['directoryId']);
650
- const tenantId = readString(record['tenantId']);
651
- const userId = readString(record['userId']);
652
- const workspaceId = readString(record['workspaceId']);
653
- const path = readString(record['path']);
654
- const createdAt = readString(record['createdAt']);
655
- const archivedAt = readNullableString(record['archivedAt']);
656
- if (
657
- projectId === null ||
658
- tenantId === null ||
659
- userId === null ||
660
- workspaceId === null ||
661
- path === null ||
662
- createdAt === null ||
663
- archivedAt === undefined
664
- ) {
424
+ const parsed = parseContractDirectoryRecord(value);
425
+ if (parsed === null || parsed.createdAt === null) {
665
426
  return null;
666
427
  }
667
428
  return {
668
- projectId,
669
- tenantId,
670
- userId,
671
- workspaceId,
672
- path,
673
- createdAt,
674
- archivedAt,
429
+ projectId: parsed.directoryId,
430
+ tenantId: parsed.tenantId,
431
+ userId: parsed.userId,
432
+ workspaceId: parsed.workspaceId,
433
+ path: parsed.path,
434
+ createdAt: parsed.createdAt,
435
+ archivedAt: parsed.archivedAt,
675
436
  };
676
437
  }
677
438
 
@@ -772,8 +533,8 @@ function parseThreadRecord(value: unknown): AgentThread | null {
772
533
  const agentType = readString(record['agentType']);
773
534
  const createdAt = readString(record['createdAt']);
774
535
  const archivedAt = readNullableString(record['archivedAt']);
775
- const runtimeStatus = parseRuntimeStatus(record['runtimeStatus']);
776
- const runtimeStatusModel = parseRuntimeStatusModel(record['runtimeStatusModel']);
536
+ const runtimeStatus = parseStreamSessionRuntimeStatus(record['runtimeStatus']);
537
+ const runtimeStatusModel = parseStreamSessionStatusModel(record['runtimeStatusModel']);
777
538
  const runtimeLive = readBoolean(record['runtimeLive']);
778
539
  const runtimeAttentionReason = readNullableString(record['runtimeAttentionReason']);
779
540
  const runtimeProcessId = readNullableNumber(record['runtimeProcessId']);
@@ -822,190 +583,85 @@ function parseThreadRecord(value: unknown): AgentThread | null {
822
583
  };
823
584
  }
824
585
 
825
- function parseRepositoryRecord(value: unknown): AgentRepository | null {
826
- const record = asRecord(value);
827
- if (record === null) {
828
- return null;
829
- }
830
- const repositoryId = readString(record['repositoryId']);
831
- const tenantId = readString(record['tenantId']);
832
- const userId = readString(record['userId']);
833
- const workspaceId = readString(record['workspaceId']);
834
- const name = readString(record['name']);
835
- const remoteUrl = readString(record['remoteUrl']);
836
- const defaultBranch = readString(record['defaultBranch']);
837
- const metadata = asRecord(record['metadata']);
838
- const createdAt = readString(record['createdAt']);
839
- const archivedAt = readNullableString(record['archivedAt']);
840
- if (
841
- repositoryId === null ||
842
- tenantId === null ||
843
- userId === null ||
844
- workspaceId === null ||
845
- name === null ||
846
- remoteUrl === null ||
847
- defaultBranch === null ||
848
- metadata === null ||
849
- createdAt === null ||
850
- archivedAt === undefined
851
- ) {
586
+ function toAgentRepository(record: ControlPlaneRepositoryRecord): AgentRepository | null {
587
+ if (record.createdAt === null) {
852
588
  return null;
853
589
  }
854
590
  return {
855
- repositoryId,
856
- tenantId,
857
- userId,
858
- workspaceId,
859
- name,
860
- remoteUrl,
861
- defaultBranch,
862
- metadata,
863
- createdAt,
864
- archivedAt,
591
+ repositoryId: record.repositoryId,
592
+ tenantId: record.tenantId,
593
+ userId: record.userId,
594
+ workspaceId: record.workspaceId,
595
+ name: record.name,
596
+ remoteUrl: record.remoteUrl,
597
+ defaultBranch: record.defaultBranch,
598
+ metadata: record.metadata,
599
+ createdAt: record.createdAt,
600
+ archivedAt: record.archivedAt,
865
601
  };
866
602
  }
867
603
 
604
+ function parseRepositoryRecord(value: unknown): AgentRepository | null {
605
+ const parsed = parseContractRepositoryRecord(value);
606
+ return parsed === null ? null : toAgentRepository(parsed);
607
+ }
608
+
868
609
  function parseProjectGitStatusRecord(value: unknown): AgentProjectGitStatus | null {
869
- const record = asRecord(value);
870
- if (record === null) {
610
+ const parsed = parseContractDirectoryGitStatusRecord(value);
611
+ if (parsed === null) {
871
612
  return null;
872
613
  }
873
- const directoryId = readString(record['directoryId']);
874
- const summaryRecord = asRecord(record['summary']);
875
- const repositorySnapshotRecord = asRecord(record['repositorySnapshot']);
876
- const repositoryId = readNullableString(record['repositoryId']);
877
- const observedAt = readString(record['observedAt']);
878
- const repositoryRaw = record['repository'];
879
- const repository =
880
- repositoryRaw === null || repositoryRaw === undefined
881
- ? null
882
- : parseRepositoryRecord(repositoryRaw);
883
- if (
884
- directoryId === null ||
885
- summaryRecord === null ||
886
- repositorySnapshotRecord === null ||
887
- repositoryId === undefined ||
888
- observedAt === null ||
889
- (repositoryRaw !== null && repositoryRaw !== undefined && repository === null)
890
- ) {
891
- return null;
892
- }
893
- const branch = readString(summaryRecord['branch']);
894
- const changedFiles = readNumber(summaryRecord['changedFiles']);
895
- const additions = readNumber(summaryRecord['additions']);
896
- const deletions = readNumber(summaryRecord['deletions']);
897
- const normalizedRemoteUrl = readNullableString(repositorySnapshotRecord['normalizedRemoteUrl']);
898
- const commitCount = readNullableNumber(repositorySnapshotRecord['commitCount']);
899
- const lastCommitAt = readNullableString(repositorySnapshotRecord['lastCommitAt']);
900
- const shortCommitHash = readNullableString(repositorySnapshotRecord['shortCommitHash']);
901
- const inferredName = readNullableString(repositorySnapshotRecord['inferredName']);
902
- const defaultBranch = readNullableString(repositorySnapshotRecord['defaultBranch']);
903
- if (
904
- branch === null ||
905
- changedFiles === null ||
906
- additions === null ||
907
- deletions === null ||
908
- normalizedRemoteUrl === undefined ||
909
- commitCount === undefined ||
910
- lastCommitAt === undefined ||
911
- shortCommitHash === undefined ||
912
- inferredName === undefined ||
913
- defaultBranch === undefined
914
- ) {
614
+ const repository = parsed.repository === null ? null : toAgentRepository(parsed.repository);
615
+ if (parsed.repository !== null && repository === null) {
915
616
  return null;
916
617
  }
917
618
  return {
918
- directoryId,
619
+ directoryId: parsed.directoryId,
919
620
  summary: {
920
- branch,
921
- changedFiles,
922
- additions,
923
- deletions,
621
+ branch: parsed.summary.branch,
622
+ changedFiles: parsed.summary.changedFiles,
623
+ additions: parsed.summary.additions,
624
+ deletions: parsed.summary.deletions,
924
625
  },
925
626
  repositorySnapshot: {
926
- normalizedRemoteUrl,
927
- commitCount,
928
- lastCommitAt,
929
- shortCommitHash,
930
- inferredName,
931
- defaultBranch,
627
+ normalizedRemoteUrl: parsed.repositorySnapshot.normalizedRemoteUrl,
628
+ commitCount: parsed.repositorySnapshot.commitCount,
629
+ lastCommitAt: parsed.repositorySnapshot.lastCommitAt,
630
+ shortCommitHash: parsed.repositorySnapshot.shortCommitHash,
631
+ inferredName: parsed.repositorySnapshot.inferredName,
632
+ defaultBranch: parsed.repositorySnapshot.defaultBranch,
932
633
  },
933
- repositoryId,
634
+ repositoryId: parsed.repositoryId,
934
635
  repository,
935
- observedAt,
636
+ observedAt: parsed.observedAt,
936
637
  };
937
638
  }
938
639
 
939
640
  function parseTaskRecord(value: unknown): AgentTask | null {
940
- const record = asRecord(value);
941
- if (record === null) {
942
- return null;
943
- }
944
- const taskId = readString(record['taskId']);
945
- const tenantId = readString(record['tenantId']);
946
- const userId = readString(record['userId']);
947
- const workspaceId = readString(record['workspaceId']);
948
- const repositoryId = readNullableString(record['repositoryId']);
949
- const projectId = readNullableString(record['projectId']);
950
- const title = readString(record['title']);
951
- const description = readString(record['description']);
952
- const status = parseTaskStatus(record['status']);
953
- const scopeKind = parseTaskScopeKind(record['scopeKind'], repositoryId, projectId);
954
- const orderIndex = readNumber(record['orderIndex']);
955
- const claimedByControllerId = readNullableString(record['claimedByControllerId']);
956
- const claimedByProjectId = readNullableString(record['claimedByDirectoryId']);
957
- const branchName = readNullableString(record['branchName']);
958
- const baseBranch = readNullableString(record['baseBranch']);
959
- const claimedAt = readNullableString(record['claimedAt']);
960
- const completedAt = readNullableString(record['completedAt']);
961
- const linear = parseTaskLinearRecord(record['linear']);
962
- const createdAt = readString(record['createdAt']);
963
- const updatedAt = readString(record['updatedAt']);
964
- if (
965
- taskId === null ||
966
- tenantId === null ||
967
- userId === null ||
968
- workspaceId === null ||
969
- repositoryId === undefined ||
970
- projectId === undefined ||
971
- scopeKind === null ||
972
- title === null ||
973
- description === null ||
974
- status === null ||
975
- orderIndex === null ||
976
- claimedByControllerId === undefined ||
977
- claimedByProjectId === undefined ||
978
- branchName === undefined ||
979
- baseBranch === undefined ||
980
- claimedAt === undefined ||
981
- completedAt === undefined ||
982
- linear === null ||
983
- createdAt === null ||
984
- updatedAt === null
985
- ) {
641
+ const parsed = parseContractTaskRecord(value);
642
+ if (parsed === null) {
986
643
  return null;
987
644
  }
988
645
  return {
989
- taskId,
990
- tenantId,
991
- userId,
992
- workspaceId,
993
- repositoryId,
994
- scopeKind,
995
- projectId,
996
- title,
997
- description,
998
- status,
999
- orderIndex,
1000
- claimedByControllerId,
1001
- claimedByProjectId,
1002
- branchName,
1003
- baseBranch,
1004
- claimedAt,
1005
- completedAt,
1006
- linear,
1007
- createdAt,
1008
- updatedAt,
646
+ taskId: parsed.taskId,
647
+ tenantId: parsed.tenantId,
648
+ userId: parsed.userId,
649
+ workspaceId: parsed.workspaceId,
650
+ repositoryId: parsed.repositoryId,
651
+ scopeKind: parsed.scopeKind,
652
+ projectId: parsed.projectId,
653
+ title: parsed.title,
654
+ body: parsed.body,
655
+ status: parsed.status,
656
+ orderIndex: parsed.orderIndex,
657
+ claimedByControllerId: parsed.claimedByControllerId,
658
+ claimedByProjectId: parsed.claimedByDirectoryId,
659
+ branchName: parsed.branchName,
660
+ baseBranch: parsed.baseBranch,
661
+ claimedAt: parsed.claimedAt,
662
+ completedAt: parsed.completedAt,
663
+ createdAt: parsed.createdAt,
664
+ updatedAt: parsed.updatedAt,
1009
665
  };
1010
666
  }
1011
667
 
@@ -1883,9 +1539,8 @@ export class HarnessAgentRealtimeClient {
1883
1539
  ...optionalField('workspaceId', input.workspaceId),
1884
1540
  ...optionalField('repositoryId', input.repositoryId),
1885
1541
  ...optionalField('projectId', input.projectId),
1886
- title: input.title,
1887
- ...optionalField('description', input.description),
1888
- ...optionalField('linear', input.linear),
1542
+ ...optionalField('title', input.title),
1543
+ body: input.body,
1889
1544
  });
1890
1545
  return requireParsed(
1891
1546
  result['task'],