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
@@ -49,6 +49,12 @@ export const HOST_URL_ENV = 'DEEPLINE_HOST_URL';
49
49
  export const API_KEY_ENV = 'DEEPLINE_API_KEY';
50
50
  export const ACTIVE_ORG_ID_ENV = 'DEEPLINE_ACTIVE_ORG_ID';
51
51
  export const ACTIVE_ORG_NAME_ENV = 'DEEPLINE_ACTIVE_ORG_NAME';
52
+ /**
53
+ * Comma-separated gated feature keys the server reported for the active
54
+ * workspace (`github-deploy`, …). Refreshed whenever credentials are saved;
55
+ * the CLI hides gated command groups whose key is absent.
56
+ */
57
+ export const FEATURES_ENV = 'DEEPLINE_FEATURES';
52
58
 
53
59
  /** Production API base URL. */
54
60
  const PROD_URL = 'https://code.deepline.com';
@@ -83,8 +89,70 @@ const CLI_ENV_ALLOWED_KEYS = new Set([
83
89
  API_KEY_ENV,
84
90
  ACTIVE_ORG_ID_ENV,
85
91
  ACTIVE_ORG_NAME_ENV,
92
+ FEATURES_ENV,
86
93
  ]);
87
94
 
95
+ /** Env line for a server-reported `features` list; absent input writes nothing. */
96
+ export function featureEnvValues(data: {
97
+ features?: unknown;
98
+ }): Record<string, string> {
99
+ if (!Array.isArray(data.features)) return {};
100
+ return {
101
+ [FEATURES_ENV]: data.features
102
+ .filter(
103
+ (key): key is string => typeof key === 'string' && key.trim() !== '',
104
+ )
105
+ .map((key) => key.trim())
106
+ .join(','),
107
+ };
108
+ }
109
+
110
+ /** The API key saved in the host's global credentials, or '' when none. */
111
+ export function storedHostApiKey(baseUrl: string): string {
112
+ return loadCliEnv(normalizeBaseUrl(baseUrl) || baseUrl)[API_KEY_ENV] ?? '';
113
+ }
114
+
115
+ /** The raw features line saved with the host's global credentials, if any. */
116
+ export function storedHostFeatures(baseUrl: string): string | undefined {
117
+ return loadCliEnv(normalizeBaseUrl(baseUrl) || baseUrl)[FEATURES_ENV];
118
+ }
119
+
120
+ /** Whether a stored features list names `feature`. */
121
+ export function envHasFeature(env: EnvValues, feature: string): boolean {
122
+ return (env[FEATURES_ENV] ?? '')
123
+ .split(',')
124
+ .map((key) => key.trim())
125
+ .includes(feature);
126
+ }
127
+
128
+ /**
129
+ * Whether the active workspace was last seen with `feature` enabled. Reads
130
+ * the same credential sources, in the same order, as the API key: process
131
+ * env, the folder credentials pinned to the resolved host, then the host's
132
+ * global credentials. A host that cannot be resolved counts as no feature.
133
+ */
134
+ export function cliFeatureEnabled(feature: string): boolean {
135
+ const processEnv = process.env as EnvValues;
136
+ if (envHasFeature(processEnv, feature)) return true;
137
+ // A process-env key wins for API calls, so only process-env features may
138
+ // describe it: a stored file's list belongs to a different credential.
139
+ if (processEnv[API_KEY_ENV]?.trim()) return false;
140
+ try {
141
+ const baseUrl = resolveBaseUrlOnly();
142
+ // The credential source that supplies the key also owns the features:
143
+ // a folder credential with no features line means "none", never "ask
144
+ // the global file", which may belong to a different workspace.
145
+ const projectEnv = loadProjectEnvCandidates().find(
146
+ ({ env }) =>
147
+ normalizeBaseUrl(env[HOST_URL_ENV] ?? '') === baseUrl &&
148
+ Boolean(env[API_KEY_ENV]),
149
+ );
150
+ return envHasFeature(projectEnv?.env ?? loadCliEnv(baseUrl), feature);
151
+ } catch {
152
+ return false;
153
+ }
154
+ }
155
+
88
156
  export type CliCommandContext = {
89
157
  active_organization: {
90
158
  org_id: string;
@@ -402,6 +470,12 @@ function mergePersistedEnvValues(
402
470
  ) {
403
471
  delete merged[ACTIVE_ORG_ID_ENV];
404
472
  delete merged[ACTIVE_ORG_NAME_ENV];
473
+ delete merged[FEATURES_ENV];
474
+ }
475
+ // An explicit empty features list means "none": drop the stale line
476
+ // rather than keeping the previous workspace's features around.
477
+ if (values[FEATURES_ENV] === '') {
478
+ delete merged[FEATURES_ENV];
405
479
  }
406
480
  return merged;
407
481
  }
@@ -582,6 +656,9 @@ export function resolveConfig(options?: DeeplineClientOptions): ResolvedConfig {
582
656
  baseUrl,
583
657
  timeout: options?.timeout ?? DEFAULT_TIMEOUT,
584
658
  maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES,
659
+ // Pass through untouched: the transport owns case-insensitive merging so
660
+ // there is exactly one place that decides which header wins.
661
+ ...(options?.headers ? { headers: { ...options.headers } } : {}),
585
662
  };
586
663
  }
587
664
 
@@ -104,6 +104,31 @@ function normalizeRequestAbortError(
104
104
  return normalized;
105
105
  }
106
106
 
107
+ /**
108
+ * Merge caller-supplied headers over everything the transport already derived
109
+ * from the environment, so an explicitly passed header always wins.
110
+ *
111
+ * HTTP header names are case-insensitive, so an existing header is removed by
112
+ * case-insensitive match before the normalized lowercase name is set. Without
113
+ * that, `Authorization` and `authorization` would both survive into the record
114
+ * and `new Headers(record)` would concatenate the two values.
115
+ */
116
+ function applyExplicitHeaders(
117
+ headers: Record<string, string>,
118
+ explicit: Record<string, string> | undefined,
119
+ ): Record<string, string> {
120
+ if (!explicit) return headers;
121
+ for (const [rawName, value] of Object.entries(explicit)) {
122
+ const name = rawName.trim().toLowerCase();
123
+ if (!name) continue;
124
+ for (const existing of Object.keys(headers)) {
125
+ if (existing.toLowerCase() === name) delete headers[existing];
126
+ }
127
+ headers[name] = value;
128
+ }
129
+ return headers;
130
+ }
131
+
107
132
  function isAbortLikeError(error: Error): boolean {
108
133
  const name = error.name.toLowerCase();
109
134
  const message = error.message.toLowerCase();
@@ -114,6 +139,17 @@ function isAbortLikeError(error: Error): boolean {
114
139
  );
115
140
  }
116
141
 
142
+ function withErrorCause<T extends Error>(error: T, cause: unknown): T {
143
+ if (cause !== null && cause !== undefined) {
144
+ Object.defineProperty(error, 'cause', {
145
+ value: cause,
146
+ configurable: true,
147
+ writable: true,
148
+ });
149
+ }
150
+ return error;
151
+ }
152
+
117
153
  function mapNetworkError(
118
154
  baseUrl: string,
119
155
  error: Error | null,
@@ -312,7 +348,11 @@ export class HttpClient {
312
348
  headers[COORDINATOR_INTERNAL_TOKEN_HEADER] =
313
349
  coordinatorInternalToken.trim();
314
350
  }
315
- return headers;
351
+ // Explicit client-option headers (e.g. `deepline plays run --header`) are
352
+ // applied last so an operator can override an env-derived header without
353
+ // rewriting the environment. Authorization of these headers stays
354
+ // server-side.
355
+ return applyExplicitHeaders(headers, this.config.headers);
316
356
  }
317
357
 
318
358
  /**
@@ -540,37 +580,43 @@ export class HttpClient {
540
580
  );
541
581
  if (options?.toolId) {
542
582
  const code = mappedNetworkError.code;
543
- throw new ToolExecutionError(
544
- withCoworkNetworkHint(mappedNetworkError.message),
545
- {
546
- toolId: options.toolId,
547
- provider: providerLabelFromToolId(options.toolId),
548
- operation: options.toolId,
549
- code,
550
- origin: 'deepline',
551
- category: 'network',
552
- // A direct client timeout has ambiguous delivery. Fail closed unless
553
- // the server returns the authoritative action delivery contract.
554
- retryable: false,
555
- statusCode: null,
556
- requestId: null,
557
- retryAfterMs: null,
558
- networkKind:
559
- code === 'NETWORK_TIMEOUT'
560
- ? 'timeout'
561
- : code === 'NETWORK_ABORTED'
562
- ? 'unknown'
563
- : 'unavailable',
564
- networkScope: 'client_to_deepline',
565
- details: mappedNetworkError.details,
566
- },
583
+ throw withErrorCause(
584
+ new ToolExecutionError(
585
+ withCoworkNetworkHint(mappedNetworkError.message),
586
+ {
587
+ toolId: options.toolId,
588
+ provider: providerLabelFromToolId(options.toolId),
589
+ operation: options.toolId,
590
+ code,
591
+ origin: 'deepline',
592
+ category: 'network',
593
+ // A direct client timeout has ambiguous delivery. Fail closed unless
594
+ // the server returns the authoritative action delivery contract.
595
+ retryable: false,
596
+ statusCode: null,
597
+ requestId: null,
598
+ retryAfterMs: null,
599
+ networkKind:
600
+ code === 'NETWORK_TIMEOUT'
601
+ ? 'timeout'
602
+ : code === 'NETWORK_ABORTED'
603
+ ? 'unknown'
604
+ : 'unavailable',
605
+ networkScope: 'client_to_deepline',
606
+ details: mappedNetworkError.details,
607
+ },
608
+ ),
609
+ lastError,
567
610
  );
568
611
  }
569
- throw new DeeplineError(
570
- withCoworkNetworkHint(mappedNetworkError.message),
571
- undefined,
572
- mappedNetworkError.code,
573
- mappedNetworkError.details,
612
+ throw withErrorCause(
613
+ new DeeplineError(
614
+ withCoworkNetworkHint(mappedNetworkError.message),
615
+ undefined,
616
+ mappedNetworkError.code,
617
+ mappedNetworkError.details,
618
+ ),
619
+ lastError,
574
620
  );
575
621
  }
576
622
 
@@ -94,6 +94,8 @@ export type {
94
94
  MonitorFleetWaitOptions,
95
95
  MonitorFleetResult,
96
96
  MonitorFleetsNamespace,
97
+ CreateNotificationGroupInput,
98
+ CreateNotificationGroupResult,
97
99
  IngestionStorageRepairResult,
98
100
  PlayStatus,
99
101
  PlaySheetRow,
@@ -270,6 +272,10 @@ export type {
270
272
  PlayDatasetInput,
271
273
  PlayCallExecution,
272
274
  PlayCallOptions,
275
+ PlayAsyncCallOptions,
276
+ AsyncPlayRunRef,
277
+ PlayRunId,
278
+ PlayReferenceLike,
273
279
  PlayFetchResponse,
274
280
  RuntimeStepOptions,
275
281
  FetchOptions,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * The fleet member ceiling, mirrored — deliberately a literal.
3
3
  *
4
- * The canonical declaration is shared_libs/monitors/monitor-fleet-limits.ts,
4
+ * The canonical declaration is packages/monitors/monitor-fleet-limits.ts,
5
5
  * which the Convex commit mutation reads to size its transaction. This package
6
6
  * cannot import it: the workspace-architecture ratchet forbids NEW shared_libs
7
7
  * imports from packages absolutely (only relocations of pre-existing edges
@@ -113,6 +113,9 @@ import type { ToolExecution } from './client.js';
113
113
  import type {
114
114
  DurableCallStaleAfterSeconds,
115
115
  PlayAuthoringBindings,
116
+ AsyncPlayRunRef as PlayAuthoringAsyncPlayRunRef,
117
+ PlayAuthoringAsyncCallOptions,
118
+ PlayRunId as PlayAuthoringRunId,
116
119
  PlayAuthoringCallExecution,
117
120
  PlayAuthoringCallOptions,
118
121
  PlayAuthoringColumnResolver,
@@ -676,7 +679,18 @@ export type PrebuiltPlayRef = {
676
679
  readonly name: string;
677
680
  };
678
681
 
679
- export type PlayReferenceLike = PlayAuthoringReferenceLike;
682
+ export type PlayReferenceLike<
683
+ TInput extends Record<string, unknown> = Record<string, unknown>,
684
+ > = PlayAuthoringReferenceLike<TInput>;
685
+
686
+ /** Branded durable identity returned by ctx.runPlayAsync. */
687
+ export type PlayRunId = PlayAuthoringRunId;
688
+
689
+ /** Serializable reference to an independently scheduled Play Run. */
690
+ export type AsyncPlayRunRef = PlayAuthoringAsyncPlayRunRef;
691
+
692
+ /** Author intent for an independently scheduled child Run. */
693
+ export type PlayAsyncCallOptions = PlayAuthoringAsyncCallOptions;
680
694
 
681
695
  export type {
682
696
  PlayDataset,
@@ -40,7 +40,7 @@ export type {
40
40
 
41
41
  export { extractDefinedPlayName } from '../../../shared_libs/plays/bundling/index.js';
42
42
 
43
- const PLAY_BUNDLE_CACHE_VERSION = 35;
43
+ const PLAY_BUNDLE_CACHE_VERSION = 37;
44
44
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
45
45
  const SDK_PACKAGE_ROOT = resolve(MODULE_DIR, '..', '..');
46
46
  const SOURCE_REPO_ROOT = resolve(SDK_PACKAGE_ROOT, '..', '..');
@@ -84,7 +84,7 @@ let hasWarnedAboutNonDevelopmentBundling = false;
84
84
  * The SDK's job is to turn a local play file into a portable artifact using
85
85
  * only SDK/runtime sources. It must work for installed packages, source
86
86
  * checkouts, CI smoke jobs, and clean worktrees without app-generated files
87
- * such as `src/lib/generated/tool-typecheck-catalog.jsonl`.
87
+ * such as `packages/integrations/generated/tool-typecheck-catalog.jsonl`.
88
88
  *
89
89
  * Tool-aware validation belongs to the Deepline API after upload:
90
90
  * `compilePlayManifest` / server preflight runs the cloud typechecker inside
@@ -199,7 +199,7 @@ export const SDK_RELEASE = {
199
199
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
200
200
  // getters keep their established compatibility behavior.
201
201
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
202
- version: '0.3.88',
202
+ version: '0.3.89',
203
203
  updateSummary:
204
204
  'Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.',
205
205
  packageCapabilities: {
@@ -19,6 +19,19 @@ import type {
19
19
  PlayBootstrapStageKind,
20
20
  PlayBootstrapTemplate,
21
21
  } from '../../shared_libs/plays/bootstrap-routes';
22
+ import type {
23
+ EffectiveProductNotificationConfiguration,
24
+ ProductNotificationConfigurationChange,
25
+ ProductNotificationDefaultPolicy,
26
+ } from '../../shared_libs/product-notifications/configuration';
27
+ import type { ProductNotificationTypeCatalogItem } from '../../shared_libs/product-notifications/catalog';
28
+
29
+ export type {
30
+ EffectiveProductNotificationConfiguration,
31
+ ProductNotificationConfigurationChange,
32
+ ProductNotificationDefaultPolicy,
33
+ ProductNotificationTypeCatalogItem,
34
+ };
22
35
 
23
36
  // ——————————————————————————————————————————————————————————
24
37
  // Config
@@ -56,6 +69,17 @@ export interface DeeplineClientOptions {
56
69
  timeout?: number;
57
70
  /** Maximum retry attempts for transient failures (network errors, 429s). Default: `3`. */
58
71
  maxRetries?: number;
72
+ /**
73
+ * Extra request headers attached to every request this client sends.
74
+ *
75
+ * They are merged *after* the headers the transport derives from the
76
+ * environment, so an explicit header replaces the env-derived one. Header
77
+ * names match case-insensitively and are normalized to lowercase.
78
+ *
79
+ * This is transport plumbing only: the server still authorizes every
80
+ * internal header it honors.
81
+ */
82
+ headers?: Record<string, string>;
59
83
  }
60
84
 
61
85
  /**
@@ -72,6 +96,12 @@ export interface ResolvedConfig {
72
96
  timeout: number;
73
97
  /** Max retry count for transient failures. */
74
98
  maxRetries: number;
99
+ /**
100
+ * Caller-supplied headers merged over the env-derived headers on every
101
+ * request. Absent unless the caller passed
102
+ * {@link DeeplineClientOptions.headers}.
103
+ */
104
+ headers?: Record<string, string>;
75
105
  }
76
106
 
77
107
  /** Column metadata returned by a customer data query. */
@@ -795,8 +825,9 @@ export interface PlayStatus {
795
825
  /**
796
826
  * Projected settled-charge billing for the run. Returned by `runs.get`.
797
827
  * `totalCredits`/`providerEvents` describe THIS run only; `rollup` (present
798
- * with `--full`) carries the true subtree cost including ctx.runPlay children.
799
- * Deepline credits only — provider spend is never exposed.
828
+ * with `--full`) carries the true subtree cost including independently
829
+ * executing ctx.runPlayAsync descendants. Deepline credits only — provider
830
+ * spend is never exposed.
800
831
  */
801
832
  billing?: RunBillingSummary;
802
833
  /**
@@ -808,14 +839,26 @@ export interface PlayStatus {
808
839
  billingChildCredits?: number;
809
840
  /** True when the child-run billing rollup could not be fully resolved. */
810
841
  billingRollupIncomplete?: boolean;
811
- /** Durable summaries of ctx.runPlay children, returned by `runs.get --full`. */
842
+ /** Durable summaries of ctx.runPlayAsync children, returned by `runs.get --full`. */
812
843
  childRuns?: ChildRunSummary[];
844
+ /**
845
+ * Child Runs grouped by the authored ctx.runPlayAsync launch key. `complete`
846
+ * is false when the bounded response is a lower bound rather than the full
847
+ * direct-child set; use each opaque `runId` to retrieve a child Run.
848
+ */
849
+ childRunProjection?: AsyncChildRunProjection;
813
850
  }
814
851
 
815
- /** One ctx.runPlay child run exposed on the parent's `--full` payload. */
852
+ /** One ctx.runPlayAsync child Run exposed on the parent's `--full` payload. */
816
853
  export interface ChildRunSummary {
817
854
  runId: string;
818
855
  playName?: string | null;
856
+ /** Authored ctx.runPlayAsync key; stable across row fanout. */
857
+ launchKey?: string | null;
858
+ /** Opaque durable identity for one authored invocation. */
859
+ invocationKey?: string | null;
860
+ /** Whether this child uses root-owned Deepline billing attribution. */
861
+ rootBillingOwned?: boolean;
819
862
  status: string;
820
863
  parentRunId?: string | null;
821
864
  rootRunId?: string | null;
@@ -824,6 +867,32 @@ export interface ChildRunSummary {
824
867
  finishedAt?: number | null;
825
868
  }
826
869
 
870
+ export interface AsyncChildRunStatusCounts {
871
+ total: number;
872
+ queued: number;
873
+ active: number;
874
+ waiting: number;
875
+ succeeded: number;
876
+ failed: number;
877
+ cancelled: number;
878
+ unknown: number;
879
+ }
880
+
881
+ export interface AsyncChildRunLaunchProjection {
882
+ launchKey: string | null;
883
+ playName: string | null;
884
+ counts: AsyncChildRunStatusCounts;
885
+ children: ChildRunSummary[];
886
+ }
887
+
888
+ export interface AsyncChildRunProjection {
889
+ kind: 'async_child_runs';
890
+ returnedCount: number;
891
+ complete: boolean;
892
+ counts: AsyncChildRunStatusCounts;
893
+ launches: AsyncChildRunLaunchProjection[];
894
+ }
895
+
827
896
  /**
828
897
  * Rolled-up billing for a run subtree, projected from settled Charge Lifecycle
829
898
  * facts. Deepline credits only — never provider spend.
@@ -1189,6 +1258,16 @@ export interface ProductNotification {
1189
1258
  lastErrorMessage?: string;
1190
1259
  }
1191
1260
 
1261
+ export interface ProductNotificationConfigurationResponse {
1262
+ configuration: EffectiveProductNotificationConfiguration;
1263
+ catalog: readonly ProductNotificationTypeCatalogItem[];
1264
+ slackConnection: {
1265
+ connected: boolean;
1266
+ status: string;
1267
+ connectionId?: string;
1268
+ };
1269
+ }
1270
+
1192
1271
  export interface PlayDescription {
1193
1272
  name: string;
1194
1273
  /** Stable registry key. Same value `plays list` reports for this play. */
@@ -0,0 +1,9 @@
1
+ # Integration Contracts
2
+
3
+ This package is the only integration-owned boundary shared with public clients.
4
+
5
+ - Put a value here only when both `packages/integrations` and a public client such as `packages/sdk` must interpret it identically.
6
+ - Keep contracts pure and dependency-light. Do not import provider runtimes, generated catalogs, credentials, billing implementations, action schemas, or application code.
7
+ - Provider implementations and server-only policy remain in `packages/integrations`.
8
+ - The public SDK bundles this package; it must not acquire a runtime dependency on a private workspace package.
9
+ - Prefer a server-driven protocol over adding provider-specific client knowledge when compatibility permits it.
@@ -0,0 +1,3 @@
1
+ # `@deepline/integration-contracts`
2
+
3
+ Pure contracts that must be interpreted identically by integration runtimes and public clients. Server-only integration code belongs in `packages/integrations`; SDK-only behavior belongs in `packages/sdk`.
@@ -0,0 +1,2 @@
1
+ export * from './bettercontact/execution-policy';
2
+ export * from './theirstack/execution-policy';
@@ -0,0 +1,77 @@
1
+ export type AnalyticsInstallGuide = {
2
+ id: 'html' | 'wordpress' | 'react' | 'nextjs' | 'gtm' | 'webflow' | 'shopify';
3
+ label: string;
4
+ steps: string[];
5
+ };
6
+
7
+ /** Kept as data so the UI, email preview, and regression test share one guide source. */
8
+ export const ANALYTICS_INSTALL_GUIDES: readonly AnalyticsInstallGuide[] = [
9
+ {
10
+ id: 'html',
11
+ label: 'HTML',
12
+ steps: [
13
+ 'Open the shared layout or template used by every page.',
14
+ 'Paste the loader immediately before the closing </head> tag, publish, then validate below.',
15
+ ],
16
+ },
17
+ {
18
+ id: 'wordpress',
19
+ label: 'WordPress',
20
+ steps: [
21
+ 'Install or open WPCode / Insert Headers and Footers.',
22
+ 'Add the loader to the site-wide Header area, save it, clear any cache, then validate below.',
23
+ ],
24
+ },
25
+ {
26
+ id: 'react',
27
+ label: 'React',
28
+ steps: [
29
+ 'Open the root HTML template (usually public/index.html).',
30
+ 'Paste the loader in <head>, not inside a rendered component, deploy, then validate below.',
31
+ ],
32
+ },
33
+ {
34
+ id: 'nextjs',
35
+ label: 'Next.js',
36
+ steps: [
37
+ 'Open app/layout.tsx (or pages/_document.tsx in the Pages Router).',
38
+ 'Use the Next.js code below once in the document head, deploy, then validate below.',
39
+ ],
40
+ },
41
+ {
42
+ id: 'gtm',
43
+ label: 'Google Tag Manager',
44
+ steps: [
45
+ 'Create a new Custom HTML tag and paste the loader.',
46
+ 'Trigger it on All Pages, publish the container, then validate below.',
47
+ ],
48
+ },
49
+ {
50
+ id: 'webflow',
51
+ label: 'Webflow',
52
+ steps: [
53
+ 'Open Project settings → Custom code.',
54
+ 'Paste the loader in Head code, publish the site, then validate below.',
55
+ ],
56
+ },
57
+ {
58
+ id: 'shopify',
59
+ label: 'Shopify',
60
+ steps: [
61
+ 'Open Online Store → Themes → Edit code → layout/theme.liquid.',
62
+ 'Paste the loader immediately before </head>, save the theme, then validate below.',
63
+ ],
64
+ },
65
+ ];
66
+
67
+ function scriptBody(loader: string) {
68
+ return loader.replace(/^<script>\s*/i, '').replace(/\s*<\/script>$/i, '');
69
+ }
70
+
71
+ export function analyticsGuideCode(
72
+ guide: AnalyticsInstallGuide,
73
+ loader: string,
74
+ ) {
75
+ if (guide.id !== 'nextjs') return loader;
76
+ return `import Script from 'next/script';\n\n<Script\n id="deepline-analytics"\n strategy="afterInteractive"\n dangerouslySetInnerHTML={{ __html: ${JSON.stringify(scriptBody(loader))} }}\n/>`;
77
+ }