deepline 0.3.245 → 0.3.246

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.
@@ -113,7 +113,10 @@ import type { MonitorFleetDefinition } from './monitor-fleets.js';
113
113
  import type { PlayStagedFileRef } from './plays/local-file-discovery.js';
114
114
  import type { PlayCompilerManifest } from '../../shared_libs/plays/compiler-manifest.js';
115
115
  import type { EnrichCompiledConfig } from './cli/enrich-play-compiler.js';
116
- import { RUNTIME_ENVIRONMENT_TOKEN_HEADER } from '../../shared_libs/play-runtime/coordinator-headers.js';
116
+ import {
117
+ RUNTIME_ENVIRONMENT_TOKEN_HEADER,
118
+ RETAINED_PIPELINE_RECEIVERS_HEADER,
119
+ } from '../../shared_libs/play-runtime/coordinator-headers.js';
117
120
  import {
118
121
  normalizePlayRuntimeEnvironment,
119
122
  normalizePlayRuntimeNamespace,
@@ -123,6 +126,7 @@ import {
123
126
  } from '../../shared_libs/play-runtime/runtime-environment.js';
124
127
  import {
125
128
  decodePlayRunPublicStatus,
129
+ isTerminalPlayRunLifecycleStatus,
126
130
  type PlayRunPublicStatus,
127
131
  } from '../../shared_libs/play-runtime/run-lifecycle-policy.js';
128
132
  export type SlackNotificationTarget =
@@ -209,7 +213,6 @@ function notificationObjectKey(kind: 'group' | 'destination') {
209
213
  return `${kind}.${globalThis.crypto.randomUUID()}`;
210
214
  }
211
215
 
212
- const TERMINAL_PLAY_STATUSES = new Set(['completed', 'failed', 'cancelled']);
213
216
  const MONITOR_NON_RETRYABLE_MUTATION_OPTIONS = {
214
217
  maxRetries: 0,
215
218
  exactUrlOnly: true,
@@ -403,7 +406,12 @@ function runtimeSelectionHeaders(
403
406
  'RUNTIME_ENVIRONMENT_TOKEN_REQUIRED',
404
407
  );
405
408
  }
406
- return { [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token };
409
+ const receivers =
410
+ process.env.DEEPLINE_RUNTIME_RETAINED_PIPELINE_RECEIVERS?.trim();
411
+ return {
412
+ [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token,
413
+ ...(receivers ? { [RETAINED_PIPELINE_RECEIVERS_HEADER]: receivers } : {}),
414
+ };
407
415
  }
408
416
 
409
417
  function normalizeTestPolicyOverrides(
@@ -2306,7 +2314,9 @@ function normalizePlayRunStart(raw: Record<string, unknown>): PlayRunStart {
2306
2314
  ...(runPackage.run.dashboardUrl
2307
2315
  ? { dashboardUrl: runPackage.run.dashboardUrl }
2308
2316
  : {}),
2309
- ...(TERMINAL_PLAY_STATUSES.has(status) ? { finalStatus: runPackage } : {}),
2317
+ ...(isTerminalPlayRunLifecycleStatus(status)
2318
+ ? { finalStatus: runPackage }
2319
+ : {}),
2310
2320
  package: runPackage,
2311
2321
  };
2312
2322
  }
@@ -2469,18 +2479,22 @@ function getPlayLiveEventPayload(
2469
2479
  : {};
2470
2480
  }
2471
2481
 
2472
- function normalizeLiveStatus(value: unknown): PlayStatus['status'] | null {
2482
+ /** Run lifecycle events are the only events that can finish a watch. */
2483
+ function playLiveRunStatus(event: PlayLiveEvent): PlayStatus['status'] | null {
2473
2484
  if (
2474
- value === 'queued' ||
2475
- value === 'running' ||
2476
- value === 'waiting' ||
2477
- value === 'completed' ||
2478
- value === 'failed' ||
2479
- value === 'cancelled'
2485
+ event.type !== 'play.run.snapshot' &&
2486
+ event.type !== 'play.run.status' &&
2487
+ event.type !== 'play.run.final_status'
2480
2488
  ) {
2481
- return value;
2489
+ return null;
2482
2490
  }
2483
- return null;
2491
+ const payload = getPlayLiveEventPayload(event);
2492
+ return (
2493
+ decodePlayRunPublicStatus(payload.status) ??
2494
+ (isPlayRunPackage(payload)
2495
+ ? decodePlayRunPublicStatus(payload.run.status)
2496
+ : null)
2497
+ );
2484
2498
  }
2485
2499
 
2486
2500
  function appendPlayLiveLogLines(
@@ -2545,12 +2559,7 @@ function updatePlayLiveStatusState(
2545
2559
  : isPlayRunPackage(payload)
2546
2560
  ? payload.run.id
2547
2561
  : state.runId;
2548
- const status =
2549
- normalizeLiveStatus(payload.status) ??
2550
- (isPlayRunPackage(payload)
2551
- ? normalizeLiveStatus(payload.run.status)
2552
- : null) ??
2553
- state.status;
2562
+ const status = playLiveRunStatus(event) ?? state.status;
2554
2563
  const progressPayload = isRecord(payload.progress) ? payload.progress : {};
2555
2564
  // Snapshots no longer REPLACE accumulated logs (ADR-0009): the snapshot
2556
2565
  // only retains a bounded tail, so replacing would clobber the seq-keyed
@@ -4221,13 +4230,8 @@ export class DeeplineClient {
4221
4230
  runId: string,
4222
4231
  options?: RunsWatchOptions,
4223
4232
  ): Promise<PlayStatus> {
4224
- const state: PlayLiveStatusState = {
4225
- runId,
4226
- status: 'running',
4227
- logs: [],
4228
- lastLogSeq: 0,
4229
- latest: null,
4230
- };
4233
+ // Forward events without retaining their log history. Only lifecycle
4234
+ // evidence is needed here; the final package comes from the durable read.
4231
4235
  let terminalObserved = false;
4232
4236
  for await (const event of this.watchRunEvents(runId, {
4233
4237
  signal: options?.signal,
@@ -4235,19 +4239,20 @@ export class DeeplineClient {
4235
4239
  onRetry: options?.onRetry ?? options?.onReconnect,
4236
4240
  })) {
4237
4241
  options?.onEvent?.(event);
4238
- const status = updatePlayLiveStatusState(state, event);
4239
- if (status && TERMINAL_PLAY_STATUSES.has(status.status)) {
4242
+ if (isTerminalPlayRunLifecycleStatus(playLiveRunStatus(event))) {
4240
4243
  terminalObserved = true;
4241
4244
  }
4242
4245
  }
4243
4246
  if (options?.signal?.aborted) {
4244
4247
  throw new DeeplineError('Run watch aborted.', undefined, 'ABORTED');
4245
4248
  }
4246
- if (terminalObserved) {
4247
- return await this.getRunStatus(runId);
4248
- }
4249
4249
  const refreshed = await this.getRunStatus(runId);
4250
- if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) return refreshed;
4250
+ if (
4251
+ terminalObserved ||
4252
+ isTerminalPlayRunLifecycleStatus(refreshed.status)
4253
+ ) {
4254
+ return refreshed;
4255
+ }
4251
4256
  throw new DeeplineError(
4252
4257
  `Run watch for ${runId} ended before a terminal status.`,
4253
4258
  undefined,
@@ -4474,23 +4479,7 @@ export class DeeplineClient {
4474
4479
  `/api/v2/runs/${encodeURIComponent(runId)}${query}`,
4475
4480
  { headers: { 'x-deepline-run-status': '1' } },
4476
4481
  );
4477
- const responseRunStatus = isPlayRunPackage(response)
4478
- ? response.runStatus
4479
- : isPlayRunPackage(response.package)
4480
- ? response.package.runStatus
4481
- : response.runStatus;
4482
- const responseOverview = isPlayRunPackage(response)
4483
- ? response.overview
4484
- : isPlayRunPackage(response.package)
4485
- ? response.package.overview
4486
- : response.overview;
4487
4482
  const status = normalizePlayStatus(response);
4488
- if (isRecord(responseRunStatus)) {
4489
- status.runStatus = responseRunStatus as unknown as RunGetStatus;
4490
- }
4491
- if (isRecord(responseOverview)) {
4492
- status.overview = responseOverview as unknown as RunLifecycleStatus;
4493
- }
4494
4483
  if (options?.failedLogs !== true || status.status !== 'failed') {
4495
4484
  return status;
4496
4485
  }
@@ -5796,7 +5785,7 @@ export class DeeplineClient {
5796
5785
  options?.onProgress?.(status);
5797
5786
  }
5798
5787
 
5799
- if (TERMINAL_PLAY_STATUSES.has(status.status)) {
5788
+ if (isTerminalPlayRunLifecycleStatus(status.status)) {
5800
5789
  terminalObserved = status;
5801
5790
  }
5802
5791
  }
@@ -38,6 +38,7 @@ import { readSdkSkillsLocalVersion } from './skills-version.js';
38
38
  import { deploymentProtectionHeaders } from './deployment-protection.js';
39
39
  import {
40
40
  ABSURD_RELEASE_OVERRIDE_HEADER,
41
+ RETAINED_PIPELINE_RECEIVERS_HEADER,
41
42
  COORDINATOR_INTERNAL_TOKEN_HEADER,
42
43
  COORDINATOR_URL_OVERRIDE_HEADER,
43
44
  PREFERRED_RECEIPT_GATEWAY_MACHINE_ID_HEADER,
@@ -345,6 +346,15 @@ export class HttpClient {
345
346
  if (runtimeTestFault?.trim()) {
346
347
  headers[PLAY_RUNTIME_TEST_FAULT_HEADER] = runtimeTestFault.trim();
347
348
  }
349
+ const retainedReceivers =
350
+ typeof process !== 'undefined'
351
+ ? process.env?.DEEPLINE_RUNTIME_RETAINED_PIPELINE_RECEIVERS?.trim()
352
+ : undefined;
353
+ if (retainedReceivers && coordinatorInternalToken?.trim()) {
354
+ headers[RETAINED_PIPELINE_RECEIVERS_HEADER] = retainedReceivers;
355
+ headers[COORDINATOR_INTERNAL_TOKEN_HEADER] =
356
+ coordinatorInternalToken.trim();
357
+ }
348
358
  if (absurdReleaseOverride?.trim() && coordinatorInternalToken?.trim()) {
349
359
  headers[ABSURD_RELEASE_OVERRIDE_HEADER] = absurdReleaseOverride.trim();
350
360
  }
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
200
200
  // getters keep their established compatibility behavior.
201
201
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
202
202
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
203
- version: '0.3.245',
203
+ version: '0.3.246',
204
204
  updateSummary:
205
205
  'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
206
206
  packageCapabilities: {
@@ -0,0 +1,19 @@
1
+ import { DeeplineError } from '../errors.js';
2
+
3
+ export function isTransientPlayRunReadError(error: unknown): boolean {
4
+ if (
5
+ error instanceof DeeplineError &&
6
+ error.code === 'PLAY_STREAM_NETWORK_ABORTED'
7
+ ) {
8
+ return true;
9
+ }
10
+ if (error instanceof DeeplineError && typeof error.statusCode === 'number') {
11
+ // 5xx responses and network-level failures may recover. Client errors,
12
+ // especially 404, stay visible instead of disappearing into a retry loop.
13
+ return error.statusCode >= 500 && error.statusCode < 600;
14
+ }
15
+ const text = error instanceof Error ? error.message : String(error);
16
+ return /auth validation backend timed out|coordinator \/submit(?:\?[^ ]*)? 5\d\d|Worker threw exception|Internal Server Error|Service Unavailable|fetch failed|eaddrnotavail|econnreset|etimedout|eai_again|socket hang up/i.test(
17
+ text,
18
+ );
19
+ }
@@ -7,7 +7,7 @@ import {
7
7
  type PlayRunStreamDiffState,
8
8
  type PlayRunStreamEvent,
9
9
  } from '../../../shared_libs/play-runtime/run-snapshot-stream.js';
10
- import { isTransientPlayRunReadError } from '../stream-reconnect.js';
10
+ import { isTransientPlayRunReadError } from './read-errors.js';
11
11
 
12
12
  /** The watch endpoint is a small authenticated REST read, polled every two seconds. */
13
13
  export const RUN_WATCH_POLL_INTERVAL_MS = 2_000;
@@ -22,6 +22,16 @@ export const RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER =
22
22
  */
23
23
  export const RUNTIME_ENVIRONMENT_TOKEN_HEADER =
24
24
  'x-deepline-runtime-environment-token';
25
+ /** Authenticated target-owner assertion, issued only after deployment reproof. */
26
+ export const RETAINED_PIPELINE_RECEIVERS_HEADER =
27
+ 'x-deepline-retained-pipeline-receivers';
28
+ export type RetainedPipelineReceivers = {
29
+ namespace: string;
30
+ schedulerSchema?: string;
31
+ backend: string;
32
+ callbackOrigin: string;
33
+ runtimeApiOrigin: string;
34
+ };
25
35
  /**
26
36
  * Internal top-level `profile=absurd` launches, including deploy canaries, use
27
37
  * this header to pin an exact candidate release before activation. Public API
@@ -4,9 +4,11 @@ import { staticPipelineStorageCodec } from './static-pipeline-storage-codec';
4
4
 
5
5
  export {
6
6
  retainedPlayPipelineFields,
7
+ WRITE_RETAINED_PIPELINE_GRAPHS,
7
8
  type RetainedPlayContract,
8
9
  type RetainedPipelineCarrier,
9
10
  encodeRetainedPlayPipelines,
11
+ createRetainedPlayPipelinesForTransport,
10
12
  hydrateRetainedPlayPipelines,
11
13
  prepareRetainedPlayPipelinesForTransport,
12
14
  type RetainedPipelineGraph,
@@ -6,7 +6,7 @@
6
6
  * This is an additive named representation. Readers must be deployed before
7
7
  * WRITE_RETAINED_PIPELINE_GRAPHS is enabled in a separate release.
8
8
  */
9
- export const WRITE_RETAINED_PIPELINE_GRAPHS = false;
9
+ export const WRITE_RETAINED_PIPELINE_GRAPHS = true;
10
10
 
11
11
  type Scalar = null | boolean | number | string;
12
12
  type GraphValue = Scalar | { ref: number };
@@ -255,12 +255,18 @@ function hydrateContractRoots(
255
255
  return result;
256
256
  }
257
257
 
258
- /** Production writers remain inert until the separate reader rollout completes. */
258
+ /** Create a graph only when the owner has selected reader-capable receivers. */
259
+ export function createRetainedPlayPipelinesForTransport<T>(input: T): T {
260
+ return WRITE_RETAINED_PIPELINE_GRAPHS
261
+ ? encodeRetainedPlayPipelines(input)
262
+ : prepareRetainedPlayPipelinesForTransport(input);
263
+ }
264
+
265
+ /** Forward an immutable launch in its original representation. */
259
266
  export function prepareRetainedPlayPipelinesForTransport<T>(input: T): T {
260
- // Reader-only builds must preserve new representations when forwarding
261
- // them. The rollout switch controls creation from legacy envelopes only.
262
- return WRITE_RETAINED_PIPELINE_GRAPHS ||
263
- (record(input) && input.retainedPipelineGraph !== undefined)
267
+ // A historical launch may still call an older pinned app after adoption.
268
+ // New workers and projectors must not upgrade that receiver's wire format.
269
+ return record(input) && input.retainedPipelineGraph !== undefined
264
270
  ? encodeRetainedPlayPipelines(input)
265
271
  : input;
266
272
  }
@@ -10,7 +10,6 @@ import {
10
10
  retainedPlayPipelineFields,
11
11
  encodeRetainedPlayPipelines,
12
12
  hydrateRetainedPlayPipelines,
13
- WRITE_RETAINED_PIPELINE_GRAPHS,
14
13
  type RetainedPipelineGraph,
15
14
  type RetainedPipelineCarrier,
16
15
  } from './retained-pipeline-graph';
@@ -29,7 +28,7 @@ function readExecutionPipeline(
29
28
  return readStoredStaticPipeline(record);
30
29
  }
31
30
 
32
- /** Runs use the shared graph after all storage readers have been deployed. */
31
+ /** Preserve the representation selected by the immutable launch owner. */
33
32
  function executionStorageFields(
34
33
  pipeline: PlayStaticPipeline | null | undefined,
35
34
  carrier?: RetainedPipelineCarrier,
@@ -38,11 +37,7 @@ function executionStorageFields(
38
37
  staticPipelineV2?: ReturnType<typeof createStoredStaticPipelineV2>;
39
38
  retainedPipelineGraph?: RetainedPipelineGraph;
40
39
  } {
41
- if (
42
- (!WRITE_RETAINED_PIPELINE_GRAPHS &&
43
- carrier?.retainedPipelineGraph === undefined) ||
44
- pipeline === undefined
45
- ) {
40
+ if (carrier?.retainedPipelineGraph === undefined || pipeline === undefined) {
46
41
  return createStaticPipelineStorageFields(pipeline);
47
42
  }
48
43
  const compact = encodeRetainedPlayPipelines(
package/dist/cli/index.js CHANGED
@@ -3473,7 +3473,7 @@ var SDK_RELEASE = {
3473
3473
  // getters keep their established compatibility behavior.
3474
3474
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3475
3475
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3476
- version: "0.3.245",
3476
+ version: "0.3.246",
3477
3477
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3478
3478
  packageCapabilities: {
3479
3479
  updatePreferences: 1
@@ -3816,6 +3816,7 @@ var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
3816
3816
  var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
3817
3817
  var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
3818
3818
  var RUNTIME_ENVIRONMENT_TOKEN_HEADER = "x-deepline-runtime-environment-token";
3819
+ var RETAINED_PIPELINE_RECEIVERS_HEADER = "x-deepline-retained-pipeline-receivers";
3819
3820
  var ABSURD_RELEASE_OVERRIDE_HEADER = "x-deepline-absurd-release";
3820
3821
  var PREFERRED_RECEIPT_GATEWAY_MACHINE_ID_HEADER = "x-deepline-preferred-receipt-gateway-machine-id";
3821
3822
  var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
@@ -4235,6 +4236,11 @@ var HttpClient = class {
4235
4236
  if (runtimeTestFault?.trim()) {
4236
4237
  headers[PLAY_RUNTIME_TEST_FAULT_HEADER] = runtimeTestFault.trim();
4237
4238
  }
4239
+ const retainedReceivers = typeof process !== "undefined" ? process.env?.DEEPLINE_RUNTIME_RETAINED_PIPELINE_RECEIVERS?.trim() : void 0;
4240
+ if (retainedReceivers && coordinatorInternalToken?.trim()) {
4241
+ headers[RETAINED_PIPELINE_RECEIVERS_HEADER] = retainedReceivers;
4242
+ headers[COORDINATOR_INTERNAL_TOKEN_HEADER] = coordinatorInternalToken.trim();
4243
+ }
4238
4244
  if (absurdReleaseOverride?.trim() && coordinatorInternalToken?.trim()) {
4239
4245
  headers[ABSURD_RELEASE_OVERRIDE_HEADER] = absurdReleaseOverride.trim();
4240
4246
  }
@@ -5589,7 +5595,7 @@ function diffPlayRunStreamEvents(input2) {
5589
5595
  return { events, next };
5590
5596
  }
5591
5597
 
5592
- // src/stream-reconnect.ts
5598
+ // src/runs/read-errors.ts
5593
5599
  function isTransientPlayRunReadError(error) {
5594
5600
  if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
5595
5601
  return true;
@@ -5857,7 +5863,6 @@ function parseNotificationGroupTarget(value) {
5857
5863
  function notificationObjectKey(kind) {
5858
5864
  return `${kind}.${globalThis.crypto.randomUUID()}`;
5859
5865
  }
5860
- var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
5861
5866
  var MONITOR_NON_RETRYABLE_MUTATION_OPTIONS = {
5862
5867
  maxRetries: 0,
5863
5868
  exactUrlOnly: true
@@ -5964,7 +5969,11 @@ function runtimeSelectionHeaders(runtime) {
5964
5969
  "RUNTIME_ENVIRONMENT_TOKEN_REQUIRED"
5965
5970
  );
5966
5971
  }
5967
- return { [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token };
5972
+ const receivers = process.env.DEEPLINE_RUNTIME_RETAINED_PIPELINE_RECEIVERS?.trim();
5973
+ return {
5974
+ [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token,
5975
+ ...receivers ? { [RETAINED_PIPELINE_RECEIVERS_HEADER]: receivers } : {}
5976
+ };
5968
5977
  }
5969
5978
  function normalizeTestPolicyOverrides(value, source) {
5970
5979
  if (value && typeof value === "object" && !Array.isArray(value)) {
@@ -6127,7 +6136,7 @@ function normalizePlayRunStart(raw) {
6127
6136
  name: runPackage.run.playName,
6128
6137
  status,
6129
6138
  ...runPackage.run.dashboardUrl ? { dashboardUrl: runPackage.run.dashboardUrl } : {},
6130
- ...TERMINAL_PLAY_STATUSES.has(status) ? { finalStatus: runPackage } : {},
6139
+ ...isTerminalPlayRunLifecycleStatus(status) ? { finalStatus: runPackage } : {},
6131
6140
  package: runPackage
6132
6141
  };
6133
6142
  }
@@ -6205,11 +6214,12 @@ function readStringArray(value) {
6205
6214
  function getPlayLiveEventPayload(event) {
6206
6215
  return event.payload && typeof event.payload === "object" ? event.payload : {};
6207
6216
  }
6208
- function normalizeLiveStatus(value) {
6209
- if (value === "queued" || value === "running" || value === "waiting" || value === "completed" || value === "failed" || value === "cancelled") {
6210
- return value;
6217
+ function playLiveRunStatus(event) {
6218
+ if (event.type !== "play.run.snapshot" && event.type !== "play.run.status" && event.type !== "play.run.final_status") {
6219
+ return null;
6211
6220
  }
6212
- return null;
6221
+ const payload = getPlayLiveEventPayload(event);
6222
+ return decodePlayRunPublicStatus(payload.status) ?? (isPlayRunPackage(payload) ? decodePlayRunPublicStatus(payload.run.status) : null);
6213
6223
  }
6214
6224
  function appendPlayLiveLogLines(state, payload) {
6215
6225
  const lines = readStringArray(payload.lines);
@@ -6242,7 +6252,7 @@ function updatePlayLiveStatusState(state, event) {
6242
6252
  return null;
6243
6253
  }
6244
6254
  const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : isPlayRunPackage(payload) ? payload.run.id : state.runId;
6245
- const status = normalizeLiveStatus(payload.status) ?? (isPlayRunPackage(payload) ? normalizeLiveStatus(payload.run.status) : null) ?? state.status;
6255
+ const status = playLiveRunStatus(event) ?? state.status;
6246
6256
  const progressPayload = isRecord4(payload.progress) ? payload.progress : {};
6247
6257
  if (event.type === "play.run.final_status" && state.logs.length === 0 && state.lastLogSeq === 0) {
6248
6258
  const payloadLogs = readStringArray(payload.logs);
@@ -7400,13 +7410,6 @@ var DeeplineClient = class _DeeplineClient {
7400
7410
  }
7401
7411
  /** Poll snapshots to terminal status and return the durable package. */
7402
7412
  async watchRunToTerminal(runId, options) {
7403
- const state = {
7404
- runId,
7405
- status: "running",
7406
- logs: [],
7407
- lastLogSeq: 0,
7408
- latest: null
7409
- };
7410
7413
  let terminalObserved = false;
7411
7414
  for await (const event of this.watchRunEvents(runId, {
7412
7415
  signal: options?.signal,
@@ -7414,19 +7417,17 @@ var DeeplineClient = class _DeeplineClient {
7414
7417
  onRetry: options?.onRetry ?? options?.onReconnect
7415
7418
  })) {
7416
7419
  options?.onEvent?.(event);
7417
- const status = updatePlayLiveStatusState(state, event);
7418
- if (status && TERMINAL_PLAY_STATUSES.has(status.status)) {
7420
+ if (isTerminalPlayRunLifecycleStatus(playLiveRunStatus(event))) {
7419
7421
  terminalObserved = true;
7420
7422
  }
7421
7423
  }
7422
7424
  if (options?.signal?.aborted) {
7423
7425
  throw new DeeplineError("Run watch aborted.", void 0, "ABORTED");
7424
7426
  }
7425
- if (terminalObserved) {
7426
- return await this.getRunStatus(runId);
7427
- }
7428
7427
  const refreshed = await this.getRunStatus(runId);
7429
- if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) return refreshed;
7428
+ if (terminalObserved || isTerminalPlayRunLifecycleStatus(refreshed.status)) {
7429
+ return refreshed;
7430
+ }
7430
7431
  throw new DeeplineError(
7431
7432
  `Run watch for ${runId} ended before a terminal status.`,
7432
7433
  void 0,
@@ -7607,15 +7608,7 @@ var DeeplineClient = class _DeeplineClient {
7607
7608
  `/api/v2/runs/${encodeURIComponent(runId)}${query}`,
7608
7609
  { headers: { "x-deepline-run-status": "1" } }
7609
7610
  );
7610
- const responseRunStatus = isPlayRunPackage(response) ? response.runStatus : isPlayRunPackage(response.package) ? response.package.runStatus : response.runStatus;
7611
- const responseOverview = isPlayRunPackage(response) ? response.overview : isPlayRunPackage(response.package) ? response.package.overview : response.overview;
7612
7611
  const status = normalizePlayStatus(response);
7613
- if (isRecord4(responseRunStatus)) {
7614
- status.runStatus = responseRunStatus;
7615
- }
7616
- if (isRecord4(responseOverview)) {
7617
- status.overview = responseOverview;
7618
- }
7619
7612
  if (options?.failedLogs !== true || status.status !== "failed") {
7620
7613
  return status;
7621
7614
  }
@@ -8593,7 +8586,7 @@ var DeeplineClient = class _DeeplineClient {
8593
8586
  if (event.type !== "play.run.status" || status.status !== previousStatus) {
8594
8587
  options?.onProgress?.(status);
8595
8588
  }
8596
- if (TERMINAL_PLAY_STATUSES.has(status.status)) {
8589
+ if (isTerminalPlayRunLifecycleStatus(status.status)) {
8597
8590
  terminalObserved = status;
8598
8591
  }
8599
8592
  }
@@ -23419,7 +23412,7 @@ function pendingStartFailureStatus(input2) {
23419
23412
  }
23420
23413
  };
23421
23414
  }
23422
- var TERMINAL_PLAY_STATUSES2 = /* @__PURE__ */ new Set([
23415
+ var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set([
23423
23416
  "completed",
23424
23417
  "failed",
23425
23418
  "cancelled"
@@ -23919,18 +23912,12 @@ function openPlayDashboard(dashboardUrl, open2) {
23919
23912
  }
23920
23913
  }
23921
23914
  function printPlayLogLines(input2) {
23915
+ if (!input2.emitLogs) return;
23922
23916
  for (const line of input2.lines) {
23923
- if (input2.emitLogs) {
23924
- const formatted = formatPlayLogLine(
23925
- line,
23926
- input2.status ?? void 0,
23927
- input2.state
23928
- );
23929
- if (formatted) {
23930
- input2.progress.writeLogLine(formatted);
23931
- }
23917
+ const formatted = formatPlayLogLine(line, input2.state);
23918
+ if (formatted) {
23919
+ input2.progress.writeLogLine(formatted);
23932
23920
  }
23933
- input2.state.lastLogIndex += 1;
23934
23921
  }
23935
23922
  }
23936
23923
  function assertPlayWaitNotTimedOut(input2) {
@@ -23991,7 +23978,7 @@ async function waitForPlayCompletionByWatch(input2) {
23991
23978
  if (refreshed.runId === input2.workflowId && statusProvesPlayRunExecution(refreshed.status)) {
23992
23979
  await confirmAdmission();
23993
23980
  }
23994
- return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
23981
+ return TERMINAL_PLAY_STATUSES.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
23995
23982
  };
23996
23983
  const handleLiveEvent = async (event) => {
23997
23984
  assertPlayWaitNotTimedOut({ ...input2, lastPhase });
@@ -24018,8 +24005,6 @@ async function waitForPlayCompletionByWatch(input2) {
24018
24005
  });
24019
24006
  printPlayLogLines({
24020
24007
  lines: getLogLinesFromLiveEvent(event),
24021
- status: null,
24022
- jsonOutput: input2.jsonOutput,
24023
24008
  emitLogs: input2.emitLogs,
24024
24009
  state: input2.state,
24025
24010
  progress: input2.progress
@@ -24052,7 +24037,7 @@ async function waitForPlayCompletionByWatch(input2) {
24052
24037
  return withDashboardUrl(finalStatus);
24053
24038
  }
24054
24039
  const status = getStatusFromLiveEvent(event);
24055
- if (status && TERMINAL_PLAY_STATUSES2.has(status)) {
24040
+ if (status && TERMINAL_PLAY_STATUSES.has(status)) {
24056
24041
  terminalStatusRead ??= fetchTerminalStatus();
24057
24042
  return await terminalStatusRead;
24058
24043
  }
@@ -24136,7 +24121,6 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
24136
24121
  input2.playName
24137
24122
  );
24138
24123
  const state = {
24139
- lastLogIndex: 0,
24140
24124
  emittedRunnerStarted: false,
24141
24125
  verbose: input2.verboseLogs === true,
24142
24126
  logLevel: input2.logLevel ?? "info",
@@ -24183,7 +24167,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
24183
24167
  if (refreshed.runId === lastKnownWorkflowId && statusProvesPlayRunExecution(refreshed.status)) {
24184
24168
  await confirmAdmission(lastKnownWorkflowId);
24185
24169
  }
24186
- return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? {
24170
+ return TERMINAL_PLAY_STATUSES.has(refreshed.status) ? {
24187
24171
  ...refreshed,
24188
24172
  dashboardUrl,
24189
24173
  ...launchedRevisionId ? { revisionId: launchedRevisionId } : {}
@@ -24247,8 +24231,6 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
24247
24231
  });
24248
24232
  printPlayLogLines({
24249
24233
  lines: getLogLinesFromLiveEvent(event),
24250
- status: null,
24251
- jsonOutput: input2.jsonOutput,
24252
24234
  emitLogs: input2.emitLogs,
24253
24235
  state,
24254
24236
  progress: input2.progress
@@ -24519,7 +24501,7 @@ var BULKY_RETURN_KEYS = /* @__PURE__ */ new Set([
24519
24501
  "sequenceTrace",
24520
24502
  "logs"
24521
24503
  ]);
24522
- function formatPlayLogLine(rawLine, status, state) {
24504
+ function formatPlayLogLine(rawLine, state) {
24523
24505
  const classified = classifyLogLine(rawLine);
24524
24506
  const line = classified.line;
24525
24507
  const timestampMatch = line.match(/^\[([^\]]+)\]\s*(.*)$/);
@@ -24551,12 +24533,6 @@ function formatPlayLogLine(rawLine, status, state) {
24551
24533
  state.emittedRunnerStarted = true;
24552
24534
  return `${prefix}runner started`;
24553
24535
  }
24554
- const stages = (status?.contract?.staticPipeline?.stages ?? []).filter((stage) => stage.tableNamespace);
24555
- const sourceLabelForNamespace = (namespace) => {
24556
- const stage = stages.find((entry) => entry.tableNamespace === namespace);
24557
- const range = stage?.sourceRange;
24558
- return range?.startLine && range?.endLine ? `${namespace} lines ${range.startLine}-${range.endLine}` : namespace;
24559
- };
24560
24536
  const mapStart = message.match(
24561
24537
  /^Starting map over (\d+) items with (\d+) fields \(key: ([^;]+); (\d+) already satisfied; (\d+) pending\)$/
24562
24538
  );
@@ -24565,7 +24541,7 @@ function formatPlayLogLine(rawLine, status, state) {
24565
24541
  return null;
24566
24542
  }
24567
24543
  const [, rows, fields2, namespace, cached, pending] = mapStart;
24568
- return `${prefix}map ${sourceLabelForNamespace(namespace)}: ${formatInteger(Number(rows))} rows, ${fields2} fields, ${formatInteger(Number(cached))} cached, ${formatInteger(Number(pending))} pending`;
24544
+ return `${prefix}map ${namespace}: ${formatInteger(Number(rows))} rows, ${fields2} fields, ${formatInteger(Number(cached))} cached, ${formatInteger(Number(pending))} pending`;
24569
24545
  }
24570
24546
  const mapDone = message.match(
24571
24547
  /^Map completed: (\d+) results \((\d+) executed, (\d+) already satisfied\)$/
@@ -28643,7 +28619,6 @@ async function handleRunTail(args) {
28643
28619
  const compact = args.includes("--compact");
28644
28620
  const showLiveLogs = debug || hasExplicitLogLevel || !jsonOutput && !compact;
28645
28621
  const compactState = {
28646
- lastLogIndex: 0,
28647
28622
  emittedRunnerStarted: false,
28648
28623
  lastProgressSignature: null,
28649
28624
  lastProgressHeartbeatAt: 0,
@@ -28664,14 +28639,9 @@ async function handleRunTail(args) {
28664
28639
  } : compact || showLiveLogs ? (event) => {
28665
28640
  if (showLiveLogs) {
28666
28641
  for (const line of getLogLinesFromLiveEvent(event)) {
28667
- const formatted = formatPlayLogLine(
28668
- line,
28669
- void 0,
28670
- compactState
28671
- );
28642
+ const formatted = formatPlayLogLine(line, compactState);
28672
28643
  if (formatted) process.stderr.write(`${formatted}
28673
28644
  `);
28674
- compactState.lastLogIndex += 1;
28675
28645
  }
28676
28646
  }
28677
28647
  if (!compact || jsonOutput) return;