@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
@@ -17,17 +17,12 @@ import type {
17
17
  ControlPlaneProjectTaskFocusMode,
18
18
  ControlPlaneProjectThreadSpawnMode,
19
19
  ControlPlaneRepositoryRecord,
20
- ControlPlaneTaskLinearPriority,
21
- ControlPlaneTaskLinearRecord,
22
20
  ControlPlaneTaskRecord,
23
21
  ControlPlaneTaskScopeKind,
24
22
  ControlPlaneTaskStatus,
25
23
  ControlPlaneTelemetryRecord,
26
- TaskLinearInput,
27
24
  } from './control-plane-store-types.ts';
28
25
 
29
- const DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
30
-
31
26
  export function asRecord(value: unknown): Record<string, unknown> {
32
27
  if (typeof value !== 'object' || value === null) {
33
28
  throw new Error('expected object row');
@@ -151,16 +146,8 @@ function normalizeRuntimeStatusModel(value: unknown): StreamSessionStatusModel |
151
146
  const attentionReason = asStringOrNull(model.attentionReason, 'attentionReason');
152
147
  const lastKnownWork = asStringOrNull(model.lastKnownWork, 'lastKnownWork');
153
148
  const lastKnownWorkAt = asStringOrNull(model.lastKnownWorkAt, 'lastKnownWorkAt');
154
- const phaseHintRaw = asStringOrNull(model.phaseHint, 'phaseHint');
149
+ const activityHintRaw = normalizeLegacyActivityHint(model.activityHint);
155
150
  const observedAt = asString(model.observedAt, 'observedAt');
156
- if (
157
- phaseHintRaw !== null &&
158
- phaseHintRaw !== 'needs-action' &&
159
- phaseHintRaw !== 'working' &&
160
- phaseHintRaw !== 'idle'
161
- ) {
162
- throw new Error('expected phaseHint enum value');
163
- }
164
151
  return {
165
152
  runtimeStatus: runtimeStatusRaw,
166
153
  phase: phaseRaw,
@@ -170,11 +157,40 @@ function normalizeRuntimeStatusModel(value: unknown): StreamSessionStatusModel |
170
157
  attentionReason,
171
158
  lastKnownWork,
172
159
  lastKnownWorkAt,
173
- phaseHint: phaseHintRaw,
160
+ activityHint: activityHintRaw,
174
161
  observedAt,
175
162
  };
176
163
  }
177
164
 
165
+ function normalizeLegacyActivityHint(value: unknown): StreamSessionStatusModel['activityHint'] {
166
+ if (value === undefined || value === null) {
167
+ return null;
168
+ }
169
+ if (typeof value === 'string') {
170
+ if (value === 'needs-action' || value === 'working' || value === 'idle') {
171
+ return value;
172
+ }
173
+ throw new Error('expected activityHint enum value');
174
+ }
175
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
176
+ const legacy = value as Record<string, unknown>;
177
+ const legacyCandidate =
178
+ typeof legacy.kind === 'string'
179
+ ? legacy.kind
180
+ : typeof legacy.value === 'string'
181
+ ? legacy.value
182
+ : null;
183
+ if (
184
+ legacyCandidate === 'needs-action' ||
185
+ legacyCandidate === 'working' ||
186
+ legacyCandidate === 'idle'
187
+ ) {
188
+ return legacyCandidate;
189
+ }
190
+ }
191
+ return null;
192
+ }
193
+
178
194
  export function normalizeStoredDirectoryRow(value: unknown): ControlPlaneDirectoryRecord {
179
195
  const row = asRecord(value);
180
196
  return {
@@ -287,231 +303,6 @@ function normalizeRepositoryMetadata(value: unknown): Record<string, unknown> {
287
303
  }
288
304
  }
289
305
 
290
- export function defaultTaskLinearRecord(): ControlPlaneTaskLinearRecord {
291
- return {
292
- issueId: null,
293
- identifier: null,
294
- url: null,
295
- teamId: null,
296
- projectId: null,
297
- projectMilestoneId: null,
298
- cycleId: null,
299
- stateId: null,
300
- assigneeId: null,
301
- priority: null,
302
- estimate: null,
303
- dueDate: null,
304
- labelIds: [],
305
- };
306
- }
307
-
308
- function normalizeOptionalTaskLinearString(value: string | null, field: string): string | null {
309
- if (value === null) {
310
- return null;
311
- }
312
- return normalizeNonEmptyLabel(value, field);
313
- }
314
-
315
- function normalizeTaskLinearPriority(
316
- value: number | null,
317
- field: string,
318
- ): ControlPlaneTaskLinearPriority | null {
319
- if (value === null) {
320
- return null;
321
- }
322
- if (!Number.isInteger(value) || value < 0 || value > 4) {
323
- throw new Error(`expected integer [0..4] for ${field}`);
324
- }
325
- return value as ControlPlaneTaskLinearPriority;
326
- }
327
-
328
- function normalizeTaskLinearEstimate(value: number | null, field: string): number | null {
329
- if (value === null) {
330
- return null;
331
- }
332
- if (!Number.isInteger(value) || value < 0) {
333
- throw new Error(`expected non-negative integer for ${field}`);
334
- }
335
- return value;
336
- }
337
-
338
- function normalizeTaskLinearDueDate(value: string | null, field: string): string | null {
339
- if (value === null) {
340
- return null;
341
- }
342
- const normalized = value.trim();
343
- if (!DATE_ONLY_PATTERN.test(normalized)) {
344
- throw new Error(`expected YYYY-MM-DD for ${field}`);
345
- }
346
- return normalized;
347
- }
348
-
349
- function normalizeTaskLinearLabelIds(
350
- value: readonly string[] | null,
351
- field: string,
352
- ): readonly string[] {
353
- if (value === null) {
354
- return [];
355
- }
356
- return uniqueValues(
357
- value.map((entry, idx) => normalizeNonEmptyLabel(entry, `${field}[${String(idx)}]`)),
358
- );
359
- }
360
-
361
- function parseTaskLinearInputRecord(
362
- record: Record<string, unknown>,
363
- field: string,
364
- ): TaskLinearInput {
365
- const parsed: TaskLinearInput = {};
366
- if ('issueId' in record) {
367
- parsed.issueId = asStringOrNull(record.issueId, `${field}.issueId`);
368
- }
369
- if ('identifier' in record) {
370
- parsed.identifier = asStringOrNull(record.identifier, `${field}.identifier`);
371
- }
372
- if ('url' in record) {
373
- parsed.url = asStringOrNull(record.url, `${field}.url`);
374
- }
375
- if ('teamId' in record) {
376
- parsed.teamId = asStringOrNull(record.teamId, `${field}.teamId`);
377
- }
378
- if ('projectId' in record) {
379
- parsed.projectId = asStringOrNull(record.projectId, `${field}.projectId`);
380
- }
381
- if ('projectMilestoneId' in record) {
382
- parsed.projectMilestoneId = asStringOrNull(
383
- record.projectMilestoneId,
384
- `${field}.projectMilestoneId`,
385
- );
386
- }
387
- if ('cycleId' in record) {
388
- parsed.cycleId = asStringOrNull(record.cycleId, `${field}.cycleId`);
389
- }
390
- if ('stateId' in record) {
391
- parsed.stateId = asStringOrNull(record.stateId, `${field}.stateId`);
392
- }
393
- if ('assigneeId' in record) {
394
- parsed.assigneeId = asStringOrNull(record.assigneeId, `${field}.assigneeId`);
395
- }
396
- if ('priority' in record) {
397
- parsed.priority = asNumberOrNull(record.priority, `${field}.priority`);
398
- }
399
- if ('estimate' in record) {
400
- parsed.estimate = asNumberOrNull(record.estimate, `${field}.estimate`);
401
- }
402
- if ('dueDate' in record) {
403
- parsed.dueDate = asStringOrNull(record.dueDate, `${field}.dueDate`);
404
- }
405
- if ('labelIds' in record) {
406
- const raw = record.labelIds;
407
- if (raw === null) {
408
- parsed.labelIds = null;
409
- } else if (Array.isArray(raw) && raw.every((entry) => typeof entry === 'string')) {
410
- parsed.labelIds = raw;
411
- } else {
412
- throw new Error(`expected string array or null for ${field}.labelIds`);
413
- }
414
- }
415
- return parsed;
416
- }
417
-
418
- export function applyTaskLinearInput(
419
- base: ControlPlaneTaskLinearRecord,
420
- input: TaskLinearInput,
421
- ): ControlPlaneTaskLinearRecord {
422
- return {
423
- issueId:
424
- input.issueId === undefined
425
- ? base.issueId
426
- : normalizeOptionalTaskLinearString(input.issueId, 'linear.issueId'),
427
- identifier:
428
- input.identifier === undefined
429
- ? base.identifier
430
- : normalizeOptionalTaskLinearString(input.identifier, 'linear.identifier'),
431
- url:
432
- input.url === undefined
433
- ? base.url
434
- : normalizeOptionalTaskLinearString(input.url, 'linear.url'),
435
- teamId:
436
- input.teamId === undefined
437
- ? base.teamId
438
- : normalizeOptionalTaskLinearString(input.teamId, 'linear.teamId'),
439
- projectId:
440
- input.projectId === undefined
441
- ? base.projectId
442
- : normalizeOptionalTaskLinearString(input.projectId, 'linear.projectId'),
443
- projectMilestoneId:
444
- input.projectMilestoneId === undefined
445
- ? base.projectMilestoneId
446
- : normalizeOptionalTaskLinearString(input.projectMilestoneId, 'linear.projectMilestoneId'),
447
- cycleId:
448
- input.cycleId === undefined
449
- ? base.cycleId
450
- : normalizeOptionalTaskLinearString(input.cycleId, 'linear.cycleId'),
451
- stateId:
452
- input.stateId === undefined
453
- ? base.stateId
454
- : normalizeOptionalTaskLinearString(input.stateId, 'linear.stateId'),
455
- assigneeId:
456
- input.assigneeId === undefined
457
- ? base.assigneeId
458
- : normalizeOptionalTaskLinearString(input.assigneeId, 'linear.assigneeId'),
459
- priority:
460
- input.priority === undefined
461
- ? base.priority
462
- : normalizeTaskLinearPriority(input.priority, 'linear.priority'),
463
- estimate:
464
- input.estimate === undefined
465
- ? base.estimate
466
- : normalizeTaskLinearEstimate(input.estimate, 'linear.estimate'),
467
- dueDate:
468
- input.dueDate === undefined
469
- ? base.dueDate
470
- : normalizeTaskLinearDueDate(input.dueDate, 'linear.dueDate'),
471
- labelIds:
472
- input.labelIds === undefined
473
- ? base.labelIds
474
- : normalizeTaskLinearLabelIds(input.labelIds, 'linear.labelIds'),
475
- };
476
- }
477
-
478
- export function serializeTaskLinear(linear: ControlPlaneTaskLinearRecord): string {
479
- return JSON.stringify({
480
- issueId: linear.issueId,
481
- identifier: linear.identifier,
482
- url: linear.url,
483
- teamId: linear.teamId,
484
- projectId: linear.projectId,
485
- projectMilestoneId: linear.projectMilestoneId,
486
- cycleId: linear.cycleId,
487
- stateId: linear.stateId,
488
- assigneeId: linear.assigneeId,
489
- priority: linear.priority,
490
- estimate: linear.estimate,
491
- dueDate: linear.dueDate,
492
- labelIds: [...linear.labelIds],
493
- });
494
- }
495
-
496
- function normalizeTaskLinear(value: unknown): ControlPlaneTaskLinearRecord {
497
- if (typeof value !== 'string') {
498
- throw new Error('expected string for linear_json');
499
- }
500
- let parsed: unknown;
501
- try {
502
- parsed = JSON.parse(value) as unknown;
503
- } catch {
504
- return defaultTaskLinearRecord();
505
- }
506
- if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
507
- return defaultTaskLinearRecord();
508
- }
509
- return applyTaskLinearInput(
510
- defaultTaskLinearRecord(),
511
- parseTaskLinearInputRecord(parsed as Record<string, unknown>, 'linear_json'),
512
- );
513
- }
514
-
515
306
  function normalizeTaskStatus(value: unknown): ControlPlaneTaskStatus {
516
307
  const status = asString(value, 'status');
517
308
  if (
@@ -615,6 +406,7 @@ export function normalizeTaskRow(value: unknown): ControlPlaneTaskRecord {
615
406
  const row = asRecord(value);
616
407
  const repositoryId = asStringOrNull(row.repository_id, 'repository_id');
617
408
  const projectId = asStringOrNull(row.project_id, 'project_id');
409
+ const bodyValue = row.body ?? row.description;
618
410
  return {
619
411
  taskId: asString(row.task_id, 'task_id'),
620
412
  tenantId: asString(row.tenant_id, 'tenant_id'),
@@ -624,7 +416,7 @@ export function normalizeTaskRow(value: unknown): ControlPlaneTaskRecord {
624
416
  scopeKind: normalizeTaskScopeKind(row.scope_kind, repositoryId, projectId),
625
417
  projectId,
626
418
  title: asString(row.title, 'title'),
627
- description: asString(row.description, 'description'),
419
+ body: asString(bodyValue, 'body'),
628
420
  status: normalizeTaskStatus(row.status),
629
421
  orderIndex: asNumberOrNull(row.order_index, 'order_index') as number,
630
422
  claimedByControllerId: asStringOrNull(row.claimed_by_controller_id, 'claimed_by_controller_id'),
@@ -633,7 +425,6 @@ export function normalizeTaskRow(value: unknown): ControlPlaneTaskRecord {
633
425
  baseBranch: asStringOrNull(row.base_branch, 'base_branch'),
634
426
  claimedAt: asStringOrNull(row.claimed_at, 'claimed_at'),
635
427
  completedAt: asStringOrNull(row.completed_at, 'completed_at'),
636
- linear: normalizeTaskLinear(row.linear_json),
637
428
  createdAt: asString(row.created_at, 'created_at'),
638
429
  updatedAt: asString(row.updated_at, 'updated_at'),
639
430
  };
@@ -59,7 +59,6 @@ export interface ControlPlaneTelemetrySummary {
59
59
 
60
60
  export type ControlPlaneTaskStatus = 'draft' | 'ready' | 'in-progress' | 'completed';
61
61
  export type ControlPlaneTaskScopeKind = 'global' | 'repository' | 'project';
62
- export type ControlPlaneTaskLinearPriority = 0 | 1 | 2 | 3 | 4;
63
62
  export type ControlPlaneProjectTaskFocusMode = 'balanced' | 'own-only';
64
63
  export type ControlPlaneProjectThreadSpawnMode = 'new-thread' | 'reuse-thread';
65
64
  export type ControlPlaneAutomationPolicyScope = 'global' | 'repository' | 'project';
@@ -72,38 +71,6 @@ export type ControlPlaneGitHubCiRollup =
72
71
  | 'neutral'
73
72
  | 'none';
74
73
 
75
- export interface ControlPlaneTaskLinearRecord {
76
- readonly issueId: string | null;
77
- readonly identifier: string | null;
78
- readonly url: string | null;
79
- readonly teamId: string | null;
80
- readonly projectId: string | null;
81
- readonly projectMilestoneId: string | null;
82
- readonly cycleId: string | null;
83
- readonly stateId: string | null;
84
- readonly assigneeId: string | null;
85
- readonly priority: ControlPlaneTaskLinearPriority | null;
86
- readonly estimate: number | null;
87
- readonly dueDate: string | null;
88
- readonly labelIds: readonly string[];
89
- }
90
-
91
- export interface TaskLinearInput {
92
- issueId?: string | null;
93
- identifier?: string | null;
94
- url?: string | null;
95
- teamId?: string | null;
96
- projectId?: string | null;
97
- projectMilestoneId?: string | null;
98
- cycleId?: string | null;
99
- stateId?: string | null;
100
- assigneeId?: string | null;
101
- priority?: number | null;
102
- estimate?: number | null;
103
- dueDate?: string | null;
104
- labelIds?: readonly string[] | null;
105
- }
106
-
107
74
  export interface ControlPlaneRepositoryRecord {
108
75
  readonly repositoryId: string;
109
76
  readonly tenantId: string;
@@ -126,7 +93,7 @@ export interface ControlPlaneTaskRecord {
126
93
  readonly scopeKind: ControlPlaneTaskScopeKind;
127
94
  readonly projectId: string | null;
128
95
  readonly title: string;
129
- readonly description: string;
96
+ readonly body: string;
130
97
  readonly status: ControlPlaneTaskStatus;
131
98
  readonly orderIndex: number;
132
99
  readonly claimedByControllerId: string | null;
@@ -135,7 +102,6 @@ export interface ControlPlaneTaskRecord {
135
102
  readonly baseBranch: string | null;
136
103
  readonly claimedAt: string | null;
137
104
  readonly completedAt: string | null;
138
- readonly linear: ControlPlaneTaskLinearRecord;
139
105
  readonly createdAt: string;
140
106
  readonly updatedAt: string;
141
107
  }