deepline 0.3.88 → 0.3.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +534 -4
  2. package/dist/bundling-sources/sdk/src/config.ts +77 -0
  3. package/dist/bundling-sources/sdk/src/http.ts +76 -30
  4. package/dist/bundling-sources/sdk/src/index.ts +6 -0
  5. package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +1 -1
  6. package/dist/bundling-sources/sdk/src/play.ts +15 -1
  7. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +2 -2
  8. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  9. package/dist/bundling-sources/sdk/src/types.ts +83 -4
  10. package/dist/bundling-sources/shared_libs/integration-contracts/AGENTS.md +9 -0
  11. package/dist/bundling-sources/shared_libs/integration-contracts/README.md +3 -0
  12. package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +2 -0
  13. package/dist/bundling-sources/shared_libs/monitors/analytics-install-guides.ts +77 -0
  14. package/dist/bundling-sources/shared_libs/monitors/billing/charges.ts +125 -0
  15. package/dist/bundling-sources/shared_libs/monitors/billing/policy-builders.ts +686 -0
  16. package/dist/bundling-sources/shared_libs/monitors/billing/pricing.ts +54 -0
  17. package/dist/bundling-sources/shared_libs/monitors/billing/public-pricing.ts +72 -0
  18. package/dist/bundling-sources/shared_libs/monitors/billing/session.ts +45 -0
  19. package/dist/bundling-sources/shared_libs/monitors/billing/state.ts +454 -0
  20. package/dist/bundling-sources/shared_libs/monitors/billing/tamradar.ts +260 -0
  21. package/dist/bundling-sources/shared_libs/monitors/billing/types.ts +215 -0
  22. package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +333 -0
  23. package/dist/bundling-sources/shared_libs/monitors/cursor-page.ts +42 -0
  24. package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +16 -0
  25. package/dist/bundling-sources/shared_libs/monitors/framework-managed-payload-fields.ts +71 -0
  26. package/dist/bundling-sources/shared_libs/monitors/generated/provider-monitor-callback-admission-targets.ts +16 -0
  27. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +267 -0
  28. package/dist/bundling-sources/shared_libs/monitors/inbound-publish-key.ts +39 -0
  29. package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +82 -0
  30. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +473 -0
  31. package/dist/bundling-sources/shared_libs/monitors/org-monitor-limits.ts +1 -1
  32. package/dist/bundling-sources/shared_libs/monitors/package.json +29 -0
  33. package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +1125 -0
  34. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +263 -0
  35. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-capability.ts +964 -0
  36. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +56 -0
  37. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-errors.ts +131 -0
  38. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +535 -0
  39. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-legacy-aliases.ts +16 -0
  40. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-priority-execution.ts +56 -0
  41. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +28 -0
  42. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-runtime-read-eligibility.ts +38 -0
  43. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +122 -0
  44. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-status.ts +10 -0
  45. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +112 -0
  46. package/dist/bundling-sources/shared_libs/monitors/provider-webhook-monitor-runtime.ts +300 -0
  47. package/dist/bundling-sources/shared_libs/monitors/quickstart-prompts.ts +22 -0
  48. package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +93 -0
  49. package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +332 -0
  50. package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +221 -0
  51. package/dist/bundling-sources/shared_libs/monitors/starter-templates.ts +105 -0
  52. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-guidance.ts +73 -0
  53. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +81 -0
  54. package/dist/bundling-sources/shared_libs/monitors/tsconfig.json +10 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/activity-observation.ts +6 -11
  56. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +90 -12
  57. package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +78 -0
  58. package/dist/bundling-sources/shared_libs/play-runtime/checkpoint-boundaries.ts +70 -0
  59. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +407 -53
  60. package/dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts +1 -32
  61. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +57 -0
  62. package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +20 -1
  63. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +6 -0
  64. package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +7 -1
  65. package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +189 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +28 -0
  67. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
  68. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +23 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +1 -1
  70. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +18 -4
  71. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +68 -0
  72. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +2 -0
  73. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +1 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +10 -8
  75. package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +20 -0
  76. package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +6 -0
  77. package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +24 -0
  79. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +30 -1
  80. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +1 -1
  81. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +1 -1
  82. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +6 -3
  83. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +454 -17
  84. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +19 -4
  85. package/dist/bundling-sources/shared_libs/plays/contracts.ts +6 -14
  86. package/dist/bundling-sources/shared_libs/plays/core.ts +11 -6
  87. package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +16 -11
  88. package/dist/bundling-sources/shared_libs/plays/email-status.ts +1 -1
  89. package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +1 -1
  90. package/dist/bundling-sources/shared_libs/plays/slug.ts +115 -0
  91. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +44 -14
  92. package/dist/bundling-sources/shared_libs/plays/tool-category-descriptions.ts +2 -2
  93. package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +877 -0
  94. package/dist/bundling-sources/shared_libs/product-notifications/configuration-draft.ts +456 -0
  95. package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +560 -0
  96. package/dist/bundling-sources/shared_libs/product-notifications/content.ts +28 -0
  97. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +59 -0
  98. package/dist/bundling-sources/shared_libs/product-notifications/email.ts +246 -0
  99. package/dist/bundling-sources/shared_libs/product-notifications/evaluation.ts +280 -0
  100. package/dist/bundling-sources/shared_libs/product-notifications/events.ts +433 -0
  101. package/dist/bundling-sources/shared_libs/product-notifications/legacy-slack.ts +80 -0
  102. package/dist/bundling-sources/shared_libs/product-notifications/workspace.ts +38 -0
  103. package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
  104. package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +28 -0
  105. package/dist/bundling-sources/shared_libs/security/internal-actor.ts +50 -0
  106. package/dist/bundling-sources/shared_libs/security/secret-redaction.ts +267 -0
  107. package/dist/cli/index.js +1070 -193
  108. package/dist/cli/index.mjs +1057 -180
  109. package/dist/{compiler-manifest-Dbov16F7.d.mts → compiler-manifest-DsLbQaew.d.mts} +132 -8
  110. package/dist/{compiler-manifest-Dbov16F7.d.ts → compiler-manifest-DsLbQaew.d.ts} +132 -8
  111. package/dist/index.d.mts +834 -12
  112. package/dist/index.d.ts +834 -12
  113. package/dist/index.js +469 -40
  114. package/dist/index.mjs +469 -40
  115. package/dist/install-integrity.json +65 -4
  116. package/dist/plays/bundle-play-file.d.mts +8 -3
  117. package/dist/plays/bundle-play-file.d.ts +8 -3
  118. package/dist/plays/bundle-play-file.mjs +100 -20
  119. package/package.json +3 -1
  120. /package/dist/bundling-sources/shared_libs/{integrations/bettercontact-execution-policy.ts → integration-contracts/bettercontact/execution-policy.ts} +0 -0
  121. /package/dist/bundling-sources/shared_libs/{integrations/theirstack-execution-policy.ts → integration-contracts/theirstack/execution-policy.ts} +0 -0
@@ -7,10 +7,10 @@ import type { ToolExecutionErrorSchemaVersion } from './tool-execution-error';
7
7
  import type { PlayDataset, PlayDatasetInput, PlayDatasetRow } from './dataset';
8
8
 
9
9
  export const LEGACY_PLAY_AUTHORING_CONTRACT_EDITION = 1 as const;
10
- export const PLAY_AUTHORING_CONTRACT_EDITION = 6 as const;
10
+ export const PLAY_AUTHORING_CONTRACT_EDITION = 7 as const;
11
11
  export const PLAY_AUTHORING_INPUT_SCHEMA_SNAPSHOT_EDITION = 3 as const;
12
12
  export const SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS = [
13
- 1, 2, 3, 4, 5, 6,
13
+ 1, 2, 3, 4, 5, 6, 7,
14
14
  ] as const;
15
15
 
16
16
  export type PlayAuthoringContractEdition =
@@ -67,6 +67,14 @@ export const PLAY_AUTHORING_CONTRACT_CHANGELOG = [
67
67
  newWritesEnd: null,
68
68
  readerRemoval: null,
69
69
  },
70
+ {
71
+ edition: 7,
72
+ changed:
73
+ 'Slack HITL calls that omit timeout wait one week. Editions 1–6 retain the historical 24-hour default.',
74
+ compatibilityOwner: 'Plays Runtime',
75
+ newWritesEnd: null,
76
+ readerRemoval: null,
77
+ },
70
78
  ] as const;
71
79
 
72
80
  /**
@@ -276,6 +284,308 @@ export function normalizeAdmittedSqlListenerWhere(
276
284
  }
277
285
  return normalized;
278
286
  }
287
+ export type PlaySqlListenerValidationIssue = {
288
+ severity: 'error' | 'warning';
289
+ code: string;
290
+ path: string;
291
+ message: string;
292
+ expected?: unknown;
293
+ received?: unknown;
294
+ suggestion?: string;
295
+ entity_type?:
296
+ | 'monitor'
297
+ | 'action'
298
+ | 'trigger'
299
+ | 'bundle'
300
+ | 'play'
301
+ | 'listener'
302
+ | 'table'
303
+ | 'tool'
304
+ | 'workflow';
305
+ entity_key?: string;
306
+ docs_ref?: string;
307
+ };
308
+
309
+ function sqlListenerIssue(
310
+ issue: Omit<PlaySqlListenerValidationIssue, 'severity'> & {
311
+ severity?: PlaySqlListenerValidationIssue['severity'];
312
+ },
313
+ ): PlaySqlListenerValidationIssue {
314
+ return { severity: issue.severity ?? 'error', ...issue };
315
+ }
316
+
317
+ const PLAY_SQL_LISTENER_OPERATIONS = new Set<string>([
318
+ 'INSERT',
319
+ 'UPDATE',
320
+ 'DELETE',
321
+ ]);
322
+
323
+ function validateAdmittedSqlListenerWhere(
324
+ input: { where: unknown; path: string; listenerKey: string },
325
+ issues: PlaySqlListenerValidationIssue[],
326
+ ): void {
327
+ if (input.where === undefined) return;
328
+ if (!isPlainRecord(input.where)) {
329
+ issues.push(
330
+ sqlListenerIssue({
331
+ code: 'invalid_sql_listener_filter_shape',
332
+ path: input.path,
333
+ message:
334
+ 'SQL listener where must be a literal object with before and/or after filters.',
335
+ expected:
336
+ '{ before?: Record<string, operators>, after?: Record<string, operators> }',
337
+ received: input.where,
338
+ entity_type: 'listener',
339
+ entity_key: input.listenerKey,
340
+ docs_ref: 'docs/monitor-sdk-architecture-plan.html#v2',
341
+ }),
342
+ );
343
+ return;
344
+ }
345
+ for (const [scope, scopeValue] of Object.entries(input.where)) {
346
+ const scopePath = `${input.path}.${scope}`;
347
+ if (scope !== 'before' && scope !== 'after') {
348
+ issues.push(
349
+ sqlListenerIssue({
350
+ code: 'unsupported_sql_listener_filter_scope',
351
+ path: scopePath,
352
+ message: 'SQL listener filters only support before and after scopes.',
353
+ expected: ['before', 'after'],
354
+ received: scope,
355
+ entity_type: 'listener',
356
+ entity_key: input.listenerKey,
357
+ docs_ref: 'docs/monitor-sdk-architecture-plan.html#v2',
358
+ }),
359
+ );
360
+ continue;
361
+ }
362
+ if (!isPlainRecord(scopeValue)) {
363
+ issues.push(
364
+ sqlListenerIssue({
365
+ code: 'invalid_sql_listener_filter_scope',
366
+ path: scopePath,
367
+ message: `SQL listener where.${scope} must be an object keyed by top-level row field.`,
368
+ expected: 'Record<field, operators>',
369
+ received: scopeValue,
370
+ entity_type: 'listener',
371
+ entity_key: input.listenerKey,
372
+ docs_ref: 'docs/monitor-sdk-architecture-plan.html#v2',
373
+ }),
374
+ );
375
+ continue;
376
+ }
377
+ for (const [field, operators] of Object.entries(scopeValue)) {
378
+ const fieldPath = `${scopePath}.${field}`;
379
+ if (!PLAY_SQL_LISTENER_FIELD_PATTERN.test(field)) {
380
+ issues.push(
381
+ sqlListenerIssue({
382
+ code: 'invalid_sql_listener_filter_field',
383
+ path: fieldPath,
384
+ message:
385
+ 'SQL listener filters only support top-level row fields with plain identifier names.',
386
+ expected: PLAY_SQL_LISTENER_FIELD_PATTERN.source,
387
+ received: field,
388
+ suggestion:
389
+ 'Use a top-level column key such as "country" instead of a path expression.',
390
+ entity_type: 'listener',
391
+ entity_key: input.listenerKey,
392
+ docs_ref: 'docs/monitor-sdk-architecture-plan.html#v2',
393
+ }),
394
+ );
395
+ }
396
+ if (!isPlainRecord(operators)) {
397
+ issues.push(
398
+ sqlListenerIssue({
399
+ code: 'invalid_sql_listener_filter_condition',
400
+ path: fieldPath,
401
+ message:
402
+ 'SQL listener field filters must be an object keyed by a supported operator, e.g. { eq: <value> } — got a bare value.',
403
+ expected: PLAY_SQL_LISTENER_WHERE_OPERATORS,
404
+ received: operators,
405
+ entity_type: 'listener',
406
+ entity_key: input.listenerKey,
407
+ docs_ref: 'docs/monitor-sdk-architecture-plan.html#v2',
408
+ }),
409
+ );
410
+ continue;
411
+ }
412
+ if (Object.keys(operators).length === 0) {
413
+ issues.push(
414
+ sqlListenerIssue({
415
+ code: 'empty_sql_listener_filter_condition',
416
+ path: fieldPath,
417
+ message:
418
+ 'SQL listener field filters must contain at least one operator.',
419
+ expected: PLAY_SQL_LISTENER_WHERE_OPERATORS,
420
+ received: operators,
421
+ entity_type: 'listener',
422
+ entity_key: input.listenerKey,
423
+ docs_ref: 'docs/monitor-sdk-architecture-plan.html#v2',
424
+ }),
425
+ );
426
+ }
427
+ for (const [operator, value] of Object.entries(operators)) {
428
+ const operatorPath = `${fieldPath}.${operator}`;
429
+ if (!PLAY_SQL_LISTENER_WHERE_OPERATOR_SET.has(operator)) {
430
+ issues.push(
431
+ sqlListenerIssue({
432
+ code: 'unsupported_sql_listener_filter_operator',
433
+ path: operatorPath,
434
+ message: `SQL listener filter operator "${operator}" is not supported.`,
435
+ expected: PLAY_SQL_LISTENER_WHERE_OPERATORS,
436
+ received: operator,
437
+ suggestion: `Use ${PLAY_SQL_LISTENER_WHERE_OPERATORS.slice(0, -1).join(', ')}, or ${PLAY_SQL_LISTENER_WHERE_OPERATORS.at(-1)}.`,
438
+ entity_type: 'listener',
439
+ entity_key: input.listenerKey,
440
+ docs_ref: 'docs/monitor-sdk-architecture-plan.html#v2',
441
+ }),
442
+ );
443
+ continue;
444
+ }
445
+ const valid =
446
+ ((operator === 'in' || operator === 'notIn') &&
447
+ Array.isArray(value) &&
448
+ value.length > 0 &&
449
+ value.every(isPlaySqlListenerFilterScalar)) ||
450
+ ((operator === 'isNull' || operator === 'isNotNull') &&
451
+ value === true) ||
452
+ (operator === 'ilike' &&
453
+ typeof value === 'string' &&
454
+ value.length > 0) ||
455
+ ((operator === 'eq' || operator === 'neq') &&
456
+ isPlaySqlListenerFilterScalar(value));
457
+ if (!valid) {
458
+ issues.push(
459
+ sqlListenerIssue({
460
+ code: 'invalid_sql_listener_filter_value',
461
+ path: operatorPath,
462
+ message: `SQL listener filter operator "${operator}" has an invalid value.`,
463
+ received: value,
464
+ entity_type: 'listener',
465
+ entity_key: input.listenerKey,
466
+ docs_ref: 'docs/monitor-sdk-architecture-plan.html#v2',
467
+ }),
468
+ );
469
+ }
470
+ }
471
+ }
472
+ }
473
+ }
474
+
475
+ /** Validate only a stored binding snapshot that already crossed admission. */
476
+ export function validateAdmittedSqlListenerBindings(
477
+ bindings: PlayAuthoringAstBindings | null | undefined,
478
+ input: { playName?: string; pathPrefix?: string } = {},
479
+ ): PlaySqlListenerValidationIssue[] {
480
+ const issues: PlaySqlListenerValidationIssue[] = [];
481
+ const listeners = bindings?.sqlListeners;
482
+ if (!listeners) return issues;
483
+ const seen = new Set<string>();
484
+ listeners.forEach((listener, index) => {
485
+ const path = `${input.pathPrefix ?? 'sqlListeners'}[${index}]`;
486
+ const listenerKey = input.playName
487
+ ? `${input.playName}.${listener.id}`
488
+ : listener.id;
489
+ if (!listener.id || !PLAY_SQL_LISTENER_ID_PATTERN.test(listener.id)) {
490
+ issues.push(
491
+ sqlListenerIssue({
492
+ code: 'invalid_sql_listener_id',
493
+ path: `${path}.id`,
494
+ message:
495
+ 'SQL listener id must start with a letter and contain only letters, numbers, underscores, or hyphens.',
496
+ expected: PLAY_SQL_LISTENER_ID_PATTERN.source,
497
+ received: listener.id,
498
+ entity_type: 'listener',
499
+ entity_key: listenerKey,
500
+ }),
501
+ );
502
+ }
503
+ if (seen.has(listener.id)) {
504
+ issues.push(
505
+ sqlListenerIssue({
506
+ code: 'duplicate_sql_listener_id',
507
+ path: `${path}.id`,
508
+ message: `SQL listener id "${listener.id}" is already used in this play.`,
509
+ received: listener.id,
510
+ entity_type: 'listener',
511
+ entity_key: listenerKey,
512
+ }),
513
+ );
514
+ }
515
+ seen.add(listener.id);
516
+ if (!listener.tool || !PLAY_SQL_LISTENER_TOOL_PATTERN.test(listener.tool)) {
517
+ issues.push(
518
+ sqlListenerIssue({
519
+ code: listener.tool
520
+ ? 'invalid_sql_listener_tool'
521
+ : 'missing_sql_listener_tool',
522
+ path: `${path}.tool`,
523
+ message: 'SQL listener tool must use provider.tool syntax.',
524
+ expected: PLAY_SQL_LISTENER_TOOL_PATTERN.source,
525
+ received: listener.tool,
526
+ entity_type: 'tool',
527
+ entity_key: listener.tool || listenerKey,
528
+ }),
529
+ );
530
+ }
531
+ if (
532
+ !listener.stream ||
533
+ !PLAY_SQL_LISTENER_ID_PATTERN.test(listener.stream)
534
+ ) {
535
+ issues.push(
536
+ sqlListenerIssue({
537
+ code: listener.stream
538
+ ? 'invalid_sql_listener_stream'
539
+ : 'missing_sql_listener_stream',
540
+ path: `${path}.stream`,
541
+ message:
542
+ 'SQL listener stream keys must start with a letter and contain only letters, numbers, underscores, or hyphens.',
543
+ expected: PLAY_SQL_LISTENER_ID_PATTERN.source,
544
+ received: listener.stream,
545
+ entity_type: 'listener',
546
+ entity_key: listenerKey,
547
+ }),
548
+ );
549
+ }
550
+ validateAdmittedSqlListenerWhere(
551
+ { where: listener.where, path: `${path}.where`, listenerKey },
552
+ issues,
553
+ );
554
+ if (
555
+ !Array.isArray(listener.operations) ||
556
+ listener.operations.length === 0
557
+ ) {
558
+ issues.push(
559
+ sqlListenerIssue({
560
+ code: 'empty_sql_listener_operations',
561
+ path: `${path}.operations`,
562
+ message: 'SQL listener operations must not be empty.',
563
+ expected: [...PLAY_SQL_LISTENER_OPERATIONS],
564
+ received: listener.operations,
565
+ entity_type: 'listener',
566
+ entity_key: listenerKey,
567
+ }),
568
+ );
569
+ } else if (
570
+ listener.operations.some(
571
+ (operation) => !PLAY_SQL_LISTENER_OPERATIONS.has(operation),
572
+ )
573
+ ) {
574
+ issues.push(
575
+ sqlListenerIssue({
576
+ code: 'invalid_sql_listener_operation',
577
+ path: `${path}.operations`,
578
+ message: 'SQL listener operations must be INSERT, UPDATE, or DELETE.',
579
+ expected: [...PLAY_SQL_LISTENER_OPERATIONS],
580
+ received: listener.operations,
581
+ entity_type: 'listener',
582
+ entity_key: listenerKey,
583
+ }),
584
+ );
585
+ }
586
+ });
587
+ return issues;
588
+ }
279
589
  export type PlaySqlListenerDeclaration = {
280
590
  id: string;
281
591
  tool: string;
@@ -615,6 +925,8 @@ export type PlayAuthoringDefinedPlay<
615
925
  readonly runtime?: PlayAuthoringBindings<TInput>['runtime'];
616
926
  readonly compatibility?: PlayAuthoringBindings<TInput>['compatibility'];
617
927
  readonly playName: string;
928
+ /** Type-only input carrier used by typed Play-reference consumers. */
929
+ readonly __inputType?: TInput;
618
930
  };
619
931
 
620
932
  /** Canonical resolver shape for a customer-authored durable step. */
@@ -851,20 +1163,14 @@ export type PlayAuthoringDatasetBuilder<
851
1163
  TContext
852
1164
  >;
853
1165
  /** Add all columns declared by one reusable step program. */
854
- withColumns<
855
- Program extends PlayAuthoringStepProgram<
1166
+ withColumns<ProgramOutput extends OutputRow, Return>(
1167
+ program: PlayAuthoringStepProgram<
856
1168
  OutputRow,
857
- object,
1169
+ ProgramOutput,
858
1170
  TContext,
859
- unknown
1171
+ Return
860
1172
  >,
861
- >(
862
- program: Program,
863
- ): PlayAuthoringDatasetBuilder<
864
- InputRow,
865
- PlayAuthoringStepProgramOutput<Program>,
866
- TContext
867
- >;
1173
+ ): PlayAuthoringDatasetBuilder<InputRow, ProgramOutput, TContext>;
868
1174
  /** @deprecated Dataset `.step(...)` was replaced by `.withColumn(...)`. */
869
1175
  step<Name extends string, Value>(
870
1176
  name: Name,
@@ -881,9 +1187,34 @@ export type PlayAuthoringDatasetBuilder<
881
1187
  ): Promise<PlayDataset<OutputRow>>;
882
1188
  };
883
1189
 
884
- export type PlayAuthoringReferenceLike =
1190
+ export type PlayAuthoringReferenceLike<
1191
+ TInput extends Record<string, unknown> = Record<string, unknown>,
1192
+ > = (
885
1193
  | { readonly playName: string; readonly name?: string }
886
- | { readonly name: string; readonly playName?: string };
1194
+ | { readonly name: string; readonly playName?: string }
1195
+ ) & {
1196
+ /** Type-only input carrier used by ctx.runPlayAsync. */
1197
+ readonly __inputType?: TInput;
1198
+ };
1199
+
1200
+ declare const PLAY_RUN_ID_BRAND: unique symbol;
1201
+
1202
+ /** Branded run identity returned inside {@link AsyncPlayRunRef}. */
1203
+ export type PlayRunId = string & {
1204
+ readonly [PLAY_RUN_ID_BRAND]: 'PlayRunId';
1205
+ };
1206
+
1207
+ /**
1208
+ * Serializable reference returned after an async child Run is durable.
1209
+ * @sdkReference runtime 143 AsyncPlayRunRef
1210
+ */
1211
+ export type AsyncPlayRunRef = Readonly<{
1212
+ runId: PlayRunId;
1213
+ }>;
1214
+
1215
+ export type PlayAuthoringAsyncCallOptions = Readonly<{
1216
+ description: string;
1217
+ }>;
887
1218
 
888
1219
  /** Discoverable, non-deprecated Runtime Context members shown to Play authors. */
889
1220
  export const PLAY_AUTHORING_RUNTIME_CONTEXT_MEMBERS = [
@@ -894,6 +1225,7 @@ export const PLAY_AUTHORING_RUNTIME_CONTEXT_MEMBERS = [
894
1225
  'log',
895
1226
  'run',
896
1227
  'runPlay',
1228
+ 'runPlayAsync',
897
1229
  'runSteps',
898
1230
  'secrets',
899
1231
  'sleep',
@@ -1239,6 +1571,27 @@ export interface PlayAuthoringRuntimeContext {
1239
1571
  options: PlayAuthoringCallOptions,
1240
1572
  ): Promise<TOutput>;
1241
1573
 
1574
+ /**
1575
+ * Admit an independent scalar Play Run and return its durable identity after scheduler admission, before child completion.
1576
+ * @sdkReference runtime 141 ctx.runPlayAsync(key, playRef, input, options)
1577
+ */
1578
+ runPlayAsync<TInput extends Record<string, unknown>>(
1579
+ /** Replay-stable identity for this launch site and row scope. */
1580
+ key: string,
1581
+ /** Independently published Play name or definePlay handle carrying its input type. */
1582
+ playRef: PlayAuthoringReferenceLike<TInput>,
1583
+ /** Input checked against the referenced definePlay handle when available. */
1584
+ input: NoInfer<TInput>,
1585
+ /** Human-readable launch purpose recorded in the parent's step history. */
1586
+ options: PlayAuthoringAsyncCallOptions,
1587
+ ): Promise<AsyncPlayRunRef>;
1588
+ runPlayAsync(
1589
+ key: string,
1590
+ playRef: string,
1591
+ input: Record<string, unknown>,
1592
+ options: PlayAuthoringAsyncCallOptions,
1593
+ ): Promise<AsyncPlayRunRef>;
1594
+
1242
1595
  /**
1243
1596
  * Write a customer-safe line to the durable Run Log Stream. Omitting level
1244
1597
  * preserves the historical info-level behavior.
@@ -2298,6 +2651,84 @@ export const PLAY_AUTHORING_FIELD_REGISTRY = {
2298
2651
  errorMessage:
2299
2652
  'ctx.runPlay timeoutMs is unsupported because child Plays execute inline.',
2300
2653
  },
2654
+ 'ctx.runPlayAsync.key': {
2655
+ schema: Type.String({ minLength: 1 }),
2656
+ fixtures: {
2657
+ valid: 'request-approval',
2658
+ invalid: '',
2659
+ absent: undefined,
2660
+ unresolved: { expression: 'callKey' },
2661
+ edition1: 'request-approval',
2662
+ },
2663
+ referenceType: 'string',
2664
+ required: true,
2665
+ resolution: 'runtime-dynamic',
2666
+ issueCode: 'play_authoring_run_play_option_invalid',
2667
+ description: 'Stable identity for one independent child Play Run.',
2668
+ errorMessage: 'ctx.runPlayAsync key must be a non-empty string.',
2669
+ },
2670
+ 'ctx.runPlayAsync.playRef': {
2671
+ schema: Type.Union([
2672
+ Type.String({ minLength: 1 }),
2673
+ Type.Union([
2674
+ Type.Object(
2675
+ { playName: Type.String({ minLength: 1 }) },
2676
+ { additionalProperties: true },
2677
+ ),
2678
+ Type.Object(
2679
+ { name: Type.String({ minLength: 1 }) },
2680
+ { additionalProperties: true },
2681
+ ),
2682
+ ]),
2683
+ ]),
2684
+ fixtures: {
2685
+ valid: 'request-approval',
2686
+ invalid: {},
2687
+ absent: undefined,
2688
+ unresolved: { expression: 'playRef' },
2689
+ edition1: 'request-approval',
2690
+ },
2691
+ referenceType: 'string | PlayReferenceLike',
2692
+ required: true,
2693
+ resolution: 'runtime-dynamic',
2694
+ issueCode: 'play_authoring_run_play_option_invalid',
2695
+ description:
2696
+ 'Independently published scalar child Play name or strongly typed definition handle.',
2697
+ errorMessage:
2698
+ 'ctx.runPlayAsync playRef must be a non-empty Play name or definition handle.',
2699
+ },
2700
+ 'ctx.runPlayAsync.input': {
2701
+ schema: Type.Record(Type.String(), Type.Unknown()),
2702
+ fixtures: {
2703
+ valid: { draftId: 'draft-1' },
2704
+ invalid: 'draft-1',
2705
+ absent: undefined,
2706
+ unresolved: 'childInput',
2707
+ edition1: {},
2708
+ },
2709
+ referenceType: 'Record<string, unknown>',
2710
+ required: true,
2711
+ resolution: 'runtime-dynamic',
2712
+ issueCode: 'play_authoring_run_play_option_invalid',
2713
+ description: 'Scalar input object submitted to the independent child Run.',
2714
+ errorMessage: 'ctx.runPlayAsync input must be an object.',
2715
+ },
2716
+ 'ctx.runPlayAsync.options.description': {
2717
+ schema: Type.String({ minLength: 1 }),
2718
+ fixtures: {
2719
+ valid: 'Request approval.',
2720
+ invalid: '',
2721
+ absent: undefined,
2722
+ unresolved: { expression: 'description' },
2723
+ edition1: 'Request approval.',
2724
+ },
2725
+ referenceType: 'string',
2726
+ required: true,
2727
+ resolution: 'runtime-dynamic',
2728
+ issueCode: 'play_authoring_run_play_option_invalid',
2729
+ description: 'Non-empty purpose for one independent child Play Run.',
2730
+ errorMessage: 'ctx.runPlayAsync options.description must be non-empty.',
2731
+ },
2301
2732
  'runtime.timeout': {
2302
2733
  schema: Type.String({ pattern: '^\\d+\\s*[mh]$' }),
2303
2734
  fixtures: {
@@ -2747,6 +3178,10 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
2747
3178
  `export type CsvOptions = { description?: ${cloudReferenceType('ctx.csv.options.description')}; columns?: ${cloudReferenceType('ctx.csv.options.columns')}; rename?: ${cloudReferenceType('ctx.csv.options.rename')}; required?: ${cloudReferenceType('ctx.csv.options.required')} };`,
2748
3179
  "export type PlayCallExecution = 'inline';",
2749
3180
  `export type PlayCallOptions = { description: ${cloudReferenceType('ctx.runPlay.options.description')}; execution?: ${cloudReferenceType('ctx.runPlay.options.execution')}; timeoutMs?: ${cloudReferenceType('ctx.runPlay.options.timeoutMs')} };`,
3181
+ `export type PlayAsyncCallOptions = { description: ${cloudReferenceType('ctx.runPlayAsync.options.description')} };`,
3182
+ 'declare const PLAY_RUN_ID_BRAND: unique symbol;',
3183
+ "export type PlayRunId = string & { readonly [PLAY_RUN_ID_BRAND]: 'PlayRunId' };",
3184
+ 'export type AsyncPlayRunRef = Readonly<{ runId: PlayRunId }>;',
2750
3185
  `export type RuntimeStepOptions = { semanticKey?: ${cloudReferenceType('ctx.step.semanticKey')}; staleAfterSeconds?: ${cloudReferenceType('ctx.step.staleAfterSeconds')} };`,
2751
3186
  `export type FetchOptions = { staleAfterSeconds?: ${cloudReferenceType('ctx.fetch.staleAfterSeconds')}; transient?: boolean };`,
2752
3187
  'export type PlayFetchResponse = { ok: boolean; status: number; statusText: string; url: string; headers: Record<string, string>; bodyText: string; json: unknown | null };',
@@ -2772,11 +3207,11 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
2772
3207
  ' withColumn<Name extends string, Value>(name: Name, definition: DatasetColumnDefinition<OutputRow, Value> & { readonly runIf: (row: OutputRow, index: number) => boolean | Promise<boolean> }): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;',
2773
3208
  ' withColumn<Name extends string, Value>(name: Name, definition: DatasetColumnDefinition<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value>>;',
2774
3209
  ' withColumn<Name extends string, Value>(name: Name, resolver: StepResolver<OutputRow, Value> | RunnableColumnStepProgram<Value>, options: StepOptions<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;',
2775
- ' withColumns<Program extends StepProgram<OutputRow, object, unknown>>(program: Program): DatasetBuilder<InputRow, StepProgramOutput<Program>>;',
3210
+ ' withColumns<ProgramOutput extends OutputRow, Return>(program: StepProgram<OutputRow, ProgramOutput, Return>): DatasetBuilder<InputRow, ProgramOutput>;',
2776
3211
  ' step<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): never;',
2777
3212
  ' run(options?: DatasetRunOptions<InputRow>): Promise<PlayDataset<OutputRow>>;',
2778
3213
  '};',
2779
- 'export type PlayReferenceLike = { readonly playName: string; readonly name?: string } | { readonly name: string; readonly playName?: string };',
3214
+ 'export type PlayReferenceLike<TInput extends Record<string, unknown> = Record<string, unknown>> = ({ readonly playName: string; readonly name?: string } | { readonly name: string; readonly playName?: string }) & { readonly __inputType?: TInput };',
2780
3215
  'export interface DeeplinePlayRuntimeContext {',
2781
3216
  ' csv<T = Record<string, unknown>>(path: string | CsvInput<T & object>, options?: CsvOptions): Promise<PlayDataset<T>>;',
2782
3217
  ' dataset<TSource extends PlayDatasetInput<object>>(key: string, items: TSource): DatasetBuilder<PlayDatasetRow<TSource> & object, PlayDatasetRow<TSource> & object>;',
@@ -2790,6 +3225,8 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
2790
3225
  " fetch(key: string, url: string | URL, init?: RequestInit & { headers?: HeadersInit & { 'Idempotency-Key'?: string; 'X-Idempotency-Key'?: string }; auth?: SecretAuthInput }, options?: FetchOptions): Promise<PlayFetchResponse>;",
2791
3226
  ' secrets: { get(name: string): SecretPromise; bearer(secret: string | SecretPromise | SecretHandle): SecretAuth; header(header: string, secret: string | SecretPromise | SecretHandle): SecretAuth };',
2792
3227
  ` runPlay<TOutput = unknown>(key: string, playRef: ${cloudReferenceType('ctx.runPlay.playRef')}, input: ${cloudReferenceType('ctx.runPlay.input')}, options: PlayCallOptions): Promise<TOutput>;`,
3228
+ ' runPlayAsync<TInput extends Record<string, unknown>>(key: string, playRef: PlayReferenceLike<TInput>, input: NoInfer<TInput>, options: PlayAsyncCallOptions): Promise<AsyncPlayRunRef>;',
3229
+ ' runPlayAsync(key: string, playRef: string, input: Record<string, unknown>, options: PlayAsyncCallOptions): Promise<AsyncPlayRunRef>;',
2793
3230
  " log(message: string, options?: { level?: 'debug' | 'info' | 'warn' | 'error' }): void;",
2794
3231
  ` sleep(ms: ${cloudReferenceType('ctx.sleep.ms')}): Promise<void>;`,
2795
3232
  '}',
@@ -63,7 +63,7 @@ import { PLAY_AUTHORING_CONTRACT_EDITION } from '../authoring-contract';
63
63
  // of the artifact bytes. Do not reuse a local bundle cached before either
64
64
  // compatibility selection or docflow instrumentation entered graph analysis.
65
65
  // Keep this aligned with the app and SDK adapters' cache namespace.
66
- const PLAY_BUNDLE_CACHE_VERSION = 36;
66
+ const PLAY_BUNDLE_CACHE_VERSION = 37;
67
67
  const PLAY_ARTIFACT_CACHE_DIR = join(
68
68
  tmpdir(),
69
69
  `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`,
@@ -122,7 +122,12 @@ export type PlayLocalFileDiscoveryResult = {
122
122
 
123
123
  export type PlayBundlingAdapter = {
124
124
  projectRoot: string;
125
- /** Optional root used only to make source-graph identity independent of temporary absolute paths. */
125
+ /**
126
+ * Optional root that makes the artifact independent of where it was built:
127
+ * source paths in the graph hash and esbuild's working directory (which it
128
+ * writes into every module-header comment, and so into `artifactHash`) are
129
+ * both taken relative to it instead of to the build's absolute location.
130
+ */
126
131
  sourceIdentityRoot?: string;
127
132
  nodeModulesDir: string;
128
133
  cacheDir?: string;
@@ -2247,6 +2252,7 @@ async function runEsbuildForCjsNode(
2247
2252
  importedPlayDependencies: ImportedPlayDependency[],
2248
2253
  adapter: PlayBundlingAdapter,
2249
2254
  exportName: string,
2255
+ bundleRoot: string,
2250
2256
  ): Promise<EsbuildBundleOutput | string[]> {
2251
2257
  const sdkAliasPlugin = localSdkAliasPlugin(adapter);
2252
2258
  const playProxyPlugin = importedPlayProxyPlugin(importedPlayDependencies);
@@ -2269,7 +2275,14 @@ async function runEsbuildForCjsNode(
2269
2275
  },
2270
2276
  }
2271
2277
  : { entryPoints: [entryFile] }),
2272
- absWorkingDir: adapter.projectRoot,
2278
+ // esbuild writes `// <path relative to absWorkingDir>` above every module
2279
+ // it inlines, and artifactHash is sha256 of those bytes. Rooting the build
2280
+ // at the identity root keeps the customer's own files repo-relative, so a
2281
+ // deploy worker building the same commit in a fresh temp directory each
2282
+ // time produces the same bytes. Files outside the root (the SDK on the
2283
+ // worker image) come out as a `..`-prefixed path whose shape depends only
2284
+ // on the image's layout, which is fixed, not on the build's name.
2285
+ absWorkingDir: bundleRoot,
2273
2286
  bundle: true,
2274
2287
  format: 'cjs',
2275
2288
  nodePaths: [adapter.nodeModulesDir],
@@ -2416,12 +2429,14 @@ export async function bundlePlayFile(
2416
2429
  };
2417
2430
  }
2418
2431
 
2432
+ const bundleRoot = resolve(sourceIdentityRoot ?? adapter.projectRoot);
2419
2433
  const buildOutcome = await runEsbuildForCjsNode(
2420
2434
  absolutePath,
2421
2435
  analysis.importPolicy.localFiles,
2422
2436
  analysis.importedPlayDependencies,
2423
2437
  adapter,
2424
2438
  exportName,
2439
+ bundleRoot,
2425
2440
  );
2426
2441
  if (Array.isArray(buildOutcome)) {
2427
2442
  return {
@@ -2434,7 +2449,7 @@ export async function bundlePlayFile(
2434
2449
 
2435
2450
  const normalizedSourceMap = normalizeSourceMapForRuntime(
2436
2451
  sourceMapText,
2437
- resolve(adapter.projectRoot),
2452
+ bundleRoot,
2438
2453
  );
2439
2454
  const virtualBaseName =
2440
2455
  exportName === 'default'
@@ -28,21 +28,16 @@ export type PlayRuntimeFeature =
28
28
  | 'durable_sleep'
29
29
  | 'packaged_files';
30
30
 
31
- export const PLAY_PUBLIC_API_VERSION = 1;
32
31
  export const PLAY_ARTIFACT_VERSION = CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION;
33
- export const PLAY_MIN_RUNNER_VERSION = 1;
34
- export const PLAY_RUNTIME_FEATURES: PlayRuntimeFeature[] = [
35
- 'artifact_storage',
36
- 'checkpoint_resume',
37
- 'durable_sleep',
38
- 'packaged_files',
39
- ];
40
32
 
41
33
  export type PlayContractCompatibilitySnapshot = {
42
- apiVersion: number;
34
+ /** Historical marker. Nothing admits, gates, or branches on it. */
35
+ apiVersion?: number;
43
36
  artifactVersion: number;
44
- minRunnerVersion: number;
45
- runtimeFeatures: PlayRuntimeFeature[];
37
+ /** Historical marker. Every runner reads every artifact. */
38
+ minRunnerVersion?: number;
39
+ /** Historical marker. Capabilities are named per operation, not listed here. */
40
+ runtimeFeatures?: PlayRuntimeFeature[];
46
41
  runtimeBackend?: string | null;
47
42
  /** Every Play run uses the structured tool-error contract. */
48
43
  toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
@@ -142,10 +137,7 @@ export function buildPlayContractCompatibility(input?: {
142
137
  toolResponseReceiptRevision?: string;
143
138
  }): PlayContractCompatibilitySnapshot {
144
139
  return {
145
- apiVersion: PLAY_PUBLIC_API_VERSION,
146
140
  artifactVersion: PLAY_ARTIFACT_VERSION,
147
- minRunnerVersion: PLAY_MIN_RUNNER_VERSION,
148
- runtimeFeatures: [...PLAY_RUNTIME_FEATURES],
149
141
  runtimeBackend: input?.runtimeBackend ?? null,
150
142
  toolErrorSchemaVersion:
151
143
  input?.toolErrorSchemaVersion ?? TOOL_EXECUTION_ERROR_SCHEMA_VERSION,