deepline 0.3.237 → 0.3.238

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -3454,7 +3454,7 @@ var SDK_RELEASE = {
3454
3454
  // getters keep their established compatibility behavior.
3455
3455
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3456
3456
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3457
- version: "0.3.237",
3457
+ version: "0.3.238",
3458
3458
  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.",
3459
3459
  packageCapabilities: {
3460
3460
  updatePreferences: 1
@@ -4103,19 +4103,19 @@ function withErrorCause(error, cause) {
4103
4103
  }
4104
4104
  return error;
4105
4105
  }
4106
- function mapNetworkError(baseUrl, error, targetLabel2) {
4106
+ function mapNetworkError(baseUrl, error, targetLabel) {
4107
4107
  const tagged = error;
4108
4108
  const timeoutMs = tagged?.[REQUEST_TIMEOUT_MARKER];
4109
4109
  if (typeof timeoutMs === "number") {
4110
4110
  return {
4111
- message: `Request to ${targetLabel2} timed out after ${timeoutMs}ms while waiting for a response.`,
4111
+ message: `Request to ${targetLabel} timed out after ${timeoutMs}ms while waiting for a response.`,
4112
4112
  code: "NETWORK_TIMEOUT",
4113
- details: { timeoutMs, target: targetLabel2 }
4113
+ details: { timeoutMs, target: targetLabel }
4114
4114
  };
4115
4115
  }
4116
4116
  if (tagged?.[REQUEST_ABORT_MARKER]) {
4117
4117
  return {
4118
- message: `Request to ${targetLabel2} was aborted before it completed.`,
4118
+ message: `Request to ${targetLabel} was aborted before it completed.`,
4119
4119
  code: "NETWORK_ABORTED"
4120
4120
  };
4121
4121
  }
@@ -4878,30 +4878,6 @@ var DEFAULT_PRODUCT_NOTIFICATION_DELIVERY_TIMING = {
4878
4878
  windowMs: 36e5
4879
4879
  };
4880
4880
 
4881
- // src/stream-reconnect.ts
4882
- var STREAM_RECONNECT_BASE_DELAY_MS = 500;
4883
- var STREAM_RECONNECT_MAX_DELAY_MS = 15e3;
4884
- var STREAM_HEALTHY_CONNECTION_MS = 3e4;
4885
- function streamReconnectDelayMs(attempt) {
4886
- const cappedExponentialMs = Math.min(
4887
- STREAM_RECONNECT_MAX_DELAY_MS,
4888
- STREAM_RECONNECT_BASE_DELAY_MS * 2 ** Math.max(0, attempt)
4889
- );
4890
- return Math.max(1, Math.floor(Math.random() * (cappedExponentialMs + 1)));
4891
- }
4892
- function isTransientPlayStreamError(error) {
4893
- if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
4894
- return true;
4895
- }
4896
- if (error instanceof DeeplineError && typeof error.statusCode === "number") {
4897
- return error.statusCode >= 500 && error.statusCode < 600;
4898
- }
4899
- const text = error instanceof Error ? error.message : String(error);
4900
- 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(
4901
- text
4902
- );
4903
- }
4904
-
4905
4881
  // ../play-runtime/live-events.ts
4906
4882
  function resolveTimingWindow(input2) {
4907
4883
  const startedAt = typeof input2.startedAt === "number" && Number.isFinite(input2.startedAt) ? input2.startedAt : null;
@@ -4917,19 +4893,6 @@ function resolveTimingWindow(input2) {
4917
4893
  // ../play-runtime/run-failure.ts
4918
4894
  var PUBLIC_FAILURE_TEXT_BYTE_LIMIT = 64 * 1024;
4919
4895
 
4920
- // ../play-runtime/run-terminal-source.ts
4921
- var PLAY_RUN_LEDGER_EVENT_SOURCES = [
4922
- "worker",
4923
- "convex",
4924
- "coordinator",
4925
- "system"
4926
- ];
4927
- function normalizePlayRunLedgerTerminalSource(value) {
4928
- return PLAY_RUN_LEDGER_EVENT_SOURCES.includes(
4929
- value
4930
- ) ? value : null;
4931
- }
4932
-
4933
4896
  // ../play-runtime/run-log-buffer.ts
4934
4897
  var RUNNER_LOG_MAX_BYTES = 5 * 1024 * 1024;
4935
4898
  var TERMINAL_RESERVE_BYTES = 64 * 1024;
@@ -5100,12 +5063,12 @@ function createSecretRedactionContext(initialValues = []) {
5100
5063
  }
5101
5064
  return output2;
5102
5065
  }
5103
- function redactString2(value) {
5066
+ function redactString(value) {
5104
5067
  const output2 = redactRegisteredSecrets(value);
5105
5068
  return redactSecretLikeString(output2);
5106
5069
  }
5107
5070
  function redact(value) {
5108
- if (typeof value === "string") return redactString2(value);
5071
+ if (typeof value === "string") return redactString(value);
5109
5072
  if (Array.isArray(value)) {
5110
5073
  let changed = false;
5111
5074
  const next = new Array(value.length);
@@ -5138,7 +5101,7 @@ function createSecretRedactionContext(initialValues = []) {
5138
5101
  return value;
5139
5102
  }
5140
5103
  function redactKnownSecrets(value) {
5141
- if (typeof value === "string") return redactString2(value);
5104
+ if (typeof value === "string") return redactString(value);
5142
5105
  if (Array.isArray(value)) {
5143
5106
  return value.map((entry) => redactKnownSecrets(entry));
5144
5107
  }
@@ -5157,7 +5120,7 @@ function createSecretRedactionContext(initialValues = []) {
5157
5120
  containsRegisteredSecret,
5158
5121
  matchesRegisteredSecret,
5159
5122
  redactRegisteredSecrets,
5160
- redactString: redactString2,
5123
+ redactString,
5161
5124
  redactKnownSecrets,
5162
5125
  redact
5163
5126
  };
@@ -5181,981 +5144,8 @@ var JSON_SIZE_LIMIT_REACHED = Symbol("JSON_SIZE_LIMIT_REACHED");
5181
5144
  var ledgerIngressRedactor = createSecretRedactionContext();
5182
5145
 
5183
5146
  // ../play-runtime/docflow-node-io.ts
5184
- var DOCFLOW_NODE_IO_LIMITS = {
5185
- maxPaths: 16,
5186
- maxDepth: 3,
5187
- maxObjectFields: 12,
5188
- maxArrayItems: 3,
5189
- maxStringBytes: 256,
5190
- maxPhaseBytes: 2e3,
5191
- maxErrorBytes: 512
5192
- };
5193
5147
  var utf8Encoder = new TextEncoder();
5194
5148
  var PLAY_DATASET_BRAND = Symbol.for("deepline.play.dataset");
5195
- var MAX_CONVEX_PREVIEW_KEY_LENGTH = 1024;
5196
- function ledgerSafeDocflowPreviewKey(key) {
5197
- const source = key.startsWith("$") ? key.replace(/^\$+/, "") || "output" : key || "output";
5198
- let encoded = "";
5199
- for (const character of source) {
5200
- const code = character.charCodeAt(0);
5201
- if (code >= 32 && code < 127) {
5202
- encoded += character;
5203
- continue;
5204
- }
5205
- for (const byte of utf8Encoder.encode(character)) {
5206
- encoded += `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
5207
- }
5208
- }
5209
- if (encoded.length <= MAX_CONVEX_PREVIEW_KEY_LENGTH) return encoded;
5210
- let hashA = 2166136261;
5211
- let hashB = 2654435769;
5212
- for (let index = 0; index < encoded.length; index += 1) {
5213
- const code = encoded.charCodeAt(index);
5214
- hashA = Math.imul(hashA ^ code, 16777619);
5215
- hashB = Math.imul(hashB ^ code, 16777619);
5216
- }
5217
- const suffix = `~${(hashA >>> 0).toString(16).padStart(8, "0")}${(hashB >>> 0).toString(16).padStart(8, "0")}`;
5218
- return `${encoded.slice(0, MAX_CONVEX_PREVIEW_KEY_LENGTH - suffix.length)}${suffix}`;
5219
- }
5220
- function utf8Bytes(value) {
5221
- return utf8Encoder.encode(value).byteLength;
5222
- }
5223
- function truncateUtf8(value, maxBytes) {
5224
- if (utf8Bytes(value) <= maxBytes) return value;
5225
- let output2 = "";
5226
- for (const character of value) {
5227
- if (utf8Bytes(`${output2}${character}\u2026`) > maxBytes) break;
5228
- output2 += character;
5229
- }
5230
- return `${output2}\u2026`;
5231
- }
5232
- function redactString(redactor, value, key) {
5233
- if (!key) return redactor.redactString(value);
5234
- const wrapped = redactor.redact({ [key]: value });
5235
- return typeof wrapped[key] === "string" ? wrapped[key] : redactor.redactString(value);
5236
- }
5237
- function safeString(value, redactor, key) {
5238
- if (typeof value !== "string") return void 0;
5239
- return truncateUtf8(
5240
- redactString(redactor, value, key),
5241
- DOCFLOW_NODE_IO_LIMITS.maxStringBytes
5242
- );
5243
- }
5244
- function previewValue(value, input2) {
5245
- if (value === null) return { kind: "null" };
5246
- if (value === void 0) return { kind: "unavailable", reason: "undefined" };
5247
- if (typeof value === "string") {
5248
- return {
5249
- kind: "scalar",
5250
- value: safeString(value, input2.redactor, input2.key) ?? ""
5251
- };
5252
- }
5253
- if (typeof value === "number") {
5254
- return Number.isFinite(value) ? { kind: "scalar", value } : { kind: "unavailable", reason: "unsupported" };
5255
- }
5256
- if (typeof value === "boolean") return { kind: "scalar", value };
5257
- if (typeof value === "bigint") {
5258
- return { kind: "unavailable", reason: "bigint" };
5259
- }
5260
- if (typeof value === "function") {
5261
- return { kind: "unavailable", reason: "function" };
5262
- }
5263
- if (typeof value === "symbol") {
5264
- return { kind: "unavailable", reason: "symbol" };
5265
- }
5266
- if (typeof value !== "object") {
5267
- return { kind: "unavailable", reason: "unsupported" };
5268
- }
5269
- try {
5270
- const brand = readDataProperty(value, PLAY_DATASET_BRAND);
5271
- const datasetKind = readDataProperty(value, "datasetKind");
5272
- const datasetId = readDataProperty(value, "datasetId");
5273
- const tableNamespace = readDataProperty(value, "tableNamespace");
5274
- if (brand.ok && brand.value === true && datasetKind.ok && (datasetKind.value === "csv" || datasetKind.value === "map") && datasetId.ok && typeof datasetId.value === "string") {
5275
- return {
5276
- kind: "dataset",
5277
- datasetId: safeString(datasetId.value, input2.redactor, "datasetId") ?? "dataset",
5278
- datasetKind: datasetKind.value,
5279
- tableNamespace: tableNamespace.ok && tableNamespace.value === null ? null : tableNamespace.ok ? safeString(
5280
- tableNamespace.value,
5281
- input2.redactor,
5282
- "tableNamespace"
5283
- ) : void 0
5284
- };
5285
- }
5286
- const kind = readDataProperty(value, "kind");
5287
- const count = readDataProperty(value, "count");
5288
- const preview = readDataProperty(value, "preview");
5289
- if (kind.ok && kind.value === "dataset" && datasetKind.ok && (datasetKind.value === "csv" || datasetKind.value === "map") && datasetId.ok && typeof datasetId.value === "string" && count.ok && typeof count.value === "number" && preview.ok && Array.isArray(preview.value)) {
5290
- return {
5291
- kind: "dataset",
5292
- datasetId: safeString(datasetId.value, input2.redactor, "datasetId") ?? "dataset",
5293
- datasetKind: datasetKind.value,
5294
- tableNamespace: tableNamespace.ok && tableNamespace.value === null ? null : tableNamespace.ok ? safeString(
5295
- tableNamespace.value,
5296
- input2.redactor,
5297
- "tableNamespace"
5298
- ) : void 0,
5299
- rowCount: Math.max(0, Math.floor(count.value))
5300
- };
5301
- }
5302
- } catch {
5303
- return { kind: "unavailable", reason: "access_error" };
5304
- }
5305
- if (input2.ancestors.has(value)) {
5306
- return { kind: "unavailable", reason: "cycle" };
5307
- }
5308
- if (input2.depth >= DOCFLOW_NODE_IO_LIMITS.maxDepth) {
5309
- return { kind: "unavailable", reason: "depth" };
5310
- }
5311
- input2.ancestors.add(value);
5312
- try {
5313
- if (Array.isArray(value)) {
5314
- const items = [];
5315
- for (let index = 0; index < Math.min(value.length, DOCFLOW_NODE_IO_LIMITS.maxArrayItems); index += 1) {
5316
- const descriptor = Object.getOwnPropertyDescriptor(
5317
- value,
5318
- String(index)
5319
- );
5320
- items.push(
5321
- descriptor && "value" in descriptor ? previewValue(descriptor.value, {
5322
- ...input2,
5323
- depth: input2.depth + 1
5324
- }) : { kind: "unavailable", reason: "access_error" }
5325
- );
5326
- }
5327
- return {
5328
- kind: "array",
5329
- items,
5330
- totalItems: value.length,
5331
- ...value.length > items.length ? { truncated: true } : {}
5332
- };
5333
- }
5334
- let descriptors;
5335
- try {
5336
- descriptors = Object.getOwnPropertyDescriptors(value);
5337
- } catch {
5338
- return { kind: "unavailable", reason: "access_error" };
5339
- }
5340
- const entries = Object.entries(descriptors).filter(
5341
- ([, descriptor]) => descriptor.enumerable
5342
- );
5343
- const selected = entries.slice(0, DOCFLOW_NODE_IO_LIMITS.maxObjectFields);
5344
- const fields2 = {};
5345
- for (const [key, descriptor] of selected) {
5346
- const safeKey = truncateUtf8(
5347
- ledgerSafeDocflowPreviewKey(input2.redactor.redactString(key)),
5348
- DOCFLOW_NODE_IO_LIMITS.maxStringBytes
5349
- );
5350
- fields2[safeKey] = "value" in descriptor ? previewValue(descriptor.value, {
5351
- ...input2,
5352
- depth: input2.depth + 1,
5353
- key
5354
- }) : { kind: "unavailable", reason: "access_error" };
5355
- }
5356
- return {
5357
- kind: "object",
5358
- fields: fields2,
5359
- totalFields: entries.length,
5360
- ...entries.length > selected.length ? { truncated: true } : {}
5361
- };
5362
- } catch {
5363
- return { kind: "unavailable", reason: "access_error" };
5364
- } finally {
5365
- input2.ancestors.delete(value);
5366
- }
5367
- }
5368
- function readDataProperty(value, property) {
5369
- if ((typeof value !== "object" || value === null) && typeof value !== "function") {
5370
- return { ok: false };
5371
- }
5372
- try {
5373
- let owner = value;
5374
- while (owner) {
5375
- const descriptor = Object.getOwnPropertyDescriptor(owner, property);
5376
- if (descriptor) {
5377
- return "value" in descriptor ? { ok: true, value: descriptor.value } : { ok: false };
5378
- }
5379
- owner = Object.getPrototypeOf(owner);
5380
- }
5381
- } catch {
5382
- return { ok: false };
5383
- }
5384
- return { ok: false };
5385
- }
5386
- function buildPlayDocflowNodeErrorPreview(error, redactor = createSecretRedactionContext()) {
5387
- try {
5388
- const message = error instanceof Error ? error.message : String(error);
5389
- return truncateUtf8(
5390
- redactor.redactString(message),
5391
- DOCFLOW_NODE_IO_LIMITS.maxErrorBytes
5392
- );
5393
- } catch {
5394
- return "Non-Error value thrown (message unavailable)";
5395
- }
5396
- }
5397
- function isRecord4(value) {
5398
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
5399
- }
5400
- function normalizePreview(value, depth) {
5401
- if (!isRecord4(value) || typeof value.kind !== "string") return null;
5402
- if (value.kind === "null") return { kind: "null" };
5403
- if (value.kind === "scalar") {
5404
- if (typeof value.value === "string" || typeof value.value === "boolean" || typeof value.value === "number" && Number.isFinite(value.value)) {
5405
- return previewValue(value.value, {
5406
- depth: 0,
5407
- ancestors: /* @__PURE__ */ new WeakSet(),
5408
- redactor: createSecretRedactionContext()
5409
- });
5410
- }
5411
- return null;
5412
- }
5413
- if (value.kind === "unavailable") {
5414
- const reason = value.reason;
5415
- return typeof reason === "string" && [
5416
- "undefined",
5417
- "function",
5418
- "symbol",
5419
- "bigint",
5420
- "cycle",
5421
- "depth",
5422
- "access_error",
5423
- "limit",
5424
- "unsupported"
5425
- ].includes(reason) ? {
5426
- kind: "unavailable",
5427
- reason
5428
- } : null;
5429
- }
5430
- if (value.kind === "dataset") {
5431
- const datasetId = safeString(
5432
- value.datasetId,
5433
- createSecretRedactionContext(),
5434
- "datasetId"
5435
- );
5436
- if (!datasetId || value.datasetKind !== "csv" && value.datasetKind !== "map") {
5437
- return null;
5438
- }
5439
- return {
5440
- kind: "dataset",
5441
- datasetId,
5442
- datasetKind: value.datasetKind,
5443
- ...value.tableNamespace === null ? { tableNamespace: null } : typeof value.tableNamespace === "string" ? {
5444
- tableNamespace: safeString(
5445
- value.tableNamespace,
5446
- createSecretRedactionContext(),
5447
- "tableNamespace"
5448
- )
5449
- } : {},
5450
- ...typeof value.rowCount === "number" && Number.isFinite(value.rowCount) ? { rowCount: Math.max(0, Math.floor(value.rowCount)) } : {}
5451
- };
5452
- }
5453
- if (depth >= DOCFLOW_NODE_IO_LIMITS.maxDepth) {
5454
- return { kind: "unavailable", reason: "depth" };
5455
- }
5456
- if (value.kind === "array" && Array.isArray(value.items)) {
5457
- const items = value.items.slice(0, DOCFLOW_NODE_IO_LIMITS.maxArrayItems).map((item) => normalizePreview(item, depth + 1)).filter((item) => item !== null);
5458
- const totalItems = typeof value.totalItems === "number" && Number.isFinite(value.totalItems) ? Math.max(items.length, Math.floor(value.totalItems)) : items.length;
5459
- return {
5460
- kind: "array",
5461
- items,
5462
- totalItems,
5463
- ...value.truncated === true || totalItems > items.length ? { truncated: true } : {}
5464
- };
5465
- }
5466
- if (value.kind === "object" && isRecord4(value.fields)) {
5467
- const fields2 = {};
5468
- for (const [key, field] of Object.entries(value.fields).slice(
5469
- 0,
5470
- DOCFLOW_NODE_IO_LIMITS.maxObjectFields
5471
- )) {
5472
- const normalized = normalizePreview(field, depth + 1);
5473
- if (normalized) fields2[ledgerSafeDocflowPreviewKey(key)] = normalized;
5474
- }
5475
- const totalFields = typeof value.totalFields === "number" && Number.isFinite(value.totalFields) ? Math.max(Object.keys(fields2).length, Math.floor(value.totalFields)) : Object.keys(fields2).length;
5476
- return {
5477
- kind: "object",
5478
- fields: fields2,
5479
- totalFields,
5480
- ...value.truncated === true || totalFields > Object.keys(fields2).length ? { truncated: true } : {}
5481
- };
5482
- }
5483
- return null;
5484
- }
5485
- function normalizePlayDocflowNodeIoState(value) {
5486
- if (!isRecord4(value)) return void 0;
5487
- const attempt = typeof value.attempt === "number" && Number.isFinite(value.attempt) ? Math.max(0, Math.floor(value.attempt)) : 0;
5488
- const normalizeMap = (raw) => {
5489
- if (!isRecord4(raw)) return void 0;
5490
- const output2 = {};
5491
- for (const [path, preview] of Object.entries(raw).slice(
5492
- 0,
5493
- DOCFLOW_NODE_IO_LIMITS.maxPaths
5494
- )) {
5495
- const normalized = normalizePreview(preview, 0);
5496
- if (!normalized) continue;
5497
- const safePath = ledgerSafeDocflowPreviewKey(path);
5498
- const candidate = { ...output2, [safePath]: normalized };
5499
- if (utf8Bytes(JSON.stringify(candidate)) > DOCFLOW_NODE_IO_LIMITS.maxPhaseBytes) {
5500
- break;
5501
- }
5502
- output2[safePath] = normalized;
5503
- }
5504
- return output2;
5505
- };
5506
- const inputs = normalizeMap(value.inputs);
5507
- const outputs = normalizeMap(value.outputs);
5508
- const error = typeof value.error === "string" ? buildPlayDocflowNodeErrorPreview(value.error) : value.error === null ? null : void 0;
5509
- return {
5510
- attempt,
5511
- ...typeof value.invocationId === "string" && value.invocationId.trim() ? {
5512
- invocationId: truncateUtf8(
5513
- value.invocationId.trim(),
5514
- DOCFLOW_NODE_IO_LIMITS.maxStringBytes
5515
- )
5516
- } : {},
5517
- ...inputs ? { inputs } : {},
5518
- ...outputs ? { outputs } : {},
5519
- ...value.inputsTruncated === true ? { inputsTruncated: true } : {},
5520
- ...value.outputsTruncated === true ? { outputsTruncated: true } : {},
5521
- ...error !== void 0 ? { error } : {}
5522
- };
5523
- }
5524
-
5525
- // ../play-runtime/activity-observation.ts
5526
- function isRecord5(value) {
5527
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
5528
- }
5529
- function isPlayActivityObservation(value) {
5530
- if (!isRecord5(value) || value.schemaVersion !== void 0 && value.schemaVersion !== 1 || typeof value.activityId !== "string" || !value.activityId.trim() || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || !isRecord5(value.target) || !isRecord5(value.state)) {
5531
- return false;
5532
- }
5533
- const targetKinds = /* @__PURE__ */ new Set([
5534
- "provider",
5535
- "dataset",
5536
- "lease",
5537
- "runner",
5538
- "step",
5539
- "capacity"
5540
- ]);
5541
- const stateKinds = /* @__PURE__ */ new Set([
5542
- "active",
5543
- "queued",
5544
- "waiting",
5545
- "retrying",
5546
- "scheduled",
5547
- "completed",
5548
- "failed"
5549
- ]);
5550
- return typeof value.target.kind === "string" && targetKinds.has(value.target.kind) && typeof value.state.kind === "string" && stateKinds.has(value.state.kind);
5551
- }
5552
- function derivePlayActivityVisibility(input2) {
5553
- const { state } = input2.observation;
5554
- if (state.kind === "failed") return "action";
5555
- if (state.kind === "waiting") {
5556
- return state.reason.kind === "external_event" ? "action" : "headline";
5557
- }
5558
- if (state.kind === "queued" || state.kind === "scheduled") return "headline";
5559
- if (state.kind === "retrying") {
5560
- if (state.reason === "rate_limit" && input2.observation.target.kind === "capacity") {
5561
- return "headline";
5562
- }
5563
- if (state.retryAt - input2.now <= 3e4) return "hidden";
5564
- return state.reason === "rate_limit" ? "headline" : "timeline";
5565
- }
5566
- if (state.kind === "active") return "headline";
5567
- return "timeline";
5568
- }
5569
- function targetLabel(target) {
5570
- switch (target.kind) {
5571
- case "provider":
5572
- return target.label ?? `${target.provider} ${target.operation}`;
5573
- case "dataset":
5574
- return target.label ?? `dataset ${target.tableNamespace}`;
5575
- case "lease":
5576
- return `${target.resourceKind} ${target.resourceLabel}`;
5577
- case "runner":
5578
- return target.label ?? `${target.backend} runner`;
5579
- case "step":
5580
- return target.label ?? target.stepId;
5581
- case "capacity":
5582
- return target.label ?? `${target.pool} capacity`;
5583
- }
5584
- }
5585
- function summarizePlayActivity(observation) {
5586
- const label = targetLabel(observation.target);
5587
- const { state } = observation;
5588
- switch (state.kind) {
5589
- case "active": {
5590
- const progress = state.progress;
5591
- const counts = typeof progress?.completed === "number" && typeof progress.total === "number" ? ` (${progress.completed}/${progress.total})` : "";
5592
- return `Active: ${label}${counts}.`;
5593
- }
5594
- case "queued":
5595
- return `Queued: waiting for ${label}.`;
5596
- case "waiting":
5597
- if (state.reason.kind === "external_event") {
5598
- const provider = state.reason.provider ? ` from ${state.reason.provider}` : "";
5599
- return `Blocked: waiting for an external event${provider}.`;
5600
- }
5601
- if (state.reason.kind === "dataset") {
5602
- return `Blocked: waiting for dataset ${state.reason.tableNamespace} to become ${state.reason.requiredPhase}.`;
5603
- }
5604
- if (state.reason.kind === "lease") {
5605
- return `Contended: waiting for ${state.reason.resourceKind} lease ${state.reason.resourceLabel}.`;
5606
- }
5607
- return `Paused: ${label}; the legacy producer did not report a typed reason.`;
5608
- case "retrying":
5609
- if (state.reason === "rate_limit") {
5610
- return `Waiting for ${label} request capacity; the run will retry automatically.`;
5611
- }
5612
- return `Delayed: ${label} will retry automatically.`;
5613
- case "scheduled":
5614
- return `Scheduled: ${label} will resume automatically.`;
5615
- case "completed":
5616
- return `Completed: ${label}.`;
5617
- case "failed":
5618
- return `Failed: ${label}.`;
5619
- }
5620
- }
5621
- function isTerminalActivityState(state) {
5622
- return state.kind === "completed" || state.kind === "failed";
5623
- }
5624
- function projection(observation, now, classified = true) {
5625
- return {
5626
- observation,
5627
- summary: summarizePlayActivity(observation),
5628
- visibility: derivePlayActivityVisibility({ observation, now }),
5629
- classified
5630
- };
5631
- }
5632
- function projectPlayRunActivity(input2) {
5633
- const now = input2.now ?? Date.now();
5634
- const observedAt = input2.updatedAt ?? now;
5635
- const normalizedStatus = input2.status.trim().toLowerCase();
5636
- if (normalizedStatus === "completed" || normalizedStatus === "failed" || normalizedStatus === "cancelled" || normalizedStatus === "terminated" || normalizedStatus === "timed_out") {
5637
- return null;
5638
- }
5639
- const latestExplicit = [...input2.explicit ?? []].filter((candidate) => !isTerminalActivityState(candidate.state)).sort((left, right) => right.observedAt - left.observedAt)[0];
5640
- const explicit = latestExplicit?.target.kind === "capacity" && latestExplicit.target.pool === "provider" && latestExplicit.state.kind === "retrying" && latestExplicit.state.retryAt < now ? null : latestExplicit;
5641
- if (explicit) return projection(explicit, now);
5642
- if (input2.waitKind === "detached_runner") {
5643
- return projection(
5644
- {
5645
- activityId: "runner:managed",
5646
- target: {
5647
- kind: "runner",
5648
- backend: input2.runtimeBackend ?? "managed",
5649
- label: "managed play runner"
5650
- },
5651
- state: { kind: "active" },
5652
- observedAt
5653
- },
5654
- now
5655
- );
5656
- }
5657
- if (input2.waitKind === "sleep") {
5658
- return projection(
5659
- {
5660
- activityId: "run:sleep",
5661
- target: {
5662
- kind: "step",
5663
- stepId: input2.activeNodeId ?? "run",
5664
- label: input2.playName ?? "play"
5665
- },
5666
- state: {
5667
- kind: "scheduled",
5668
- reason: "sleep",
5669
- resumeAt: input2.waitUntil ?? observedAt
5670
- },
5671
- observedAt
5672
- },
5673
- now
5674
- );
5675
- }
5676
- if (input2.waitKind === "integration_event" || input2.waitKind === "integration_event_batch") {
5677
- return projection(
5678
- {
5679
- activityId: `event:${input2.activeNodeId ?? "run"}`,
5680
- stepId: input2.activeNodeId ?? void 0,
5681
- target: {
5682
- kind: "step",
5683
- stepId: input2.activeNodeId ?? "run",
5684
- label: input2.playName ?? "play"
5685
- },
5686
- state: {
5687
- kind: "waiting",
5688
- reason: {
5689
- kind: "external_event",
5690
- eventKey: input2.eventKey ?? void 0,
5691
- deadlineAt: input2.waitUntil ?? void 0
5692
- }
5693
- },
5694
- observedAt
5695
- },
5696
- now
5697
- );
5698
- }
5699
- if (normalizedStatus === "waiting") {
5700
- return projection(
5701
- {
5702
- activityId: "run:legacy-wait",
5703
- target: {
5704
- kind: "step",
5705
- stepId: input2.activeNodeId ?? "run",
5706
- label: input2.playName ?? "play"
5707
- },
5708
- state: { kind: "waiting", reason: { kind: "unknown" } },
5709
- observedAt
5710
- },
5711
- now,
5712
- false
5713
- );
5714
- }
5715
- const pendingDataset = [...input2.datasets ?? []].filter(
5716
- (dataset) => dataset.phase === "registered" || dataset.complete !== true && dataset.phase !== "failed"
5717
- ).sort((left, right) => (right.updatedAt ?? 0) - (left.updatedAt ?? 0))[0];
5718
- if (pendingDataset) {
5719
- const activeDatasetStep = input2.nodeStates?.find(
5720
- (candidate) => candidate.nodeId === input2.activeNodeId && candidate.status === "running" && candidate.artifactTableNamespace === pendingDataset.tableNamespace
5721
- );
5722
- const datasetStep = activeDatasetStep ?? input2.nodeStates?.find(
5723
- (candidate) => candidate.artifactTableNamespace === pendingDataset.tableNamespace
5724
- );
5725
- const datasetProgress = datasetStep?.progress ?? null;
5726
- return projection(
5727
- {
5728
- activityId: `dataset:${pendingDataset.datasetId ?? pendingDataset.tableNamespace}`,
5729
- target: {
5730
- kind: "dataset",
5731
- tableNamespace: pendingDataset.tableNamespace,
5732
- operation: "materializing"
5733
- },
5734
- state: {
5735
- kind: "active",
5736
- progress: {
5737
- completed: datasetProgress?.completed ?? pendingDataset.persistedRows,
5738
- total: datasetProgress?.total ?? (typeof pendingDataset.succeededRows === "number" || typeof pendingDataset.failedRows === "number" ? (pendingDataset.succeededRows ?? 0) + (pendingDataset.failedRows ?? 0) : void 0),
5739
- failed: datasetProgress?.failed ?? pendingDataset.failedRows
5740
- }
5741
- },
5742
- observedAt: datasetStep?.updatedAt ?? pendingDataset.updatedAt ?? observedAt
5743
- },
5744
- now
5745
- );
5746
- }
5747
- const activeStep = input2.nodeStates?.find(
5748
- (candidate) => candidate.nodeId === input2.activeNodeId
5749
- ) ?? input2.nodeStates?.find((candidate) => candidate.status === "running") ?? null;
5750
- if (activeStep) {
5751
- const toolId = activeStep.nodeId.startsWith("tool:") ? activeStep.nodeId.split(":").at(-1)?.trim() || null : null;
5752
- const provider = toolId?.split(/[._]/)[0]?.trim() || null;
5753
- return projection(
5754
- {
5755
- activityId: `step:${activeStep.nodeId}`,
5756
- stepId: activeStep.nodeId,
5757
- target: toolId && provider ? {
5758
- kind: "provider",
5759
- provider,
5760
- operation: toolId,
5761
- label: activeStep.label ?? toolId
5762
- } : {
5763
- kind: "step",
5764
- stepId: activeStep.nodeId,
5765
- label: activeStep.label
5766
- },
5767
- state: {
5768
- kind: "active",
5769
- progress: activeStep.progress ?? void 0
5770
- },
5771
- observedAt: activeStep.updatedAt ?? observedAt
5772
- },
5773
- now
5774
- );
5775
- }
5776
- if (normalizedStatus === "queued") {
5777
- return projection(
5778
- {
5779
- activityId: "capacity:worker",
5780
- target: { kind: "capacity", pool: "worker" },
5781
- state: { kind: "queued", reason: "capacity" },
5782
- observedAt
5783
- },
5784
- now
5785
- );
5786
- }
5787
- const fallback = {
5788
- activityId: "run:legacy",
5789
- target: {
5790
- kind: "step",
5791
- stepId: input2.activeNodeId ?? "run",
5792
- label: input2.playName ?? "play"
5793
- },
5794
- state: normalizedStatus === "waiting" ? { kind: "waiting", reason: { kind: "unknown" } } : { kind: "active" },
5795
- observedAt
5796
- };
5797
- return projection(fallback, now, normalizedStatus !== "waiting");
5798
- }
5799
-
5800
- // ../play-runtime/cell-provenance.ts
5801
- function finiteNonNegativeInteger2(value) {
5802
- if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
5803
- return null;
5804
- }
5805
- return Math.trunc(value);
5806
- }
5807
- function nonEmptyString(value) {
5808
- if (typeof value !== "string") return null;
5809
- const trimmed = value.trim();
5810
- return trimmed ? trimmed : null;
5811
- }
5812
- function normalizeDatasetBornFrom(value) {
5813
- if (!value || typeof value !== "object" || Array.isArray(value)) return null;
5814
- const record3 = value;
5815
- const table = nonEmptyString(record3.table);
5816
- const rowCountIn = finiteNonNegativeInteger2(record3.rowCountIn);
5817
- if (!table || rowCountIn === null) return null;
5818
- return { table, rowCountIn };
5819
- }
5820
-
5821
- // ../play-runtime/run-ledger.ts
5822
- var LOG_TAIL_LIMIT = 100;
5823
- var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
5824
- "completed",
5825
- "failed",
5826
- "cancelled",
5827
- "terminated",
5828
- "timed_out"
5829
- ]);
5830
- function isRecord6(value) {
5831
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
5832
- }
5833
- function finiteNumber(value) {
5834
- return typeof value === "number" && Number.isFinite(value) ? value : null;
5835
- }
5836
- function nonnegativeSafeInteger(value) {
5837
- return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
5838
- }
5839
- function isWorkCounterSegmentId(value) {
5840
- return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
5841
- value
5842
- );
5843
- }
5844
- function normalizePlayRunLedgerTerminalWorkCounterSegment(value) {
5845
- if (!isRecord6(value)) return void 0;
5846
- if (!nonnegativeSafeInteger(value.attempt) || !nonnegativeSafeInteger(value.invocationSeq) || value.invocationSeq === 0 || !isWorkCounterSegmentId(value.segmentId)) {
5847
- return void 0;
5848
- }
5849
- return {
5850
- attempt: value.attempt,
5851
- invocationSeq: value.invocationSeq,
5852
- segmentId: value.segmentId
5853
- };
5854
- }
5855
- function hasConfirmedPlayRunLedgerWorkCounters(snapshot) {
5856
- const counters = snapshot.workCounters;
5857
- const terminal = snapshot.terminalWorkCounterSegment;
5858
- return Boolean(
5859
- isTerminalPlayRunLedgerStatus(snapshot.status) && (snapshot.terminalSource === "worker" || snapshot.terminalSource === "system") && counters?.final && counters.completeThroughAttempt && counters.consistent && terminal && counters.attempt === terminal.attempt && counters.invocationSeq === terminal.invocationSeq && counters.segmentId === terminal.segmentId && Number.isSafeInteger(
5860
- counters.completedLogicalCalls + counters.logicalCalls
5861
- ) && Number.isSafeInteger(
5862
- counters.completedProviderRequests + counters.providerRequests
5863
- ) && Number.isSafeInteger(
5864
- counters.completedProvider429s + counters.provider429s
5865
- )
5866
- );
5867
- }
5868
- function normalizeWorkCounters(value) {
5869
- if (!isRecord6(value)) return void 0;
5870
- for (const field of [
5871
- "attempt",
5872
- "invocationSeq",
5873
- "logicalCalls",
5874
- "providerRequests",
5875
- "provider429s",
5876
- "completedLogicalCalls",
5877
- "completedProviderRequests",
5878
- "completedProvider429s"
5879
- ]) {
5880
- if (!nonnegativeSafeInteger(value[field])) return void 0;
5881
- }
5882
- if (value.invocationSeq === 0 || !isWorkCounterSegmentId(value.segmentId) || typeof value.final !== "boolean" || typeof value.completeThroughAttempt !== "boolean" || typeof value.consistent !== "boolean") {
5883
- return void 0;
5884
- }
5885
- return {
5886
- ...value,
5887
- attempt: value.attempt,
5888
- invocationSeq: value.invocationSeq,
5889
- segmentId: value.segmentId,
5890
- logicalCalls: value.logicalCalls,
5891
- providerRequests: value.providerRequests,
5892
- provider429s: value.provider429s,
5893
- final: value.final,
5894
- completedLogicalCalls: value.completedLogicalCalls,
5895
- completedProviderRequests: value.completedProviderRequests,
5896
- completedProvider429s: value.completedProvider429s,
5897
- completeThroughAttempt: value.completeThroughAttempt,
5898
- consistent: value.consistent
5899
- };
5900
- }
5901
- function optionalFiniteNumber(value) {
5902
- const normalized = finiteNumber(value);
5903
- return normalized === null ? void 0 : normalized;
5904
- }
5905
- function optionalString(value) {
5906
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
5907
- }
5908
- function optionalNullableString(value) {
5909
- if (value === null) return null;
5910
- return optionalString(value);
5911
- }
5912
- function normalizePlayRunLedgerStatus(value) {
5913
- const normalized = String(value ?? "").trim().toLowerCase();
5914
- switch (normalized) {
5915
- case "queued":
5916
- case "pending":
5917
- return "queued";
5918
- case "running":
5919
- case "started":
5920
- return "running";
5921
- case "waiting":
5922
- return "waiting";
5923
- case "completed":
5924
- case "complete":
5925
- case "succeeded":
5926
- return "completed";
5927
- case "failed":
5928
- case "error":
5929
- return "failed";
5930
- case "cancelled":
5931
- case "canceled":
5932
- return "cancelled";
5933
- case "terminated":
5934
- return "terminated";
5935
- case "timed_out":
5936
- case "timeout":
5937
- return "timed_out";
5938
- default:
5939
- return "unknown";
5940
- }
5941
- }
5942
- function isTerminalPlayRunLedgerStatus(status) {
5943
- return TERMINAL_STATUSES.has(status);
5944
- }
5945
- function summarizeRunRowOutcomes(snapshot) {
5946
- let completedRows = 0;
5947
- let failedRows = 0;
5948
- let totalRows = 0;
5949
- let supersededRows = 0;
5950
- for (const step of Object.values(snapshot.stepsById)) {
5951
- const progress = step.progress;
5952
- if (!progress) continue;
5953
- completedRows += Math.max(0, finiteNumber(progress.completed) ?? 0);
5954
- failedRows += Math.max(0, finiteNumber(progress.failed) ?? 0);
5955
- supersededRows += Math.max(0, finiteNumber(progress.supersededRows) ?? 0);
5956
- const stepTotal = finiteNumber(progress.total);
5957
- totalRows += stepTotal !== null && stepTotal >= 0 ? stepTotal : Math.max(0, finiteNumber(progress.completed) ?? 0) + Math.max(0, finiteNumber(progress.failed) ?? 0) + Math.max(0, finiteNumber(progress.supersededRows) ?? 0);
5958
- }
5959
- const resultSummary = isRecord6(snapshot.resultSummary) ? snapshot.resultSummary : null;
5960
- const resultRowOutcomes = isRecord6(resultSummary?.rowOutcomes) ? resultSummary.rowOutcomes : null;
5961
- const terminalCompletedRows = finiteNumber(resultRowOutcomes?.completedRows);
5962
- const terminalFailedRows = finiteNumber(resultRowOutcomes?.failedRows);
5963
- const terminalTotalRows = finiteNumber(resultRowOutcomes?.totalRows);
5964
- const terminalSupersededRows = finiteNumber(
5965
- resultRowOutcomes?.supersededRows
5966
- );
5967
- const settledCompletedRows = terminalCompletedRows ?? completedRows;
5968
- const settledFailedRows = terminalFailedRows ?? failedRows;
5969
- return {
5970
- completedRows: settledCompletedRows,
5971
- failedRows: settledFailedRows,
5972
- totalRows: terminalTotalRows ?? totalRows,
5973
- hasRowFailures: settledFailedRows > 0,
5974
- ...(terminalSupersededRows ?? supersededRows) > 0 ? { supersededRows: terminalSupersededRows ?? supersededRows } : {}
5975
- };
5976
- }
5977
- function createEmptyPlayRunLedgerSnapshot(input2) {
5978
- const status = normalizePlayRunLedgerStatus(input2.status ?? "unknown");
5979
- const startedAt = finiteNumber(input2.startedAt) ?? null;
5980
- const finishedAt = finiteNumber(input2.finishedAt) ?? null;
5981
- return {
5982
- runId: input2.runId,
5983
- playName: input2.playName ?? null,
5984
- status,
5985
- waitKind: null,
5986
- waitUntil: null,
5987
- error: optionalNullableString(input2.error) ?? null,
5988
- createdAt: finiteNumber(input2.createdAt) ?? null,
5989
- startedAt,
5990
- updatedAt: finiteNumber(input2.updatedAt) ?? finishedAt ?? startedAt ?? finiteNumber(input2.createdAt) ?? null,
5991
- finishedAt,
5992
- durationMs: startedAt !== null && finishedAt !== null ? Math.max(0, finishedAt - startedAt) : null,
5993
- orderedStepIds: [],
5994
- stepsById: {},
5995
- orderedDatasetIds: [],
5996
- datasetsById: {},
5997
- orderedActivityIds: [],
5998
- activitiesById: {},
5999
- logTail: [],
6000
- totalLogCount: 0,
6001
- logsTruncated: false,
6002
- activeStepId: null,
6003
- activeActivityId: null,
6004
- activeArtifactTableNamespace: null,
6005
- resultTableNamespace: null
6006
- };
6007
- }
6008
- function normalizePlayRunLedgerSnapshot(value, fallback) {
6009
- if (!isRecord6(value)) {
6010
- return createEmptyPlayRunLedgerSnapshot(fallback);
6011
- }
6012
- const orderedStepIds = Array.isArray(value.orderedStepIds) ? value.orderedStepIds.filter(
6013
- (entry) => typeof entry === "string" && Boolean(entry.trim())
6014
- ) : [];
6015
- const rawSteps = isRecord6(value.stepsById) ? value.stepsById : {};
6016
- const stepsById = {};
6017
- for (const [stepId, rawStep] of Object.entries(rawSteps)) {
6018
- if (!stepId.trim() || !isRecord6(rawStep)) continue;
6019
- const rawStatus = normalizeStepStatus(rawStep.status);
6020
- if (!rawStatus) continue;
6021
- const completedAt = finiteNumber(rawStep.completedAt);
6022
- const status = rawStatus === "running" && completedAt !== null ? "completed" : rawStatus;
6023
- const rawProgress = isRecord6(rawStep.progress) ? rawStep.progress : null;
6024
- stepsById[stepId] = {
6025
- stepId,
6026
- label: optionalString(rawStep.label),
6027
- kind: optionalString(rawStep.kind),
6028
- status,
6029
- error: optionalNullableString(rawStep.error),
6030
- artifactTableNamespace: optionalNullableString(
6031
- rawStep.artifactTableNamespace
6032
- ),
6033
- startedAt: finiteNumber(rawStep.startedAt),
6034
- completedAt,
6035
- updatedAt: finiteNumber(rawStep.updatedAt),
6036
- progress: rawProgress ? normalizeStepProgress(rawProgress) : null
6037
- };
6038
- }
6039
- const rawDatasets = isRecord6(value.datasetsById) ? value.datasetsById : {};
6040
- const datasetsById = {};
6041
- for (const [datasetId, rawDataset] of Object.entries(rawDatasets)) {
6042
- if (!datasetId.trim() || !isRecord6(rawDataset)) continue;
6043
- const phase = rawDataset.phase === "available" || rawDataset.phase === "failed" ? rawDataset.phase : "registered";
6044
- const datasetBornFrom = normalizeDatasetBornFrom(rawDataset.bornFrom);
6045
- datasetsById[datasetId] = {
6046
- datasetId,
6047
- path: optionalString(rawDataset.path) ?? `datasets.${datasetId}`,
6048
- tableNamespace: optionalString(rawDataset.tableNamespace) ?? datasetId,
6049
- phase,
6050
- persistedRows: Math.max(0, finiteNumber(rawDataset.persistedRows) ?? 0),
6051
- persistedRowsObserved: rawDataset.persistedRowsObserved === true,
6052
- succeededRows: Math.max(0, finiteNumber(rawDataset.succeededRows) ?? 0),
6053
- succeededRowsObserved: rawDataset.succeededRowsObserved === true,
6054
- failedRows: Math.max(0, finiteNumber(rawDataset.failedRows) ?? 0),
6055
- failedRowsObserved: rawDataset.failedRowsObserved === true,
6056
- complete: rawDataset.complete === true,
6057
- completeObserved: rawDataset.completeObserved === true,
6058
- // ADR 0019 birth survives the snapshot round trip. A partial record is
6059
- // dropped rather than half-admitted, so a dataset either states where its
6060
- // rows came from or says nothing.
6061
- ...datasetBornFrom ? { bornFrom: datasetBornFrom } : {},
6062
- updatedAt: finiteNumber(rawDataset.updatedAt) ?? 0
6063
- };
6064
- }
6065
- const rawActivities = isRecord6(value.activitiesById) ? value.activitiesById : {};
6066
- const activitiesById = {};
6067
- for (const [activityId, rawActivity] of Object.entries(rawActivities)) {
6068
- if (activityId.trim() && isPlayActivityObservation(rawActivity) && rawActivity.activityId === activityId) {
6069
- activitiesById[activityId] = rawActivity;
6070
- }
6071
- }
6072
- const createdAt = finiteNumber(value.createdAt) ?? fallback.createdAt ?? null;
6073
- const startedAt = finiteNumber(value.startedAt) ?? fallback.startedAt ?? null;
6074
- const finishedAt = finiteNumber(value.finishedAt) ?? fallback.finishedAt ?? null;
6075
- const updatedAt = finiteNumber(value.updatedAt) ?? fallback.updatedAt ?? finishedAt ?? startedAt ?? createdAt ?? null;
6076
- const error = Object.prototype.hasOwnProperty.call(value, "error") ? optionalNullableString(value.error) ?? null : fallback.error ?? null;
6077
- const rawTail = Array.isArray(value.logTail) ? value.logTail : value.logs;
6078
- const logTail = Array.isArray(rawTail) ? rawTail.filter((line) => typeof line === "string") : [];
6079
- const workCounters = normalizeWorkCounters(value.workCounters);
6080
- const terminalWorkCounterSegment = normalizePlayRunLedgerTerminalWorkCounterSegment(
6081
- value.terminalWorkCounterSegment
6082
- );
6083
- return {
6084
- runId: optionalString(value.runId) ?? fallback.runId,
6085
- playName: optionalNullableString(value.playName) ?? fallback.playName ?? null,
6086
- status: normalizePlayRunLedgerStatus(value.status ?? fallback.status),
6087
- waitKind: optionalNullableString(value.waitKind),
6088
- waitUntil: finiteNumber(value.waitUntil),
6089
- error,
6090
- createdAt,
6091
- startedAt,
6092
- updatedAt,
6093
- finishedAt,
6094
- durationMs: startedAt !== null && finishedAt !== null ? Math.max(0, finishedAt - startedAt) : finiteNumber(value.durationMs),
6095
- orderedStepIds: orderedStepIds.filter((stepId) => stepsById[stepId]),
6096
- stepsById,
6097
- orderedDatasetIds: (Array.isArray(value.orderedDatasetIds) ? value.orderedDatasetIds : Object.keys(datasetsById)).filter(
6098
- (datasetId) => typeof datasetId === "string" && Boolean(datasetsById[datasetId])
6099
- ),
6100
- datasetsById,
6101
- orderedActivityIds: (Array.isArray(value.orderedActivityIds) ? value.orderedActivityIds : Object.keys(activitiesById)).filter(
6102
- (activityId) => typeof activityId === "string" && Boolean(activitiesById[activityId])
6103
- ),
6104
- activitiesById,
6105
- ...workCounters ? { workCounters } : {},
6106
- ...terminalWorkCounterSegment ? { terminalWorkCounterSegment } : {},
6107
- logTail: logTail.slice(-LOG_TAIL_LIMIT),
6108
- // Snapshots persisted before totalLogCount existed only know the retained
6109
- // tail, so the best lower bound for the cumulative count is the tail size.
6110
- totalLogCount: Math.max(
6111
- finiteNumber(value.totalLogCount) ?? logTail.length,
6112
- logTail.length
6113
- ),
6114
- // A persisted snapshot carrying more lines than the tail keeps is
6115
- // truncated here, whatever the stored flag says. Reporting `false` while
6116
- // dropping lines is silent loss: a reader would take the tail for the
6117
- // whole log.
6118
- logsTruncated: value.logsTruncated === true || logTail.length > LOG_TAIL_LIMIT,
6119
- activeStepId: optionalNullableString(value.activeStepId),
6120
- activeActivityId: optionalNullableString(value.activeActivityId),
6121
- activeArtifactTableNamespace: optionalNullableString(
6122
- value.activeArtifactTableNamespace
6123
- ),
6124
- resultTableNamespace: optionalNullableString(value.resultTableNamespace),
6125
- resultSummary: value.resultSummary,
6126
- result: value.result,
6127
- terminalSource: normalizePlayRunLedgerTerminalSource(value.terminalSource)
6128
- };
6129
- }
6130
- function normalizeStepStatus(value) {
6131
- const normalized = String(value ?? "").trim().toLowerCase();
6132
- if (normalized === "running" || normalized === "completed" || normalized === "failed" || normalized === "skipped") {
6133
- return normalized;
6134
- }
6135
- return null;
6136
- }
6137
- function normalizeStepProgress(value) {
6138
- return {
6139
- ...optionalFiniteNumber(value.completed) !== void 0 ? { completed: optionalFiniteNumber(value.completed) } : {},
6140
- ...optionalFiniteNumber(value.total) !== void 0 ? { total: optionalFiniteNumber(value.total) } : {},
6141
- ...optionalFiniteNumber(value.failed) !== void 0 ? { failed: optionalFiniteNumber(value.failed) } : {},
6142
- ...optionalFiniteNumber(value.startedRows) !== void 0 ? { startedRows: optionalFiniteNumber(value.startedRows) } : {},
6143
- ...optionalFiniteNumber(value.activeRows) !== void 0 ? { activeRows: optionalFiniteNumber(value.activeRows) } : {},
6144
- ...optionalFiniteNumber(value.waitingRows) !== void 0 ? { waitingRows: optionalFiniteNumber(value.waitingRows) } : {},
6145
- ...optionalFiniteNumber(value.completedRows) !== void 0 ? { completedRows: optionalFiniteNumber(value.completedRows) } : {},
6146
- ...optionalFiniteNumber(value.supersededRows) !== void 0 ? { supersededRows: optionalFiniteNumber(value.supersededRows) } : {},
6147
- ...optionalString(value.message) ? { message: optionalString(value.message) } : {},
6148
- ...optionalNullableString(value.artifactTableNamespace) !== void 0 ? {
6149
- artifactTableNamespace: optionalNullableString(
6150
- value.artifactTableNamespace
6151
- )
6152
- } : {},
6153
- ...finiteNumber(value.startedAt) !== null ? { startedAt: finiteNumber(value.startedAt) } : {},
6154
- ...finiteNumber(value.completedAt) !== null ? { completedAt: finiteNumber(value.completedAt) } : {},
6155
- ...finiteNumber(value.updatedAt) !== null ? { updatedAt: finiteNumber(value.updatedAt) } : {},
6156
- ...normalizePlayDocflowNodeIoState(value.nodeIo) ? { nodeIo: normalizePlayDocflowNodeIoState(value.nodeIo) } : {}
6157
- };
6158
- }
6159
5149
 
6160
5150
  // ../play-runtime/run-lifecycle-policy.ts
6161
5151
  var TERMINAL_PLAY_RUN_STATUSES = /* @__PURE__ */ new Set([
@@ -6271,9 +5261,6 @@ function readProvenanceTag(line) {
6271
5261
  const provenance = LOG_PROVENANCE_CLASSES.includes(candidate) ? candidate : null;
6272
5262
  return { provenance, line: line.slice(end + 1) };
6273
5263
  }
6274
- function stripProvenanceTag(line) {
6275
- return readProvenanceTag(line).line;
6276
- }
6277
5264
  function classifyLegacyLogLine(line) {
6278
5265
  const message = stripLeadingTimestamp(line);
6279
5266
  if (/recovered (?:from checkpoint|response from checkpoint)/i.test(message)) {
@@ -6346,143 +5333,9 @@ function stripLeadingTimestamp(line) {
6346
5333
  }
6347
5334
 
6348
5335
  // ../play-runtime/run-snapshot-stream.ts
6349
- function normalizePlayRunLiveStatus(value) {
6350
- return normalizePlayRunLifecycleStatus(value);
6351
- }
6352
5336
  function isTerminalPlayRunLiveStatus(status) {
6353
5337
  return isTerminalPlayRunLifecycleStatus(status);
6354
5338
  }
6355
- function isRecord7(value) {
6356
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
6357
- }
6358
- function finiteNumber2(value) {
6359
- return typeof value === "number" && Number.isFinite(value) ? value : null;
6360
- }
6361
- function extractTerminalRunLogTail(result) {
6362
- if (!isRecord7(result) || !isRecord7(result._metadata)) {
6363
- return null;
6364
- }
6365
- const runLogTail = result._metadata.runLogTail;
6366
- if (!isRecord7(runLogTail) || !Array.isArray(runLogTail.tail)) {
6367
- return null;
6368
- }
6369
- const logTail = runLogTail.tail.filter(
6370
- (line) => typeof line === "string" && line.trim().length > 0
6371
- );
6372
- if (logTail.length === 0) {
6373
- return null;
6374
- }
6375
- const totalLogCount = Math.max(
6376
- finiteNumber2(runLogTail.totalLogCount) ?? logTail.length,
6377
- logTail.length
6378
- );
6379
- return {
6380
- logTail: logTail.slice(-LOG_TAIL_LIMIT),
6381
- totalLogCount
6382
- };
6383
- }
6384
- function buildSnapshotFromLedger(snapshot) {
6385
- const nodeStates = snapshot.orderedStepIds.map((stepId) => snapshot.stepsById[stepId]).filter((step) => Boolean(step)).map((step) => ({
6386
- nodeId: step.stepId,
6387
- status: step.status,
6388
- error: step.error ?? null,
6389
- artifactTableNamespace: step.artifactTableNamespace ?? null,
6390
- progress: step.progress ? {
6391
- completed: step.progress.completed,
6392
- total: step.progress.total,
6393
- failed: step.progress.failed,
6394
- startedRows: step.progress.startedRows,
6395
- activeRows: step.progress.activeRows,
6396
- waitingRows: step.progress.waitingRows,
6397
- completedRows: step.progress.completedRows,
6398
- supersededRows: step.progress.supersededRows,
6399
- message: step.progress.message,
6400
- artifactTableNamespace: step.progress.artifactTableNamespace ?? step.artifactTableNamespace ?? null,
6401
- startedAt: step.startedAt ?? null,
6402
- completedAt: step.completedAt ?? null,
6403
- updatedAt: step.progress.updatedAt ?? step.updatedAt ?? null,
6404
- nodeIo: step.progress.nodeIo
6405
- } : null,
6406
- startedAt: step.startedAt ?? null,
6407
- completedAt: step.completedAt ?? null,
6408
- updatedAt: step.updatedAt ?? null,
6409
- ...step.progress?.nodeIo ? { nodeIo: step.progress.nodeIo } : {}
6410
- }));
6411
- const liveStatus = normalizePlayRunLiveStatus(snapshot.status);
6412
- const terminalRowOutcomes = isTerminalPlayRunLiveStatus(liveStatus) ? summarizeRunRowOutcomes(snapshot) : null;
6413
- const rowOutcomes = terminalRowOutcomes && (Object.keys(snapshot.stepsById).length > 0 || terminalRowOutcomes.totalRows > 0 || (terminalRowOutcomes.supersededRows ?? 0) > 0) ? terminalRowOutcomes : null;
6414
- const workCounters = snapshot.workCounters;
6415
- const calls = workCounters ? {
6416
- logicalCalls: workCounters.completedLogicalCalls + workCounters.logicalCalls,
6417
- providerRequests: workCounters.completedProviderRequests + workCounters.providerRequests,
6418
- provider429s: workCounters.completedProvider429s + workCounters.provider429s,
6419
- confirmed: isTerminalPlayRunLiveStatus(liveStatus) && hasConfirmedPlayRunLedgerWorkCounters(snapshot)
6420
- } : null;
6421
- return {
6422
- runId: snapshot.runId,
6423
- status: liveStatus,
6424
- createdAt: snapshot.createdAt ?? null,
6425
- startedAt: snapshot.startedAt ?? null,
6426
- finishedAt: snapshot.finishedAt ?? null,
6427
- durationMs: snapshot.durationMs ?? null,
6428
- updatedAt: snapshot.updatedAt ?? snapshot.finishedAt ?? snapshot.startedAt ?? null,
6429
- // This snapshot is public SDK/API transport. Keep the historical plain
6430
- // timestamp-prefixed text while provenance remains runtime metadata.
6431
- logs: snapshot.logTail.map(stripProvenanceTag),
6432
- totalLogCount: snapshot.totalLogCount,
6433
- ...snapshot.logsTruncated ? { logsTruncated: true } : {},
6434
- activeArtifactTableNamespace: snapshot.activeArtifactTableNamespace ?? null,
6435
- resultTableNamespace: snapshot.resultTableNamespace ?? null,
6436
- datasets: snapshot.orderedDatasetIds.map((datasetId) => snapshot.datasetsById[datasetId]).filter(
6437
- (dataset) => Boolean(dataset)
6438
- ),
6439
- activities: snapshot.orderedActivityIds.map((activityId) => snapshot.activitiesById[activityId]).filter(
6440
- (activity) => Boolean(activity)
6441
- ),
6442
- activeActivity: snapshot.activeActivityId ? snapshot.activitiesById[snapshot.activeActivityId] ?? null : null,
6443
- nodeStates,
6444
- activeNodeId: snapshot.activeStepId ?? null,
6445
- ...rowOutcomes ? { rowOutcomes } : {},
6446
- ...calls && Object.values(calls).every(
6447
- (value) => typeof value === "boolean" || Number.isSafeInteger(value)
6448
- ) ? { calls } : {}
6449
- };
6450
- }
6451
- function buildPlayRunStatusSnapshot(input2) {
6452
- const ledgerSnapshot = normalizePlayRunLedgerSnapshot(input2.run.runSnapshot, {
6453
- runId: input2.run.workflowId,
6454
- playName: input2.run.name ?? null,
6455
- status: input2.run.status,
6456
- createdAt: input2.run.createdAt ?? null,
6457
- startedAt: input2.run.startedAt ?? null,
6458
- updatedAt: input2.run.updatedAt ?? null,
6459
- finishedAt: input2.run.finishedAt ?? null
6460
- });
6461
- const terminalRunLogTail = extractTerminalRunLogTail(input2.run.result);
6462
- const projectedSnapshot = terminalRunLogTail && terminalRunLogTail.totalLogCount > ledgerSnapshot.totalLogCount ? buildSnapshotFromLedger({
6463
- ...ledgerSnapshot,
6464
- logTail: terminalRunLogTail.logTail,
6465
- totalLogCount: terminalRunLogTail.totalLogCount
6466
- }) : buildSnapshotFromLedger(ledgerSnapshot);
6467
- const activity = projectPlayRunActivity({
6468
- runId: input2.run.workflowId,
6469
- playName: input2.run.name,
6470
- status: projectedSnapshot.status,
6471
- updatedAt: projectedSnapshot.updatedAt,
6472
- waitKind: input2.run.waitKind ?? input2.run.wait?.kind ?? null,
6473
- waitUntil: input2.run.waitUntil,
6474
- eventKey: input2.run.wait?.eventKey ?? null,
6475
- runtimeBackend: input2.run.runtimeBackend,
6476
- activeNodeId: input2.run.activeBoundaryId ?? projectedSnapshot.activeNodeId,
6477
- nodeStates: projectedSnapshot.nodeStates,
6478
- datasets: projectedSnapshot.datasets,
6479
- explicit: projectedSnapshot.activities
6480
- });
6481
- return {
6482
- ...projectedSnapshot,
6483
- activity
6484
- };
6485
- }
6486
5339
  function makeRunStreamEvent(input2) {
6487
5340
  return {
6488
5341
  ...input2,
@@ -6565,7 +5418,7 @@ function diffLogLines(input2) {
6565
5418
  const missingCount = tailFirstSeq - 1 - input2.lastLogSeq;
6566
5419
  return {
6567
5420
  lines: [
6568
- `[stream] ${missingCount} log lines not retained in the live window; full logs via runs logs`,
5421
+ `[watch] ${missingCount} log lines not retained in the live window; full logs via runs logs`,
6569
5422
  ...logs
6570
5423
  ],
6571
5424
  lastLogSeq: totalLogCount,
@@ -6711,310 +5564,156 @@ function diffPlayRunStreamEvents(input2) {
6711
5564
  return { events, next };
6712
5565
  }
6713
5566
 
6714
- // src/runs/observe-transport.ts
6715
- var RunObserveTransportUnavailableError = class extends Error {
6716
- constructor(message, reason) {
6717
- super(message);
6718
- this.reason = reason;
6719
- this.name = "RunObserveTransportUnavailableError";
5567
+ // src/stream-reconnect.ts
5568
+ function isTransientPlayRunReadError(error) {
5569
+ if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
5570
+ return true;
6720
5571
  }
6721
- };
6722
- var OBSERVE_BOOTSTRAP_TIMEOUT_MS = 1e4;
6723
- var OBSERVE_RECONNECT_NOTICE_MS = 1e4;
6724
- var OBSERVE_STALE_WARNING_MS = 12e4;
6725
- var OBSERVE_WATCHDOG_TICK_MS = 5e3;
6726
- var GRANT_REFRESH_MARGIN_MS = 5 * 6e4;
6727
- var BACKFILL_PAGE_LIMIT = 1e3;
6728
- var BACKFILL_MAX_PAGES = 30;
6729
- var OBSERVER_SNAPSHOT_QUERY = "runObservers:getPlayRunSnapshotForObserver";
6730
- var OBSERVER_LOG_PAGE_QUERY = "runObservers:getRunLogPageForObserver";
6731
- function errorText(error) {
6732
- return error instanceof Error ? error.message : String(error);
5572
+ if (error instanceof DeeplineError && typeof error.statusCode === "number") {
5573
+ return error.statusCode >= 500 && error.statusCode < 600;
5574
+ }
5575
+ const text = error instanceof Error ? error.message : String(error);
5576
+ 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(
5577
+ text
5578
+ );
6733
5579
  }
6734
- async function mintRunObserveGrant(http, runId) {
6735
- let response;
6736
- try {
6737
- response = await http.post(
6738
- `/api/v2/runs/${encodeURIComponent(runId)}/observe-grant`,
6739
- {}
6740
- );
6741
- } catch (error) {
6742
- if (error instanceof DeeplineError) {
6743
- if (error.statusCode === 401 || error.statusCode === 403) {
6744
- throw error;
6745
- }
6746
- throw new RunObserveTransportUnavailableError(
6747
- `observe-grant endpoint unavailable (${error.statusCode ?? "network"}): ${error.message}`,
6748
- "grant_endpoint_unavailable"
6749
- );
6750
- }
6751
- throw new RunObserveTransportUnavailableError(
6752
- `observe-grant request failed: ${errorText(error)}`,
6753
- "grant_request_failed"
6754
- );
5580
+
5581
+ // src/runs/watch-polling.ts
5582
+ var RUN_WATCH_POLL_INTERVAL_MS = 2e3;
5583
+ function waitForNextPoll(ms, signal) {
5584
+ if (signal?.aborted) {
5585
+ return Promise.resolve(false);
6755
5586
  }
6756
- const grant = response;
6757
- if (!grant || typeof grant.convexUrl !== "string" || !grant.convexUrl.trim() || typeof grant.token !== "string" || !grant.token.trim() || typeof grant.expiresAt !== "number") {
6758
- throw new RunObserveTransportUnavailableError(
6759
- "observe-grant endpoint returned an invalid grant payload.",
6760
- "grant_payload_invalid"
6761
- );
5587
+ return new Promise((resolve22) => {
5588
+ const finish = (elapsed) => {
5589
+ clearTimeout(timeout);
5590
+ signal?.removeEventListener("abort", onAbort);
5591
+ resolve22(elapsed);
5592
+ };
5593
+ const onAbort = () => finish(false);
5594
+ const timeout = setTimeout(() => finish(true), ms);
5595
+ signal?.addEventListener("abort", onAbort, { once: true });
5596
+ });
5597
+ }
5598
+ function readSnapshotResponse(response, runId) {
5599
+ if (!response || typeof response !== "object" || Array.isArray(response)) {
5600
+ throw new Error("Run watch returned an invalid snapshot response.");
5601
+ }
5602
+ const record3 = response;
5603
+ const snapshot = record3.snapshot;
5604
+ if (record3.runId !== runId || !snapshot || typeof snapshot !== "object" || Array.isArray(snapshot) || snapshot.runId !== runId || typeof snapshot.status !== "string" || !Array.isArray(snapshot.logs) || !snapshot.logs.every(
5605
+ (line) => typeof line === "string"
5606
+ ) || typeof snapshot.totalLogCount !== "number" || !Array.isArray(snapshot.nodeStates)) {
5607
+ throw new Error(`Run watch returned an invalid snapshot for ${runId}.`);
6762
5608
  }
6763
- return grant;
5609
+ return { runId, snapshot };
6764
5610
  }
6765
- async function backfillLogGap(input2) {
5611
+ async function backfillRotatedLogTail(input2) {
5612
+ if (!input2.previous.runSignature) {
5613
+ return input2.snapshot;
5614
+ }
5615
+ const gap = resolvePlayRunLogGap(input2.snapshot, input2.previous.lastLogSeq);
5616
+ if (!gap) {
5617
+ return input2.snapshot;
5618
+ }
6766
5619
  const lines = [];
6767
- let cursor = input2.lastLogSeq;
6768
- for (let page = 0; page < BACKFILL_MAX_PAGES; page += 1) {
6769
- if (cursor >= input2.tailFirstSeq - 1) {
6770
- break;
6771
- }
6772
- let logPage;
6773
- try {
6774
- logPage = await input2.queryLogPage(
6775
- cursor,
6776
- Math.min(BACKFILL_PAGE_LIMIT, input2.tailFirstSeq - 1 - cursor)
6777
- );
6778
- } catch {
6779
- return null;
6780
- }
6781
- const entries = (logPage?.entries ?? []).filter(
6782
- (entry) => entry.seq > cursor && entry.seq < input2.tailFirstSeq
5620
+ let cursor = input2.previous.lastLogSeq;
5621
+ const targetSeq = gap.tailFirstSeq - 1;
5622
+ while (cursor < targetSeq) {
5623
+ const limit = Math.min(1e3, targetSeq - cursor);
5624
+ const page = await input2.http.get(
5625
+ `/api/v2/runs/${encodeURIComponent(input2.runId)}/logs?afterSeq=${cursor}&limit=${limit}`,
5626
+ { signal: input2.signal }
6783
5627
  );
6784
- if (entries.length === 0) {
6785
- break;
5628
+ if (!page || !Array.isArray(page.entries) || page.entries.length === 0) {
5629
+ return input2.snapshot;
6786
5630
  }
6787
- for (const entry of entries) {
6788
- if (entry.seq !== cursor + 1) {
6789
- return null;
5631
+ for (const entry of page.entries) {
5632
+ if (!entry || entry.seq !== cursor + 1 || typeof entry.line !== "string") {
5633
+ return input2.snapshot;
6790
5634
  }
6791
5635
  lines.push(entry.line);
6792
5636
  cursor = entry.seq;
6793
5637
  }
6794
5638
  }
6795
- if (cursor < input2.tailFirstSeq - 1) {
6796
- return null;
5639
+ if (cursor !== targetSeq) {
5640
+ return input2.snapshot;
6797
5641
  }
6798
- return lines;
5642
+ return { ...input2.snapshot, logs: [...lines, ...input2.snapshot.logs] };
6799
5643
  }
6800
- async function* observeRunEvents(options) {
6801
- const { http, runId } = options;
6802
- let grant = await mintRunObserveGrant(http, runId);
6803
- let convexBrowser;
6804
- let convexServer;
6805
- try {
6806
- convexBrowser = await import("convex/browser");
6807
- convexServer = await import("convex/server");
6808
- } catch (error) {
6809
- throw new RunObserveTransportUnavailableError(
6810
- `convex client module unavailable: ${errorText(error)}`,
6811
- "convex_module_unavailable"
6812
- );
6813
- }
6814
- let webSocketConstructor;
6815
- if (typeof WebSocket === "undefined") {
5644
+ async function* watchRunEvents(options) {
5645
+ const { http, runId, signal } = options;
5646
+ const path = `/api/v2/runs/${encodeURIComponent(runId)}?watchSnapshot=true`;
5647
+ const streamId = `play-run-watch:${runId}`;
5648
+ const pollIntervalMs = options.pollIntervalMs ?? RUN_WATCH_POLL_INTERVAL_MS;
5649
+ let previous = EMPTY_PLAY_RUN_STREAM_DIFF_STATE;
5650
+ let consecutiveFailures = 0;
5651
+ let outageNoticeSent = false;
5652
+ while (!signal?.aborted) {
5653
+ const pollStartedAt = Date.now();
5654
+ let snapshot;
6816
5655
  try {
6817
- const wsModuleName = "ws";
6818
- const ws = await import(wsModuleName);
6819
- webSocketConstructor = ws.default;
6820
- } catch (error) {
6821
- throw new RunObserveTransportUnavailableError(
6822
- `no WebSocket implementation available: ${errorText(error)}`,
6823
- "websocket_unavailable"
6824
- );
6825
- }
6826
- }
6827
- const snapshotQuery = convexServer.makeFunctionReference(
6828
- OBSERVER_SNAPSHOT_QUERY
6829
- );
6830
- const logPageQuery = convexServer.makeFunctionReference(
6831
- OBSERVER_LOG_PAGE_QUERY
6832
- );
6833
- const client2 = new convexBrowser.ConvexClient(grant.convexUrl, {
6834
- ...webSocketConstructor ? { webSocketConstructor } : {},
6835
- unsavedChangesWarning: false
6836
- });
6837
- const queue = [];
6838
- let wake = null;
6839
- const push = (item) => {
6840
- queue.push(item);
6841
- wake?.();
6842
- wake = null;
6843
- };
6844
- let lastForcedRefreshAt = 0;
6845
- client2.setAuth(async ({ forceRefreshToken }) => {
6846
- const now = Date.now();
6847
- if (!forceRefreshToken && grant.expiresAt - now > GRANT_REFRESH_MARGIN_MS) {
6848
- return grant.token;
6849
- }
6850
- if (forceRefreshToken && now - lastForcedRefreshAt < 5e3) {
6851
- push({
6852
- kind: "error",
6853
- error: new DeeplineError(
6854
- `Run observe grant for ${runId} was rejected after a re-mint. The server and Convex deployment disagree on the grant issuer/JWKS.`,
6855
- 401,
6856
- "RUN_OBSERVE_GRANT_REJECTED"
6857
- )
5656
+ const response = await http.get(path, { signal });
5657
+ snapshot = await backfillRotatedLogTail({
5658
+ http,
5659
+ runId,
5660
+ snapshot: readSnapshotResponse(response, runId).snapshot,
5661
+ previous,
5662
+ signal
6858
5663
  });
6859
- return null;
6860
- }
6861
- if (forceRefreshToken) {
6862
- lastForcedRefreshAt = now;
6863
- }
6864
- try {
6865
- grant = await mintRunObserveGrant(http, runId);
6866
- return grant.token;
6867
5664
  } catch (error) {
6868
- push({ kind: "error", error });
6869
- return null;
6870
- }
6871
- });
6872
- const unsubscribe = client2.onUpdate(
6873
- snapshotQuery,
6874
- { workflowId: runId },
6875
- (run) => push({ kind: "run", run: run ?? null }),
6876
- (error) => push({ kind: "error", error })
6877
- );
6878
- let lastUpdateAt = Date.now();
6879
- let lastStatusTerminal = false;
6880
- let disconnectedSince = null;
6881
- let warnedReconnecting = false;
6882
- let warnedStale = false;
6883
- const watchdog = setInterval(() => {
6884
- const now = Date.now();
6885
- try {
6886
- const connectionState = client2.connectionState();
6887
- if (connectionState.isWebSocketConnected) {
6888
- disconnectedSince = null;
6889
- warnedReconnecting = false;
6890
- } else {
6891
- disconnectedSince ??= now;
6892
- if (!warnedReconnecting && now - disconnectedSince >= OBSERVE_RECONNECT_NOTICE_MS) {
6893
- warnedReconnecting = true;
6894
- options.onNotice?.(
6895
- `[observe] connection lost; reconnecting to live run ${runId}\u2026`
6896
- );
6897
- }
6898
- }
6899
- } catch {
6900
- }
6901
- if (!lastStatusTerminal && !warnedStale && now - lastUpdateAt >= OBSERVE_STALE_WARNING_MS) {
6902
- warnedStale = true;
6903
- options.onNotice?.(
6904
- `[observe] no live updates for ${Math.round((now - lastUpdateAt) / 1e3)}s; run ${runId} may be stalled (status checks continue)`
6905
- );
6906
- }
6907
- }, OBSERVE_WATCHDOG_TICK_MS);
6908
- watchdog.unref?.();
6909
- const abortListener = () => push({
6910
- kind: "error",
6911
- error: new DeeplineError(
6912
- "Run observation aborted.",
6913
- void 0,
6914
- "ABORTED"
6915
- )
6916
- });
6917
- options.signal?.addEventListener("abort", abortListener, { once: true });
6918
- let diffState = EMPTY_PLAY_RUN_STREAM_DIFF_STATE;
6919
- const streamId = ["observe", runId].join(":");
6920
- let sawFirstSnapshot = false;
6921
- try {
6922
- for (; ; ) {
6923
- if (queue.length === 0) {
6924
- const waitForItem = new Promise((resolve22) => {
6925
- wake = resolve22;
6926
- });
6927
- if (!sawFirstSnapshot) {
6928
- const timedOut = await Promise.race([
6929
- waitForItem.then(() => false),
6930
- new Promise(
6931
- (resolve22) => setTimeout(() => resolve22(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
6932
- )
6933
- ]);
6934
- if (timedOut && queue.length === 0) {
6935
- throw new RunObserveTransportUnavailableError(
6936
- `no snapshot from Convex at ${grant.convexUrl} within ${OBSERVE_BOOTSTRAP_TIMEOUT_MS}ms`,
6937
- "convex_unreachable"
6938
- );
6939
- }
6940
- } else {
6941
- await waitForItem;
6942
- }
6943
- continue;
6944
- }
6945
- const item = queue.shift();
6946
- if (item.kind === "error") {
6947
- if (options.signal?.aborted) {
6948
- return;
6949
- }
6950
- throw item.error;
5665
+ if (signal?.aborted) {
5666
+ return;
6951
5667
  }
6952
- sawFirstSnapshot = true;
6953
- lastUpdateAt = Date.now();
6954
- warnedStale = false;
6955
- if (item.run === null) {
6956
- throw new DeeplineError(
6957
- `Run ${runId} was not found (or is not visible to this grant).`,
6958
- 404,
6959
- "RUN_NOT_FOUND"
6960
- );
5668
+ if (!isTransientPlayRunReadError(error)) {
5669
+ throw error;
6961
5670
  }
6962
- const snapshot = buildPlayRunStatusSnapshot({ run: item.run });
6963
- lastStatusTerminal = isTerminalPlayRunLiveStatus(snapshot.status);
6964
- const gap = resolvePlayRunLogGap(snapshot, diffState.lastLogSeq);
6965
- if (gap && diffState.lastLogSeq > 0) {
6966
- const backfilled = await backfillLogGap({
6967
- queryLogPage: (afterSeq, limit) => client2.query(logPageQuery, {
6968
- workflowId: runId,
6969
- afterSeq,
6970
- limit
6971
- }),
6972
- lastLogSeq: diffState.lastLogSeq,
6973
- tailFirstSeq: gap.tailFirstSeq
5671
+ consecutiveFailures += 1;
5672
+ const reason = error instanceof Error ? error.message : String(error);
5673
+ if (!outageNoticeSent) {
5674
+ options.onRetry?.({
5675
+ attempt: consecutiveFailures,
5676
+ delayMs: pollIntervalMs,
5677
+ reason
6974
5678
  });
6975
- if (backfilled && backfilled.length > 0) {
6976
- yield {
6977
- cursor: String(snapshot.updatedAt ?? Date.now()),
6978
- streamId,
6979
- scope: "play",
6980
- type: "play.run.log",
6981
- at: (/* @__PURE__ */ new Date()).toISOString(),
6982
- payload: {
6983
- runId: snapshot.runId,
6984
- lines: backfilled,
6985
- source: "worker",
6986
- firstSeq: diffState.lastLogSeq + 1,
6987
- totalLogCount: snapshot.totalLogCount
6988
- }
6989
- };
6990
- diffState = { ...diffState, lastLogSeq: gap.tailFirstSeq - 1 };
6991
- }
6992
- }
6993
- const { events, next } = diffPlayRunStreamEvents({
6994
- streamId,
6995
- snapshot,
6996
- previous: diffState
6997
- });
6998
- diffState = next;
6999
- const ordered = [
7000
- ...events.filter((event) => event.type === "play.run.snapshot"),
7001
- ...events.filter((event) => event.type !== "play.run.snapshot")
7002
- ];
7003
- for (const event of ordered) {
7004
- yield event;
5679
+ options.onNotice?.(
5680
+ `[watch] run snapshot request failed; retrying every ${pollIntervalMs / 1e3}s (${reason})`
5681
+ );
5682
+ outageNoticeSent = true;
7005
5683
  }
7006
- if (lastStatusTerminal) {
5684
+ const remaining2 = Math.max(
5685
+ 0,
5686
+ pollIntervalMs - (Date.now() - pollStartedAt)
5687
+ );
5688
+ if (!await waitForNextPoll(remaining2, signal)) {
7007
5689
  return;
7008
5690
  }
5691
+ continue;
7009
5692
  }
7010
- } finally {
7011
- clearInterval(watchdog);
7012
- options.signal?.removeEventListener("abort", abortListener);
7013
- try {
7014
- unsubscribe();
7015
- } catch {
5693
+ if (outageNoticeSent) {
5694
+ options.onNotice?.("[watch] run snapshot polling recovered");
5695
+ outageNoticeSent = false;
5696
+ }
5697
+ consecutiveFailures = 0;
5698
+ const diff = diffPlayRunStreamEvents({
5699
+ streamId,
5700
+ snapshot,
5701
+ previous
5702
+ });
5703
+ previous = diff.next;
5704
+ for (const event of diff.events) {
5705
+ yield event;
5706
+ }
5707
+ if (isTerminalPlayRunLiveStatus(snapshot.status)) {
5708
+ return;
5709
+ }
5710
+ const remaining = Math.max(
5711
+ 0,
5712
+ pollIntervalMs - (Date.now() - pollStartedAt)
5713
+ );
5714
+ if (!await waitForNextPoll(remaining, signal)) {
5715
+ return;
7016
5716
  }
7017
- await client2.close().catch(() => void 0);
7018
5717
  }
7019
5718
  }
7020
5719
 
@@ -7345,7 +6044,7 @@ function requireTargetBillingIdempotencyKey(value) {
7345
6044
  }
7346
6045
  return normalized;
7347
6046
  }
7348
- function isRecord8(value) {
6047
+ function isRecord4(value) {
7349
6048
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
7350
6049
  }
7351
6050
  function isPrebuiltPlayDescription(play) {
@@ -7377,10 +6076,10 @@ function normalizePlayStatus(raw) {
7377
6076
  return {
7378
6077
  ...raw,
7379
6078
  runId,
7380
- ...isRecord8(legacyOverview) ? {
6079
+ ...isRecord4(legacyOverview) ? {
7381
6080
  overview: legacyOverview
7382
6081
  } : {},
7383
- ...isRecord8(runStatus) ? { runStatus } : {},
6082
+ ...isRecord4(runStatus) ? { runStatus } : {},
7384
6083
  ...runPackage ? {
7385
6084
  package: runPackage,
7386
6085
  outputs: runPackage.outputs
@@ -7519,7 +6218,7 @@ function updatePlayLiveStatusState(state, event) {
7519
6218
  }
7520
6219
  const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : isPlayRunPackage(payload) ? payload.run.id : state.runId;
7521
6220
  const status = normalizeLiveStatus(payload.status) ?? (isPlayRunPackage(payload) ? normalizeLiveStatus(payload.run.status) : null) ?? state.status;
7522
- const progressPayload = isRecord8(payload.progress) ? payload.progress : {};
6221
+ const progressPayload = isRecord4(payload.progress) ? payload.progress : {};
7523
6222
  if (event.type === "play.run.final_status" && state.logs.length === 0 && state.lastLogSeq === 0) {
7524
6223
  const payloadLogs = readStringArray(payload.logs);
7525
6224
  const progressLogs = readStringArray(progressPayload.logs);
@@ -7598,6 +6297,7 @@ var DeeplineClient = class _DeeplineClient {
7598
6297
  status: (runId) => this.getRunLifecycleStatus(runId),
7599
6298
  list: (options2) => this.listRuns(options2),
7600
6299
  listPage: (options2) => this.listRunsPage(options2),
6300
+ watch: (runId, options2) => this.watchRunToTerminal(runId, options2),
7601
6301
  tail: (runId, options2) => this.tailRun(runId, options2),
7602
6302
  logs: (runId, options2) => this.getRunLogs(runId, options2),
7603
6303
  input: (runId) => this.getRunInput(runId),
@@ -7720,9 +6420,9 @@ var DeeplineClient = class _DeeplineClient {
7720
6420
  return fields2.length > 0 ? { fields: fields2 } : schema;
7721
6421
  }
7722
6422
  schemaMetadata(schema, key) {
7723
- if (!isRecord8(schema)) return null;
6423
+ if (!isRecord4(schema)) return null;
7724
6424
  const value = schema[key];
7725
- return isRecord8(value) ? value : null;
6425
+ return isRecord4(value) ? value : null;
7726
6426
  }
7727
6427
  playRunCommand(play, options) {
7728
6428
  const target = play.reference || play.name;
@@ -7777,7 +6477,7 @@ var DeeplineClient = class _DeeplineClient {
7777
6477
  aliases,
7778
6478
  inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
7779
6479
  outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
7780
- staticPipeline: isRecord8(play.staticPipeline) ? play.staticPipeline : isRecord8(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord8(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
6480
+ staticPipeline: isRecord4(play.staticPipeline) ? play.staticPipeline : isRecord4(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord4(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
7781
6481
  ...csvInput ? { csvInput } : {},
7782
6482
  ...rowOutputSchema ? { rowOutputSchema } : {},
7783
6483
  runCommand: runCommand2,
@@ -8137,15 +6837,17 @@ var DeeplineClient = class _DeeplineClient {
8137
6837
  return normalizePlayRunStart(response);
8138
6838
  }
8139
6839
  /**
8140
- * Start a play run and stream live runtime events from the same request.
6840
+ * Submit a play run through the legacy event response.
8141
6841
  *
8142
- * Use this when a caller wants low-level event handling instead of submitting
8143
- * first and then connecting to `streamPlayRunEvents(runId)`.
6842
+ * This reports admission from the start request; it does not watch an
6843
+ * existing run. Use `startPlayRun()` and `watchRunEvents(runId)` separately.
6844
+ *
6845
+ * @deprecated Use the separate start and watch methods.
8144
6846
  *
8145
6847
  * @param request - Play run configuration.
8146
- * @param options - Optional streaming options.
8147
- * @param options.signal - Optional abort signal for the streaming request.
8148
- * @returns Async stream of play-scoped live events.
6848
+ * @param options - Optional compatibility response options.
6849
+ * @param options.signal - Abort the start response.
6850
+ * @returns Async generator of play-scoped live events.
8149
6851
  */
8150
6852
  async *startPlayRunStream(request, options) {
8151
6853
  const integrationMode = resolvePlayRunIntegrationMode(request);
@@ -8627,11 +7329,23 @@ var DeeplineClient = class _DeeplineClient {
8627
7329
  );
8628
7330
  return normalizePlayStatus(response);
8629
7331
  }
7332
+ /** Poll authenticated run snapshots every two seconds and emit changed events. */
7333
+ async *watchRunEvents(workflowId, options) {
7334
+ for await (const event of watchRunEvents({
7335
+ http: this.http,
7336
+ runId: workflowId,
7337
+ signal: options?.signal,
7338
+ onNotice: options?.onNotice,
7339
+ onRetry: options?.onRetry
7340
+ })) {
7341
+ yield event;
7342
+ }
7343
+ }
8630
7344
  /**
8631
- * Stream semantic play-run events using the same SSE feed as the dashboard.
7345
+ * Read raw legacy SSE events for callers that explicitly require that
7346
+ * compatibility endpoint. Ordinary run watching uses REST snapshot polling.
8632
7347
  *
8633
- * The server emits a canonical `play.run.snapshot` event first for every
8634
- * connection, then incremental live events until terminal state or reconnect.
7348
+ * @deprecated Use `watchRunEvents` for ordinary run watching.
8635
7349
  */
8636
7350
  async *streamPlayRunEvents(workflowId, options) {
8637
7351
  const headers = options?.lastEventId && options.lastEventId.trim() ? { "Last-Event-ID": options.lastEventId.trim() } : void 0;
@@ -8646,6 +7360,68 @@ var DeeplineClient = class _DeeplineClient {
8646
7360
  }
8647
7361
  }
8648
7362
  }
7363
+ /**
7364
+ * Compatibility alias for polling canonical run snapshots and emitting
7365
+ * their changed events.
7366
+ *
7367
+ * @deprecated Use `watchRunEvents`; kept as a source-compatible alias.
7368
+ * The `fallback` option is ignored because watching uses REST polling.
7369
+ */
7370
+ async *observeRunEvents(runId, options) {
7371
+ yield* this.watchRunEvents(runId, {
7372
+ signal: options?.signal,
7373
+ onNotice: options?.onNotice
7374
+ });
7375
+ }
7376
+ /** Poll snapshots to terminal status and return the durable package. */
7377
+ async watchRunToTerminal(runId, options) {
7378
+ const state = {
7379
+ runId,
7380
+ status: "running",
7381
+ logs: [],
7382
+ lastLogSeq: 0,
7383
+ latest: null
7384
+ };
7385
+ let terminalObserved = false;
7386
+ for await (const event of this.watchRunEvents(runId, {
7387
+ signal: options?.signal,
7388
+ onNotice: options?.onNotice,
7389
+ onRetry: options?.onRetry ?? options?.onReconnect
7390
+ })) {
7391
+ options?.onEvent?.(event);
7392
+ const status = updatePlayLiveStatusState(state, event);
7393
+ if (status && TERMINAL_PLAY_STATUSES.has(status.status)) {
7394
+ terminalObserved = true;
7395
+ }
7396
+ }
7397
+ if (options?.signal?.aborted) {
7398
+ throw new DeeplineError("Run watch aborted.", void 0, "ABORTED");
7399
+ }
7400
+ if (terminalObserved) {
7401
+ return await this.getRunStatus(runId);
7402
+ }
7403
+ const refreshed = await this.getRunStatus(runId);
7404
+ if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) return refreshed;
7405
+ throw new DeeplineError(
7406
+ `Run watch for ${runId} ended before a terminal status.`,
7407
+ void 0,
7408
+ "PLAY_WATCH_ENDED"
7409
+ );
7410
+ }
7411
+ /**
7412
+ * Wait for a run and return its terminal status.
7413
+ *
7414
+ * This source-compatible alias uses the same authenticated two-second REST
7415
+ * snapshot polling as `client.runs.watch`.
7416
+ *
7417
+ * @deprecated Use `client.runs.watch`; retained for SDK compatibility.
7418
+ * @param runId - Public Deepline play-run id.
7419
+ * @param options - Optional callbacks and cancellation signal.
7420
+ * @returns The final durable run status.
7421
+ */
7422
+ async tailRun(runId, options) {
7423
+ return this.watchRunToTerminal(runId, options);
7424
+ }
8649
7425
  /**
8650
7426
  * Cancel a running play execution.
8651
7427
  *
@@ -8809,10 +7585,10 @@ var DeeplineClient = class _DeeplineClient {
8809
7585
  const responseRunStatus = isPlayRunPackage(response) ? response.runStatus : isPlayRunPackage(response.package) ? response.package.runStatus : response.runStatus;
8810
7586
  const responseOverview = isPlayRunPackage(response) ? response.overview : isPlayRunPackage(response.package) ? response.package.overview : response.overview;
8811
7587
  const status = normalizePlayStatus(response);
8812
- if (isRecord8(responseRunStatus)) {
7588
+ if (isRecord4(responseRunStatus)) {
8813
7589
  status.runStatus = responseRunStatus;
8814
7590
  }
8815
- if (isRecord8(responseOverview)) {
7591
+ if (isRecord4(responseOverview)) {
8816
7592
  status.overview = responseOverview;
8817
7593
  }
8818
7594
  if (options?.failedLogs !== true || status.status !== "failed") {
@@ -8911,222 +7687,6 @@ var DeeplineClient = class _DeeplineClient {
8911
7687
  );
8912
7688
  return { ...response, runs: response.runs ?? [] };
8913
7689
  }
8914
- /**
8915
- * Observe one run's live events. Uses the Convex Run Snapshot subscription
8916
- * transport first (ADR-0008), then falls back to the canonical SSE stream
8917
- * when the subscription transport or its optional client modules are not
8918
- * available. Pass `fallback: 'none'` to receive
8919
- * {@link RunObserveTransportUnavailableError} instead.
8920
- */
8921
- async *observeRunEvents(runId, options) {
8922
- let yieldedObserveEvent = false;
8923
- try {
8924
- for await (const event of observeRunEvents({
8925
- http: this.http,
8926
- runId,
8927
- signal: options?.signal,
8928
- onNotice: options?.onNotice
8929
- })) {
8930
- yieldedObserveEvent = true;
8931
- yield event;
8932
- }
8933
- } catch (error) {
8934
- if (!(error instanceof RunObserveTransportUnavailableError) || yieldedObserveEvent || options?.fallback === "none") {
8935
- throw error;
8936
- }
8937
- options?.onNotice?.(
8938
- `[observe] live subscription unavailable (${error.reason}); falling back to SSE tail (support window, ADR-0008)`
8939
- );
8940
- yield* this.streamPlayRunEventsUntilTerminal(runId, options);
8941
- }
8942
- }
8943
- async *streamPlayRunEventsUntilTerminal(runId, options) {
8944
- const state = {
8945
- runId,
8946
- status: "running",
8947
- logs: [],
8948
- lastLogSeq: 0,
8949
- latest: null
8950
- };
8951
- let lastEventId;
8952
- let reconnectAttempt = 0;
8953
- for (; ; ) {
8954
- if (options?.signal?.aborted) {
8955
- return;
8956
- }
8957
- const connectedAt = Date.now();
8958
- let sawEvent = false;
8959
- let endedReason = "stream window ended before a terminal event";
8960
- try {
8961
- for await (const event of this.streamPlayRunEvents(runId, {
8962
- mode: "cli",
8963
- signal: options?.signal,
8964
- ...lastEventId ? { lastEventId } : {}
8965
- })) {
8966
- sawEvent = true;
8967
- if (event.cursor?.trim()) {
8968
- lastEventId = event.cursor;
8969
- }
8970
- yield event;
8971
- const status = updatePlayLiveStatusState(state, event);
8972
- if (status && TERMINAL_PLAY_STATUSES.has(status.status)) {
8973
- return;
8974
- }
8975
- }
8976
- } catch (error) {
8977
- if (options?.signal?.aborted) {
8978
- return;
8979
- }
8980
- if (!isTransientPlayStreamError(error)) {
8981
- throw error;
8982
- }
8983
- endedReason = error instanceof Error ? error.message : String(error);
8984
- }
8985
- let refreshed = null;
8986
- try {
8987
- refreshed = await this.getRunStatus(runId);
8988
- } catch (error) {
8989
- if (!isTransientPlayStreamError(error)) {
8990
- throw error;
8991
- }
8992
- }
8993
- if (refreshed && TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
8994
- yield {
8995
- cursor: String(Date.now()),
8996
- streamId: `sse-fallback:${runId}`,
8997
- scope: "play",
8998
- type: "play.run.status",
8999
- at: (/* @__PURE__ */ new Date()).toISOString(),
9000
- payload: refreshed
9001
- };
9002
- return;
9003
- }
9004
- if (sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
9005
- reconnectAttempt = 0;
9006
- }
9007
- const delayMs = streamReconnectDelayMs(reconnectAttempt);
9008
- reconnectAttempt += 1;
9009
- options?.onNotice?.(
9010
- `[observe] SSE tail window ended before terminal status (${endedReason}); reconnecting to run ${runId}`
9011
- );
9012
- await sleep2(delayMs);
9013
- }
9014
- }
9015
- /**
9016
- * Tail one run through the subscription transport until terminal, then
9017
- * return one durable REST status read (the final Run Response Package).
9018
- */
9019
- async tailRunViaObserveTransport(runId, options) {
9020
- const state = {
9021
- runId,
9022
- status: "running",
9023
- logs: [],
9024
- lastLogSeq: 0,
9025
- latest: null
9026
- };
9027
- for await (const event of this.observeRunEvents(runId, {
9028
- signal: options?.signal,
9029
- onNotice: options?.onNotice,
9030
- fallback: "none"
9031
- })) {
9032
- options?.onEvent?.(event);
9033
- const status = updatePlayLiveStatusState(state, event);
9034
- if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
9035
- continue;
9036
- }
9037
- return await this.getRunStatus(status.runId || runId);
9038
- }
9039
- if (options?.signal?.aborted) {
9040
- throw new DeeplineError("Run observation aborted.", void 0, "ABORTED");
9041
- }
9042
- const refreshed = await this.getRunStatus(runId);
9043
- if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
9044
- return refreshed;
9045
- }
9046
- throw new DeeplineError(
9047
- `Run observation for ${runId} ended before a terminal status.`,
9048
- void 0,
9049
- "PLAY_LIVE_STREAM_ENDED"
9050
- );
9051
- }
9052
- /**
9053
- * Read the canonical run stream until a terminal run status is observed.
9054
- *
9055
- * Tries the Convex Run Snapshot subscription transport first (ADR-0008);
9056
- * when the server cannot serve it (grant endpoint missing/unconfigured or
9057
- * Convex unreachable) it falls back — with one `onNotice` message — to the
9058
- * support-window SSE stream below.
9059
- *
9060
- * Server stream windows are finite: they end cleanly at the function
9061
- * ceiling even while the run keeps executing. A window that ends (cleanly
9062
- * or via transient network error) without a terminal event triggers one
9063
- * durable-status re-check followed by a backed-off reconnect, so long runs
9064
- * tail to completion. Abort via `options.signal` to stop waiting.
9065
- */
9066
- async tailRun(runId, options) {
9067
- try {
9068
- return await this.tailRunViaObserveTransport(runId, options);
9069
- } catch (error) {
9070
- if (!(error instanceof RunObserveTransportUnavailableError)) {
9071
- throw error;
9072
- }
9073
- options?.onNotice?.(
9074
- `[observe] live subscription unavailable (${error.reason}); falling back to SSE tail (support window, ADR-0008)`
9075
- );
9076
- }
9077
- const state = {
9078
- runId,
9079
- status: "running",
9080
- logs: [],
9081
- lastLogSeq: 0,
9082
- latest: null
9083
- };
9084
- let reconnectAttempt = 0;
9085
- for (; ; ) {
9086
- const connectedAt = Date.now();
9087
- let sawEvent = false;
9088
- let terminalRunId = null;
9089
- let endedReason = "stream window ended before a terminal event";
9090
- try {
9091
- for await (const event of this.streamPlayRunEvents(runId, {
9092
- mode: "cli",
9093
- signal: options?.signal
9094
- })) {
9095
- options?.onEvent?.(event);
9096
- sawEvent = true;
9097
- const status = updatePlayLiveStatusState(state, event);
9098
- if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
9099
- continue;
9100
- }
9101
- terminalRunId = status.runId || runId;
9102
- break;
9103
- }
9104
- } catch (error) {
9105
- if (options?.signal?.aborted || !isTransientPlayStreamError(error)) {
9106
- throw error;
9107
- }
9108
- endedReason = error instanceof Error ? error.message : String(error);
9109
- }
9110
- if (terminalRunId) {
9111
- return await this.getRunStatus(terminalRunId);
9112
- }
9113
- const refreshed = await this.getRunStatus(runId);
9114
- if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
9115
- return refreshed;
9116
- }
9117
- if (sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
9118
- reconnectAttempt = 0;
9119
- }
9120
- const delayMs = streamReconnectDelayMs(reconnectAttempt);
9121
- reconnectAttempt += 1;
9122
- options?.onReconnect?.({
9123
- attempt: reconnectAttempt,
9124
- delayMs,
9125
- reason: endedReason
9126
- });
9127
- await sleep2(delayMs);
9128
- }
9129
- }
9130
7690
  /** Get the exact original input retained for a run. This is intentionally separate from status. */
9131
7691
  async getRunInput(runId) {
9132
7692
  return this.http.get(`/api/v2/runs/${encodeURIComponent(runId)}/input`);
@@ -9917,10 +8477,10 @@ var DeeplineClient = class _DeeplineClient {
9917
8477
  // Plays — high-level orchestration
9918
8478
  // ——————————————————————————————————————————————————————————
9919
8479
  /**
9920
- * Run a play end-to-end: submit, stream until terminal, return result.
8480
+ * Run a play end-to-end: submit, poll progress until terminal, return result.
9921
8481
  *
9922
8482
  * This is the highest-level play execution method. It submits the play,
9923
- * reads the canonical run stream for status updates, and returns a structured
8483
+ * reads the canonical run snapshot for status updates, and returns a structured
9924
8484
  * result with logs and timing. Supports cancellation via `AbortSignal`.
9925
8485
  *
9926
8486
  * @param code - Source string fallback; pass the bundled artifact in `options.artifact`
@@ -9976,6 +8536,7 @@ var DeeplineClient = class _DeeplineClient {
9976
8536
  lastLogSeq: 0,
9977
8537
  latest: null
9978
8538
  };
8539
+ let terminalObserved = null;
9979
8540
  if (options?.signal?.aborted) {
9980
8541
  await this.cancelPlay(workflowId);
9981
8542
  return {
@@ -9986,8 +8547,7 @@ var DeeplineClient = class _DeeplineClient {
9986
8547
  error: "Cancelled by user"
9987
8548
  };
9988
8549
  }
9989
- for await (const event of this.streamPlayRunEvents(workflowId, {
9990
- mode: "cli",
8550
+ for await (const event of this.watchRunEvents(workflowId, {
9991
8551
  signal: options?.signal
9992
8552
  })) {
9993
8553
  if (options?.signal?.aborted) {
@@ -10000,20 +8560,36 @@ var DeeplineClient = class _DeeplineClient {
10000
8560
  error: "Cancelled by user"
10001
8561
  };
10002
8562
  }
8563
+ const previousStatus = state.latest?.status;
10003
8564
  const status = updatePlayLiveStatusState(state, event);
10004
8565
  if (!status) {
10005
8566
  continue;
10006
8567
  }
10007
- options?.onProgress?.(status);
8568
+ if (event.type !== "play.run.status" || status.status !== previousStatus) {
8569
+ options?.onProgress?.(status);
8570
+ }
10008
8571
  if (TERMINAL_PLAY_STATUSES.has(status.status)) {
10009
- const finalStatus = await this.getPlayStatus(
10010
- status.runId || workflowId
10011
- ).catch(() => status);
10012
- return playRunResultFromStatus(finalStatus, start, workflowId);
8572
+ terminalObserved = status;
10013
8573
  }
10014
8574
  }
8575
+ if (options?.signal?.aborted) {
8576
+ await this.cancelPlay(workflowId);
8577
+ return {
8578
+ success: false,
8579
+ runId: workflowId,
8580
+ logs: state.logs,
8581
+ durationMs: Date.now() - start,
8582
+ error: "Cancelled by user"
8583
+ };
8584
+ }
8585
+ if (terminalObserved) {
8586
+ const finalStatus = await this.getPlayStatus(
8587
+ terminalObserved.runId || workflowId
8588
+ ).catch(() => terminalObserved);
8589
+ return playRunResultFromStatus(finalStatus, start, workflowId);
8590
+ }
10015
8591
  throw new DeeplineError(
10016
- `Run stream for ${workflowId} ended before the run reached a terminal state.`,
8592
+ `Run watch for ${workflowId} ended before the run reached a terminal state.`,
10017
8593
  void 0,
10018
8594
  "PLAY_RUN_STREAM_ENDED",
10019
8595
  { runId: workflowId, workflowId }
@@ -14645,24 +13221,24 @@ function sanitizeCsvProjectionInfo(input2) {
14645
13221
  const rows = input2.rows.map(stripCsvProjectionFields);
14646
13222
  return { rows, columns };
14647
13223
  }
14648
- function isRecord9(value) {
13224
+ function isRecord5(value) {
14649
13225
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
14650
13226
  }
14651
13227
  function isSerializedDataset(value) {
14652
- return isRecord9(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
13228
+ return isRecord5(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
14653
13229
  }
14654
13230
  function isPackagedDatasetOutput(value) {
14655
- return isRecord9(value) && value.kind === "dataset" && isRecord9(value.preview) && Array.isArray(value.preview.rows);
13231
+ return isRecord5(value) && value.kind === "dataset" && isRecord5(value.preview) && Array.isArray(value.preview.rows);
14656
13232
  }
14657
13233
  function hasCurrentTableExport(value) {
14658
- if (!isRecord9(value) || !isRecord9(value.actions)) return false;
13234
+ if (!isRecord5(value) || !isRecord5(value.actions)) return false;
14659
13235
  const exportCsv = value.actions.exportCsv;
14660
- return isRecord9(exportCsv) && isRecord9(exportCsv.scope) && exportCsv.scope.kind === "database" && exportCsv.scope.mutability === "current";
13236
+ return isRecord5(exportCsv) && isRecord5(exportCsv.scope) && exportCsv.scope.kind === "database" && exportCsv.scope.mutability === "current";
14661
13237
  }
14662
13238
  function currentTableQueryCommand(value) {
14663
- if (!isRecord9(value) || !isRecord9(value.actions)) return void 0;
13239
+ if (!isRecord5(value) || !isRecord5(value.actions)) return void 0;
14664
13240
  const query = value.actions.queryCurrentTable;
14665
- const command = isRecord9(query) ? query.command : void 0;
13241
+ const command = isRecord5(query) ? query.command : void 0;
14666
13242
  return typeof command === "string" && command.trim() ? command.trim() : void 0;
14667
13243
  }
14668
13244
  function recoveredReturnPaths(value) {
@@ -14681,7 +13257,7 @@ function pathParts(path) {
14681
13257
  function valueAtPath(root, path) {
14682
13258
  let cursor = root;
14683
13259
  for (const part of pathParts(path)) {
14684
- if (!isRecord9(cursor)) {
13260
+ if (!isRecord5(cursor)) {
14685
13261
  return void 0;
14686
13262
  }
14687
13263
  cursor = cursor[part];
@@ -14689,17 +13265,17 @@ function valueAtPath(root, path) {
14689
13265
  return cursor;
14690
13266
  }
14691
13267
  function totalRowsForDataset(result, datasetPath) {
14692
- const metadata = isRecord9(result._metadata) ? result._metadata : null;
13268
+ const metadata = isRecord5(result._metadata) ? result._metadata : null;
14693
13269
  const parentPath = datasetPath.split(".").slice(0, -1).join(".");
14694
13270
  const parent = parentPath ? valueAtPath({ result }, parentPath) : result;
14695
- return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord9(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
13271
+ return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord5(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
14696
13272
  }
14697
13273
  function rowArray(value) {
14698
13274
  if (!Array.isArray(value)) {
14699
13275
  return null;
14700
13276
  }
14701
13277
  const rows = value.filter(
14702
- (row) => isRecord9(row)
13278
+ (row) => isRecord5(row)
14703
13279
  );
14704
13280
  return rows.length === value.length ? rows : null;
14705
13281
  }
@@ -14723,7 +13299,7 @@ function inferColumns(rows) {
14723
13299
  return columns;
14724
13300
  }
14725
13301
  function columnsFromDatasetSummary(summary) {
14726
- if (!isRecord9(summary) || !isRecord9(summary.columnStats)) {
13302
+ if (!isRecord5(summary) || !isRecord5(summary.columnStats)) {
14727
13303
  return [];
14728
13304
  }
14729
13305
  return Object.keys(summary.columnStats).filter((column) => column);
@@ -14780,7 +13356,7 @@ function canonicalRowsInfoFromCandidate(input2) {
14780
13356
  candidate.value.recoveredReturnPaths
14781
13357
  )
14782
13358
  } : {},
14783
- ...isRecord9(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace" || candidate.value.exportUnavailable.reason === "returned_dataset_not_persisted") ? {
13359
+ ...isRecord5(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace" || candidate.value.exportUnavailable.reason === "returned_dataset_not_persisted") ? {
14784
13360
  exportUnavailableReason: candidate.value.exportUnavailable.reason,
14785
13361
  ...typeof candidate.value.exportUnavailable.message === "string" ? {
14786
13362
  exportUnavailableMessage: candidate.value.exportUnavailable.message
@@ -14828,7 +13404,7 @@ function collectDatasetCandidates(input2) {
14828
13404
  });
14829
13405
  return;
14830
13406
  }
14831
- if (!isRecord9(input2.value)) {
13407
+ if (!isRecord5(input2.value)) {
14832
13408
  return;
14833
13409
  }
14834
13410
  for (const [key, child] of Object.entries(input2.value)) {
@@ -14845,12 +13421,12 @@ function collectDatasetCandidates(input2) {
14845
13421
  }
14846
13422
  }
14847
13423
  function collectCanonicalRowsInfos(statusOrResult) {
14848
- const root = isRecord9(statusOrResult) ? statusOrResult : null;
14849
- const result = isRecord9(root?.result) ? root.result : root;
13424
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
13425
+ const result = isRecord5(root?.result) ? root.result : root;
14850
13426
  if (!result) {
14851
13427
  return [];
14852
13428
  }
14853
- const metadata = isRecord9(result._metadata) ? result._metadata : null;
13429
+ const metadata = isRecord5(result._metadata) ? result._metadata : null;
14854
13430
  const totalFromMetadata = metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count;
14855
13431
  const candidates = [
14856
13432
  {
@@ -14874,8 +13450,8 @@ function collectCanonicalRowsInfos(statusOrResult) {
14874
13450
  total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
14875
13451
  }
14876
13452
  ];
14877
- if (isRecord9(result.output)) {
14878
- const outputMetadata = isRecord9(result.output._metadata) ? result.output._metadata : null;
13453
+ if (isRecord5(result.output)) {
13454
+ const outputMetadata = isRecord5(result.output._metadata) ? result.output._metadata : null;
14879
13455
  const outputTotalFromMetadata = outputMetadata?.totalRows ?? outputMetadata?.rowCount ?? outputMetadata?.count;
14880
13456
  candidates.push(
14881
13457
  {
@@ -14902,14 +13478,14 @@ function collectCanonicalRowsInfos(statusOrResult) {
14902
13478
  }
14903
13479
  if (Array.isArray(result.steps)) {
14904
13480
  result.steps.forEach((step, index) => {
14905
- if (!isRecord9(step) || !isRecord9(step.output)) {
13481
+ if (!isRecord5(step) || !isRecord5(step.output)) {
14906
13482
  return;
14907
13483
  }
14908
13484
  const source = typeof step.output.path === "string" ? step.output.path : typeof step.id === "string" ? `steps.${step.id}.output` : `steps.${index}.output`;
14909
13485
  candidates.push({
14910
13486
  source,
14911
13487
  value: step.output,
14912
- total: step.output.rowCount ?? (isRecord9(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord9(step.progress) ? step.progress.total : void 0)
13488
+ total: step.output.rowCount ?? (isRecord5(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord5(step.progress) ? step.progress.total : void 0)
14913
13489
  });
14914
13490
  });
14915
13491
  }
@@ -14937,15 +13513,15 @@ function collectCanonicalRowsInfos(statusOrResult) {
14937
13513
  return infos;
14938
13514
  }
14939
13515
  function collectPackagedDatasetCandidates(statusOrResult) {
14940
- const root = isRecord9(statusOrResult) ? statusOrResult : null;
13516
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
14941
13517
  if (!root) {
14942
13518
  return [];
14943
13519
  }
14944
- const pkg = isRecord9(root.package) ? root.package : root;
13520
+ const pkg = isRecord5(root.package) ? root.package : root;
14945
13521
  const datasets = Array.isArray(pkg.datasets) ? pkg.datasets : [];
14946
13522
  const candidates = [];
14947
13523
  for (const output2 of datasets) {
14948
- if (!isRecord9(output2) || !isPackagedDatasetOutput(output2)) {
13524
+ if (!isRecord5(output2) || !isPackagedDatasetOutput(output2)) {
14949
13525
  continue;
14950
13526
  }
14951
13527
  const source = typeof output2.path === "string" && output2.path.trim() ? output2.path.trim() : null;
@@ -14955,18 +13531,18 @@ function collectPackagedDatasetCandidates(statusOrResult) {
14955
13531
  candidates.push({
14956
13532
  source,
14957
13533
  value: output2,
14958
- total: output2.rowCount ?? (isRecord9(output2.preview) ? output2.preview.totalRows : void 0)
13534
+ total: output2.rowCount ?? (isRecord5(output2.preview) ? output2.preview.totalRows : void 0)
14959
13535
  });
14960
13536
  }
14961
13537
  return candidates;
14962
13538
  }
14963
13539
  function collectPackagedStepDatasetCandidates(statusOrResult) {
14964
- const root = isRecord9(statusOrResult) ? statusOrResult : null;
13540
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
14965
13541
  if (!root) return [];
14966
- const pkg = isRecord9(root.package) ? root.package : root;
13542
+ const pkg = isRecord5(root.package) ? root.package : root;
14967
13543
  const steps = Array.isArray(pkg.steps) ? pkg.steps : [];
14968
13544
  return steps.flatMap((step) => {
14969
- if (!isRecord9(step) || !isPackagedDatasetOutput(step.output)) return [];
13545
+ if (!isRecord5(step) || !isPackagedDatasetOutput(step.output)) return [];
14970
13546
  const source = typeof step.output.path === "string" && step.output.path.trim() ? step.output.path.trim() : null;
14971
13547
  return source ? [
14972
13548
  {
@@ -14978,8 +13554,8 @@ function collectPackagedStepDatasetCandidates(statusOrResult) {
14978
13554
  });
14979
13555
  }
14980
13556
  function collectSerializedDatasetRowsInfos(statusOrResult) {
14981
- const root = isRecord9(statusOrResult) ? statusOrResult : null;
14982
- const result = isRecord9(root?.result) ? root.result : root;
13557
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
13558
+ const result = isRecord5(root?.result) ? root.result : root;
14983
13559
  const candidates = [];
14984
13560
  if (result) {
14985
13561
  collectDatasetCandidates({
@@ -14987,7 +13563,7 @@ function collectSerializedDatasetRowsInfos(statusOrResult) {
14987
13563
  path: "result",
14988
13564
  output: candidates
14989
13565
  });
14990
- if (isRecord9(result.output)) {
13566
+ if (isRecord5(result.output)) {
14991
13567
  collectDatasetCandidates({
14992
13568
  value: result.output,
14993
13569
  path: "result",
@@ -15070,13 +13646,13 @@ function summarizeSampleValue(value, depth = 0) {
15070
13646
  if (typeof parsed === "number" || typeof parsed === "boolean") return parsed;
15071
13647
  if (depth >= 3) {
15072
13648
  if (Array.isArray(parsed)) return [];
15073
- if (isRecord9(parsed)) return {};
13649
+ if (isRecord5(parsed)) return {};
15074
13650
  return compactScalar(parsed);
15075
13651
  }
15076
13652
  if (Array.isArray(parsed)) {
15077
13653
  return parsed.slice(0, 3).map((item) => summarizeSampleValue(item, depth + 1));
15078
13654
  }
15079
- if (isRecord9(parsed)) {
13655
+ if (isRecord5(parsed)) {
15080
13656
  const out = {};
15081
13657
  for (const [key, nested] of Object.entries(parsed)) {
15082
13658
  if (["__dl", "meta", "metadata"].includes(key)) {
@@ -15107,7 +13683,7 @@ function compactCell(value) {
15107
13683
  }
15108
13684
  return `[${parsed.length} items]`;
15109
13685
  }
15110
- if (isRecord9(parsed)) {
13686
+ if (isRecord5(parsed)) {
15111
13687
  for (const key of ["matched_result", "output"]) {
15112
13688
  if (parsed[key] !== null && parsed[key] !== void 0 && parsed[key] !== "") {
15113
13689
  return compactCell(parsed[key]);
@@ -16502,17 +15078,17 @@ function parsePositiveInteger2(value, flagName) {
16502
15078
  }
16503
15079
  return parsed;
16504
15080
  }
16505
- function isRecord10(value) {
15081
+ function isRecord6(value) {
16506
15082
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
16507
15083
  }
16508
15084
  function stringValue(value) {
16509
15085
  return typeof value === "string" ? value.trim() : "";
16510
15086
  }
16511
15087
  function extractionEntries(value) {
16512
- if (Array.isArray(value)) return value.filter(isRecord10);
16513
- if (!isRecord10(value)) return [];
15088
+ if (Array.isArray(value)) return value.filter(isRecord6);
15089
+ if (!isRecord6(value)) return [];
16514
15090
  return Object.entries(value).map(
16515
- ([name, entry]) => isRecord10(entry) ? { name, ...entry } : { name }
15091
+ ([name, entry]) => isRecord6(entry) ? { name, ...entry } : { name }
16516
15092
  );
16517
15093
  }
16518
15094
  var PlayBootstrapError = class extends Error {
@@ -17073,7 +15649,7 @@ function readCsvSampleRows(sample) {
17073
15649
  relax_column_count: true,
17074
15650
  trim: true
17075
15651
  });
17076
- return Array.isArray(parsedRows) ? parsedRows.filter(isRecord10) : [];
15652
+ return Array.isArray(parsedRows) ? parsedRows.filter(isRecord6) : [];
17077
15653
  }
17078
15654
  function readSourceCsvColumnSpecs(csvPath) {
17079
15655
  const sample = readCsvSample(csvPath);
@@ -17106,16 +15682,16 @@ function packagedCsvPathForPlay(csvPath) {
17106
15682
  return portablePath.startsWith(".") ? portablePath : `./${portablePath}`;
17107
15683
  }
17108
15684
  function getterNamesFromTool(tool, kind) {
17109
- const usageGuidance = isRecord10(tool?.usageGuidance) ? tool.usageGuidance : {};
17110
- const resultGuidance = isRecord10(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord10(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
15685
+ const usageGuidance = isRecord6(tool?.usageGuidance) ? tool.usageGuidance : {};
15686
+ const resultGuidance = isRecord6(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord6(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
17111
15687
  const key = kind === "list" ? "extractedLists" : "extractedValues";
17112
15688
  const snakeKey = kind === "list" ? "extracted_lists" : "extracted_values";
17113
15689
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
17114
15690
  }
17115
15691
  function targetGettersFromTool(tool) {
17116
- const record3 = isRecord10(tool) ? tool : {};
15692
+ const record3 = isRecord6(tool) ? tool : {};
17117
15693
  const raw = record3.targetGetters ?? record3.target_getters;
17118
- if (!isRecord10(raw)) return {};
15694
+ if (!isRecord6(raw)) return {};
17119
15695
  const entries = [];
17120
15696
  for (const [target, value] of Object.entries(raw)) {
17121
15697
  const paths = Array.isArray(value) ? value.map((path) => typeof path === "string" ? path.trim() : "").filter(Boolean) : [];
@@ -17136,10 +15712,10 @@ function listRowCandidateKeysFromTool(tool) {
17136
15712
  return [...keys].sort();
17137
15713
  }
17138
15714
  function inputPropertyNames(schema) {
17139
- if (!isRecord10(schema)) return [];
17140
- if (isRecord10(schema.properties)) return Object.keys(schema.properties);
15715
+ if (!isRecord6(schema)) return [];
15716
+ if (isRecord6(schema.properties)) return Object.keys(schema.properties);
17141
15717
  if (Array.isArray(schema.fields)) {
17142
- return schema.fields.filter(isRecord10).map((field) => stringValue(field.name)).filter(Boolean);
15718
+ return schema.fields.filter(isRecord6).map((field) => stringValue(field.name)).filter(Boolean);
17143
15719
  }
17144
15720
  return [];
17145
15721
  }
@@ -17153,7 +15729,7 @@ function schemaFieldDetails(schema) {
17153
15729
  return { required, optional };
17154
15730
  }
17155
15731
  function jsonSchemaTypeExpression(schema) {
17156
- if (!isRecord10(schema)) return "unknown";
15732
+ if (!isRecord6(schema)) return "unknown";
17157
15733
  const type = schema.type;
17158
15734
  if (Array.isArray(type)) {
17159
15735
  return type.map((entry) => jsonSchemaTypeExpression({ ...schema, type: entry })).join(" | ");
@@ -17183,7 +15759,7 @@ function jsonSchemaTypeExpression(schema) {
17183
15759
  }
17184
15760
  }
17185
15761
  function objectPropertySchema(schema, property) {
17186
- return isRecord10(schema) && isRecord10(schema.properties) ? schema.properties[property] : null;
15762
+ return isRecord6(schema) && isRecord6(schema.properties) ? schema.properties[property] : null;
17187
15763
  }
17188
15764
  function playOutputHasField(schema, field) {
17189
15765
  return objectPropertySchema(schema, field) != null;
@@ -17359,14 +15935,14 @@ ${indent2.slice(2)}}`;
17359
15935
  }
17360
15936
  function requiredPlayInputFields(play) {
17361
15937
  const schema = play?.inputSchema;
17362
- if (!isRecord10(schema)) return [];
15938
+ if (!isRecord6(schema)) return [];
17363
15939
  if (Array.isArray(schema.required)) {
17364
15940
  return schema.required.filter(
17365
15941
  (value) => typeof value === "string"
17366
15942
  );
17367
15943
  }
17368
15944
  if (Array.isArray(schema.fields)) {
17369
- return schema.fields.filter(isRecord10).filter(
15945
+ return schema.fields.filter(isRecord6).filter(
17370
15946
  (field) => field.required === true && typeof field.name === "string"
17371
15947
  ).map((field) => String(field.name));
17372
15948
  }
@@ -17547,7 +16123,7 @@ function validateBootstrapRoutes(input2) {
17547
16123
  }
17548
16124
  }
17549
16125
  function staticPipelineSubsteps(pipeline) {
17550
- if (!isRecord10(pipeline)) return [];
16126
+ if (!isRecord6(pipeline)) return [];
17551
16127
  return [
17552
16128
  ...extractionEntries(pipeline.stages),
17553
16129
  ...extractionEntries(pipeline.substeps)
@@ -17555,7 +16131,7 @@ function staticPipelineSubsteps(pipeline) {
17555
16131
  }
17556
16132
  function playUsesMapBackedRuntime(play) {
17557
16133
  const pipeline = play?.staticPipeline;
17558
- if (!isRecord10(pipeline)) return false;
16134
+ if (!isRecord6(pipeline)) return false;
17559
16135
  if (stringValue(pipeline.tableNamespace)) return true;
17560
16136
  return staticPipelineSubsteps(pipeline).some((substep) => {
17561
16137
  if (stringValue(substep.type) === "map") return true;
@@ -17564,7 +16140,7 @@ function playUsesMapBackedRuntime(play) {
17564
16140
  aliases: [],
17565
16141
  runCommand: "",
17566
16142
  examples: [],
17567
- staticPipeline: isRecord10(substep.pipeline) ? substep.pipeline : null
16143
+ staticPipeline: isRecord6(substep.pipeline) ? substep.pipeline : null
17568
16144
  });
17569
16145
  });
17570
16146
  }
@@ -22893,35 +21469,35 @@ async function runDeployment(params, hooks) {
22893
21469
  } catch (error) {
22894
21470
  if (revokedFinalStatus(error)) throw error;
22895
21471
  const body = error instanceof DeployApiError ? error.body : null;
22896
- const errorText2 = body?.error ?? (error instanceof Error ? error.message : String(error));
22897
- if (/PLAY_DEPLOYMENT_NOT_ACTIVE/.test(errorText2)) {
21472
+ const errorText = body?.error ?? (error instanceof Error ? error.message : String(error));
21473
+ if (/PLAY_DEPLOYMENT_NOT_ACTIVE/.test(errorText)) {
22898
21474
  console.info("[deploy-worker] cancelled at promote", {
22899
21475
  deploymentId: params.deploymentId
22900
21476
  });
22901
21477
  return { finalStatus: "cancelled", outcomes: [] };
22902
21478
  }
22903
- if (/PLAY_DEPLOYMENT_STALE/.test(errorText2)) {
21479
+ if (/PLAY_DEPLOYMENT_STALE/.test(errorText)) {
22904
21480
  console.info("[deploy-worker] superseded at promote", {
22905
21481
  deploymentId: params.deploymentId
22906
21482
  });
22907
21483
  await setStatus({
22908
21484
  status: "superseded",
22909
- error: errorText2.slice(0, 2e3),
21485
+ error: errorText.slice(0, 2e3),
22910
21486
  buildSeconds: buildSeconds()
22911
21487
  });
22912
21488
  return { finalStatus: "superseded", outcomes: [] };
22913
21489
  }
22914
21490
  return await failWithCheck({
22915
21491
  title: "Deploy failed during promotion",
22916
- summary: errorText2,
22917
- error: errorText2,
21492
+ summary: errorText,
21493
+ error: errorText,
22918
21494
  outcomes: [
22919
21495
  ...outcomes,
22920
21496
  ...(body?.outcomes ?? toPromote).map((entry) => ({
22921
21497
  name: entry.name,
22922
21498
  file: playByName.get(entry.name)?.file ?? entry.name,
22923
21499
  status: "failed",
22924
- error: ("error" in entry ? entry.error : void 0) ?? errorText2
21500
+ error: ("error" in entry ? entry.error : void 0) ?? errorText
22925
21501
  }))
22926
21502
  ]
22927
21503
  });
@@ -24796,7 +23372,7 @@ function playStatusErrorText(status) {
24796
23372
  function isRetryablePendingStartFailure(status) {
24797
23373
  if (status.status !== "failed") return false;
24798
23374
  if (status.runId && status.runId !== "pending") return false;
24799
- return isTransientPlayStreamError(new Error(playStatusErrorText(status)));
23375
+ return isTransientPlayRunReadError(new Error(playStatusErrorText(status)));
24800
23376
  }
24801
23377
  function pendingStartFailureStatus(input2) {
24802
23378
  const message = input2.error instanceof Error ? input2.error.message : String(input2.error);
@@ -25331,7 +23907,7 @@ function assertPlayWaitNotTimedOut(input2) {
25331
23907
  if (input2.waitTimeoutMs !== null && Date.now() - input2.startedAt >= input2.waitTimeoutMs) {
25332
23908
  const hasRealRunId = input2.workflowId.length > 0 && input2.workflowId !== "pending";
25333
23909
  const phaseSuffix = input2.lastPhase && input2.lastPhase.trim() ? ` (last observed phase: ${input2.lastPhase.trim()})` : "";
25334
- const tailHint = hasRealRunId ? ` The CLI stopped waiting; it did not cancel the run. Check its current state with 'deepline runs get ${input2.workflowId} --json', or reattach with 'deepline runs tail ${input2.workflowId} --json'. Do not start another run just to retrieve results.` : ` No run id was received, so acceptance is unknown. Check recent runs with 'deepline runs list --play <play-name> --json' before submitting again.`;
23910
+ const tailHint = hasRealRunId ? ` The CLI stopped waiting; it did not cancel the run. Check its current state with 'deepline runs get ${input2.workflowId} --json', or reattach with 'deepline runs watch ${input2.workflowId} --json'. Do not start another run just to retrieve results.` : ` No run id was received, so acceptance is unknown. Check recent runs with 'deepline runs list --play <play-name> --json' before submitting again.`;
25335
23911
  throw new DeeplineError(
25336
23912
  `Timed out waiting for play ${hasRealRunId ? input2.workflowId : "<no run id>"} after ${Math.ceil(input2.waitTimeoutMs / 1e3)}s${phaseSuffix}.${tailHint}`,
25337
23913
  void 0,
@@ -25344,63 +23920,54 @@ function assertPlayWaitNotTimedOut(input2) {
25344
23920
  );
25345
23921
  }
25346
23922
  }
25347
- var PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS = 15e3;
23923
+ var RUN_WATCH_RETRY_INTERVAL_MS = 2e3;
25348
23924
  function isAdmittedRunVisibilityDelay(error) {
25349
23925
  return error instanceof DeeplineError && error.statusCode === 404 && error.message.trim() === "Workflow run not found.";
25350
23926
  }
25351
- async function waitForPlayCompletionByStream(input2) {
23927
+ async function waitForPlayCompletionByWatch(input2) {
25352
23928
  let lastPhase = null;
25353
- let reconnectAttempt = 0;
25354
- const durableStatusProbeIntervalMs = input2.durableStatusProbeIntervalMs ?? PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
25355
- let nextDurableProbeAt = Date.now() + durableStatusProbeIntervalMs;
25356
- let durableStatusProbe = null;
25357
23929
  let admissionConfirmed = false;
23930
+ let visibilityNoticeSent = false;
23931
+ let terminalStatusRead = null;
23932
+ const controller = new AbortController();
23933
+ let timedOut = false;
23934
+ const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
23935
+ const remaining = remainingWaitMs();
23936
+ const timeout = remaining === null ? null : setTimeout(
23937
+ () => {
23938
+ timedOut = true;
23939
+ controller.abort();
23940
+ },
23941
+ Math.max(1, remaining)
23942
+ );
25358
23943
  const confirmAdmission = async () => {
25359
23944
  if (admissionConfirmed) return;
25360
23945
  admissionConfirmed = true;
25361
23946
  await input2.onRunAdmitted?.(input2.workflowId);
25362
23947
  };
25363
23948
  const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
25364
- const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
25365
23949
  const fetchTerminalStatus = async () => {
25366
- if (durableStatusProbe) return durableStatusProbe;
25367
- const probe = (async () => {
25368
- let refreshed;
25369
- try {
25370
- refreshed = await input2.client.getPlayStatus(input2.workflowId, {
25371
- billing: false
25372
- });
25373
- } catch (error) {
25374
- if (isTransientPlayStreamError(error) || isAdmittedRunVisibilityDelay(error)) {
25375
- return null;
25376
- }
25377
- throw error;
25378
- }
25379
- if (refreshed.runId === input2.workflowId && statusProvesPlayRunExecution(refreshed.status)) {
25380
- await confirmAdmission();
25381
- }
25382
- return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
25383
- })();
25384
- durableStatusProbe = probe;
23950
+ let refreshed;
25385
23951
  try {
25386
- return await probe;
25387
- } finally {
25388
- if (durableStatusProbe === probe) durableStatusProbe = null;
23952
+ refreshed = await input2.client.getPlayStatus(input2.workflowId, {
23953
+ billing: false
23954
+ });
23955
+ } catch (error) {
23956
+ if (isTransientPlayRunReadError(error) || isAdmittedRunVisibilityDelay(error)) {
23957
+ return null;
23958
+ }
23959
+ throw error;
25389
23960
  }
23961
+ if (refreshed.runId === input2.workflowId && statusProvesPlayRunExecution(refreshed.status)) {
23962
+ await confirmAdmission();
23963
+ }
23964
+ return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
25390
23965
  };
25391
- const handleLiveEvent = async (event, probeDurableStatus) => {
23966
+ const handleLiveEvent = async (event) => {
25392
23967
  assertPlayWaitNotTimedOut({ ...input2, lastPhase });
25393
23968
  if (getRunIdFromLiveEvent(event) === input2.workflowId && (eventConfirmsPlayRunLaunch(event) || eventProvesPlayRunExecution(event))) {
25394
23969
  await confirmAdmission();
25395
23970
  }
25396
- const now = Date.now();
25397
- if (now >= nextDurableProbeAt) {
25398
- nextDurableProbeAt = now + durableStatusProbeIntervalMs;
25399
- const durableTerminal = await probeDurableStatus();
25400
- if (durableTerminal) {
25401
- return durableTerminal;
25402
- }
25403
- }
25404
23971
  const phase = describeLiveEventPhase(event);
25405
23972
  if (phase) {
25406
23973
  lastPhase = phase;
@@ -25451,144 +24018,57 @@ async function waitForPlayCompletionByStream(input2) {
25451
24018
  }
25452
24019
  }
25453
24020
  const finalStatus = getFinalStatusFromLiveEvent(event);
25454
- if (finalStatus) {
24021
+ if (event.type === "play.run.final_status" && finalStatus) {
25455
24022
  return withDashboardUrl(finalStatus);
25456
24023
  }
25457
24024
  const status = getStatusFromLiveEvent(event);
25458
24025
  if (status && TERMINAL_PLAY_STATUSES2.has(status)) {
25459
- const refreshedStatus = await probeDurableStatus();
25460
- if (refreshedStatus) return refreshedStatus;
24026
+ terminalStatusRead ??= fetchTerminalStatus();
24027
+ return await terminalStatusRead;
25461
24028
  }
25462
24029
  return null;
25463
24030
  };
25464
- const streamOneWindow = async () => {
25465
- const controller = new AbortController();
25466
- let timedOut = false;
25467
- let sawEvent = false;
25468
- let durableTerminal = null;
25469
- let durableProbeError = null;
25470
- let durableProbeTimer = null;
25471
- const remaining = remainingWaitMs();
25472
- const timeout = remaining === null ? null : setTimeout(
25473
- () => {
25474
- timedOut = true;
25475
- controller.abort();
25476
- },
25477
- Math.max(1, remaining)
25478
- );
25479
- const scheduleDurableStatusProbe = () => {
25480
- durableProbeTimer = setTimeout(() => {
25481
- durableProbeTimer = null;
25482
- if (controller.signal.aborted) return;
25483
- nextDurableProbeAt = Date.now() + durableStatusProbeIntervalMs;
25484
- void fetchTerminalStatus().then((status) => {
25485
- if (controller.signal.aborted) return;
25486
- if (status) {
25487
- durableTerminal = status;
25488
- controller.abort();
25489
- return;
25490
- }
25491
- scheduleDurableStatusProbe();
25492
- }).catch((error) => {
25493
- if (controller.signal.aborted) return;
25494
- durableProbeError = error;
25495
- controller.abort();
25496
- });
25497
- }, durableStatusProbeIntervalMs);
25498
- };
25499
- try {
25500
- scheduleDurableStatusProbe();
25501
- for await (const event of input2.client.streamPlayRunEvents(
25502
- input2.workflowId,
25503
- { signal: controller.signal }
25504
- )) {
25505
- sawEvent = true;
25506
- if (durableTerminal) {
25507
- return { kind: "terminal", status: durableTerminal };
24031
+ try {
24032
+ for (; ; ) {
24033
+ try {
24034
+ let terminalFromWatch = null;
24035
+ for await (const event of input2.client.watchRunEvents(
24036
+ input2.workflowId,
24037
+ { signal: controller.signal }
24038
+ )) {
24039
+ const terminal3 = await handleLiveEvent(event);
24040
+ if (terminal3) terminalFromWatch = terminal3;
25508
24041
  }
25509
- const terminal = await handleLiveEvent(event, fetchTerminalStatus);
25510
- if (terminal) {
25511
- return { kind: "terminal", status: terminal };
24042
+ if (terminalFromWatch) return terminalFromWatch;
24043
+ } catch (error) {
24044
+ if (timedOut || controller.signal.aborted) break;
24045
+ if (!isAdmittedRunVisibilityDelay(error)) throw error;
24046
+ if (!visibilityNoticeSent && !input2.jsonOutput) {
24047
+ input2.progress.writeLine(
24048
+ `[play watch] run is accepted and waiting for its snapshot; checking again in ${RUN_WATCH_RETRY_INTERVAL_MS / 1e3}s`
24049
+ );
24050
+ visibilityNoticeSent = true;
25512
24051
  }
25513
24052
  }
25514
- } catch (error) {
25515
- if (timedOut) {
25516
- return { kind: "timed_out", sawEvent };
25517
- }
25518
- if (durableTerminal) {
25519
- return { kind: "terminal", status: durableTerminal };
25520
- }
25521
- if (durableProbeError) {
25522
- throw durableProbeError;
25523
- }
25524
- if (!isTransientPlayStreamError(error) && !isAdmittedRunVisibilityDelay(error)) {
25525
- throw error;
25526
- }
25527
- return {
25528
- kind: "ended",
25529
- sawEvent,
25530
- reason: error instanceof Error ? error.message : String(error)
25531
- };
25532
- } finally {
25533
- if (timeout) {
25534
- clearTimeout(timeout);
25535
- }
25536
- if (durableProbeTimer) {
25537
- clearTimeout(durableProbeTimer);
25538
- }
25539
- controller.abort();
25540
- }
25541
- if (timedOut) {
25542
- return { kind: "timed_out", sawEvent };
25543
- }
25544
- if (durableTerminal) {
25545
- return { kind: "terminal", status: durableTerminal };
25546
- }
25547
- if (durableProbeError) {
25548
- throw durableProbeError;
25549
- }
25550
- return {
25551
- kind: "ended",
25552
- sawEvent,
25553
- reason: "stream window ended before a terminal event"
25554
- };
25555
- };
25556
- for (; ; ) {
25557
- const connectedAt = Date.now();
25558
- const window = await streamOneWindow();
25559
- if (window.kind === "terminal") {
25560
- return window.status;
24053
+ const terminal2 = await fetchTerminalStatus();
24054
+ if (terminal2) return terminal2;
24055
+ assertPlayWaitNotTimedOut({ ...input2, lastPhase });
24056
+ const nextWait = remainingWaitMs();
24057
+ await sleep5(
24058
+ nextWait === null ? RUN_WATCH_RETRY_INTERVAL_MS : Math.min(RUN_WATCH_RETRY_INTERVAL_MS, Math.max(1, nextWait))
24059
+ );
25561
24060
  }
25562
24061
  const terminal = await fetchTerminalStatus();
25563
- if (terminal) {
25564
- return terminal;
25565
- }
24062
+ if (terminal) return terminal;
25566
24063
  assertPlayWaitNotTimedOut({ ...input2, lastPhase });
25567
- if (window.sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
25568
- reconnectAttempt = 0;
25569
- }
25570
- const delayMs = streamReconnectDelayMs(reconnectAttempt);
25571
- reconnectAttempt += 1;
25572
- const reason = window.kind === "ended" ? window.reason : "wait timeout raced the stream";
25573
- if (!input2.jsonOutput) {
25574
- input2.progress.writeLine(
25575
- `[play watch] stream ended without a terminal status; reconnecting to run ${input2.workflowId} (${reason})`
25576
- );
25577
- }
25578
- recordCliTrace({
25579
- phase: "cli.play_tail_stream_reconnect",
25580
- ms: Date.now() - input2.startedAt,
25581
- ok: true,
25582
- playName: input2.playName,
25583
- workflowId: input2.workflowId,
25584
- attempt: reconnectAttempt,
25585
- delayMs,
25586
- reason
25587
- });
25588
- const remainingBeforeSleep = remainingWaitMs();
25589
- await sleep5(
25590
- remainingBeforeSleep === null ? delayMs : Math.min(delayMs, Math.max(1, remainingBeforeSleep))
24064
+ throw new DeeplineError(
24065
+ `Run watch for ${input2.workflowId} ended before a terminal status.`,
24066
+ void 0,
24067
+ "PLAY_WATCH_ENDED"
25591
24068
  );
24069
+ } finally {
24070
+ if (timeout) clearTimeout(timeout);
24071
+ controller.abort();
25592
24072
  }
25593
24073
  }
25594
24074
  async function startAndWaitForPlayCompletionByStream(input2) {
@@ -25665,7 +24145,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25665
24145
  billing: false
25666
24146
  });
25667
24147
  } catch (error) {
25668
- if (isTransientPlayStreamError(error)) {
24148
+ if (isTransientPlayRunReadError(error)) {
25669
24149
  return null;
25670
24150
  }
25671
24151
  throw error;
@@ -25836,7 +24316,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25836
24316
  firstRunIdMs,
25837
24317
  lastPhase
25838
24318
  });
25839
- return waitForPlayCompletionByStream({
24319
+ return waitForPlayCompletionByWatch({
25840
24320
  client: input2.client,
25841
24321
  playName: input2.playName,
25842
24322
  workflowId: lastKnownWorkflowId,
@@ -25875,7 +24355,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25875
24355
  lastPhase
25876
24356
  });
25877
24357
  }
25878
- if (lastKnownWorkflowId && isTransientPlayStreamError(error)) {
24358
+ if (lastKnownWorkflowId && isTransientPlayRunReadError(error)) {
25879
24359
  if (timeout) {
25880
24360
  clearTimeout(timeout);
25881
24361
  }
@@ -25897,7 +24377,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25897
24377
  lastPhase,
25898
24378
  reason
25899
24379
  });
25900
- return waitForPlayCompletionByStream({
24380
+ return waitForPlayCompletionByWatch({
25901
24381
  client: input2.client,
25902
24382
  playName: input2.playName,
25903
24383
  workflowId: lastKnownWorkflowId,
@@ -25911,7 +24391,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25911
24391
  onRunAdmitted: confirmAdmission
25912
24392
  });
25913
24393
  }
25914
- if (!lastKnownWorkflowId && isTransientPlayStreamError(error)) {
24394
+ if (!lastKnownWorkflowId && isTransientPlayRunReadError(error)) {
25915
24395
  recordCliTrace({
25916
24396
  phase: "cli.play_start_stream_transient_failure",
25917
24397
  ms: Date.now() - startedAt,
@@ -25951,7 +24431,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25951
24431
  lastPhase,
25952
24432
  reason: "stream ended before terminal event"
25953
24433
  });
25954
- return waitForPlayCompletionByStream({
24434
+ return waitForPlayCompletionByWatch({
25955
24435
  client: input2.client,
25956
24436
  playName: input2.playName,
25957
24437
  workflowId: lastKnownWorkflowId,
@@ -25968,7 +24448,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25968
24448
  const phaseSuffix = lastPhase && lastPhase.trim() ? ` (last observed phase: ${lastPhase.trim()})` : "";
25969
24449
  const idSuffix = lastKnownWorkflowId ? ` runId=${lastKnownWorkflowId}` : "";
25970
24450
  throw new DeeplineError(
25971
- `Play start stream ended before a terminal status was observed${idSuffix}${phaseSuffix}. If a run id was printed, inspect it with 'deepline runs get <run-id> --full --json' or continue watching with 'deepline runs tail <run-id>'.`,
24451
+ `Play start request ended before terminal status was observed${idSuffix}${phaseSuffix}. If a run id was printed, inspect it with 'deepline runs get <run-id> --full --json' or continue watching with 'deepline runs watch <run-id>'.`,
25972
24452
  void 0,
25973
24453
  "PLAY_START_STREAM_ENDED",
25974
24454
  {
@@ -28081,7 +26561,7 @@ function extractPlayValidationErrors(value) {
28081
26561
  if (value instanceof DeeplineError) {
28082
26562
  return extractPlayValidationErrors(value.details);
28083
26563
  }
28084
- if (!isRecord11(value)) {
26564
+ if (!isRecord7(value)) {
28085
26565
  return [];
28086
26566
  }
28087
26567
  const directErrors = stringArrayField(value, "errors");
@@ -28477,7 +26957,7 @@ function parsePlayRunOptions(args) {
28477
26957
  }
28478
26958
  if (arg === "--poll-interval-ms" || arg === "--interval-ms") {
28479
26959
  throw new Error(
28480
- `${arg} was removed. --watch uses the canonical run stream directly.`
26960
+ `${arg} was removed. --watch polls the canonical run snapshot.`
28481
26961
  );
28482
26962
  }
28483
26963
  if ((arg === "--tail-timeout-ms" || arg === "--timeout-ms") && args[index + 1]) {
@@ -28745,7 +27225,7 @@ function formatPlayRuntimeLimit(runtimeLimit) {
28745
27225
  if (seconds % 60 === 0) return `${seconds / 60} min`;
28746
27226
  return `${seconds} sec`;
28747
27227
  }
28748
- function isRecord11(value) {
27228
+ function isRecord7(value) {
28749
27229
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
28750
27230
  }
28751
27231
  function stringValue3(value) {
@@ -28755,14 +27235,14 @@ function asArray(value) {
28755
27235
  return Array.isArray(value) ? value : [];
28756
27236
  }
28757
27237
  function extractionEntries2(value) {
28758
- if (Array.isArray(value)) return value.filter(isRecord11);
28759
- if (!isRecord11(value)) return [];
27238
+ if (Array.isArray(value)) return value.filter(isRecord7);
27239
+ if (!isRecord7(value)) return [];
28760
27240
  return Object.entries(value).map(
28761
- ([name, entry]) => isRecord11(entry) ? { name, ...entry } : { name }
27241
+ ([name, entry]) => isRecord7(entry) ? { name, ...entry } : { name }
28762
27242
  );
28763
27243
  }
28764
27244
  function firstRawPath(entry) {
28765
- const details = isRecord11(entry.details) ? entry.details : {};
27245
+ const details = isRecord7(entry.details) ? entry.details : {};
28766
27246
  const paths = [
28767
27247
  ...asArray(details.rawToolOutputPaths),
28768
27248
  ...asArray(details.raw_tool_output_paths),
@@ -28780,12 +27260,12 @@ function checkHintRawPath(value) {
28780
27260
  function collectStaticPipelineToolIds(staticPipeline) {
28781
27261
  const seen = /* @__PURE__ */ new Set();
28782
27262
  const visitPipeline = (pipeline) => {
28783
- if (!isRecord11(pipeline)) return;
27263
+ if (!isRecord7(pipeline)) return;
28784
27264
  for (const step of [
28785
27265
  ...asArray(pipeline.stages),
28786
27266
  ...asArray(pipeline.substeps)
28787
27267
  ]) {
28788
- if (!isRecord11(step)) continue;
27268
+ if (!isRecord7(step)) continue;
28789
27269
  if (step.type === "tool") {
28790
27270
  const toolId = stringValue3(step.toolId) || stringValue3(step.tool);
28791
27271
  if (toolId) seen.add(toolId);
@@ -28799,9 +27279,9 @@ function collectStaticPipelineToolIds(staticPipeline) {
28799
27279
  return [...seen].sort();
28800
27280
  }
28801
27281
  function toolGetterHintFromMetadata(toolId, tool) {
28802
- const usageGuidance = isRecord11(tool.usageGuidance) ? tool.usageGuidance : {};
28803
- const resultGuidance = isRecord11(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord11(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
28804
- const toolResponse = isRecord11(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord11(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
27282
+ const usageGuidance = isRecord7(tool.usageGuidance) ? tool.usageGuidance : {};
27283
+ const resultGuidance = isRecord7(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord7(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
27284
+ const toolResponse = isRecord7(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord7(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
28805
27285
  const lists = extractionEntries2(
28806
27286
  resultGuidance.extractedLists ?? resultGuidance.extracted_lists
28807
27287
  ).map((entry) => ({
@@ -29164,7 +27644,7 @@ function artifactForProductionCompatibilityCheck(artifact) {
29164
27644
  "DEEPLINE_PROD_CHECK_AUTHORING_CONTRACT_EDITION must be a positive integer."
29165
27645
  );
29166
27646
  }
29167
- const compatibility = isRecord11(artifact.compatibility) ? artifact.compatibility : {};
27647
+ const compatibility = isRecord7(artifact.compatibility) ? artifact.compatibility : {};
29168
27648
  return {
29169
27649
  ...artifact,
29170
27650
  compatibility: {
@@ -30064,7 +28544,7 @@ Active runs: ${next.running}`
30064
28544
  return 0;
30065
28545
  }
30066
28546
  async function handleRunTail(args) {
30067
- const usage = "Usage: deepline runs tail <run-id> [--json | --jsonl] [--compact] [--log-level debug|info|warn|error]";
28547
+ const usage = "Usage: deepline runs watch <run-id> [--json | --jsonl] [--compact] [--log-level debug|info|warn|error]";
30068
28548
  let runId;
30069
28549
  try {
30070
28550
  runId = parseRunIdPositional(args, usage);
@@ -30079,7 +28559,7 @@ async function handleRunTail(args) {
30079
28559
  const arg = args[index];
30080
28560
  if (arg === "--cursor") {
30081
28561
  console.error(
30082
- "--cursor was removed. deepline runs tail reads the canonical run stream."
28562
+ "--cursor was removed. deepline runs watch polls the canonical run snapshot."
30083
28563
  );
30084
28564
  return 1;
30085
28565
  }
@@ -30105,7 +28585,7 @@ async function handleRunTail(args) {
30105
28585
  continue;
30106
28586
  }
30107
28587
  if (arg.startsWith("--") && arg !== "--json" && arg !== "--jsonl" && arg !== "--compact") {
30108
- console.error(`${arg} is not supported by deepline runs tail.`);
28588
+ console.error(`${arg} is not supported by deepline runs watch.`);
30109
28589
  return 1;
30110
28590
  }
30111
28591
  }
@@ -30141,7 +28621,7 @@ async function handleRunTail(args) {
30141
28621
  verbose: debug,
30142
28622
  logLevel
30143
28623
  };
30144
- const status = await client2.runs.tail(runId, {
28624
+ const status = await client2.runs.watch(runId, {
30145
28625
  onEvent: jsonLines ? (event) => {
30146
28626
  process.stdout.write(
30147
28627
  `${JSON.stringify({
@@ -30187,9 +28667,9 @@ async function handleRunTail(args) {
30187
28667
  }
30188
28668
  } : void 0,
30189
28669
  // Human mode only: in --json mode emit nothing non-protocol.
30190
- onReconnect: jsonOutput && !debug && !hasExplicitLogLevel ? void 0 : ({ reason }) => {
28670
+ onRetry: jsonOutput && !debug && !hasExplicitLogLevel ? void 0 : ({ reason }) => {
30191
28671
  process.stderr.write(
30192
- `[runs tail] stream ended without a terminal status; reconnecting to run ${runId} (${reason})
28672
+ `[runs watch] snapshot polling failed; retrying for run ${runId} (${reason})
30193
28673
  `
30194
28674
  );
30195
28675
  }
@@ -31856,7 +30336,10 @@ Examples:
31856
30336
  ).option(
31857
30337
  "--log-level <level>",
31858
30338
  "Minimum live log severity: debug, info (default), warn, or error"
31859
- ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
30339
+ ).option(
30340
+ "--tail-timeout-ms <ms>",
30341
+ "Timeout while waiting for terminal run status"
30342
+ ).option("--force", "Start a fresh run graph").option(
31860
30343
  "--force-tool-refresh",
31861
30344
  "Refresh completed tool receipts; may repeat billed provider calls"
31862
30345
  ).option(
@@ -32326,13 +30809,13 @@ Concepts:
32326
30809
  stop mutates cloud state by requesting cancellation.
32327
30810
 
32328
30811
  Debug a run:
32329
- Active: deepline runs tail <run-id> --log-level debug
30812
+ Active: deepline runs watch <run-id> --log-level debug
32330
30813
  Historical: deepline runs logs <run-id> --out run.log --log-level debug --json
32331
30814
  Full state: deepline runs get <run-id> --full --json
32332
30815
 
32333
30816
  Examples:
32334
30817
  deepline runs get play/my-play/run/20260501t000000-000 --json
32335
- deepline runs tail play/my-play/run/20260501t000000-000
30818
+ deepline runs watch play/my-play/run/20260501t000000-000
32336
30819
  deepline runs logs play/my-play/run/20260501t000000-000 --out run.log --log-level debug --json
32337
30820
  deepline runs list --play my-play --status failed --json
32338
30821
  deepline runs list --status running --json
@@ -32466,29 +30949,30 @@ Examples:
32466
30949
  ...options.json ? ["--json"] : []
32467
30950
  ]);
32468
30951
  });
32469
- runs.command("tail <runId>").description("Read the canonical live stream for a play run.").addHelpText(
30952
+ runs.command("watch <runId>").alias("tail").description("Poll the canonical run snapshot until terminal status.").addHelpText(
32470
30953
  "after",
32471
30954
  `
32472
30955
  Notes:
32473
- Streams live run events until the stream ends. Human output shows info and
32474
- warning logs as they arrive. Use get for current status and logs for persisted
32475
- log history. In human output, --compact prints deduplicated
32476
- step transitions and progress instead of the full event stream. --json emits
32477
- one terminal package. --jsonl emits canonical live events as JSON Lines and
32478
- ends with the same compact package shape as runs get --json. --log-level
30956
+ Polls the authenticated run snapshot every two seconds. Human output shows
30957
+ info and warning logs as snapshots change. Use get for current status and
30958
+ logs for persisted log history. In human output, --compact prints
30959
+ deduplicated step transitions and progress. --json emits one terminal
30960
+ package. --jsonl emits canonical watched events as JSON Lines and ends with
30961
+ the same compact package shape as runs get --json. The tail command remains
30962
+ an alias. --log-level
32479
30963
  filters the rendered customer-safe runtime log lines; debug includes runtime
32480
30964
  and receipt diagnostics and writes them to stderr alongside JSON output.
32481
30965
 
32482
30966
  Examples:
32483
- deepline runs tail play/my-play/run/20260501t000000-000
32484
- deepline runs tail play/my-play/run/20260501t000000-000 --compact
32485
- deepline runs tail play/my-play/run/20260501t000000-000 --log-level debug
32486
- deepline runs tail play/my-play/run/20260501t000000-000 --log-level error
32487
- deepline runs tail play/my-play/run/20260501t000000-000 --jsonl
30967
+ deepline runs watch play/my-play/run/20260501t000000-000
30968
+ deepline runs watch play/my-play/run/20260501t000000-000 --compact
30969
+ deepline runs watch play/my-play/run/20260501t000000-000 --log-level debug
30970
+ deepline runs watch play/my-play/run/20260501t000000-000 --log-level error
30971
+ deepline runs watch play/my-play/run/20260501t000000-000 --jsonl
32488
30972
  `
32489
30973
  ).option("--json", "Emit one terminal JSON package after the run completes").option(
32490
30974
  "--jsonl",
32491
- "Stream live events as JSON Lines, then the terminal package"
30975
+ "Emit watched events as JSON Lines, then the terminal package"
32492
30976
  ).option(
32493
30977
  "--compact",
32494
30978
  "Show deduplicated human step transitions and progress"
@@ -34406,7 +32890,7 @@ function isMarkedTestAiInferenceCommand(command) {
34406
32890
  if (normalizeEnrichPlayRef(command.tool) !== "run_javascript") {
34407
32891
  return false;
34408
32892
  }
34409
- return isRecord12(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
32893
+ return isRecord8(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
34410
32894
  }
34411
32895
  function enrichDebugEnabled(env = process.env) {
34412
32896
  const raw = String(env.DEEPLINE_DEBUG_ENRICH ?? "").trim().toLowerCase();
@@ -34670,7 +33154,7 @@ function rewriteGeneratedPlayRerunForEnrich(status, enrichCommand) {
34670
33154
  if (Array.isArray(value)) {
34671
33155
  return value.map(rewrite);
34672
33156
  }
34673
- if (!isRecord12(value)) {
33157
+ if (!isRecord8(value)) {
34674
33158
  return value;
34675
33159
  }
34676
33160
  const next = Object.fromEntries(
@@ -34679,7 +33163,7 @@ function rewriteGeneratedPlayRerunForEnrich(status, enrichCommand) {
34679
33163
  key === "rerunCommand" && typeof entry === "string" ? enrichCommand : rewrite(entry)
34680
33164
  ])
34681
33165
  );
34682
- if (isRecord12(next.next) && typeof next.next.run === "string") {
33166
+ if (isRecord8(next.next) && typeof next.next.run === "string") {
34683
33167
  next.next = { ...next.next, run: enrichCommand };
34684
33168
  }
34685
33169
  return next;
@@ -35161,7 +33645,7 @@ async function resolveWatchedGeneratedPlayStatus(input2) {
35161
33645
  }
35162
33646
  return input2.client.runs.get(runId, { full: true });
35163
33647
  }
35164
- function isRecord12(value) {
33648
+ function isRecord8(value) {
35165
33649
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
35166
33650
  }
35167
33651
  async function captureStdout(run, options = {}) {
@@ -35413,15 +33897,15 @@ function readFirstEnrichDatasetActions(value) {
35413
33897
  return null;
35414
33898
  }
35415
33899
  const record3 = candidate;
35416
- const actions = isRecord12(record3.actions) ? record3.actions : null;
35417
- const currentQuery = isRecord12(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
35418
- const legacyQuery = isRecord12(actions?.query) ? actions.query : null;
33900
+ const actions = isRecord8(record3.actions) ? record3.actions : null;
33901
+ const currentQuery = isRecord8(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
33902
+ const legacyQuery = isRecord8(actions?.query) ? actions.query : null;
35419
33903
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
35420
33904
  if (query?.kind === "deepline_db_query") {
35421
33905
  return {
35422
33906
  dataset: record3,
35423
33907
  query,
35424
- ...isRecord12(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
33908
+ ...isRecord8(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
35425
33909
  };
35426
33910
  }
35427
33911
  if (options.allowLegacy && record3.kind === "dataset" && typeof record3.queryDatasetCommand === "string" && record3.queryDatasetCommand.trim()) {
@@ -35474,7 +33958,7 @@ function enrichCustomerDbJson(input2) {
35474
33958
  const dataset = actions.dataset;
35475
33959
  const sql = actionStringField(query, "sql") ?? parseSqlFromDbQueryCommand(actions.queryDatasetCommand);
35476
33960
  const datasetPath = actionStringField(query, "datasetPath") ?? actionStringField(dataset, "path") ?? actionStringField(dataset, "tableNamespace");
35477
- const api = isRecord12(query.api) ? query.api : null;
33961
+ const api = isRecord8(query.api) ? query.api : null;
35478
33962
  const apiPath = actionStringField(api ?? {}, "path") ?? "/api/v2/db/query";
35479
33963
  const apiMethod = actionStringField(api ?? {}, "method") ?? "POST";
35480
33964
  if (!datasetPath) {
@@ -35543,11 +34027,11 @@ function sqlStringLiteral(value) {
35543
34027
  return `'${value.replace(/'/g, "''")}'`;
35544
34028
  }
35545
34029
  function failureAliasFromCellMeta(cellMeta) {
35546
- if (!isRecord12(cellMeta)) {
34030
+ if (!isRecord8(cellMeta)) {
35547
34031
  return null;
35548
34032
  }
35549
34033
  for (const [alias, meta] of Object.entries(cellMeta)) {
35550
- if (!isRecord12(meta)) {
34034
+ if (!isRecord8(meta)) {
35551
34035
  continue;
35552
34036
  }
35553
34037
  const failure = failureCellFromMeta(meta, {});
@@ -36041,7 +34525,7 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
36041
34525
  return fallback;
36042
34526
  }
36043
34527
  function failureCellFromMeta(meta, fallback) {
36044
- if (!isRecord12(meta)) {
34528
+ if (!isRecord8(meta)) {
36045
34529
  return null;
36046
34530
  }
36047
34531
  const status = typeof meta.status === "string" ? meta.status.trim().toLowerCase() : "";
@@ -36061,7 +34545,7 @@ function failureCellFromMeta(meta, fallback) {
36061
34545
  };
36062
34546
  }
36063
34547
  function applyFailureCellMeta(row, cellMeta, fallback) {
36064
- if (!isRecord12(cellMeta)) {
34548
+ if (!isRecord8(cellMeta)) {
36065
34549
  return;
36066
34550
  }
36067
34551
  for (const [field, meta] of Object.entries(cellMeta)) {
@@ -36289,7 +34773,7 @@ function stableRowSnapshot(value) {
36289
34773
  }
36290
34774
  function cellFailureError(value) {
36291
34775
  const parsed = parseMaybeJsonObject(value);
36292
- if (!isRecord12(parsed)) {
34776
+ if (!isRecord8(parsed)) {
36293
34777
  const text = typeof parsed === "string" ? parsed.trim() : "";
36294
34778
  if (/^(?:[A-Za-z0-9_:-]+:\s*)?(?:Error|TypeError|ReferenceError|SyntaxError|RangeError):\s+/.test(
36295
34779
  text
@@ -36297,12 +34781,12 @@ function cellFailureError(value) {
36297
34781
  return { message: text };
36298
34782
  }
36299
34783
  }
36300
- if (!isRecord12(parsed)) {
34784
+ if (!isRecord8(parsed)) {
36301
34785
  return null;
36302
34786
  }
36303
34787
  const status = typeof parsed.status === "string" ? parsed.status.trim().toLowerCase() : "";
36304
34788
  const directError = typeof parsed.error === "string" ? parsed.error.trim() : typeof parsed.last_error === "string" ? parsed.last_error.trim() : "";
36305
- const result = isRecord12(parsed.result) ? parsed.result : null;
34789
+ const result = isRecord8(parsed.result) ? parsed.result : null;
36306
34790
  const resultError = typeof result?.error === "string" ? result.error.trim() : typeof result?.message === "string" ? result.message.trim() : "";
36307
34791
  if (!directError && !resultError && status !== "error" && status !== "failed") {
36308
34792
  return null;
@@ -36372,7 +34856,7 @@ function assignFlattenedFailurePath(target, field, value) {
36372
34856
  let cursor = target;
36373
34857
  for (const part of normalized.slice(0, -1)) {
36374
34858
  const existing = cursor[part];
36375
- if (!isRecord12(existing)) {
34859
+ if (!isRecord8(existing)) {
36376
34860
  const next = {};
36377
34861
  cursor[part] = next;
36378
34862
  cursor = next;
@@ -36536,10 +35020,10 @@ function waterfallExecutionSignal(status, spec) {
36536
35020
  let everyChildStatOnlyConditionSkipped = true;
36537
35021
  const childAliasesWithStats = /* @__PURE__ */ new Set();
36538
35022
  for (const childAlias of childAliases) {
36539
- for (const stat5 of summaries.map((summary) => summary[childAlias]).filter(isRecord12)) {
35023
+ for (const stat5 of summaries.map((summary) => summary[childAlias]).filter(isRecord8)) {
36540
35024
  sawChildStats = true;
36541
35025
  childAliasesWithStats.add(childAlias);
36542
- const execution = isRecord12(stat5.execution) ? stat5.execution : null;
35026
+ const execution = isRecord8(stat5.execution) ? stat5.execution : null;
36543
35027
  const executedSummary = parseExecutionSummary(
36544
35028
  execution?.["completed:executed"]
36545
35029
  );
@@ -36569,7 +35053,7 @@ function waterfallExecutionSignal(status, spec) {
36569
35053
  }
36570
35054
  function emptyWaterfallStatsEvidence(status, spec) {
36571
35055
  const summaries = collectColumnStats(status);
36572
- const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord12);
35056
+ const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord8);
36573
35057
  for (const stat5 of parentStats) {
36574
35058
  const nonEmpty = parseExecutionSummary(stat5.non_empty);
36575
35059
  if (nonEmpty?.total && nonEmpty.count === 0) {
@@ -36583,7 +35067,7 @@ function emptyWaterfallStatsEvidence(status, spec) {
36583
35067
  let selectedRows = 0;
36584
35068
  let sawStatsForEveryChild = true;
36585
35069
  for (const childAlias of childAliases) {
36586
- const stat5 = summaries.map((summary) => summary[childAlias]).find(isRecord12);
35070
+ const stat5 = summaries.map((summary) => summary[childAlias]).find(isRecord8);
36587
35071
  if (!stat5) {
36588
35072
  sawStatsForEveryChild = false;
36589
35073
  break;
@@ -36592,7 +35076,7 @@ function emptyWaterfallStatsEvidence(status, spec) {
36592
35076
  if ((nonEmpty?.count ?? 0) > 0) {
36593
35077
  return null;
36594
35078
  }
36595
- const execution = isRecord12(stat5.execution) ? stat5.execution : null;
35079
+ const execution = isRecord8(stat5.execution) ? stat5.execution : null;
36596
35080
  const executed = parseExecutionSummary(execution?.["completed:executed"]);
36597
35081
  const reused = parseExecutionSummary(execution?.["completed:reused"]);
36598
35082
  const skipped = parseExecutionSummary(execution?.["skipped:condition"]);
@@ -36634,11 +35118,11 @@ function collectStatusFailureJobs(input2) {
36634
35118
  const jobs = [];
36635
35119
  aliases.forEach((spec, aliasIndex) => {
36636
35120
  const { alias } = spec;
36637
- const stat5 = summaries.map((summary) => summary[alias]).find(isRecord12);
35121
+ const stat5 = summaries.map((summary) => summary[alias]).find(isRecord8);
36638
35122
  if (!stat5) {
36639
35123
  return;
36640
35124
  }
36641
- const execution = isRecord12(stat5.execution) ? stat5.execution : null;
35125
+ const execution = isRecord8(stat5.execution) ? stat5.execution : null;
36642
35126
  const failedCount = Math.min(
36643
35127
  selectedRows,
36644
35128
  Math.max(
@@ -36745,10 +35229,10 @@ function collectColumnStats(status) {
36745
35229
  value.forEach(visit);
36746
35230
  return;
36747
35231
  }
36748
- if (!isRecord12(value)) {
35232
+ if (!isRecord8(value)) {
36749
35233
  return;
36750
35234
  }
36751
- if (isRecord12(value.columnStats)) {
35235
+ if (isRecord8(value.columnStats)) {
36752
35236
  summaries.push(value.columnStats);
36753
35237
  }
36754
35238
  Object.values(value).forEach(visit);
@@ -36760,12 +35244,12 @@ function firstAliasExecutionCounts(input2) {
36760
35244
  const aliases = collectConfigScalarAliasOrder(input2.config);
36761
35245
  const summaries = collectColumnStats(input2.status);
36762
35246
  for (const alias of aliases) {
36763
- const stat5 = summaries.map((summary) => summary[alias]).find(isRecord12);
35247
+ const stat5 = summaries.map((summary) => summary[alias]).find(isRecord8);
36764
35248
  if (!stat5) continue;
36765
35249
  if (input2.forceAliases.has(normalizeAlias2(alias))) {
36766
35250
  return { executed: input2.selectedRows, reused: 0 };
36767
35251
  }
36768
- const execution = isRecord12(stat5.execution) ? stat5.execution : null;
35252
+ const execution = isRecord8(stat5.execution) ? stat5.execution : null;
36769
35253
  if (!execution) continue;
36770
35254
  return {
36771
35255
  executed: parseExecutionCount(execution["completed:executed"]),
@@ -36792,14 +35276,14 @@ function rewriteEnrichJsonStatus(input2) {
36792
35276
  if (Array.isArray(value)) {
36793
35277
  return value.map(rewrite);
36794
35278
  }
36795
- if (!isRecord12(value)) {
35279
+ if (!isRecord8(value)) {
36796
35280
  return value;
36797
35281
  }
36798
35282
  const next = {};
36799
35283
  for (const [key, entry] of Object.entries(value)) {
36800
35284
  next[key] = rewrite(entry);
36801
35285
  }
36802
- if (isRecord12(next.progress)) {
35286
+ if (isRecord8(next.progress)) {
36803
35287
  next.progress = {
36804
35288
  ...next.progress,
36805
35289
  ...selectedRows > 0 ? { total: selectedRows } : {},
@@ -36808,8 +35292,8 @@ function rewriteEnrichJsonStatus(input2) {
36808
35292
  ...failedRows > 0 ? { failed: failedRows, pending: 0 } : {}
36809
35293
  };
36810
35294
  }
36811
- if (isRecord12(next.summary)) {
36812
- const rowCounts = isRecord12(next.summary.rowCounts) ? next.summary.rowCounts : null;
35295
+ if (isRecord8(next.summary)) {
35296
+ const rowCounts = isRecord8(next.summary.rowCounts) ? next.summary.rowCounts : null;
36813
35297
  if (failedRows > 0) {
36814
35298
  next.summary = {
36815
35299
  ...next.summary,
@@ -36822,11 +35306,11 @@ function rewriteEnrichJsonStatus(input2) {
36822
35306
  };
36823
35307
  }
36824
35308
  }
36825
- if (isRecord12(next.columnStats) && selectedRows > 0) {
35309
+ if (isRecord8(next.columnStats) && selectedRows > 0) {
36826
35310
  const columnStats = { ...next.columnStats };
36827
35311
  for (const alias of forcedAliases) {
36828
- const stat5 = isRecord12(columnStats[alias]) ? columnStats[alias] : null;
36829
- const execution = isRecord12(stat5?.execution) ? stat5.execution : null;
35312
+ const stat5 = isRecord8(columnStats[alias]) ? columnStats[alias] : null;
35313
+ const execution = isRecord8(stat5?.execution) ? stat5.execution : null;
36830
35314
  if (!stat5 || !execution) continue;
36831
35315
  columnStats[alias] = {
36832
35316
  ...stat5,
@@ -36845,14 +35329,14 @@ function rewriteEnrichJsonStatus(input2) {
36845
35329
  return next;
36846
35330
  };
36847
35331
  const rewritten = rewrite(input2.status);
36848
- if (failedRows === 0 || !isRecord12(rewritten)) {
35332
+ if (failedRows === 0 || !isRecord8(rewritten)) {
36849
35333
  return rewritten;
36850
35334
  }
36851
35335
  const partialStatus = selectedRows > 0 && failedRows < selectedRows ? "partial_success" : "failed";
36852
35336
  return {
36853
35337
  ...rewritten,
36854
35338
  ...rewritten.status === "completed" || rewritten.status === "failed" ? { status: partialStatus } : {},
36855
- ...isRecord12(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
35339
+ ...isRecord8(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
36856
35340
  };
36857
35341
  }
36858
35342
  function summarizeFailedJobError(value) {
@@ -37476,7 +35960,7 @@ function materializeCsvCellValue(value) {
37476
35960
  return value;
37477
35961
  }
37478
35962
  function compactArrayEnvelopeCompleteValue(value) {
37479
- if (!isRecord12(value) || value.kind !== "array") {
35963
+ if (!isRecord8(value) || value.kind !== "array") {
37480
35964
  return null;
37481
35965
  }
37482
35966
  if (!Array.isArray(value.preview)) {
@@ -37490,7 +35974,7 @@ function compactArrayEnvelopeCompleteValue(value) {
37490
35974
  }
37491
35975
  function disambiguateCompactAiInferencePayload(value) {
37492
35976
  const parsed = parseMaybeJsonObject(value);
37493
- if (!isRecord12(parsed) || !cellFailureError(parsed)) {
35977
+ if (!isRecord8(parsed) || !cellFailureError(parsed)) {
37494
35978
  return value;
37495
35979
  }
37496
35980
  return {
@@ -37499,14 +35983,14 @@ function disambiguateCompactAiInferencePayload(value) {
37499
35983
  };
37500
35984
  }
37501
35985
  function compactAiInferenceCellForCsv(value) {
37502
- if (!isRecord12(value)) {
35986
+ if (!isRecord8(value)) {
37503
35987
  return value;
37504
35988
  }
37505
35989
  const extractedJson = value.extracted_json;
37506
35990
  if (extractedJson !== null && extractedJson !== void 0) {
37507
35991
  return disambiguateCompactAiInferencePayload(extractedJson);
37508
35992
  }
37509
- const result = isRecord12(value.result) ? value.result : null;
35993
+ const result = isRecord8(value.result) ? value.result : null;
37510
35994
  const object = result?.object;
37511
35995
  if (object !== null && object !== void 0) {
37512
35996
  return disambiguateCompactAiInferencePayload(object);
@@ -37523,12 +36007,12 @@ function compactAiInferenceCellForCsv(value) {
37523
36007
  }
37524
36008
  function materializeEnrichAliasCellForCsv(row, alias, options) {
37525
36009
  const direct = row[alias];
37526
- if (isRecord12(direct)) {
36010
+ if (isRecord8(direct)) {
37527
36011
  const completeArray = compactArrayEnvelopeCompleteValue(direct);
37528
36012
  if (completeArray) {
37529
36013
  return materializeCsvCellValue(completeArray);
37530
36014
  }
37531
- if (options?.compactAiCell && direct.status === "completed" && (isRecord12(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
36015
+ if (options?.compactAiCell && direct.status === "completed" && (isRecord8(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
37532
36016
  return materializeCsvCellValue(compactAiInferenceCellForCsv(direct));
37533
36017
  }
37534
36018
  if (Object.prototype.hasOwnProperty.call(direct, "matched_result") || Object.prototype.hasOwnProperty.call(direct, "matchedResult") || Object.prototype.hasOwnProperty.call(direct, "result")) {
@@ -37669,11 +36153,11 @@ function normalizeEnrichRowsForCsvExport(rows, config, options) {
37669
36153
  }
37670
36154
  function legacyMetadataFromRow(row) {
37671
36155
  const direct = parseLegacyMetadataCell(row._metadata);
37672
- if (direct && isRecord12(direct.columns)) {
36156
+ if (direct && isRecord8(direct.columns)) {
37673
36157
  return direct;
37674
36158
  }
37675
36159
  const relocated = parseLegacyMetadataCell(row.metadata);
37676
- if (relocated && isRecord12(relocated.columns)) {
36160
+ if (relocated && isRecord8(relocated.columns)) {
37677
36161
  return relocated;
37678
36162
  }
37679
36163
  const flattenedColumns = parseLegacyMetadataCell(row["metadata.columns"]);
@@ -37690,7 +36174,7 @@ function legacyMetadataFromRow(row) {
37690
36174
  }
37691
36175
  function parseLegacyMetadataCell(value) {
37692
36176
  const parsed = parseMaybeJsonObject(value);
37693
- if (isRecord12(parsed)) {
36177
+ if (isRecord8(parsed)) {
37694
36178
  return parsed;
37695
36179
  }
37696
36180
  if (typeof value !== "string") {
@@ -37707,12 +36191,12 @@ function parseLegacyMetadataCell(value) {
37707
36191
  for (const candidate of candidates) {
37708
36192
  try {
37709
36193
  const decoded = JSON.parse(candidate);
37710
- if (isRecord12(decoded)) {
36194
+ if (isRecord8(decoded)) {
37711
36195
  return decoded;
37712
36196
  }
37713
36197
  if (typeof decoded === "string") {
37714
36198
  const nested = JSON.parse(decoded);
37715
- if (isRecord12(nested)) {
36199
+ if (isRecord8(nested)) {
37716
36200
  return nested;
37717
36201
  }
37718
36202
  }
@@ -37722,8 +36206,8 @@ function parseLegacyMetadataCell(value) {
37722
36206
  return null;
37723
36207
  }
37724
36208
  function mergeLegacyMetadataRecords(base, enriched) {
37725
- const baseColumns = isRecord12(base.columns) ? base.columns : null;
37726
- const enrichedColumns = isRecord12(enriched.columns) ? enriched.columns : null;
36209
+ const baseColumns = isRecord8(base.columns) ? base.columns : null;
36210
+ const enrichedColumns = isRecord8(enriched.columns) ? enriched.columns : null;
37727
36211
  const merged = {
37728
36212
  ...base,
37729
36213
  ...enriched
@@ -51030,7 +49514,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
51030
49514
  }
51031
49515
  function extractionContractEntries(entries) {
51032
49516
  return entries.flatMap((entry) => {
51033
- if (!isRecord13(entry)) return [];
49517
+ if (!isRecord9(entry)) return [];
51034
49518
  const name = stringField2(entry, "name");
51035
49519
  const expression = stringField2(entry, "expression");
51036
49520
  return name && expression ? [{ name, expression }] : [];
@@ -51051,7 +49535,7 @@ function printMonitorTypeFilters(tool) {
51051
49535
  }
51052
49536
  console.log("Deploy filters (set in the monitor payload):");
51053
49537
  for (const name of names) {
51054
- const field = isRecord13(properties[name]) ? properties[name] : {};
49538
+ const field = isRecord9(properties[name]) ? properties[name] : {};
51055
49539
  const star = required.has(name) ? "*" : "";
51056
49540
  const enumVals = arrayField2(field, "enum").filter(
51057
49541
  (v) => typeof v === "string"
@@ -51065,7 +49549,7 @@ function printMonitorTypeFilterExamples(tool) {
51065
49549
  const documentation = recordField2(tool, "documentation");
51066
49550
  const fields2 = recordField2(documentation, "fields");
51067
49551
  const examples = Object.entries(fields2).flatMap(([name, rawField]) => {
51068
- const grammar = recordField2(isRecord13(rawField) ? rawField : {}, "grammar");
49552
+ const grammar = recordField2(isRecord9(rawField) ? rawField : {}, "grammar");
51069
49553
  const example = stringField2(grammar, "example");
51070
49554
  const values = [
51071
49555
  ...arrayField2(grammar, "examples").filter(
@@ -51084,14 +49568,14 @@ function printMonitorTypeFilterExamples(tool) {
51084
49568
  }
51085
49569
  function printMonitorTypeStreams(tool) {
51086
49570
  const streams = arrayField2(tool, "streams", "output_streams").filter(
51087
- isRecord13
49571
+ isRecord9
51088
49572
  );
51089
49573
  if (!streams.length) return;
51090
49574
  console.log("");
51091
49575
  console.log("Filter columns (a play's sqlListeners.where, per stream):");
51092
49576
  for (const stream of streams) {
51093
49577
  const name = stringField2(stream, "stream");
51094
- const cols = arrayField2(stream, "columns").filter(isRecord13).map((col) => stringField2(col, "name")).filter(Boolean);
49578
+ const cols = arrayField2(stream, "columns").filter(isRecord9).map((col) => stringField2(col, "name")).filter(Boolean);
51095
49579
  console.log(`- ${name}: ${cols.join(", ")}`);
51096
49580
  }
51097
49581
  }
@@ -51108,7 +49592,7 @@ function monitorTypePricingLines(tool) {
51108
49592
  }
51109
49593
  const lines = ["Pricing (Deepline credits per accepted event):"];
51110
49594
  for (const key of keys) {
51111
- const entry = isRecord13(byType[key]) ? byType[key] : {};
49595
+ const entry = isRecord9(byType[key]) ? byType[key] : {};
51112
49596
  const credits = numberField2(entry, "deepline_credits", "deeplineCredits");
51113
49597
  const display = stringField2(entry, "display");
51114
49598
  const shown = display || (credits !== null ? `${formatDecimal(credits)} credits/event` : "see --json");
@@ -51158,8 +49642,8 @@ function printCompactToolContract(tool, requestedToolId) {
51158
49642
  return;
51159
49643
  }
51160
49644
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
51161
- const cost = isRecord13(contract.cost) ? contract.cost : {};
51162
- const getters = isRecord13(contract.getters) ? contract.getters : {};
49645
+ const cost = isRecord9(contract.cost) ? contract.cost : {};
49646
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
51163
49647
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
51164
49648
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
51165
49649
  const inputFields = recursiveToolInputFieldsForDisplay(
@@ -51176,7 +49660,7 @@ function printCompactToolContract(tool, requestedToolId) {
51176
49660
  printToolOutputArrayShape(contract);
51177
49661
  printToolExecutionHints(contract);
51178
49662
  if (contract.deprecated === true) {
51179
- const deprecation = isRecord13(contract.deprecation) ? contract.deprecation : {};
49663
+ const deprecation = isRecord9(contract.deprecation) ? contract.deprecation : {};
51180
49664
  const message = stringField2(deprecation, "message");
51181
49665
  const replacementToolId = stringField2(
51182
49666
  deprecation,
@@ -51203,7 +49687,7 @@ function printCompactToolContract(tool, requestedToolId) {
51203
49687
  console.log("");
51204
49688
  console.log("Inputs:");
51205
49689
  for (const field of inputFields) {
51206
- if (!isRecord13(field)) continue;
49690
+ if (!isRecord9(field)) continue;
51207
49691
  const name = stringField2(field, "name");
51208
49692
  if (!name) continue;
51209
49693
  const required = field.required ? "*" : "";
@@ -51223,7 +49707,7 @@ function printCompactToolContract(tool, requestedToolId) {
51223
49707
  }
51224
49708
  console.log("");
51225
49709
  printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
51226
- const starterScript = isRecord13(contract.starterScript) ? contract.starterScript : {};
49710
+ const starterScript = isRecord9(contract.starterScript) ? contract.starterScript : {};
51227
49711
  const starterPath = stringField2(starterScript, "path");
51228
49712
  if (starterPath) {
51229
49713
  console.log("");
@@ -51237,14 +49721,14 @@ function printCompactToolContract(tool, requestedToolId) {
51237
49721
  console.log("Getters:");
51238
49722
  if (listGetters.length) console.log("Lists:");
51239
49723
  for (const entry of listGetters) {
51240
- if (isRecord13(entry))
49724
+ if (isRecord9(entry))
51241
49725
  console.log(
51242
49726
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
51243
49727
  );
51244
49728
  }
51245
49729
  if (valueGetters.length) console.log("Values:");
51246
49730
  for (const entry of valueGetters) {
51247
- if (isRecord13(entry))
49731
+ if (isRecord9(entry))
51248
49732
  console.log(
51249
49733
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
51250
49734
  );
@@ -51343,10 +49827,10 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
51343
49827
  ` input: ${JSON.stringify(sampleInput || {}, null, 2).replace(/\n/g, "\n ")},`
51344
49828
  );
51345
49829
  console.log("});");
51346
- const getters = isRecord13(contract.getters) ? contract.getters : {};
49830
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
51347
49831
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
51348
49832
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
51349
- const firstGetter = [...valueGetters, ...listGetters].find(isRecord13);
49833
+ const firstGetter = [...valueGetters, ...listGetters].find(isRecord9);
51350
49834
  if (firstGetter) {
51351
49835
  const name = stringField2(firstGetter, "name") || "value";
51352
49836
  const expression = stringField2(firstGetter, "expression");
@@ -51382,7 +49866,7 @@ function printPlayLikeToolUsage(tool, requestedToolId) {
51382
49866
  }
51383
49867
  function printToolGettersOnly(tool, requestedToolId) {
51384
49868
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
51385
- const getters = isRecord13(contract.getters) ? contract.getters : {};
49869
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
51386
49870
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
51387
49871
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
51388
49872
  console.log(`Getters: ${contract.toolId}`);
@@ -51395,7 +49879,7 @@ function printToolGettersOnly(tool, requestedToolId) {
51395
49879
  if (listGetters.length) {
51396
49880
  console.log("Lists:");
51397
49881
  for (const entry of listGetters) {
51398
- if (isRecord13(entry))
49882
+ if (isRecord9(entry))
51399
49883
  console.log(
51400
49884
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
51401
49885
  );
@@ -51404,7 +49888,7 @@ function printToolGettersOnly(tool, requestedToolId) {
51404
49888
  if (valueGetters.length) {
51405
49889
  console.log("Values:");
51406
49890
  for (const entry of valueGetters) {
51407
- if (isRecord13(entry))
49891
+ if (isRecord9(entry))
51408
49892
  console.log(
51409
49893
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
51410
49894
  );
@@ -51430,7 +49914,7 @@ function sampleValueForField(field) {
51430
49914
  function samplePayloadForInputFields(fields2) {
51431
49915
  return Object.fromEntries(
51432
49916
  fields2.slice(0, 4).flatMap((field) => {
51433
- if (!isRecord13(field)) return [];
49917
+ if (!isRecord9(field)) return [];
51434
49918
  const name = stringField2(field, "name");
51435
49919
  if (!name) return [];
51436
49920
  return [[name, sampleValueForField(field)]];
@@ -51560,8 +50044,8 @@ function formatListedToolCost(tool) {
51560
50044
  }
51561
50045
  function toolInputFieldsForDisplay(inputSchema) {
51562
50046
  if (Array.isArray(inputSchema.fields)) {
51563
- const fields2 = inputSchema.fields.filter(isRecord13);
51564
- if (!isRecord13(inputSchema.jsonSchema)) return fields2;
50047
+ const fields2 = inputSchema.fields.filter(isRecord9);
50048
+ if (!isRecord9(inputSchema.jsonSchema)) return fields2;
51565
50049
  const jsonSchemaFields = new Map(
51566
50050
  recursiveToolInputFieldsForDisplay({
51567
50051
  jsonSchema: inputSchema.jsonSchema
@@ -51573,26 +50057,26 @@ function toolInputFieldsForDisplay(inputSchema) {
51573
50057
  const jsonSchemaField = typeof field.name === "string" ? jsonSchemaFields.get(field.name) : void 0;
51574
50058
  const minItems = typeof field.minItems === "number" ? field.minItems : jsonSchemaField?.minItems;
51575
50059
  const maxItems = typeof field.maxItems === "number" ? field.maxItems : jsonSchemaField?.maxItems;
51576
- const items = isRecord13(field.items) ? field.items : jsonSchemaField?.items;
50060
+ const items = isRecord9(field.items) ? field.items : jsonSchemaField?.items;
51577
50061
  return {
51578
50062
  ...field,
51579
- ...isRecord13(items) ? { items } : {},
50063
+ ...isRecord9(items) ? { items } : {},
51580
50064
  ...typeof minItems === "number" ? { minItems } : {},
51581
50065
  ...typeof maxItems === "number" ? { maxItems } : {}
51582
50066
  };
51583
50067
  });
51584
50068
  }
51585
- const jsonSchema = isRecord13(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
51586
- const properties = isRecord13(jsonSchema.properties) ? jsonSchema.properties : {};
50069
+ const jsonSchema = isRecord9(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
50070
+ const properties = isRecord9(jsonSchema.properties) ? jsonSchema.properties : {};
51587
50071
  const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
51588
50072
  return Object.entries(properties).map(([name, value]) => {
51589
- const property = isRecord13(value) ? value : {};
50073
+ const property = isRecord9(value) ? value : {};
51590
50074
  return {
51591
50075
  name,
51592
50076
  type: typeof property.type === "string" ? property.type : "unknown",
51593
50077
  required: required.has(name),
51594
50078
  description: property.description,
51595
- ...isRecord13(property.items) ? { items: property.items } : {},
50079
+ ...isRecord9(property.items) ? { items: property.items } : {},
51596
50080
  ...typeof property.minItems === "number" ? { minItems: property.minItems } : {},
51597
50081
  ...typeof property.maxItems === "number" ? { maxItems: property.maxItems } : {},
51598
50082
  ...Object.prototype.hasOwnProperty.call(property, "default") ? { default: property.default } : {}
@@ -51609,7 +50093,7 @@ function toolOutputFieldsForDisplay(outputSchema) {
51609
50093
  }
51610
50094
  function printToolOutputArrayShape(tool) {
51611
50095
  const outputFields = toolOutputFieldsForDisplay(
51612
- recordField2(isRecord13(tool) ? tool : {}, "outputSchema", "output_schema")
50096
+ recordField2(isRecord9(tool) ? tool : {}, "outputSchema", "output_schema")
51613
50097
  );
51614
50098
  if (outputFields.length === 0) return;
51615
50099
  console.log(" Output array shape (declared schema):");
@@ -51624,10 +50108,10 @@ function printToolOutputArrayShape(tool) {
51624
50108
  }
51625
50109
  }
51626
50110
  function canonicalToolJsonSchema(inputSchema) {
51627
- return isRecord13(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
50111
+ return isRecord9(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
51628
50112
  }
51629
50113
  function declaredToolJsonSchema(inputSchema) {
51630
- if (isRecord13(inputSchema.jsonSchema)) {
50114
+ if (isRecord9(inputSchema.jsonSchema)) {
51631
50115
  return inputSchema.jsonSchema;
51632
50116
  }
51633
50117
  return Array.isArray(inputSchema.fields) ? null : inputSchema;
@@ -51652,7 +50136,7 @@ function publicToolInputSchemaForDescribe(inputSchema) {
51652
50136
  };
51653
50137
  const stripDescriptions = (value) => {
51654
50138
  if (Array.isArray(value)) return value.map(stripDescriptions);
51655
- if (!isRecord13(value)) return value;
50139
+ if (!isRecord9(value)) return value;
51656
50140
  return Object.fromEntries(
51657
50141
  Object.entries(value).flatMap(([key, nested]) => {
51658
50142
  if (key === "description" && typeof nested === "string" && exposesProviderSpend(nested)) {
@@ -51673,7 +50157,7 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51673
50157
  for (const item of value) collectSchemaIds(item);
51674
50158
  return;
51675
50159
  }
51676
- if (!isRecord13(value)) return;
50160
+ if (!isRecord9(value)) return;
51677
50161
  if (typeof value.$id === "string" && value.$id.trim()) {
51678
50162
  schemasById.set(value.$id.trim(), value);
51679
50163
  }
@@ -51686,10 +50170,10 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51686
50170
  let current = root;
51687
50171
  for (const rawSegment of ref.slice(2).split("/")) {
51688
50172
  const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
51689
- if (!isRecord13(current)) return schema;
50173
+ if (!isRecord9(current)) return schema;
51690
50174
  current = current[segment];
51691
50175
  }
51692
- return isRecord13(current) ? current : schema;
50176
+ return isRecord9(current) ? current : schema;
51693
50177
  };
51694
50178
  const addField = (field) => {
51695
50179
  const name = typeof field.name === "string" ? field.name : "";
@@ -51704,7 +50188,7 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51704
50188
  if (ref && activeRefs.has(ref)) return;
51705
50189
  const schema = resolveRef(unresolvedSchema);
51706
50190
  const nextActiveRefs = ref ? /* @__PURE__ */ new Set([...activeRefs, ref]) : activeRefs;
51707
- const type = Array.isArray(schema.type) ? schema.type.map(String).join("|") : typeof schema.type === "string" ? schema.type : isRecord13(schema.properties) ? "object" : schema.items ? "array" : "unknown";
50191
+ const type = Array.isArray(schema.type) ? schema.type.map(String).join("|") : typeof schema.type === "string" ? schema.type : isRecord9(schema.properties) ? "object" : schema.items ? "array" : "unknown";
51708
50192
  if (path) {
51709
50193
  addField({
51710
50194
  name: path,
@@ -51712,18 +50196,18 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51712
50196
  required,
51713
50197
  description: schema.description,
51714
50198
  ...Array.isArray(schema.enum) ? { enum: schema.enum } : {},
51715
- ...isRecord13(schema.items) ? { items: schema.items } : {},
50199
+ ...isRecord9(schema.items) ? { items: schema.items } : {},
51716
50200
  ...typeof schema.minItems === "number" ? { minItems: schema.minItems } : {},
51717
50201
  ...typeof schema.maxItems === "number" ? { maxItems: schema.maxItems } : {},
51718
50202
  ...Object.prototype.hasOwnProperty.call(schema, "default") ? { default: schema.default } : {}
51719
50203
  });
51720
50204
  }
51721
- const properties = isRecord13(schema.properties) ? schema.properties : {};
50205
+ const properties = isRecord9(schema.properties) ? schema.properties : {};
51722
50206
  const requiredNames = new Set(
51723
50207
  Array.isArray(schema.required) ? schema.required.map(String) : []
51724
50208
  );
51725
50209
  for (const [name, value] of Object.entries(properties)) {
51726
- if (!isRecord13(value)) continue;
50210
+ if (!isRecord9(value)) continue;
51727
50211
  visit(
51728
50212
  value,
51729
50213
  path ? `${path}.${name}` : name,
@@ -51731,13 +50215,13 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51731
50215
  nextActiveRefs
51732
50216
  );
51733
50217
  }
51734
- if (isRecord13(schema.items)) {
50218
+ if (isRecord9(schema.items)) {
51735
50219
  visit(schema.items, `${path}[]`, false, nextActiveRefs);
51736
50220
  }
51737
50221
  for (const keyword of ["anyOf", "oneOf", "allOf"]) {
51738
50222
  const branches = Array.isArray(schema[keyword]) ? schema[keyword] : [];
51739
50223
  for (const branch of branches) {
51740
- if (isRecord13(branch)) {
50224
+ if (isRecord9(branch)) {
51741
50225
  visit(branch, path, required, nextActiveRefs);
51742
50226
  }
51743
50227
  }
@@ -51747,21 +50231,21 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51747
50231
  return fields2.size ? [...fields2.values()] : toolInputFieldsForDisplay(inputSchema);
51748
50232
  }
51749
50233
  function inputFieldJsonForDescribe(field) {
51750
- const publicItems = isRecord13(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
50234
+ const publicItems = isRecord9(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
51751
50235
  return {
51752
50236
  name: field.name,
51753
50237
  type: field.type ?? "unknown",
51754
50238
  required: Boolean(field.required),
51755
50239
  ...field.description ? { description: field.description } : {},
51756
- ...isRecord13(publicItems) ? { items: publicItems } : {},
50240
+ ...isRecord9(publicItems) ? { items: publicItems } : {},
51757
50241
  ...typeof field.minItems === "number" ? { minItems: field.minItems } : {},
51758
50242
  ...typeof field.maxItems === "number" ? { maxItems: field.maxItems } : {},
51759
50243
  ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
51760
50244
  };
51761
50245
  }
51762
50246
  function arrayItemBoundsSuffix(field) {
51763
- const itemSchema = isRecord13(field.items) ? field.items : null;
51764
- const itemType = itemSchema ? typeof itemSchema.type === "string" ? itemSchema.type : isRecord13(itemSchema.properties) ? "object" : "unknown" : null;
50247
+ const itemSchema = isRecord9(field.items) ? field.items : null;
50248
+ const itemType = itemSchema ? typeof itemSchema.type === "string" ? itemSchema.type : isRecord9(itemSchema.properties) ? "object" : "unknown" : null;
51765
50249
  const itemEnum = Array.isArray(itemSchema?.enum) ? ` enum=${itemSchema.enum.map(String).join("|")}` : "";
51766
50250
  const itemTypeSuffix = itemType && itemType !== "unknown" ? ` items=${itemType}${itemEnum}` : "";
51767
50251
  const minItems = typeof field.minItems === "number" && Number.isFinite(field.minItems) ? field.minItems : null;
@@ -51775,13 +50259,13 @@ function arrayItemBoundsSuffix(field) {
51775
50259
  }
51776
50260
  function printToolExecutionHints(value) {
51777
50261
  const batchCapabilityRecord = recordField2(
51778
- isRecord13(value) ? value : {},
50262
+ isRecord9(value) ? value : {},
51779
50263
  "batchCapability",
51780
50264
  "batch_capability"
51781
50265
  );
51782
50266
  const batchCapability = Object.keys(batchCapabilityRecord).length > 0 ? batchCapabilityRecord : null;
51783
50267
  const executionMetadata = recordField2(
51784
- isRecord13(value) ? value : {},
50268
+ isRecord9(value) ? value : {},
51785
50269
  "executionMetadata",
51786
50270
  "execution_metadata"
51787
50271
  );
@@ -51821,7 +50305,7 @@ function printToolExecutionHints(value) {
51821
50305
  executionMetadata,
51822
50306
  "configuredRateLimits",
51823
50307
  "configured_rate_limits"
51824
- ).filter(isRecord13);
50308
+ ).filter(isRecord9);
51825
50309
  if (configuredRateLimits.length > 0) {
51826
50310
  console.log("");
51827
50311
  console.log(
@@ -51886,17 +50370,17 @@ function printJsonPreview(label, payload) {
51886
50370
  }
51887
50371
  function samplePayload(samples, key) {
51888
50372
  const entry = samples[key];
51889
- if (!isRecord13(entry)) return void 0;
50373
+ if (!isRecord9(entry)) return void 0;
51890
50374
  return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
51891
50375
  }
51892
50376
  function commandEnvelopeFromRawResponse(rawResponse) {
51893
- return isRecord13(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
50377
+ return isRecord9(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
51894
50378
  }
51895
50379
  function toolExecuteExitCode(envelope) {
51896
50380
  return envelope.status === "failed" || envelope.ok === false ? 1 : 0;
51897
50381
  }
51898
50382
  function extractToolExecutionWarningMessages(rawResponse) {
51899
- if (!isRecord13(rawResponse)) return [];
50383
+ if (!isRecord9(rawResponse)) return [];
51900
50384
  const candidates = [
51901
50385
  recordField2(recordField2(rawResponse, "toolResponse"), "meta"),
51902
50386
  recordField2(
@@ -51913,7 +50397,7 @@ function extractToolExecutionWarningMessages(rawResponse) {
51913
50397
  for (const warning of warnings) {
51914
50398
  if (typeof warning === "string" && warning.trim()) {
51915
50399
  messages.push(warning.trim());
51916
- } else if (isRecord13(warning)) {
50400
+ } else if (isRecord9(warning)) {
51917
50401
  const message = stringField2(warning, "message");
51918
50402
  if (message) messages.push(message);
51919
50403
  }
@@ -51922,7 +50406,7 @@ function extractToolExecutionWarningMessages(rawResponse) {
51922
50406
  return [...new Set(messages)];
51923
50407
  }
51924
50408
  function apifySyncRecoveryNext(rawResponse) {
51925
- if (!isRecord13(rawResponse) || rawResponse.status !== "running") return null;
50409
+ if (!isRecord9(rawResponse) || rawResponse.status !== "running") return null;
51926
50410
  const toolResponse = recordField2(rawResponse, "toolResponse");
51927
50411
  const raw = recordField2(toolResponse, "raw");
51928
50412
  if (raw.state !== "awaiting_apify") return null;
@@ -51945,7 +50429,7 @@ function apifySyncRecoveryNext(rawResponse) {
51945
50429
  }
51946
50430
  function listExtractorPathsFromUsageGuidance(tool) {
51947
50431
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
51948
- const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord13(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
50432
+ const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord9(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
51949
50433
  return extractedLists.flatMap((entry) => {
51950
50434
  const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
51951
50435
  if (!Array.isArray(paths)) return [];
@@ -51961,7 +50445,7 @@ function formatDecimal(value) {
51961
50445
  function formatUsd(value) {
51962
50446
  return `$${formatDecimal(value)}`;
51963
50447
  }
51964
- function isRecord13(value) {
50448
+ function isRecord9(value) {
51965
50449
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
51966
50450
  }
51967
50451
  function stringField2(source, ...keys) {
@@ -51988,7 +50472,7 @@ function arrayField2(source, ...keys) {
51988
50472
  function recordField2(source, ...keys) {
51989
50473
  for (const key of keys) {
51990
50474
  const value = source[key];
51991
- if (isRecord13(value)) return value;
50475
+ if (isRecord9(value)) return value;
51992
50476
  }
51993
50477
  return {};
51994
50478
  }
@@ -52054,7 +50538,7 @@ function parseJsonObjectArgument(raw, flagName) {
52054
50538
  }
52055
50539
  throw invalidJsonError(flagName, message);
52056
50540
  }
52057
- if (!isRecord13(parsed)) {
50541
+ if (!isRecord9(parsed)) {
52058
50542
  throw invalidJsonError(flagName, "expected an object.");
52059
50543
  }
52060
50544
  return parsed;
@@ -52256,7 +50740,7 @@ function buildToolExecuteBaseEnvelope(input2) {
52256
50740
  kind: summaryEntries.length > 0 ? "object" : "raw",
52257
50741
  summary: input2.summary
52258
50742
  };
52259
- const envelopeHasCanonicalOutput = isRecord13(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
50743
+ const envelopeHasCanonicalOutput = isRecord9(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
52260
50744
  const envelopeHasDeclaredOutput = Object.prototype.hasOwnProperty.call(
52261
50745
  envelope,
52262
50746
  "output"
@@ -52283,7 +50767,7 @@ function buildToolExecuteBaseEnvelope(input2) {
52283
50767
  return {
52284
50768
  ...envelope,
52285
50769
  ...input2.idempotencyKey ? { idempotency_key: input2.idempotencyKey } : {},
52286
- ...isRecord13(input2.rawResponse) && isRecord13(input2.rawResponse.executionRecovery) ? { execution_recovery: input2.rawResponse.executionRecovery } : {},
50770
+ ...isRecord9(input2.rawResponse) && isRecord9(input2.rawResponse.executionRecovery) ? { execution_recovery: input2.rawResponse.executionRecovery } : {},
52287
50771
  ...envelopeHasCanonicalOutput || envelopeHasDeclaredOutput ? { output_preview: outputPreview } : { output: outputPreview },
52288
50772
  ...summaryEntries.length > 0 ? { summary: input2.summary } : {},
52289
50773
  ...warningMessages.length > 0 ? { warnings: warningMessages } : {},
@@ -52342,7 +50826,7 @@ function buildToolExecuteRowArtifactEnvelope(input2) {
52342
50826
  void _render;
52343
50827
  void _next;
52344
50828
  void _local;
52345
- const billingLookup = isRecord13(input2.baseEnvelope.next) && typeof input2.baseEnvelope.next.billing === "string" ? input2.baseEnvelope.next.billing : null;
50829
+ const billingLookup = isRecord9(input2.baseEnvelope.next) && typeof input2.baseEnvelope.next.billing === "string" ? input2.baseEnvelope.next.billing : null;
52346
50830
  return {
52347
50831
  ...base,
52348
50832
  status: typeof base.status === "string" ? base.status : "completed",
@@ -52518,7 +51002,7 @@ async function executeTool(args) {
52518
51002
  {
52519
51003
  ...baseEnvelope,
52520
51004
  local: {
52521
- ...isRecord13(baseEnvelope.local) ? baseEnvelope.local : {},
51005
+ ...isRecord9(baseEnvelope.local) ? baseEnvelope.local : {},
52522
51006
  payload_file: jsonPath
52523
51007
  }
52524
51008
  },
@@ -52832,7 +51316,7 @@ var PLAY_EQUIVALENT = {
52832
51316
  schema: "deepline plays describe <name>",
52833
51317
  runs: "deepline runs list --play <name>",
52834
51318
  run: "deepline runs get <run-id>",
52835
- tail: "deepline runs tail <run-id>",
51319
+ tail: "deepline runs watch <run-id>",
52836
51320
  cancel: "deepline runs stop <run-id>",
52837
51321
  delete: "deepline plays delete <name>"
52838
51322
  };