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.
- package/dist/bundling-sources/sdk/src/client.ts +534 -4
- package/dist/bundling-sources/sdk/src/config.ts +77 -0
- package/dist/bundling-sources/sdk/src/http.ts +76 -30
- package/dist/bundling-sources/sdk/src/index.ts +6 -0
- package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +1 -1
- package/dist/bundling-sources/sdk/src/play.ts +15 -1
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +2 -2
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +83 -4
- package/dist/bundling-sources/shared_libs/integration-contracts/AGENTS.md +9 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/README.md +3 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +2 -0
- package/dist/bundling-sources/shared_libs/monitors/analytics-install-guides.ts +77 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/charges.ts +125 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/policy-builders.ts +686 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/pricing.ts +54 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/public-pricing.ts +72 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/session.ts +45 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/state.ts +454 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/tamradar.ts +260 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/types.ts +215 -0
- package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +333 -0
- package/dist/bundling-sources/shared_libs/monitors/cursor-page.ts +42 -0
- package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +16 -0
- package/dist/bundling-sources/shared_libs/monitors/framework-managed-payload-fields.ts +71 -0
- package/dist/bundling-sources/shared_libs/monitors/generated/provider-monitor-callback-admission-targets.ts +16 -0
- package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +267 -0
- package/dist/bundling-sources/shared_libs/monitors/inbound-publish-key.ts +39 -0
- package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +82 -0
- package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +473 -0
- package/dist/bundling-sources/shared_libs/monitors/org-monitor-limits.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/package.json +29 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +1125 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +263 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-capability.ts +964 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +56 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-errors.ts +131 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +535 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-legacy-aliases.ts +16 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-priority-execution.ts +56 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +28 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-runtime-read-eligibility.ts +38 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +122 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-status.ts +10 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +112 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-webhook-monitor-runtime.ts +300 -0
- package/dist/bundling-sources/shared_libs/monitors/quickstart-prompts.ts +22 -0
- package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +93 -0
- package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +332 -0
- package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +221 -0
- package/dist/bundling-sources/shared_libs/monitors/starter-templates.ts +105 -0
- package/dist/bundling-sources/shared_libs/monitors/tracking-provider-guidance.ts +73 -0
- package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +81 -0
- package/dist/bundling-sources/shared_libs/monitors/tsconfig.json +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/activity-observation.ts +6 -11
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +90 -12
- package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +78 -0
- package/dist/bundling-sources/shared_libs/play-runtime/checkpoint-boundaries.ts +70 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +407 -53
- package/dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts +1 -32
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +57 -0
- package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +20 -1
- package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +7 -1
- package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +189 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +28 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +23 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +18 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +10 -8
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +24 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +30 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +6 -3
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +454 -17
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +19 -4
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +6 -14
- package/dist/bundling-sources/shared_libs/plays/core.ts +11 -6
- package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +16 -11
- package/dist/bundling-sources/shared_libs/plays/email-status.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/slug.ts +115 -0
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +44 -14
- package/dist/bundling-sources/shared_libs/plays/tool-category-descriptions.ts +2 -2
- package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +877 -0
- package/dist/bundling-sources/shared_libs/product-notifications/configuration-draft.ts +456 -0
- package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +560 -0
- package/dist/bundling-sources/shared_libs/product-notifications/content.ts +28 -0
- package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +59 -0
- package/dist/bundling-sources/shared_libs/product-notifications/email.ts +246 -0
- package/dist/bundling-sources/shared_libs/product-notifications/evaluation.ts +280 -0
- package/dist/bundling-sources/shared_libs/product-notifications/events.ts +433 -0
- package/dist/bundling-sources/shared_libs/product-notifications/legacy-slack.ts +80 -0
- package/dist/bundling-sources/shared_libs/product-notifications/workspace.ts +38 -0
- package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
- package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +28 -0
- package/dist/bundling-sources/shared_libs/security/internal-actor.ts +50 -0
- package/dist/bundling-sources/shared_libs/security/secret-redaction.ts +267 -0
- package/dist/cli/index.js +1070 -193
- package/dist/cli/index.mjs +1057 -180
- package/dist/{compiler-manifest-Dbov16F7.d.mts → compiler-manifest-DsLbQaew.d.mts} +132 -8
- package/dist/{compiler-manifest-Dbov16F7.d.ts → compiler-manifest-DsLbQaew.d.ts} +132 -8
- package/dist/index.d.mts +834 -12
- package/dist/index.d.ts +834 -12
- package/dist/index.js +469 -40
- package/dist/index.mjs +469 -40
- package/dist/install-integrity.json +65 -4
- package/dist/plays/bundle-play-file.d.mts +8 -3
- package/dist/plays/bundle-play-file.d.ts +8 -3
- package/dist/plays/bundle-play-file.mjs +100 -20
- package/package.json +3 -1
- /package/dist/bundling-sources/shared_libs/{integrations/bettercontact-execution-policy.ts → integration-contracts/bettercontact/execution-policy.ts} +0 -0
- /package/dist/bundling-sources/shared_libs/{integrations/theirstack-execution-policy.ts → integration-contracts/theirstack/execution-policy.ts} +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -587,6 +587,7 @@ var HOST_URL_ENV = "DEEPLINE_HOST_URL";
|
|
|
587
587
|
var API_KEY_ENV = "DEEPLINE_API_KEY";
|
|
588
588
|
var ACTIVE_ORG_ID_ENV = "DEEPLINE_ACTIVE_ORG_ID";
|
|
589
589
|
var ACTIVE_ORG_NAME_ENV = "DEEPLINE_ACTIVE_ORG_NAME";
|
|
590
|
+
var FEATURES_ENV = "DEEPLINE_FEATURES";
|
|
590
591
|
var PROD_URL = "https://code.deepline.com";
|
|
591
592
|
var DEFAULT_TIMEOUT = 6e4;
|
|
592
593
|
var DEFAULT_MAX_RETRIES = 3;
|
|
@@ -611,8 +612,40 @@ var CLI_ENV_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
611
612
|
HOST_URL_ENV,
|
|
612
613
|
API_KEY_ENV,
|
|
613
614
|
ACTIVE_ORG_ID_ENV,
|
|
614
|
-
ACTIVE_ORG_NAME_ENV
|
|
615
|
+
ACTIVE_ORG_NAME_ENV,
|
|
616
|
+
FEATURES_ENV
|
|
615
617
|
]);
|
|
618
|
+
function featureEnvValues(data) {
|
|
619
|
+
if (!Array.isArray(data.features)) return {};
|
|
620
|
+
return {
|
|
621
|
+
[FEATURES_ENV]: data.features.filter(
|
|
622
|
+
(key) => typeof key === "string" && key.trim() !== ""
|
|
623
|
+
).map((key) => key.trim()).join(",")
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
function storedHostApiKey(baseUrl) {
|
|
627
|
+
return loadCliEnv(normalizeBaseUrl(baseUrl) || baseUrl)[API_KEY_ENV] ?? "";
|
|
628
|
+
}
|
|
629
|
+
function storedHostFeatures(baseUrl) {
|
|
630
|
+
return loadCliEnv(normalizeBaseUrl(baseUrl) || baseUrl)[FEATURES_ENV];
|
|
631
|
+
}
|
|
632
|
+
function envHasFeature(env, feature) {
|
|
633
|
+
return (env[FEATURES_ENV] ?? "").split(",").map((key) => key.trim()).includes(feature);
|
|
634
|
+
}
|
|
635
|
+
function cliFeatureEnabled(feature) {
|
|
636
|
+
const processEnv = process.env;
|
|
637
|
+
if (envHasFeature(processEnv, feature)) return true;
|
|
638
|
+
if (processEnv[API_KEY_ENV]?.trim()) return false;
|
|
639
|
+
try {
|
|
640
|
+
const baseUrl = resolveBaseUrlOnly();
|
|
641
|
+
const projectEnv = loadProjectEnvCandidates().find(
|
|
642
|
+
({ env }) => normalizeBaseUrl(env[HOST_URL_ENV] ?? "") === baseUrl && Boolean(env[API_KEY_ENV])
|
|
643
|
+
);
|
|
644
|
+
return envHasFeature(projectEnv?.env ?? loadCliEnv(baseUrl), feature);
|
|
645
|
+
} catch {
|
|
646
|
+
return false;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
616
649
|
function baseUrlSlug(baseUrl) {
|
|
617
650
|
let url;
|
|
618
651
|
try {
|
|
@@ -812,6 +845,10 @@ function mergePersistedEnvValues(existing, values) {
|
|
|
812
845
|
if (nextApiKey !== void 0 && nextApiKey !== existing[API_KEY_ENV] && values[ACTIVE_ORG_ID_ENV] === void 0) {
|
|
813
846
|
delete merged[ACTIVE_ORG_ID_ENV];
|
|
814
847
|
delete merged[ACTIVE_ORG_NAME_ENV];
|
|
848
|
+
delete merged[FEATURES_ENV];
|
|
849
|
+
}
|
|
850
|
+
if (values[FEATURES_ENV] === "") {
|
|
851
|
+
delete merged[FEATURES_ENV];
|
|
815
852
|
}
|
|
816
853
|
return merged;
|
|
817
854
|
}
|
|
@@ -935,7 +972,10 @@ function resolveConfig(options) {
|
|
|
935
972
|
apiKey,
|
|
936
973
|
baseUrl,
|
|
937
974
|
timeout: options?.timeout ?? DEFAULT_TIMEOUT,
|
|
938
|
-
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES
|
|
975
|
+
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
976
|
+
// Pass through untouched: the transport owns case-insensitive merging so
|
|
977
|
+
// there is exactly one place that decides which header wins.
|
|
978
|
+
...options?.headers ? { headers: { ...options.headers } } : {}
|
|
939
979
|
};
|
|
940
980
|
}
|
|
941
981
|
function mergeProjectEnvFile(filePath, values) {
|
|
@@ -1225,7 +1265,7 @@ var SDK_RELEASE = {
|
|
|
1225
1265
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1226
1266
|
// getters keep their established compatibility behavior.
|
|
1227
1267
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1228
|
-
version: "0.3.
|
|
1268
|
+
version: "0.3.89",
|
|
1229
1269
|
updateSummary: "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.",
|
|
1230
1270
|
packageCapabilities: {
|
|
1231
1271
|
updatePreferences: 1
|
|
@@ -1779,11 +1819,33 @@ function normalizeRequestAbortError(error, input2) {
|
|
|
1779
1819
|
}
|
|
1780
1820
|
return normalized;
|
|
1781
1821
|
}
|
|
1822
|
+
function applyExplicitHeaders(headers, explicit) {
|
|
1823
|
+
if (!explicit) return headers;
|
|
1824
|
+
for (const [rawName, value] of Object.entries(explicit)) {
|
|
1825
|
+
const name = rawName.trim().toLowerCase();
|
|
1826
|
+
if (!name) continue;
|
|
1827
|
+
for (const existing of Object.keys(headers)) {
|
|
1828
|
+
if (existing.toLowerCase() === name) delete headers[existing];
|
|
1829
|
+
}
|
|
1830
|
+
headers[name] = value;
|
|
1831
|
+
}
|
|
1832
|
+
return headers;
|
|
1833
|
+
}
|
|
1782
1834
|
function isAbortLikeError(error) {
|
|
1783
1835
|
const name = error.name.toLowerCase();
|
|
1784
1836
|
const message = error.message.toLowerCase();
|
|
1785
1837
|
return name === "aborterror" || message.includes("operation was aborted") || message === "aborted";
|
|
1786
1838
|
}
|
|
1839
|
+
function withErrorCause(error, cause) {
|
|
1840
|
+
if (cause !== null && cause !== void 0) {
|
|
1841
|
+
Object.defineProperty(error, "cause", {
|
|
1842
|
+
value: cause,
|
|
1843
|
+
configurable: true,
|
|
1844
|
+
writable: true
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
return error;
|
|
1848
|
+
}
|
|
1787
1849
|
function mapNetworkError(baseUrl, error, targetLabel2) {
|
|
1788
1850
|
const tagged = error;
|
|
1789
1851
|
const timeoutMs = tagged?.[REQUEST_TIMEOUT_MARKER];
|
|
@@ -1900,7 +1962,7 @@ var HttpClient = class {
|
|
|
1900
1962
|
if (coordinatorInternalToken?.trim() && (coordinatorUrl?.trim() || workerCallbackUrl?.trim() || runtimeTestFault?.trim() || absurdReleaseOverride?.trim() || preferredReceiptGatewayMachineId?.trim())) {
|
|
1901
1963
|
headers[COORDINATOR_INTERNAL_TOKEN_HEADER] = coordinatorInternalToken.trim();
|
|
1902
1964
|
}
|
|
1903
|
-
return headers;
|
|
1965
|
+
return applyExplicitHeaders(headers, this.config.headers);
|
|
1904
1966
|
}
|
|
1905
1967
|
/**
|
|
1906
1968
|
* Send an HTTP request with automatic retries and error handling.
|
|
@@ -2054,32 +2116,38 @@ var HttpClient = class {
|
|
|
2054
2116
|
);
|
|
2055
2117
|
if (options?.toolId) {
|
|
2056
2118
|
const code = mappedNetworkError.code;
|
|
2057
|
-
throw
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2119
|
+
throw withErrorCause(
|
|
2120
|
+
new ToolExecutionError(
|
|
2121
|
+
withCoworkNetworkHint(mappedNetworkError.message),
|
|
2122
|
+
{
|
|
2123
|
+
toolId: options.toolId,
|
|
2124
|
+
provider: providerLabelFromToolId(options.toolId),
|
|
2125
|
+
operation: options.toolId,
|
|
2126
|
+
code,
|
|
2127
|
+
origin: "deepline",
|
|
2128
|
+
category: "network",
|
|
2129
|
+
// A direct client timeout has ambiguous delivery. Fail closed unless
|
|
2130
|
+
// the server returns the authoritative action delivery contract.
|
|
2131
|
+
retryable: false,
|
|
2132
|
+
statusCode: null,
|
|
2133
|
+
requestId: null,
|
|
2134
|
+
retryAfterMs: null,
|
|
2135
|
+
networkKind: code === "NETWORK_TIMEOUT" ? "timeout" : code === "NETWORK_ABORTED" ? "unknown" : "unavailable",
|
|
2136
|
+
networkScope: "client_to_deepline",
|
|
2137
|
+
details: mappedNetworkError.details
|
|
2138
|
+
}
|
|
2139
|
+
),
|
|
2140
|
+
lastError
|
|
2076
2141
|
);
|
|
2077
2142
|
}
|
|
2078
|
-
throw
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2143
|
+
throw withErrorCause(
|
|
2144
|
+
new DeeplineError(
|
|
2145
|
+
withCoworkNetworkHint(mappedNetworkError.message),
|
|
2146
|
+
void 0,
|
|
2147
|
+
mappedNetworkError.code,
|
|
2148
|
+
mappedNetworkError.details
|
|
2149
|
+
),
|
|
2150
|
+
lastError
|
|
2083
2151
|
);
|
|
2084
2152
|
}
|
|
2085
2153
|
/**
|
|
@@ -2453,6 +2521,13 @@ var PRODUCT_NOTIFICATION_DELIVERY_LEASE_MS = 2 * 6e4;
|
|
|
2453
2521
|
var PRODUCT_NOTIFICATION_SUCCESS_TTL_MS = 15 * 6e4;
|
|
2454
2522
|
var PRODUCT_NOTIFICATION_FAILURE_TTL_MS = 24 * 60 * 6e4;
|
|
2455
2523
|
|
|
2524
|
+
// ../product-notifications/configuration.ts
|
|
2525
|
+
var PRODUCT_NOTIFICATION_EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2526
|
+
function normalizeProductNotificationEmail(value) {
|
|
2527
|
+
const email = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
2528
|
+
return email && email.length <= 320 && PRODUCT_NOTIFICATION_EMAIL_PATTERN.test(email) ? email : null;
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2456
2531
|
// src/stream-reconnect.ts
|
|
2457
2532
|
var STREAM_RECONNECT_BASE_DELAY_MS = 500;
|
|
2458
2533
|
var STREAM_RECONNECT_MAX_DELAY_MS = 15e3;
|
|
@@ -2981,7 +3056,7 @@ function isRecord4(value) {
|
|
|
2981
3056
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
2982
3057
|
}
|
|
2983
3058
|
function isPlayActivityObservation(value) {
|
|
2984
|
-
if (!isRecord4(value) || value.schemaVersion !== 1 || typeof value.activityId !== "string" || !value.activityId.trim() || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || !isRecord4(value.target) || !isRecord4(value.state)) {
|
|
3059
|
+
if (!isRecord4(value) || value.schemaVersion !== void 0 && value.schemaVersion !== 1 || typeof value.activityId !== "string" || !value.activityId.trim() || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || !isRecord4(value.target) || !isRecord4(value.state)) {
|
|
2985
3060
|
return false;
|
|
2986
3061
|
}
|
|
2987
3062
|
const targetKinds = /* @__PURE__ */ new Set([
|
|
@@ -3088,7 +3163,6 @@ function projectPlayRunActivity(input2) {
|
|
|
3088
3163
|
if (input2.waitKind === "detached_runner") {
|
|
3089
3164
|
return projection(
|
|
3090
3165
|
{
|
|
3091
|
-
schemaVersion: 1,
|
|
3092
3166
|
activityId: "runner:managed",
|
|
3093
3167
|
target: {
|
|
3094
3168
|
kind: "runner",
|
|
@@ -3104,7 +3178,6 @@ function projectPlayRunActivity(input2) {
|
|
|
3104
3178
|
if (input2.waitKind === "sleep") {
|
|
3105
3179
|
return projection(
|
|
3106
3180
|
{
|
|
3107
|
-
schemaVersion: 1,
|
|
3108
3181
|
activityId: "run:sleep",
|
|
3109
3182
|
target: {
|
|
3110
3183
|
kind: "step",
|
|
@@ -3124,7 +3197,6 @@ function projectPlayRunActivity(input2) {
|
|
|
3124
3197
|
if (input2.waitKind === "integration_event" || input2.waitKind === "integration_event_batch") {
|
|
3125
3198
|
return projection(
|
|
3126
3199
|
{
|
|
3127
|
-
schemaVersion: 1,
|
|
3128
3200
|
activityId: `event:${input2.activeNodeId ?? "run"}`,
|
|
3129
3201
|
stepId: input2.activeNodeId ?? void 0,
|
|
3130
3202
|
target: {
|
|
@@ -3148,7 +3220,6 @@ function projectPlayRunActivity(input2) {
|
|
|
3148
3220
|
if (normalizedStatus === "waiting") {
|
|
3149
3221
|
return projection(
|
|
3150
3222
|
{
|
|
3151
|
-
schemaVersion: 1,
|
|
3152
3223
|
activityId: "run:legacy-wait",
|
|
3153
3224
|
target: {
|
|
3154
3225
|
kind: "step",
|
|
@@ -3175,7 +3246,6 @@ function projectPlayRunActivity(input2) {
|
|
|
3175
3246
|
const datasetProgress = datasetStep?.progress ?? null;
|
|
3176
3247
|
return projection(
|
|
3177
3248
|
{
|
|
3178
|
-
schemaVersion: 1,
|
|
3179
3249
|
activityId: `dataset:${pendingDataset.datasetId ?? pendingDataset.tableNamespace}`,
|
|
3180
3250
|
target: {
|
|
3181
3251
|
kind: "dataset",
|
|
@@ -3203,7 +3273,6 @@ function projectPlayRunActivity(input2) {
|
|
|
3203
3273
|
const provider = toolId?.split(/[._]/)[0]?.trim() || null;
|
|
3204
3274
|
return projection(
|
|
3205
3275
|
{
|
|
3206
|
-
schemaVersion: 1,
|
|
3207
3276
|
activityId: `step:${activeStep.nodeId}`,
|
|
3208
3277
|
stepId: activeStep.nodeId,
|
|
3209
3278
|
target: toolId && provider ? {
|
|
@@ -3228,7 +3297,6 @@ function projectPlayRunActivity(input2) {
|
|
|
3228
3297
|
if (normalizedStatus === "queued") {
|
|
3229
3298
|
return projection(
|
|
3230
3299
|
{
|
|
3231
|
-
schemaVersion: 1,
|
|
3232
3300
|
activityId: "capacity:worker",
|
|
3233
3301
|
target: { kind: "capacity", pool: "worker" },
|
|
3234
3302
|
state: { kind: "queued", reason: "capacity" },
|
|
@@ -3238,7 +3306,6 @@ function projectPlayRunActivity(input2) {
|
|
|
3238
3306
|
);
|
|
3239
3307
|
}
|
|
3240
3308
|
const fallback = {
|
|
3241
|
-
schemaVersion: 1,
|
|
3242
3309
|
activityId: "run:legacy",
|
|
3243
3310
|
target: {
|
|
3244
3311
|
kind: "step",
|
|
@@ -4353,7 +4420,7 @@ async function* observeRunEvents(options) {
|
|
|
4353
4420
|
}
|
|
4354
4421
|
}
|
|
4355
4422
|
|
|
4356
|
-
//
|
|
4423
|
+
// ../integration-contracts/theirstack/execution-policy.ts
|
|
4357
4424
|
var THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS = 135e3;
|
|
4358
4425
|
var THEIRSTACK_SLOW_JOB_SEARCH_CLIENT_TIMEOUT_MS = 6e4 + THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS + 15e3;
|
|
4359
4426
|
var THEIRSTACK_COMPANY_SEARCH_CLIENT_TIMEOUT_MS = 21e4;
|
|
@@ -4407,7 +4474,7 @@ function resolveTheirstackClientTimeoutMs(endpointId, payload) {
|
|
|
4407
4474
|
return usesExtendedTheirstackJobSearchBudget(endpointId, payload) ? THEIRSTACK_SLOW_JOB_SEARCH_CLIENT_TIMEOUT_MS : null;
|
|
4408
4475
|
}
|
|
4409
4476
|
|
|
4410
|
-
//
|
|
4477
|
+
// ../integration-contracts/bettercontact/execution-policy.ts
|
|
4411
4478
|
var BETTERCONTACT_LAUNCHER_CLIENT_TIMEOUT_MS = 12e4;
|
|
4412
4479
|
var BETTERCONTACT_LAUNCHER_TOOL_IDS = /* @__PURE__ */ new Set([
|
|
4413
4480
|
"bettercontact_enrich",
|
|
@@ -4498,6 +4565,42 @@ function providerMetaFromToolResponseRawV2(rawV2, view) {
|
|
|
4498
4565
|
}
|
|
4499
4566
|
|
|
4500
4567
|
// src/client.ts
|
|
4568
|
+
var MAX_NOTIFICATION_GROUP_CREATE_TARGETS = 50;
|
|
4569
|
+
function parseNotificationGroupTarget(value) {
|
|
4570
|
+
const normalized = value.trim();
|
|
4571
|
+
if (normalized.toLowerCase().startsWith("email:")) {
|
|
4572
|
+
const email = normalizeProductNotificationEmail(normalized.slice(6));
|
|
4573
|
+
if (!email) {
|
|
4574
|
+
throw new Error(
|
|
4575
|
+
`Invalid email notification target "${value}". Use --to email:name@example.com.`
|
|
4576
|
+
);
|
|
4577
|
+
}
|
|
4578
|
+
return { kind: "email", email };
|
|
4579
|
+
}
|
|
4580
|
+
const slack = /^slack:(.+)$/i.exec(normalized)?.[1]?.trim();
|
|
4581
|
+
if (!slack) {
|
|
4582
|
+
const provider = normalized.split(":", 1)[0] || normalized;
|
|
4583
|
+
throw new Error(
|
|
4584
|
+
`Unsupported notification destination "${provider}". Use email: or slack:.`
|
|
4585
|
+
);
|
|
4586
|
+
}
|
|
4587
|
+
const member = /^member:([UW][A-Z0-9]{8,})$/i.exec(slack);
|
|
4588
|
+
if (member?.[1]) {
|
|
4589
|
+
return { kind: "slack", memberId: member[1].toUpperCase() };
|
|
4590
|
+
}
|
|
4591
|
+
if (slack.toLowerCase().startsWith("member:")) {
|
|
4592
|
+
throw new Error(
|
|
4593
|
+
"Slack member IDs must look like slack:member:U0123456789."
|
|
4594
|
+
);
|
|
4595
|
+
}
|
|
4596
|
+
if (!slack.replace(/^#/, "").trim()) {
|
|
4597
|
+
throw new Error("Use --to slack:#channel.");
|
|
4598
|
+
}
|
|
4599
|
+
return { kind: "slack", channel: slack };
|
|
4600
|
+
}
|
|
4601
|
+
function notificationObjectKey(kind) {
|
|
4602
|
+
return `${kind}.${globalThis.crypto.randomUUID()}`;
|
|
4603
|
+
}
|
|
4501
4604
|
var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
4502
4605
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
4503
4606
|
var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
|
|
@@ -5067,6 +5170,10 @@ var DeeplineClient = class {
|
|
|
5067
5170
|
audit: (options2) => this.auditMonitors(options2),
|
|
5068
5171
|
repair: (options2) => this.repairMonitors(options2),
|
|
5069
5172
|
health: (options2) => this.readMonitorsHealth(options2),
|
|
5173
|
+
batch: {
|
|
5174
|
+
submit: (options2) => this.submitMonitorBatch(options2),
|
|
5175
|
+
get: (operationId, options2) => this.getMonitorBatch(operationId, options2)
|
|
5176
|
+
},
|
|
5070
5177
|
fleets: {
|
|
5071
5178
|
sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5072
5179
|
get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
|
|
@@ -5199,6 +5306,16 @@ var DeeplineClient = class {
|
|
|
5199
5306
|
(secret) => secret.name === normalized && secret.status === "active" && secret.hasValue
|
|
5200
5307
|
) ?? null;
|
|
5201
5308
|
}
|
|
5309
|
+
/** Check effective scope and active-version health without reading the value.
|
|
5310
|
+
* Without playName, checks the organization-scoped secret only. With a Play
|
|
5311
|
+
* name, an active Play secret takes precedence; a deleted/disabled Play
|
|
5312
|
+
* secret falls back to the organization-scoped secret.
|
|
5313
|
+
*/
|
|
5314
|
+
async inspectSecret(name, options = {}) {
|
|
5315
|
+
const params = new URLSearchParams({ name: name.trim().toUpperCase() });
|
|
5316
|
+
if (options.playName !== void 0) params.set("play", options.playName);
|
|
5317
|
+
return this.http.get(`/api/v2/secrets?${params.toString()}`);
|
|
5318
|
+
}
|
|
5202
5319
|
// ——————————————————————————————————————————————————————————
|
|
5203
5320
|
// Tools
|
|
5204
5321
|
// ——————————————————————————————————————————————————————————
|
|
@@ -5290,6 +5407,10 @@ var DeeplineClient = class {
|
|
|
5290
5407
|
`/api/v2/integrations/${encodeURIComponent(toolId)}/get`,
|
|
5291
5408
|
{
|
|
5292
5409
|
method: "GET",
|
|
5410
|
+
// Tool metadata is a read-only catalog lookup. Keep the metadata
|
|
5411
|
+
// header while opting into the same transient edge-response retries as
|
|
5412
|
+
// other GET catalog methods such as searchTools().
|
|
5413
|
+
retryApiErrors: true,
|
|
5293
5414
|
headers: {
|
|
5294
5415
|
"x-deepline-tool-meta-only": "1"
|
|
5295
5416
|
}
|
|
@@ -6745,6 +6866,197 @@ var DeeplineClient = class {
|
|
|
6745
6866
|
async getNotifications() {
|
|
6746
6867
|
return this.http.get("/api/v2/notifications");
|
|
6747
6868
|
}
|
|
6869
|
+
/** Read the group-based product-notification configuration and rule catalog. */
|
|
6870
|
+
async getNotificationConfiguration() {
|
|
6871
|
+
return this.http.get("/api/v2/notifications/configuration");
|
|
6872
|
+
}
|
|
6873
|
+
/** Atomically apply one retry-safe desired configuration change. */
|
|
6874
|
+
async changeNotificationConfiguration(expectedWorkspaceVersion, change) {
|
|
6875
|
+
return this.http.put("/api/v2/notifications/configuration", {
|
|
6876
|
+
expectedWorkspaceVersion,
|
|
6877
|
+
change
|
|
6878
|
+
});
|
|
6879
|
+
}
|
|
6880
|
+
/** Create one notification group and its destinations as a retry-safe unit. */
|
|
6881
|
+
async createNotificationGroup(input2) {
|
|
6882
|
+
const name = input2.name.trim().replace(/\s+/g, " ");
|
|
6883
|
+
if (!name) throw new Error("Notification group name is required.");
|
|
6884
|
+
if (input2.targets.length < 1 || input2.targets.length > MAX_NOTIFICATION_GROUP_CREATE_TARGETS) {
|
|
6885
|
+
throw new Error(
|
|
6886
|
+
`Choose between 1 and ${MAX_NOTIFICATION_GROUP_CREATE_TARGETS} notification targets.`
|
|
6887
|
+
);
|
|
6888
|
+
}
|
|
6889
|
+
const targets = input2.targets.map(parseNotificationGroupTarget);
|
|
6890
|
+
const legacyEvents = input2.legacyEvents ?? [];
|
|
6891
|
+
const legacyTarget = targets.length === 1 && targets[0]?.kind === "slack" && legacyEvents.length > 0 ? targets[0] : null;
|
|
6892
|
+
if (legacyEvents.length > 0 && !legacyTarget) {
|
|
6893
|
+
throw new Error(
|
|
6894
|
+
"--for is supported only by the legacy one-Slack-target form. Create the group first, then add rules in notification configuration."
|
|
6895
|
+
);
|
|
6896
|
+
}
|
|
6897
|
+
if (!legacyTarget && name.toLowerCase() === "default") {
|
|
6898
|
+
throw new Error(
|
|
6899
|
+
"Default is reserved for the workspace default notification group."
|
|
6900
|
+
);
|
|
6901
|
+
}
|
|
6902
|
+
const normalizedTargets = targets.map(
|
|
6903
|
+
(target) => target.kind === "email" ? `email:${target.email}` : "memberId" in target ? `slack:member:${target.memberId}` : `slack:${target.channel}`
|
|
6904
|
+
);
|
|
6905
|
+
if (input2.dryRun) {
|
|
6906
|
+
return {
|
|
6907
|
+
mode: "dry_run",
|
|
6908
|
+
compatibilityMode: legacyTarget !== null,
|
|
6909
|
+
name: legacyTarget ? input2.name : name,
|
|
6910
|
+
targets: normalizedTargets,
|
|
6911
|
+
legacyEvents
|
|
6912
|
+
};
|
|
6913
|
+
}
|
|
6914
|
+
if (legacyTarget) {
|
|
6915
|
+
const notification = await this.createNotification({
|
|
6916
|
+
name: input2.name,
|
|
6917
|
+
provider: "slack",
|
|
6918
|
+
..."channel" in legacyTarget ? { channel: legacyTarget.channel } : { memberId: legacyTarget.memberId },
|
|
6919
|
+
eventTypes: legacyEvents
|
|
6920
|
+
});
|
|
6921
|
+
return { mode: "legacy", notification };
|
|
6922
|
+
}
|
|
6923
|
+
const current = await this.getNotificationConfiguration();
|
|
6924
|
+
const existingGroup = current.configuration.groups.find(
|
|
6925
|
+
(candidate) => candidate.name.toLowerCase() === name.toLowerCase()
|
|
6926
|
+
);
|
|
6927
|
+
const groupKey = existingGroup?.groupKey ?? notificationObjectKey("group");
|
|
6928
|
+
const group = existingGroup ?? {
|
|
6929
|
+
groupKey,
|
|
6930
|
+
name,
|
|
6931
|
+
enabled: true,
|
|
6932
|
+
deliveryTiming: { mode: "immediate" },
|
|
6933
|
+
source: "workspace",
|
|
6934
|
+
configMode: "custom",
|
|
6935
|
+
version: 0
|
|
6936
|
+
};
|
|
6937
|
+
const destinations = current.configuration.destinations.filter(
|
|
6938
|
+
(destination) => destination.groupKey === groupKey
|
|
6939
|
+
);
|
|
6940
|
+
const emails = [
|
|
6941
|
+
...new Set(
|
|
6942
|
+
targets.flatMap(
|
|
6943
|
+
(target) => target.kind === "email" ? [target.email] : []
|
|
6944
|
+
)
|
|
6945
|
+
)
|
|
6946
|
+
].sort();
|
|
6947
|
+
const existingEmails = new Set(
|
|
6948
|
+
destinations.flatMap(
|
|
6949
|
+
(destination) => destination.settings.kind === "email_addresses" ? destination.settings.to : []
|
|
6950
|
+
)
|
|
6951
|
+
);
|
|
6952
|
+
const newEmails = emails.filter((email) => !existingEmails.has(email));
|
|
6953
|
+
if (newEmails.length > 0) {
|
|
6954
|
+
destinations.push({
|
|
6955
|
+
destinationKey: notificationObjectKey("destination"),
|
|
6956
|
+
groupKey,
|
|
6957
|
+
name: "Email recipients",
|
|
6958
|
+
enabled: true,
|
|
6959
|
+
source: "workspace",
|
|
6960
|
+
configMode: "custom",
|
|
6961
|
+
version: 0,
|
|
6962
|
+
status: "active",
|
|
6963
|
+
settings: { kind: "email_addresses", to: newEmails }
|
|
6964
|
+
});
|
|
6965
|
+
}
|
|
6966
|
+
const slackTargets = /* @__PURE__ */ new Map();
|
|
6967
|
+
for (const target of targets) {
|
|
6968
|
+
if (target.kind !== "slack") continue;
|
|
6969
|
+
const targetKey = "memberId" in target ? `member:${target.memberId}` : `channel:${target.channel.replace(/^#/, "").toLowerCase()}`;
|
|
6970
|
+
slackTargets.set(targetKey, target);
|
|
6971
|
+
}
|
|
6972
|
+
const connectionId = current.slackConnection.connectionId;
|
|
6973
|
+
if (slackTargets.size > 0 && !connectionId) {
|
|
6974
|
+
throw new Error(
|
|
6975
|
+
"Slack is not connected to this workspace. Connect it in Dashboard \u2192 Integrations, then retry."
|
|
6976
|
+
);
|
|
6977
|
+
}
|
|
6978
|
+
const resolvedSlackTargets = await Promise.all(
|
|
6979
|
+
[...slackTargets.values()].map(async (target) => {
|
|
6980
|
+
if ("memberId" in target) {
|
|
6981
|
+
return {
|
|
6982
|
+
targetKind: "member",
|
|
6983
|
+
targetId: target.memberId,
|
|
6984
|
+
targetName: target.memberId
|
|
6985
|
+
};
|
|
6986
|
+
}
|
|
6987
|
+
const channel = target.channel;
|
|
6988
|
+
const requested = channel.replace(/^#/, "");
|
|
6989
|
+
const response = await this.listNotificationChannels(channel);
|
|
6990
|
+
const matches = response.channels.filter(
|
|
6991
|
+
(candidate) => candidate.id === requested || candidate.name.toLowerCase() === requested.toLowerCase()
|
|
6992
|
+
);
|
|
6993
|
+
if (matches.length !== 1) {
|
|
6994
|
+
throw new Error(
|
|
6995
|
+
matches.length === 0 ? `Slack channel ${channel} was not found or is not visible to the Deepline app.` : `Slack channel ${channel} is ambiguous. Use its channel ID.`
|
|
6996
|
+
);
|
|
6997
|
+
}
|
|
6998
|
+
return {
|
|
6999
|
+
targetKind: "channel",
|
|
7000
|
+
targetId: matches[0].id,
|
|
7001
|
+
targetName: matches[0].name
|
|
7002
|
+
};
|
|
7003
|
+
})
|
|
7004
|
+
);
|
|
7005
|
+
const uniqueSlackTargets = new Map(
|
|
7006
|
+
resolvedSlackTargets.map((target) => [
|
|
7007
|
+
`${target.targetKind}:${target.targetId}`,
|
|
7008
|
+
target
|
|
7009
|
+
])
|
|
7010
|
+
);
|
|
7011
|
+
for (const target of uniqueSlackTargets.values()) {
|
|
7012
|
+
if (destinations.some(
|
|
7013
|
+
(destination) => destination.settings.kind === "slack" && destination.settings.targetKind === target.targetKind && destination.settings.targetId === target.targetId
|
|
7014
|
+
)) {
|
|
7015
|
+
continue;
|
|
7016
|
+
}
|
|
7017
|
+
destinations.push({
|
|
7018
|
+
destinationKey: notificationObjectKey("destination"),
|
|
7019
|
+
groupKey,
|
|
7020
|
+
name: `${target.targetKind === "channel" ? "#" : "@"}${target.targetName}`,
|
|
7021
|
+
enabled: true,
|
|
7022
|
+
source: "workspace",
|
|
7023
|
+
configMode: "custom",
|
|
7024
|
+
version: 0,
|
|
7025
|
+
status: "pending_verification",
|
|
7026
|
+
settings: {
|
|
7027
|
+
kind: "slack",
|
|
7028
|
+
...target,
|
|
7029
|
+
oauthConnectionId: connectionId
|
|
7030
|
+
}
|
|
7031
|
+
});
|
|
7032
|
+
}
|
|
7033
|
+
const draft = {
|
|
7034
|
+
group,
|
|
7035
|
+
destinations,
|
|
7036
|
+
rules: current.configuration.rules.filter(
|
|
7037
|
+
(rule) => rule.groupKey === groupKey
|
|
7038
|
+
)
|
|
7039
|
+
};
|
|
7040
|
+
const result = await this.changeNotificationConfiguration(
|
|
7041
|
+
current.configuration.workspaceVersion,
|
|
7042
|
+
{ kind: "save_group", draft }
|
|
7043
|
+
);
|
|
7044
|
+
const storedGroup = result.configuration.groups.find(
|
|
7045
|
+
(candidate) => candidate.groupKey === groupKey
|
|
7046
|
+
);
|
|
7047
|
+
if (!storedGroup) {
|
|
7048
|
+
throw new Error("Notification group creation returned no saved group.");
|
|
7049
|
+
}
|
|
7050
|
+
return {
|
|
7051
|
+
mode: "native",
|
|
7052
|
+
groupKey,
|
|
7053
|
+
targets: normalizedTargets,
|
|
7054
|
+
group: storedGroup,
|
|
7055
|
+
destinations: result.configuration.destinations.filter(
|
|
7056
|
+
(destination) => destination.groupKey === groupKey
|
|
7057
|
+
)
|
|
7058
|
+
};
|
|
7059
|
+
}
|
|
6748
7060
|
/** List Slack channels available to an already-connected Slack integration. */
|
|
6749
7061
|
async listNotificationChannels(query) {
|
|
6750
7062
|
const suffix = query ? `?search=${encodeURIComponent(query)}` : "";
|
|
@@ -7289,6 +7601,78 @@ var DeeplineClient = class {
|
|
|
7289
7601
|
{ method: "GET" }
|
|
7290
7602
|
);
|
|
7291
7603
|
}
|
|
7604
|
+
/** Submit durable monitor work; transport retries use the same idempotency key. */
|
|
7605
|
+
async submitMonitorBatch(options) {
|
|
7606
|
+
const idempotencyKey = options.idempotencyKey.trim();
|
|
7607
|
+
if (!idempotencyKey) {
|
|
7608
|
+
throw new DeeplineError(
|
|
7609
|
+
"Monitor batch idempotencyKey is required.",
|
|
7610
|
+
void 0,
|
|
7611
|
+
"INVALID_MONITOR_BATCH_IDEMPOTENCY_KEY"
|
|
7612
|
+
);
|
|
7613
|
+
}
|
|
7614
|
+
if (options.kind === "deploy") {
|
|
7615
|
+
if (!options.manifestNdjson.trim()) {
|
|
7616
|
+
throw new DeeplineError(
|
|
7617
|
+
"Monitor batch deploy requires a non-empty NDJSON manifest.",
|
|
7618
|
+
void 0,
|
|
7619
|
+
"INVALID_MONITOR_BATCH_MANIFEST"
|
|
7620
|
+
);
|
|
7621
|
+
}
|
|
7622
|
+
return this.http.request(
|
|
7623
|
+
"/api/v2/monitors/batch",
|
|
7624
|
+
{
|
|
7625
|
+
method: "POST",
|
|
7626
|
+
body: {
|
|
7627
|
+
kind: "deploy",
|
|
7628
|
+
manifest_ndjson: options.manifestNdjson,
|
|
7629
|
+
dry_run: options.dryRun === true,
|
|
7630
|
+
idempotency_key: idempotencyKey
|
|
7631
|
+
},
|
|
7632
|
+
headers: { "Idempotency-Key": idempotencyKey },
|
|
7633
|
+
maxRetries: 0,
|
|
7634
|
+
exactUrlOnly: true
|
|
7635
|
+
}
|
|
7636
|
+
);
|
|
7637
|
+
}
|
|
7638
|
+
const scope = options.scope.kind === "keys" ? { kind: "keys", monitor_keys: options.scope.monitorKeys } : options.scope.kind === "fleet" ? { kind: "fleet", fleet_id: options.scope.fleetId } : { kind: "target", target: options.scope.target };
|
|
7639
|
+
return this.http.request(
|
|
7640
|
+
"/api/v2/monitors/batch",
|
|
7641
|
+
{
|
|
7642
|
+
method: "POST",
|
|
7643
|
+
body: {
|
|
7644
|
+
kind: options.kind,
|
|
7645
|
+
scope,
|
|
7646
|
+
dry_run: options.dryRun === true,
|
|
7647
|
+
idempotency_key: idempotencyKey,
|
|
7648
|
+
...options.deactivationReason === void 0 ? {} : { deactivation_reason: options.deactivationReason }
|
|
7649
|
+
},
|
|
7650
|
+
headers: { "Idempotency-Key": idempotencyKey },
|
|
7651
|
+
// Durable submission is itself idempotent, but an ambiguous local retry
|
|
7652
|
+
// must retain the exact key and never turn a CLI attempt into two runs.
|
|
7653
|
+
maxRetries: 0,
|
|
7654
|
+
exactUrlOnly: true
|
|
7655
|
+
}
|
|
7656
|
+
);
|
|
7657
|
+
}
|
|
7658
|
+
/** Get durable batch progress and a bounded retained evidence page. */
|
|
7659
|
+
async getMonitorBatch(operationId, options) {
|
|
7660
|
+
const runId = operationId.trim();
|
|
7661
|
+
if (!runId) {
|
|
7662
|
+
throw new DeeplineError(
|
|
7663
|
+
"Monitor batch operation id is required.",
|
|
7664
|
+
void 0,
|
|
7665
|
+
"INVALID_MONITOR_BATCH_OPERATION_ID"
|
|
7666
|
+
);
|
|
7667
|
+
}
|
|
7668
|
+
const params = new URLSearchParams();
|
|
7669
|
+
if (options?.cursor) params.set("cursor", options.cursor);
|
|
7670
|
+
const suffix = params.size > 0 ? `?${params}` : "";
|
|
7671
|
+
return this.http.request(
|
|
7672
|
+
`/api/v2/monitors/batch/${encodeURIComponent(runId)}${suffix}`,
|
|
7673
|
+
{ method: "GET" }
|
|
7674
|
+
);
|
|
7675
|
+
}
|
|
7292
7676
|
/**
|
|
7293
7677
|
* The deployable monitor tools catalog. Pass a tool id (positional or
|
|
7294
7678
|
* `{ tool }`) to describe one tool's full payload/stream contract, or no tool
|
|
@@ -8594,7 +8978,9 @@ function saveEnvValues(values, baseUrl, scope) {
|
|
|
8594
8978
|
...values[HOST_URL_ENV] ? { [HOST_URL_ENV]: values[HOST_URL_ENV] } : {},
|
|
8595
8979
|
...values[API_KEY_ENV] ? { [API_KEY_ENV]: values[API_KEY_ENV] } : {},
|
|
8596
8980
|
...values[ACTIVE_ORG_ID_ENV] ? { [ACTIVE_ORG_ID_ENV]: values[ACTIVE_ORG_ID_ENV] } : {},
|
|
8597
|
-
...Object.prototype.hasOwnProperty.call(values, ACTIVE_ORG_NAME_ENV) ? { [ACTIVE_ORG_NAME_ENV]: values[ACTIVE_ORG_NAME_ENV] } : {}
|
|
8981
|
+
...Object.prototype.hasOwnProperty.call(values, ACTIVE_ORG_NAME_ENV) ? { [ACTIVE_ORG_NAME_ENV]: values[ACTIVE_ORG_NAME_ENV] } : {},
|
|
8982
|
+
// An explicit empty list must reach the store: it clears a stale line.
|
|
8983
|
+
...Object.prototype.hasOwnProperty.call(values, FEATURES_ENV) ? { [FEATURES_ENV]: values[FEATURES_ENV] } : {}
|
|
8598
8984
|
};
|
|
8599
8985
|
if (scope === "folder") {
|
|
8600
8986
|
saveProjectDeeplineEnvValues(filtered);
|
|
@@ -8608,7 +8994,8 @@ function activeOrgEnvValues(data) {
|
|
|
8608
8994
|
const orgName = typeof data.org_name === "string" ? data.org_name.trim() : "";
|
|
8609
8995
|
return {
|
|
8610
8996
|
[ACTIVE_ORG_ID_ENV]: orgId,
|
|
8611
|
-
[ACTIVE_ORG_NAME_ENV]: orgName
|
|
8997
|
+
[ACTIVE_ORG_NAME_ENV]: orgName,
|
|
8998
|
+
...featureEnvValues(data)
|
|
8612
8999
|
};
|
|
8613
9000
|
}
|
|
8614
9001
|
async function httpJson(method, url, apiKey, body, timeoutMs = AUTH_HTTP_TIMEOUT_MS) {
|
|
@@ -9133,6 +9520,8 @@ async function handleStatus(args) {
|
|
|
9133
9520
|
savedApiKeyPath = envFilePath(baseUrl);
|
|
9134
9521
|
}
|
|
9135
9522
|
}
|
|
9523
|
+
} else if (resolvedAuthScope === "folder" || storedHostApiKey(baseUrl) === apiKey) {
|
|
9524
|
+
saveEnvValues(featureEnvValues(data), baseUrl, resolvedAuthScope);
|
|
9136
9525
|
}
|
|
9137
9526
|
printCommandEnvelope(
|
|
9138
9527
|
{
|
|
@@ -10337,12 +10726,12 @@ async function handleBuyCredits(creditsRaw, options) {
|
|
|
10337
10726
|
);
|
|
10338
10727
|
}
|
|
10339
10728
|
async function handleTargetPlan(planSku, options) {
|
|
10340
|
-
if (planSku !== "payg-v1" && planSku !== "builder-v1" && planSku !== "team-v1") {
|
|
10729
|
+
if (planSku !== "payg-v1" && planSku !== "builder-v1" && planSku !== "growth-v1" && planSku !== "growth-canary-v1" && planSku !== "team-v1") {
|
|
10341
10730
|
reportBillingFailure(
|
|
10342
10731
|
{
|
|
10343
10732
|
exitCode: 2,
|
|
10344
10733
|
code: "INVALID_PLAN",
|
|
10345
|
-
message: "Plan must be payg-v1, builder-v1, or team-v1."
|
|
10734
|
+
message: "Plan must be payg-v1, builder-v1, growth-v1, growth-canary-v1, or team-v1."
|
|
10346
10735
|
},
|
|
10347
10736
|
options
|
|
10348
10737
|
);
|
|
@@ -10603,7 +10992,7 @@ Examples:
|
|
|
10603
10992
|
"Disable automatic recharge without clearing saved amounts."
|
|
10604
10993
|
).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeOff)
|
|
10605
10994
|
);
|
|
10606
|
-
billing.command("change-plan").description("Start or change the target billing plan.").argument("<plan_sku>", "payg-v1, builder-v1, or team-v1").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
|
|
10995
|
+
billing.command("change-plan").description("Start or change the target billing plan.").argument("<plan_sku>", "payg-v1, builder-v1, growth-v1, growth-canary-v1, or team-v1").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
|
|
10607
10996
|
billing.command("cancel-plan").description("Cancel a target subscription at period end, or undo it.").option("--undo", "Undo a pending period-end cancellation").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlanCancellation);
|
|
10608
10997
|
billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
|
|
10609
10998
|
billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
|
|
@@ -10889,6 +11278,12 @@ function mergeCanonicalRowsInfo(left, right) {
|
|
|
10889
11278
|
const exportUnavailableReason = left.exportUnavailableReason === "shared_table_namespace" || right.exportUnavailableReason === "shared_table_namespace" ? "shared_table_namespace" : left.exportUnavailableReason ?? right.exportUnavailableReason;
|
|
10890
11279
|
const unavailableSource = left.exportUnavailableReason === exportUnavailableReason ? left : right.exportUnavailableReason === exportUnavailableReason ? right : null;
|
|
10891
11280
|
const columns = preferred.columns.length > 0 ? preferred.columns : fallback.columns;
|
|
11281
|
+
const recoveredReturnPaths2 = [
|
|
11282
|
+
.../* @__PURE__ */ new Set([
|
|
11283
|
+
...left.recoveredReturnPaths ?? [],
|
|
11284
|
+
...right.recoveredReturnPaths ?? []
|
|
11285
|
+
])
|
|
11286
|
+
];
|
|
10892
11287
|
return {
|
|
10893
11288
|
...fallback,
|
|
10894
11289
|
...preferred,
|
|
@@ -10901,6 +11296,7 @@ function mergeCanonicalRowsInfo(left, right) {
|
|
|
10901
11296
|
datasetId: preferred.datasetId ?? fallback.datasetId,
|
|
10902
11297
|
tableNamespace: preferred.tableNamespace ?? fallback.tableNamespace,
|
|
10903
11298
|
...left.recovered || right.recovered ? { recovered: true } : {},
|
|
11299
|
+
...recoveredReturnPaths2.length ? { recoveredReturnPaths: recoveredReturnPaths2 } : {},
|
|
10904
11300
|
...exportUnavailableReason ? {
|
|
10905
11301
|
exportUnavailableReason,
|
|
10906
11302
|
...unavailableSource?.exportUnavailableMessage ? {
|
|
@@ -10961,6 +11357,16 @@ function isSerializedDataset(value) {
|
|
|
10961
11357
|
function isPackagedDatasetOutput(value) {
|
|
10962
11358
|
return isRecord8(value) && value.kind === "dataset" && isRecord8(value.preview) && Array.isArray(value.preview.rows);
|
|
10963
11359
|
}
|
|
11360
|
+
function recoveredReturnPaths(value) {
|
|
11361
|
+
if (!Array.isArray(value)) return [];
|
|
11362
|
+
return [
|
|
11363
|
+
...new Set(
|
|
11364
|
+
value.filter(
|
|
11365
|
+
(path) => typeof path === "string" && /^result\.[A-Za-z_$][A-Za-z0-9_$]*$/.test(path)
|
|
11366
|
+
).slice(0, 200)
|
|
11367
|
+
)
|
|
11368
|
+
];
|
|
11369
|
+
}
|
|
10964
11370
|
function pathParts(path) {
|
|
10965
11371
|
return path.split(".").map((part) => part.trim()).filter(Boolean);
|
|
10966
11372
|
}
|
|
@@ -11057,6 +11463,11 @@ function canonicalRowsInfoFromCandidate(input2) {
|
|
|
11057
11463
|
datasetId: typeof candidate.value.datasetId === "string" ? candidate.value.datasetId : null,
|
|
11058
11464
|
tableNamespace: typeof candidate.value.tableNamespace === "string" ? candidate.value.tableNamespace : null,
|
|
11059
11465
|
...candidate.value.recovered === true ? { recovered: true } : {},
|
|
11466
|
+
...recoveredReturnPaths(candidate.value.recoveredReturnPaths).length ? {
|
|
11467
|
+
recoveredReturnPaths: recoveredReturnPaths(
|
|
11468
|
+
candidate.value.recoveredReturnPaths
|
|
11469
|
+
)
|
|
11470
|
+
} : {},
|
|
11060
11471
|
...isRecord8(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace") ? {
|
|
11061
11472
|
exportUnavailableReason: candidate.value.exportUnavailable.reason,
|
|
11062
11473
|
...typeof candidate.value.exportUnavailable.message === "string" ? {
|
|
@@ -15162,6 +15573,82 @@ var PLAY_AUTHORING_FIELD_REGISTRY = {
|
|
|
15162
15573
|
description: "Unsupported legacy child-workflow timeout.",
|
|
15163
15574
|
errorMessage: "ctx.runPlay timeoutMs is unsupported because child Plays execute inline."
|
|
15164
15575
|
},
|
|
15576
|
+
"ctx.runPlayAsync.key": {
|
|
15577
|
+
schema: import_typebox.Type.String({ minLength: 1 }),
|
|
15578
|
+
fixtures: {
|
|
15579
|
+
valid: "request-approval",
|
|
15580
|
+
invalid: "",
|
|
15581
|
+
absent: void 0,
|
|
15582
|
+
unresolved: { expression: "callKey" },
|
|
15583
|
+
edition1: "request-approval"
|
|
15584
|
+
},
|
|
15585
|
+
referenceType: "string",
|
|
15586
|
+
required: true,
|
|
15587
|
+
resolution: "runtime-dynamic",
|
|
15588
|
+
issueCode: "play_authoring_run_play_option_invalid",
|
|
15589
|
+
description: "Stable identity for one independent child Play Run.",
|
|
15590
|
+
errorMessage: "ctx.runPlayAsync key must be a non-empty string."
|
|
15591
|
+
},
|
|
15592
|
+
"ctx.runPlayAsync.playRef": {
|
|
15593
|
+
schema: import_typebox.Type.Union([
|
|
15594
|
+
import_typebox.Type.String({ minLength: 1 }),
|
|
15595
|
+
import_typebox.Type.Union([
|
|
15596
|
+
import_typebox.Type.Object(
|
|
15597
|
+
{ playName: import_typebox.Type.String({ minLength: 1 }) },
|
|
15598
|
+
{ additionalProperties: true }
|
|
15599
|
+
),
|
|
15600
|
+
import_typebox.Type.Object(
|
|
15601
|
+
{ name: import_typebox.Type.String({ minLength: 1 }) },
|
|
15602
|
+
{ additionalProperties: true }
|
|
15603
|
+
)
|
|
15604
|
+
])
|
|
15605
|
+
]),
|
|
15606
|
+
fixtures: {
|
|
15607
|
+
valid: "request-approval",
|
|
15608
|
+
invalid: {},
|
|
15609
|
+
absent: void 0,
|
|
15610
|
+
unresolved: { expression: "playRef" },
|
|
15611
|
+
edition1: "request-approval"
|
|
15612
|
+
},
|
|
15613
|
+
referenceType: "string | PlayReferenceLike",
|
|
15614
|
+
required: true,
|
|
15615
|
+
resolution: "runtime-dynamic",
|
|
15616
|
+
issueCode: "play_authoring_run_play_option_invalid",
|
|
15617
|
+
description: "Independently published scalar child Play name or strongly typed definition handle.",
|
|
15618
|
+
errorMessage: "ctx.runPlayAsync playRef must be a non-empty Play name or definition handle."
|
|
15619
|
+
},
|
|
15620
|
+
"ctx.runPlayAsync.input": {
|
|
15621
|
+
schema: import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Unknown()),
|
|
15622
|
+
fixtures: {
|
|
15623
|
+
valid: { draftId: "draft-1" },
|
|
15624
|
+
invalid: "draft-1",
|
|
15625
|
+
absent: void 0,
|
|
15626
|
+
unresolved: "childInput",
|
|
15627
|
+
edition1: {}
|
|
15628
|
+
},
|
|
15629
|
+
referenceType: "Record<string, unknown>",
|
|
15630
|
+
required: true,
|
|
15631
|
+
resolution: "runtime-dynamic",
|
|
15632
|
+
issueCode: "play_authoring_run_play_option_invalid",
|
|
15633
|
+
description: "Scalar input object submitted to the independent child Run.",
|
|
15634
|
+
errorMessage: "ctx.runPlayAsync input must be an object."
|
|
15635
|
+
},
|
|
15636
|
+
"ctx.runPlayAsync.options.description": {
|
|
15637
|
+
schema: import_typebox.Type.String({ minLength: 1 }),
|
|
15638
|
+
fixtures: {
|
|
15639
|
+
valid: "Request approval.",
|
|
15640
|
+
invalid: "",
|
|
15641
|
+
absent: void 0,
|
|
15642
|
+
unresolved: { expression: "description" },
|
|
15643
|
+
edition1: "Request approval."
|
|
15644
|
+
},
|
|
15645
|
+
referenceType: "string",
|
|
15646
|
+
required: true,
|
|
15647
|
+
resolution: "runtime-dynamic",
|
|
15648
|
+
issueCode: "play_authoring_run_play_option_invalid",
|
|
15649
|
+
description: "Non-empty purpose for one independent child Play Run.",
|
|
15650
|
+
errorMessage: "ctx.runPlayAsync options.description must be non-empty."
|
|
15651
|
+
},
|
|
15165
15652
|
"runtime.timeout": {
|
|
15166
15653
|
schema: import_typebox.Type.String({ pattern: "^\\d+\\s*[mh]$" }),
|
|
15167
15654
|
fixtures: {
|
|
@@ -15449,6 +15936,10 @@ var PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
|
|
|
15449
15936
|
`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")} };`,
|
|
15450
15937
|
"export type PlayCallExecution = 'inline';",
|
|
15451
15938
|
`export type PlayCallOptions = { description: ${cloudReferenceType("ctx.runPlay.options.description")}; execution?: ${cloudReferenceType("ctx.runPlay.options.execution")}; timeoutMs?: ${cloudReferenceType("ctx.runPlay.options.timeoutMs")} };`,
|
|
15939
|
+
`export type PlayAsyncCallOptions = { description: ${cloudReferenceType("ctx.runPlayAsync.options.description")} };`,
|
|
15940
|
+
"declare const PLAY_RUN_ID_BRAND: unique symbol;",
|
|
15941
|
+
"export type PlayRunId = string & { readonly [PLAY_RUN_ID_BRAND]: 'PlayRunId' };",
|
|
15942
|
+
"export type AsyncPlayRunRef = Readonly<{ runId: PlayRunId }>;",
|
|
15452
15943
|
`export type RuntimeStepOptions = { semanticKey?: ${cloudReferenceType("ctx.step.semanticKey")}; staleAfterSeconds?: ${cloudReferenceType("ctx.step.staleAfterSeconds")} };`,
|
|
15453
15944
|
`export type FetchOptions = { staleAfterSeconds?: ${cloudReferenceType("ctx.fetch.staleAfterSeconds")}; transient?: boolean };`,
|
|
15454
15945
|
"export type PlayFetchResponse = { ok: boolean; status: number; statusText: string; url: string; headers: Record<string, string>; bodyText: string; json: unknown | null };",
|
|
@@ -15474,11 +15965,11 @@ var PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
|
|
|
15474
15965
|
" 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>>;",
|
|
15475
15966
|
" withColumn<Name extends string, Value>(name: Name, definition: DatasetColumnDefinition<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value>>;",
|
|
15476
15967
|
" withColumn<Name extends string, Value>(name: Name, resolver: StepResolver<OutputRow, Value> | RunnableColumnStepProgram<Value>, options: StepOptions<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;",
|
|
15477
|
-
" withColumns<
|
|
15968
|
+
" withColumns<ProgramOutput extends OutputRow, Return>(program: StepProgram<OutputRow, ProgramOutput, Return>): DatasetBuilder<InputRow, ProgramOutput>;",
|
|
15478
15969
|
" step<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): never;",
|
|
15479
15970
|
" run(options?: DatasetRunOptions<InputRow>): Promise<PlayDataset<OutputRow>>;",
|
|
15480
15971
|
"};",
|
|
15481
|
-
"export type PlayReferenceLike = { readonly playName: string; readonly name?: string } | { readonly name: string; readonly playName?: string };",
|
|
15972
|
+
"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 };",
|
|
15482
15973
|
"export interface DeeplinePlayRuntimeContext {",
|
|
15483
15974
|
" csv<T = Record<string, unknown>>(path: string | CsvInput<T & object>, options?: CsvOptions): Promise<PlayDataset<T>>;",
|
|
15484
15975
|
" dataset<TSource extends PlayDatasetInput<object>>(key: string, items: TSource): DatasetBuilder<PlayDatasetRow<TSource> & object, PlayDatasetRow<TSource> & object>;",
|
|
@@ -15492,6 +15983,8 @@ var PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
|
|
|
15492
15983
|
" fetch(key: string, url: string | URL, init?: RequestInit & { headers?: HeadersInit & { 'Idempotency-Key'?: string; 'X-Idempotency-Key'?: string }; auth?: SecretAuthInput }, options?: FetchOptions): Promise<PlayFetchResponse>;",
|
|
15493
15984
|
" secrets: { get(name: string): SecretPromise; bearer(secret: string | SecretPromise | SecretHandle): SecretAuth; header(header: string, secret: string | SecretPromise | SecretHandle): SecretAuth };",
|
|
15494
15985
|
` runPlay<TOutput = unknown>(key: string, playRef: ${cloudReferenceType("ctx.runPlay.playRef")}, input: ${cloudReferenceType("ctx.runPlay.input")}, options: PlayCallOptions): Promise<TOutput>;`,
|
|
15986
|
+
" runPlayAsync<TInput extends Record<string, unknown>>(key: string, playRef: PlayReferenceLike<TInput>, input: NoInfer<TInput>, options: PlayAsyncCallOptions): Promise<AsyncPlayRunRef>;",
|
|
15987
|
+
" runPlayAsync(key: string, playRef: string, input: Record<string, unknown>, options: PlayAsyncCallOptions): Promise<AsyncPlayRunRef>;",
|
|
15495
15988
|
" log(message: string, options?: { level?: 'debug' | 'info' | 'warn' | 'error' }): void;",
|
|
15496
15989
|
` sleep(ms: ${cloudReferenceType("ctx.sleep.ms")}): Promise<void>;`,
|
|
15497
15990
|
"}",
|
|
@@ -15766,7 +16259,7 @@ function collectInlineSecretFindings(sourceCode) {
|
|
|
15766
16259
|
var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
|
|
15767
16260
|
|
|
15768
16261
|
// ../plays/bundling/index.ts
|
|
15769
|
-
var PLAY_BUNDLE_CACHE_VERSION =
|
|
16262
|
+
var PLAY_BUNDLE_CACHE_VERSION = 37;
|
|
15770
16263
|
var PLAY_ARTIFACT_CACHE_DIR = (0, import_node_path11.join)(
|
|
15771
16264
|
(0, import_node_os7.tmpdir)(),
|
|
15772
16265
|
`deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`
|
|
@@ -16498,7 +16991,7 @@ var RunDataset = class _RunDataset {
|
|
|
16498
16991
|
return this.#info.exportUnavailableMessage;
|
|
16499
16992
|
}
|
|
16500
16993
|
matches(path) {
|
|
16501
|
-
return this.source === path || this.datasetId === path || this.tableNamespace === path;
|
|
16994
|
+
return this.source === path || this.datasetId === path || this.tableNamespace === path || this.#info.recoveredReturnPaths?.includes(path) === true;
|
|
16502
16995
|
}
|
|
16503
16996
|
/** Return a new Handle when its preview has been replaced by fetched rows. */
|
|
16504
16997
|
withRows(info) {
|
|
@@ -17008,7 +17501,7 @@ function resolveDaytonaSandboxComputeItem(input2) {
|
|
|
17008
17501
|
};
|
|
17009
17502
|
}
|
|
17010
17503
|
|
|
17011
|
-
//
|
|
17504
|
+
// ../billing/compute-pricing-contract.ts
|
|
17012
17505
|
var COMPUTE_BILLING_MARKUP_MULTIPLIER = 5;
|
|
17013
17506
|
var DEFAULT_USD_PER_CUSTOMER_CREDIT = 0.1;
|
|
17014
17507
|
var DEFAULT_PROVIDER_MARKUP_MULTIPLIER = 1.4;
|
|
@@ -17343,6 +17836,39 @@ var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
17343
17836
|
"--open",
|
|
17344
17837
|
"--debug-map-latency"
|
|
17345
17838
|
]);
|
|
17839
|
+
var PLAY_RUN_HEADER_FLAG_USAGE = `--header requires "<name>: <value>", for example: --header 'x-deepline-absurd-release: 2026-09-07.1'`;
|
|
17840
|
+
var HTTP_HEADER_NAME_PATTERN = /^[!#$%&'*+\-.^_`|~0-9a-z]+$/;
|
|
17841
|
+
function parsePlayRunHeaderFlag(raw) {
|
|
17842
|
+
const separator = raw.indexOf(":");
|
|
17843
|
+
if (separator < 0) {
|
|
17844
|
+
throw new Error(
|
|
17845
|
+
`${PLAY_RUN_HEADER_FLAG_USAGE}. Got ${JSON.stringify(raw)} with no ":" separator.`
|
|
17846
|
+
);
|
|
17847
|
+
}
|
|
17848
|
+
const name = raw.slice(0, separator).trim().toLowerCase();
|
|
17849
|
+
const value = raw.slice(separator + 1).trim();
|
|
17850
|
+
if (!name) {
|
|
17851
|
+
throw new Error(
|
|
17852
|
+
`${PLAY_RUN_HEADER_FLAG_USAGE}. Got ${JSON.stringify(raw)} with an empty header name.`
|
|
17853
|
+
);
|
|
17854
|
+
}
|
|
17855
|
+
if (!HTTP_HEADER_NAME_PATTERN.test(name)) {
|
|
17856
|
+
throw new Error(
|
|
17857
|
+
`${PLAY_RUN_HEADER_FLAG_USAGE}. ${JSON.stringify(name)} is not a valid HTTP header name.`
|
|
17858
|
+
);
|
|
17859
|
+
}
|
|
17860
|
+
if (!value) {
|
|
17861
|
+
throw new Error(
|
|
17862
|
+
`${PLAY_RUN_HEADER_FLAG_USAGE}. Header ${JSON.stringify(name)} was given an empty value.`
|
|
17863
|
+
);
|
|
17864
|
+
}
|
|
17865
|
+
if (/[\u0000-\u001f\u007f]/.test(value)) {
|
|
17866
|
+
throw new Error(
|
|
17867
|
+
`${PLAY_RUN_HEADER_FLAG_USAGE}. Header ${JSON.stringify(name)} contains a control character.`
|
|
17868
|
+
);
|
|
17869
|
+
}
|
|
17870
|
+
return { name, value };
|
|
17871
|
+
}
|
|
17346
17872
|
function isBarePlayRunDebugFlag(args, index) {
|
|
17347
17873
|
return args[index] === "--debug" && (args[index + 1] === void 0 || args[index + 1].startsWith("--"));
|
|
17348
17874
|
}
|
|
@@ -18956,6 +19482,9 @@ function assertPlayWaitNotTimedOut(input2) {
|
|
|
18956
19482
|
}
|
|
18957
19483
|
}
|
|
18958
19484
|
var PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS = 15e3;
|
|
19485
|
+
function isAdmittedRunVisibilityDelay(error) {
|
|
19486
|
+
return error instanceof DeeplineError && error.statusCode === 404 && error.message.trim() === "Workflow run not found.";
|
|
19487
|
+
}
|
|
18959
19488
|
async function waitForPlayCompletionByStream(input2) {
|
|
18960
19489
|
let lastPhase = null;
|
|
18961
19490
|
let reconnectAttempt = 0;
|
|
@@ -18969,7 +19498,7 @@ async function waitForPlayCompletionByStream(input2) {
|
|
|
18969
19498
|
billing: false
|
|
18970
19499
|
});
|
|
18971
19500
|
} catch (error) {
|
|
18972
|
-
if (isTransientPlayStreamError(error)) {
|
|
19501
|
+
if (isTransientPlayStreamError(error) || isAdmittedRunVisibilityDelay(error)) {
|
|
18973
19502
|
return null;
|
|
18974
19503
|
}
|
|
18975
19504
|
throw error;
|
|
@@ -19080,7 +19609,7 @@ async function waitForPlayCompletionByStream(input2) {
|
|
|
19080
19609
|
if (timedOut) {
|
|
19081
19610
|
return { kind: "timed_out", sawEvent };
|
|
19082
19611
|
}
|
|
19083
|
-
if (!isTransientPlayStreamError(error)) {
|
|
19612
|
+
if (!isTransientPlayStreamError(error) && !isAdmittedRunVisibilityDelay(error)) {
|
|
19084
19613
|
throw error;
|
|
19085
19614
|
}
|
|
19086
19615
|
return {
|
|
@@ -21316,7 +21845,7 @@ function writeStartedPlayRun(input2) {
|
|
|
21316
21845
|
);
|
|
21317
21846
|
}
|
|
21318
21847
|
function parsePlayRunOptions(args) {
|
|
21319
|
-
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--json] [--full] [--<input> value]\n Runs use the Absurd CJS runtime.\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotent call caching and ctx.dataset guidance.";
|
|
21848
|
+
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--json] [--full] [--<input> value]\n Runs use the Absurd CJS runtime.\n --header '<name>: <value>' may repeat; each is sent on every request for this run.\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotent call caching and ctx.dataset guidance.";
|
|
21320
21849
|
let filePath = null;
|
|
21321
21850
|
let playName = null;
|
|
21322
21851
|
let input2 = null;
|
|
@@ -21337,8 +21866,20 @@ function parsePlayRunOptions(args) {
|
|
|
21337
21866
|
let profile = null;
|
|
21338
21867
|
let fixtureBehavior = null;
|
|
21339
21868
|
let runIdFile = null;
|
|
21869
|
+
let headers = null;
|
|
21340
21870
|
for (let index = 0; index < args.length; index += 1) {
|
|
21341
21871
|
const arg = args[index];
|
|
21872
|
+
if (arg === "--header" || arg.startsWith("--header=")) {
|
|
21873
|
+
const raw = arg === "--header" ? args[index + 1] : arg.slice("--header=".length);
|
|
21874
|
+
if (raw === void 0 || arg === "--header" && raw.startsWith("--")) {
|
|
21875
|
+
throw new Error(`${PLAY_RUN_HEADER_FLAG_USAGE}. No value was given.`);
|
|
21876
|
+
}
|
|
21877
|
+
const header = parsePlayRunHeaderFlag(raw);
|
|
21878
|
+
headers ??= {};
|
|
21879
|
+
headers[header.name] = header.value;
|
|
21880
|
+
if (arg === "--header") index += 1;
|
|
21881
|
+
continue;
|
|
21882
|
+
}
|
|
21342
21883
|
if (arg === "--file" && args[index + 1]) {
|
|
21343
21884
|
filePath = args[++index];
|
|
21344
21885
|
continue;
|
|
@@ -21577,7 +22118,8 @@ function parsePlayRunOptions(args) {
|
|
|
21577
22118
|
profile,
|
|
21578
22119
|
debugMapLatency,
|
|
21579
22120
|
fixtureBehavior,
|
|
21580
|
-
runIdFile
|
|
22121
|
+
runIdFile,
|
|
22122
|
+
headers
|
|
21581
22123
|
};
|
|
21582
22124
|
}
|
|
21583
22125
|
function parsePlayCheckOptions(args) {
|
|
@@ -22333,11 +22875,14 @@ function printPlayCheckOutcomes(outcomes, target) {
|
|
|
22333
22875
|
printPlayCheckOutcome(outcome, target, `[${outcome.exportName}] `);
|
|
22334
22876
|
}
|
|
22335
22877
|
}
|
|
22878
|
+
function playRunClientOptions(options) {
|
|
22879
|
+
return options.headers ? { headers: options.headers } : void 0;
|
|
22880
|
+
}
|
|
22336
22881
|
async function handleFileBackedRun(options, hooks) {
|
|
22337
22882
|
if (options.target.kind !== "file") {
|
|
22338
22883
|
throw new Error("Expected a file-backed play run target.");
|
|
22339
22884
|
}
|
|
22340
|
-
const client2 = new DeeplineClient();
|
|
22885
|
+
const client2 = new DeeplineClient(playRunClientOptions(options));
|
|
22341
22886
|
const progress = getActiveCliProgress() ?? createCliProgress(!options.jsonOutput);
|
|
22342
22887
|
const absolutePlayPath = (0, import_node_path14.resolve)(options.target.path);
|
|
22343
22888
|
progress.phase("compiling play");
|
|
@@ -22545,7 +23090,7 @@ async function handleNamedRun(options, hooks) {
|
|
|
22545
23090
|
if (options.target.kind !== "name") {
|
|
22546
23091
|
throw new Error("Expected a named play run target.");
|
|
22547
23092
|
}
|
|
22548
|
-
const client2 = new DeeplineClient();
|
|
23093
|
+
const client2 = new DeeplineClient(playRunClientOptions(options));
|
|
22549
23094
|
const progress = getActiveCliProgress() ?? createCliProgress(!options.jsonOutput);
|
|
22550
23095
|
const playName = options.target.name;
|
|
22551
23096
|
const runtimeInput = options.input ? { ...options.input } : {};
|
|
@@ -32633,7 +33178,7 @@ function renderDeployedListText(payload, requestedStatus) {
|
|
|
32633
33178
|
}
|
|
32634
33179
|
const applied = asString(payload.status_filter_applied) ?? requestedStatus ?? "active";
|
|
32635
33180
|
lines.push(
|
|
32636
|
-
`Status filter: ${applied}${requestedStatus === void 0 && applied === "active" ? " (default)" : ""} \u2014 use --status all to include
|
|
33181
|
+
`Status filter: ${applied}${requestedStatus === void 0 && applied === "active" ? " (default)" : ""} \u2014 use --status all to include inactive monitors.`
|
|
32637
33182
|
);
|
|
32638
33183
|
const summary = Array.isArray(payload.status_summary) ? payload.status_summary.flatMap((raw) => {
|
|
32639
33184
|
const item = asRecord2(raw);
|
|
@@ -32641,7 +33186,7 @@ function renderDeployedListText(payload, requestedStatus) {
|
|
|
32641
33186
|
const count = item ? asFiniteNumber(item.count) : void 0;
|
|
32642
33187
|
return status && count !== void 0 ? [`${status}: ${count}`] : [];
|
|
32643
33188
|
}).join(" ") : "";
|
|
32644
|
-
if (summary) lines.push(`All
|
|
33189
|
+
if (summary) lines.push(`All monitor states: ${summary}`);
|
|
32645
33190
|
if (payload.has_more === true || payload.is_truncated === true) {
|
|
32646
33191
|
const nextCursor = asString(payload.next_cursor);
|
|
32647
33192
|
lines.push(
|
|
@@ -33730,6 +34275,9 @@ async function handleMonitorsReactivate(key, options) {
|
|
|
33730
34275
|
}
|
|
33731
34276
|
var MONITOR_VERB_POLL_INTERVAL_MS = 2e3;
|
|
33732
34277
|
function monitorHealthLine(health) {
|
|
34278
|
+
if (health.refresh?.state === "running") {
|
|
34279
|
+
return `refreshing whole scope \xB7 scanned ${health.scanned} so far`;
|
|
34280
|
+
}
|
|
33733
34281
|
return [
|
|
33734
34282
|
`converged ${health.converged}/${health.scanned}`,
|
|
33735
34283
|
`needs_repair ${health.needs_repair}`,
|
|
@@ -33768,7 +34316,9 @@ async function watchMonitorHealth(input2) {
|
|
|
33768
34316
|
let last = await input2.client.monitors.health(scope);
|
|
33769
34317
|
input2.onProgress(last);
|
|
33770
34318
|
while (Date.now() < deadlineAt) {
|
|
33771
|
-
if (last.needs_repair === 0 && last.observed.unknown === 0)
|
|
34319
|
+
if (last.refresh?.state !== "running" && last.needs_repair === 0 && last.observed.unknown === 0) {
|
|
34320
|
+
return last;
|
|
34321
|
+
}
|
|
33772
34322
|
await new Promise(
|
|
33773
34323
|
(resolve21) => setTimeout(resolve21, MONITOR_VERB_POLL_INTERVAL_MS)
|
|
33774
34324
|
);
|
|
@@ -33778,11 +34328,21 @@ async function watchMonitorHealth(input2) {
|
|
|
33778
34328
|
return last;
|
|
33779
34329
|
}
|
|
33780
34330
|
function monitorHealthText(health) {
|
|
33781
|
-
const partial = health.truncated ? " (partial \u2014 scope larger than one read)" : "";
|
|
34331
|
+
const partial = health.refresh?.state === "running" ? " (refreshing \u2014 counts below are not final)" : health.truncated ? " (partial \u2014 scope larger than one read)" : "";
|
|
33782
34332
|
const lines = [
|
|
33783
34333
|
`scope: ${health.scope.fleet_id ?? "workspace"}${partial}`,
|
|
33784
34334
|
monitorHealthLine(health)
|
|
33785
34335
|
];
|
|
34336
|
+
if ((health.batch_operations?.length ?? 0) > 0) {
|
|
34337
|
+
lines.push("");
|
|
34338
|
+
lines.push("batch work in progress:");
|
|
34339
|
+
for (const operation of health.batch_operations ?? []) {
|
|
34340
|
+
const retry = operation.next_attempt_at === void 0 ? "" : ` \xB7 next ${new Date(operation.next_attempt_at).toISOString()}`;
|
|
34341
|
+
lines.push(
|
|
34342
|
+
` ${operation.kind} ${operation.run_id} \xB7 ${operation.state}${retry}`
|
|
34343
|
+
);
|
|
34344
|
+
}
|
|
34345
|
+
}
|
|
33786
34346
|
if (health.deactivation_reasons.length > 0) {
|
|
33787
34347
|
lines.push("");
|
|
33788
34348
|
lines.push("deactivated by Deepline:");
|
|
@@ -33855,78 +34415,143 @@ async function handleMonitorsAudit(options) {
|
|
|
33855
34415
|
);
|
|
33856
34416
|
}
|
|
33857
34417
|
async function handleMonitorsRepair(options) {
|
|
33858
|
-
|
|
34418
|
+
return await handleMonitorBatch("repair", {
|
|
34419
|
+
...options,
|
|
34420
|
+
...options.fleet?.trim() ? {} : { target: "needs-repair" }
|
|
34421
|
+
});
|
|
34422
|
+
}
|
|
34423
|
+
async function handleMonitorsHealth(options) {
|
|
33859
34424
|
const fleetId = options.fleet?.trim() || void 0;
|
|
33860
|
-
const
|
|
33861
|
-
|
|
33862
|
-
|
|
33863
|
-
|
|
34425
|
+
const health = await new DeeplineClient().monitors.health(
|
|
34426
|
+
fleetId ? { fleetId } : {}
|
|
34427
|
+
);
|
|
34428
|
+
printCommandEnvelope(health, {
|
|
34429
|
+
json: options.json,
|
|
34430
|
+
text: monitorHealthText(health)
|
|
33864
34431
|
});
|
|
33865
|
-
|
|
33866
|
-
|
|
33867
|
-
|
|
33868
|
-
|
|
34432
|
+
}
|
|
34433
|
+
function monitorBatchScope(options, kind) {
|
|
34434
|
+
const selectors = [
|
|
34435
|
+
options.target ? "target" : null,
|
|
34436
|
+
options.fleet?.trim() ? "fleet" : null,
|
|
34437
|
+
options.keys?.trim() ? "keys" : null
|
|
34438
|
+
].filter((value) => value !== null);
|
|
34439
|
+
if (selectors.length === 0 && kind === "audit") {
|
|
34440
|
+
return { kind: "target", target: "all" };
|
|
34441
|
+
}
|
|
34442
|
+
if (selectors.length !== 1) {
|
|
34443
|
+
throw new MonitorsUsageError(
|
|
34444
|
+
`monitors batch ${kind} needs exactly one selector: --target, --fleet, or --keys.`
|
|
33869
34445
|
);
|
|
33870
34446
|
}
|
|
33871
|
-
|
|
33872
|
-
if (options.
|
|
33873
|
-
|
|
33874
|
-
|
|
33875
|
-
|
|
33876
|
-
|
|
33877
|
-
|
|
33878
|
-
|
|
33879
|
-
onProgress: progress.report
|
|
33880
|
-
});
|
|
33881
|
-
} finally {
|
|
33882
|
-
progress.finish();
|
|
33883
|
-
}
|
|
34447
|
+
if (options.target) return { kind: "target", target: options.target };
|
|
34448
|
+
if (options.fleet?.trim())
|
|
34449
|
+
return { kind: "fleet", fleetId: options.fleet.trim() };
|
|
34450
|
+
const monitorKeys = (options.keys ?? "").split(",").map((key) => key.trim()).filter(Boolean);
|
|
34451
|
+
if (monitorKeys.length === 0) {
|
|
34452
|
+
throw new MonitorsUsageError(
|
|
34453
|
+
"--keys needs one or more comma-separated monitor keys."
|
|
34454
|
+
);
|
|
33884
34455
|
}
|
|
33885
|
-
|
|
33886
|
-
|
|
33887
|
-
|
|
33888
|
-
|
|
33889
|
-
|
|
33890
|
-
|
|
33891
|
-
|
|
33892
|
-
|
|
34456
|
+
return { kind: "keys", monitorKeys };
|
|
34457
|
+
}
|
|
34458
|
+
function monitorBatchIdempotencyKey(kind, value) {
|
|
34459
|
+
return value?.trim() || `monitor-batch-${kind}-${(0, import_node_crypto8.randomUUID)()}`;
|
|
34460
|
+
}
|
|
34461
|
+
async function handleMonitorBatchDeploy(options) {
|
|
34462
|
+
if (!options.file?.trim()) {
|
|
34463
|
+
throw new MonitorsUsageError(
|
|
34464
|
+
"monitors batch deploy requires --file <monitors.ndjson>."
|
|
33893
34465
|
);
|
|
33894
34466
|
}
|
|
33895
|
-
if (
|
|
33896
|
-
|
|
34467
|
+
if (options.dryRun !== true && options.yes !== true) {
|
|
34468
|
+
throw new MonitorsUsageError(
|
|
34469
|
+
"monitors batch deploy changes provider monitors asynchronously. Preview with --dry-run, then confirm with --yes."
|
|
34470
|
+
);
|
|
33897
34471
|
}
|
|
33898
|
-
|
|
33899
|
-
|
|
33900
|
-
|
|
34472
|
+
let manifestNdjson;
|
|
34473
|
+
try {
|
|
34474
|
+
manifestNdjson = (0, import_node_fs15.readFileSync)((0, import_node_path17.resolve)(options.file), "utf8");
|
|
34475
|
+
} catch (error) {
|
|
34476
|
+
throw new MonitorsUsageError(
|
|
34477
|
+
`Could not read monitor batch manifest '${options.file}': ${error instanceof Error ? error.message : String(error)}`
|
|
33901
34478
|
);
|
|
33902
34479
|
}
|
|
33903
|
-
if (
|
|
33904
|
-
|
|
33905
|
-
|
|
34480
|
+
if (!manifestNdjson.trim()) {
|
|
34481
|
+
throw new MonitorsUsageError("Monitor batch manifest is empty.");
|
|
34482
|
+
}
|
|
34483
|
+
const idempotencyKey = monitorBatchIdempotencyKey(
|
|
34484
|
+
"deploy",
|
|
34485
|
+
options.idempotencyKey
|
|
34486
|
+
);
|
|
34487
|
+
const result = await new DeeplineClient().monitors.batch.submit({
|
|
34488
|
+
kind: "deploy",
|
|
34489
|
+
manifestNdjson,
|
|
34490
|
+
dryRun: options.dryRun === true,
|
|
34491
|
+
idempotencyKey
|
|
34492
|
+
});
|
|
34493
|
+
const operation = result.operation;
|
|
34494
|
+
printCommandEnvelope(
|
|
34495
|
+
{ ...result, idempotency_key: idempotencyKey },
|
|
34496
|
+
{
|
|
34497
|
+
json: options.json,
|
|
34498
|
+
text: [
|
|
34499
|
+
`${result.rejoined ? "rejoined" : "submitted"} deploy batch ${operation.runId}`,
|
|
34500
|
+
`state ${operation.state} \xB7 retry key ${idempotencyKey}`,
|
|
34501
|
+
`inspect: deepline monitors batch get ${operation.runId} --json`
|
|
34502
|
+
].join("\n") + "\n"
|
|
34503
|
+
}
|
|
34504
|
+
);
|
|
34505
|
+
}
|
|
34506
|
+
async function handleMonitorBatch(kind, options) {
|
|
34507
|
+
if ((kind === "deactivate" || kind === "reactivate" || kind === "repair") && options.dryRun !== true && options.yes !== true) {
|
|
34508
|
+
throw new MonitorsUsageError(
|
|
34509
|
+
`monitors batch ${kind} changes provider monitors asynchronously. Preview with --dry-run, then confirm with --yes.`
|
|
33906
34510
|
);
|
|
33907
34511
|
}
|
|
33908
|
-
if (
|
|
33909
|
-
|
|
33910
|
-
|
|
34512
|
+
if (kind === "deactivate" && !options.reason?.trim()) {
|
|
34513
|
+
throw new MonitorsUsageError(
|
|
34514
|
+
"monitors batch deactivate requires --reason (for example insufficient_balance or billing_failure)."
|
|
33911
34515
|
);
|
|
33912
34516
|
}
|
|
33913
|
-
|
|
33914
|
-
|
|
34517
|
+
const idempotencyKey = monitorBatchIdempotencyKey(
|
|
34518
|
+
kind,
|
|
34519
|
+
options.idempotencyKey
|
|
34520
|
+
);
|
|
34521
|
+
const result = await new DeeplineClient().monitors.batch.submit({
|
|
34522
|
+
kind,
|
|
34523
|
+
scope: monitorBatchScope(options, kind),
|
|
34524
|
+
dryRun: options.dryRun === true,
|
|
34525
|
+
...options.reason?.trim() ? { deactivationReason: options.reason.trim() } : {},
|
|
34526
|
+
idempotencyKey
|
|
34527
|
+
});
|
|
34528
|
+
const operation = result.operation;
|
|
34529
|
+
const text = [
|
|
34530
|
+
`${result.rejoined ? "rejoined" : "submitted"} ${operation.kind} batch ${operation.runId}`,
|
|
34531
|
+
`state ${operation.state} \xB7 retry key ${idempotencyKey}`,
|
|
34532
|
+
`inspect: deepline monitors batch get ${operation.runId} --json`
|
|
34533
|
+
].join("\n");
|
|
33915
34534
|
printCommandEnvelope(
|
|
33916
|
-
{ ...result,
|
|
33917
|
-
{ json: options.json, text:
|
|
34535
|
+
{ ...result, idempotency_key: idempotencyKey },
|
|
34536
|
+
{ json: options.json, text: `${text}
|
|
34537
|
+
` }
|
|
33918
34538
|
);
|
|
33919
34539
|
}
|
|
33920
|
-
|
|
33921
|
-
|
|
33922
|
-
|
|
33923
|
-
const health = await new DeeplineClient().monitors.health(
|
|
33924
|
-
fleetId ? { fleetId } : {}
|
|
33925
|
-
);
|
|
33926
|
-
printCommandEnvelope(health, {
|
|
33927
|
-
json: options.json,
|
|
33928
|
-
text: monitorHealthText(health)
|
|
34540
|
+
async function handleMonitorBatchGet(operationId, options) {
|
|
34541
|
+
const result = await new DeeplineClient().monitors.batch.get(operationId, {
|
|
34542
|
+
...options.cursor ? { cursor: options.cursor } : {}
|
|
33929
34543
|
});
|
|
34544
|
+
const summary = result.operation.summary ?? {};
|
|
34545
|
+
const text = [
|
|
34546
|
+
`${result.operation.kind} batch ${result.operation.runId}`,
|
|
34547
|
+
`state ${result.operation.state}`,
|
|
34548
|
+
`progress ${JSON.stringify(summary)}`,
|
|
34549
|
+
...result.results ? [
|
|
34550
|
+
`results ${result.results.page.length}${result.results.isDone ? "" : " (more; pass --cursor)"}`
|
|
34551
|
+
] : []
|
|
34552
|
+
].join("\n");
|
|
34553
|
+
printCommandEnvelope(result, { json: options.json, text: `${text}
|
|
34554
|
+
` });
|
|
33930
34555
|
}
|
|
33931
34556
|
function registerMonitorsCommands(program) {
|
|
33932
34557
|
const monitors = program.command("monitors").description("Discover, deploy, and manage Deepline monitors.").showSuggestionAfterError(true).addHelpText(
|
|
@@ -33991,25 +34616,29 @@ Examples:
|
|
|
33991
34616
|
withJsonOption(
|
|
33992
34617
|
monitors.command("repair").description(
|
|
33993
34618
|
"Converge the monitors whose desired and observed states disagree."
|
|
33994
|
-
).option("--fleet <fleet-id>", "Repair one fleet instead of every monitor").option(
|
|
33995
|
-
"--
|
|
33996
|
-
"
|
|
34619
|
+
).option("--fleet <fleet-id>", "Repair one fleet instead of every monitor").option(
|
|
34620
|
+
"--dry-run",
|
|
34621
|
+
"Record the bounded repair plan without provider changes"
|
|
34622
|
+
).option("--yes", "Confirm the asynchronous provider repair").option(
|
|
34623
|
+
"--idempotency-key <key>",
|
|
34624
|
+
"Stable retry key (generated when omitted)"
|
|
33997
34625
|
).addHelpText(
|
|
33998
34626
|
"after",
|
|
33999
34627
|
`
|
|
34000
34628
|
Notes:
|
|
34001
|
-
|
|
34002
|
-
|
|
34003
|
-
|
|
34004
|
-
is
|
|
34629
|
+
This is the short spelling of 'monitors batch repair --target needs-repair'.
|
|
34630
|
+
It handles both direct monitors and Fleet members through one durable
|
|
34631
|
+
service-account worker. An active historical monitor without an upstream id
|
|
34632
|
+
is selected for repair; current Convex writes cannot create that state.
|
|
34005
34633
|
|
|
34006
|
-
|
|
34007
|
-
|
|
34008
|
-
|
|
34634
|
+
It returns a run id immediately. Inspect retained results with
|
|
34635
|
+
'deepline monitors batch get <run-id> --json'. Reuse --idempotency-key after
|
|
34636
|
+
a lost response to rejoin the exact run without another provider request.
|
|
34009
34637
|
|
|
34010
34638
|
Examples:
|
|
34011
34639
|
deepline monitors repair --dry-run
|
|
34012
|
-
deepline monitors repair --
|
|
34640
|
+
deepline monitors repair --yes
|
|
34641
|
+
deepline monitors repair --fleet accounts-eu --yes --idempotency-key repair-eu-2026-09-09
|
|
34013
34642
|
`
|
|
34014
34643
|
)
|
|
34015
34644
|
).action(monitorsAction(handleMonitorsRepair));
|
|
@@ -34032,6 +34661,75 @@ Examples:
|
|
|
34032
34661
|
`
|
|
34033
34662
|
)
|
|
34034
34663
|
).action(monitorsAction(handleMonitorsHealth));
|
|
34664
|
+
const batch = monitors.command("batch").description("Submit or inspect durable bulk monitor operations.");
|
|
34665
|
+
const batchSelectorOptions = (command) => command.option(
|
|
34666
|
+
"--target <target>",
|
|
34667
|
+
"One of: all, all-active, billing-suspended, needs-repair"
|
|
34668
|
+
).option("--fleet <fleet-id>", "Select one Fleet").option("--keys <keys>", "Up to 100 comma-separated monitor keys").option(
|
|
34669
|
+
"--dry-run",
|
|
34670
|
+
"Record the same bounded plan without provider changes"
|
|
34671
|
+
).option(
|
|
34672
|
+
"--idempotency-key <key>",
|
|
34673
|
+
"Stable retry key (generated when omitted)"
|
|
34674
|
+
);
|
|
34675
|
+
withJsonOption(
|
|
34676
|
+
batch.command("deploy").description(
|
|
34677
|
+
"Durably create complete NDJSON monitor definitions through provider bulk create."
|
|
34678
|
+
).requiredOption(
|
|
34679
|
+
"--file <path>",
|
|
34680
|
+
"NDJSON file of complete monitor definitions"
|
|
34681
|
+
).option("--dry-run", "Validate and record the durable deploy plan").option("--yes", "Confirm asynchronous provider creation").option(
|
|
34682
|
+
"--idempotency-key <key>",
|
|
34683
|
+
"Stable retry key (generated when omitted)"
|
|
34684
|
+
)
|
|
34685
|
+
).action(
|
|
34686
|
+
monitorsAction(
|
|
34687
|
+
(options) => handleMonitorBatchDeploy(options)
|
|
34688
|
+
)
|
|
34689
|
+
);
|
|
34690
|
+
withJsonOption(
|
|
34691
|
+
batchSelectorOptions(
|
|
34692
|
+
batch.command("audit").description("Durably audit a selection; defaults to --target all.")
|
|
34693
|
+
)
|
|
34694
|
+
).action(
|
|
34695
|
+
monitorsAction(
|
|
34696
|
+
(options) => handleMonitorBatch("audit", options)
|
|
34697
|
+
)
|
|
34698
|
+
);
|
|
34699
|
+
withJsonOption(
|
|
34700
|
+
batchSelectorOptions(
|
|
34701
|
+
batch.command("repair").description(
|
|
34702
|
+
"Durably re-audit and converge a selection through the existing lifecycle fences."
|
|
34703
|
+
)
|
|
34704
|
+
).option("--yes", "Confirm the asynchronous provider repair")
|
|
34705
|
+
).action(
|
|
34706
|
+
monitorsAction(
|
|
34707
|
+
(options) => handleMonitorBatch("repair", options)
|
|
34708
|
+
)
|
|
34709
|
+
);
|
|
34710
|
+
withJsonOption(
|
|
34711
|
+
batchSelectorOptions(
|
|
34712
|
+
batch.command("deactivate").description(
|
|
34713
|
+
"Durably deactivate a selection through provider batch deletes."
|
|
34714
|
+
)
|
|
34715
|
+
).requiredOption("--reason <reason>", "Declared deactivation reason").option("--yes", "Confirm the asynchronous provider deactivation")
|
|
34716
|
+
).action(
|
|
34717
|
+
monitorsAction(
|
|
34718
|
+
(options) => handleMonitorBatch("deactivate", options)
|
|
34719
|
+
)
|
|
34720
|
+
);
|
|
34721
|
+
withJsonOption(
|
|
34722
|
+
batchSelectorOptions(
|
|
34723
|
+
batch.command("reactivate").description("Durably reactivate a selection after a suspension.")
|
|
34724
|
+
).option("--yes", "Confirm provider reactivation and possible billing")
|
|
34725
|
+
).action(
|
|
34726
|
+
monitorsAction(
|
|
34727
|
+
(options) => handleMonitorBatch("reactivate", options)
|
|
34728
|
+
)
|
|
34729
|
+
);
|
|
34730
|
+
withJsonOption(
|
|
34731
|
+
batch.command("get <operation-id>").description("Read batch progress and one bounded evidence page.").option("--cursor <cursor>", "Read the next retained evidence page")
|
|
34732
|
+
).action(monitorsAction(handleMonitorBatchGet));
|
|
34035
34733
|
withJsonOption(
|
|
34036
34734
|
monitors.command("status").description("Check whether you have access to Deepline monitors.").addHelpText(
|
|
34037
34735
|
"after",
|
|
@@ -34083,8 +34781,9 @@ Examples:
|
|
|
34083
34781
|
"after",
|
|
34084
34782
|
`
|
|
34085
34783
|
Notes:
|
|
34086
|
-
Read-only.
|
|
34087
|
-
|
|
34784
|
+
Read-only. A monitor state is active or inactive; provider disagreement is
|
|
34785
|
+
reported separately by audit/health. The output echoes the state filter that
|
|
34786
|
+
was applied. The response reports
|
|
34088
34787
|
total (the true registry count, not the page size), returned, has_more, and
|
|
34089
34788
|
next_cursor. When has_more is true, page with --cursor <next_cursor> until it
|
|
34090
34789
|
is false \u2014 a "no matching
|
|
@@ -34102,7 +34801,7 @@ Examples:
|
|
|
34102
34801
|
`
|
|
34103
34802
|
).option(
|
|
34104
34803
|
"--status <status>",
|
|
34105
|
-
"Filter by monitor
|
|
34804
|
+
"Filter by monitor state: active (default), inactive, or all"
|
|
34106
34805
|
).option("--limit <n>", "Limit the number of deployed monitors returned").option(
|
|
34107
34806
|
"--cursor <cursor>",
|
|
34108
34807
|
"Page past a truncated result using the next_cursor from a prior list response"
|
|
@@ -34495,7 +35194,7 @@ Example:
|
|
|
34495
35194
|
const deployed = withJsonOption(
|
|
34496
35195
|
monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
|
|
34497
35196
|
"--status <status>",
|
|
34498
|
-
"Filter by monitor
|
|
35197
|
+
"Filter by monitor state: active (default), inactive, or all"
|
|
34499
35198
|
).option("--limit <n>", "Limit the number of deployed monitors returned").option(
|
|
34500
35199
|
"--cursor <cursor>",
|
|
34501
35200
|
"Page past a truncated result using the next_cursor from a prior list response"
|
|
@@ -34637,7 +35336,8 @@ function organizationAuthValues(input2) {
|
|
|
34637
35336
|
[HOST_URL_ENV]: input2.baseUrl,
|
|
34638
35337
|
[API_KEY_ENV]: input2.apiKey,
|
|
34639
35338
|
[ACTIVE_ORG_ID_ENV]: input2.orgId,
|
|
34640
|
-
[ACTIVE_ORG_NAME_ENV]: input2.orgName
|
|
35339
|
+
[ACTIVE_ORG_NAME_ENV]: input2.orgName,
|
|
35340
|
+
...featureEnvValues(input2)
|
|
34641
35341
|
};
|
|
34642
35342
|
}
|
|
34643
35343
|
function organizationCommandContext(input2) {
|
|
@@ -34853,6 +35553,7 @@ async function handleOrgSwitch(selection, options) {
|
|
|
34853
35553
|
if (!selection && !options.orgId && authScope === "folder" && provenance.scope === "global" && provenance.project.state === "project") {
|
|
34854
35554
|
const commandContext = resolveCliCommandContext(config);
|
|
34855
35555
|
const activeOrganization = commandContext.active_organization;
|
|
35556
|
+
const pinnedFeatures = storedHostFeatures(config.baseUrl);
|
|
34856
35557
|
const project_env_paths2 = saveProjectDeeplineEnvValues(
|
|
34857
35558
|
{
|
|
34858
35559
|
[HOST_URL_ENV]: config.baseUrl,
|
|
@@ -34860,7 +35561,8 @@ async function handleOrgSwitch(selection, options) {
|
|
|
34860
35561
|
...activeOrganization ? {
|
|
34861
35562
|
[ACTIVE_ORG_ID_ENV]: activeOrganization.org_id,
|
|
34862
35563
|
[ACTIVE_ORG_NAME_ENV]: activeOrganization.org_name ?? ""
|
|
34863
|
-
} : {}
|
|
35564
|
+
} : {},
|
|
35565
|
+
...pinnedFeatures !== void 0 ? { [FEATURES_ENV]: pinnedFeatures } : {}
|
|
34864
35566
|
},
|
|
34865
35567
|
provenance.project.dir
|
|
34866
35568
|
);
|
|
@@ -34940,11 +35642,15 @@ async function handleOrgSwitch(selection, options) {
|
|
|
34940
35642
|
const authTarget = resolveOrgSwitchAuthTarget(authScope, config);
|
|
34941
35643
|
if (target.is_current) {
|
|
34942
35644
|
let project_env_paths2 = [];
|
|
35645
|
+
const features = await http.post("/api/v2/auth/cli/status", {
|
|
35646
|
+
api_key: config.apiKey
|
|
35647
|
+
}).then((status) => status.features).catch(() => void 0);
|
|
34943
35648
|
const authValues2 = organizationAuthValues({
|
|
34944
35649
|
baseUrl: config.baseUrl,
|
|
34945
35650
|
apiKey: config.apiKey,
|
|
34946
35651
|
orgId: target.org_id,
|
|
34947
|
-
orgName: target.name
|
|
35652
|
+
orgName: target.name,
|
|
35653
|
+
features
|
|
34948
35654
|
});
|
|
34949
35655
|
if (authTarget.kind === "folder") {
|
|
34950
35656
|
project_env_paths2 = saveProjectDeeplineEnvValues(authValues2);
|
|
@@ -35011,7 +35717,8 @@ async function handleOrgSwitch(selection, options) {
|
|
|
35011
35717
|
baseUrl: config.baseUrl,
|
|
35012
35718
|
apiKey: switched.api_key,
|
|
35013
35719
|
orgId: switched.org_id,
|
|
35014
|
-
orgName: switched.org_name
|
|
35720
|
+
orgName: switched.org_name,
|
|
35721
|
+
features: switched.features
|
|
35015
35722
|
});
|
|
35016
35723
|
if (authTarget.kind === "folder") {
|
|
35017
35724
|
project_env_paths = saveProjectDeeplineEnvValues(authValues);
|
|
@@ -35083,14 +35790,20 @@ async function handleOrgCreate(name, options) {
|
|
|
35083
35790
|
const identity = await fetchWorkspaceCreationIdentity(http, config.apiKey);
|
|
35084
35791
|
let created;
|
|
35085
35792
|
let workspaceApiKey;
|
|
35793
|
+
let workspaceFeatures;
|
|
35086
35794
|
let pendingIntentPath = null;
|
|
35087
35795
|
if (!identity.orgId) {
|
|
35088
35796
|
const firstWorkspace = await http.post("/api/v2/auth/cli/org-create", {
|
|
35089
35797
|
api_key: config.apiKey,
|
|
35090
35798
|
name: normalizedName
|
|
35091
35799
|
});
|
|
35092
|
-
const {
|
|
35800
|
+
const {
|
|
35801
|
+
api_key: apiKey,
|
|
35802
|
+
features,
|
|
35803
|
+
...publicFirstWorkspace
|
|
35804
|
+
} = firstWorkspace;
|
|
35093
35805
|
workspaceApiKey = apiKey;
|
|
35806
|
+
workspaceFeatures = features;
|
|
35094
35807
|
created = publicFirstWorkspace;
|
|
35095
35808
|
} else {
|
|
35096
35809
|
const pending = loadOrCreatePendingOrgCreate({
|
|
@@ -35111,6 +35824,7 @@ async function handleOrgCreate(name, options) {
|
|
|
35111
35824
|
org_id: workspace.org_id
|
|
35112
35825
|
});
|
|
35113
35826
|
workspaceApiKey = switched.api_key;
|
|
35827
|
+
workspaceFeatures = switched.features;
|
|
35114
35828
|
created = { ...workspace };
|
|
35115
35829
|
pendingIntentPath = pending.path;
|
|
35116
35830
|
}
|
|
@@ -35118,7 +35832,8 @@ async function handleOrgCreate(name, options) {
|
|
|
35118
35832
|
baseUrl: config.baseUrl,
|
|
35119
35833
|
apiKey: workspaceApiKey,
|
|
35120
35834
|
orgId: created.org_id,
|
|
35121
|
-
orgName: created.org_name
|
|
35835
|
+
orgName: created.org_name,
|
|
35836
|
+
features: workspaceFeatures
|
|
35122
35837
|
});
|
|
35123
35838
|
saveHostEnvValues(config.baseUrl, authValues);
|
|
35124
35839
|
if (pendingIntentPath) (0, import_node_fs16.unlinkSync)(pendingIntentPath);
|
|
@@ -35315,6 +36030,7 @@ Examples:
|
|
|
35315
36030
|
}
|
|
35316
36031
|
|
|
35317
36032
|
// src/cli/commands/git.ts
|
|
36033
|
+
var GIT_DEPLOY_FEATURE = "github-deploy";
|
|
35318
36034
|
function renderProject(project) {
|
|
35319
36035
|
const root = project.rootDirectory ? ` (${project.rootDirectory})` : "";
|
|
35320
36036
|
const flags = [
|
|
@@ -35567,7 +36283,7 @@ async function handleDeploymentGet(id, options) {
|
|
|
35567
36283
|
);
|
|
35568
36284
|
}
|
|
35569
36285
|
function registerGitCommands(program) {
|
|
35570
|
-
const git = program.command("git").alias("projects").description(
|
|
36286
|
+
const git = program.command("git", { hidden: !cliFeatureEnabled(GIT_DEPLOY_FEATURE) }).alias("projects").description(
|
|
35571
36287
|
"Git deploys: link repositories to this workspace and deploy plays on push."
|
|
35572
36288
|
).addHelpText(
|
|
35573
36289
|
"after",
|
|
@@ -35888,18 +36604,25 @@ async function handleList2(options) {
|
|
|
35888
36604
|
async function handleCheck(nameInput, options) {
|
|
35889
36605
|
const name = normalizeSecretName(nameInput);
|
|
35890
36606
|
const client2 = new DeeplineClient();
|
|
35891
|
-
const
|
|
36607
|
+
const check = options.play !== void 0 ? await client2.inspectSecret(name, { playName: options.play }) : null;
|
|
36608
|
+
const secret = check ? check.secret : await client2.checkSecret(name);
|
|
36609
|
+
const ok = check ? check.ok : Boolean(secret);
|
|
36610
|
+
const quotedPlay = `'${(options.play ?? "PLAY").replace(/'/g, `'"'"'`)}'`;
|
|
36611
|
+
const scopeHint = check ? secret?.scope === "play" ? check.reason === "disabled" ? `The Play-scoped secret is disabled and no active org fallback is available. Restore it with: deepline secrets set ${name} --scope play --play ${quotedPlay}` : `The active Play-scoped secret takes precedence over the org secret.${ok ? "" : ` Restore it with: deepline secrets set ${name} --scope play --play ${quotedPlay}`}` : `No Play override.${ok ? " The org secret is available." : ` Set or rotate the org secret with: deepline secrets set ${name}`}` : `Metadata only. Verify effective scope and active version with: deepline secrets check ${name} --play <play-name>`;
|
|
35892
36612
|
printCommandEnvelope(
|
|
35893
36613
|
{
|
|
35894
|
-
ok
|
|
36614
|
+
ok,
|
|
35895
36615
|
name,
|
|
35896
36616
|
secret: secret ?? null,
|
|
36617
|
+
check: check ? { playName: check.playName, reason: check.reason } : null,
|
|
36618
|
+
scopeHint,
|
|
35897
36619
|
render: {
|
|
35898
36620
|
sections: [
|
|
35899
36621
|
{
|
|
35900
36622
|
title: "secret check",
|
|
35901
36623
|
lines: [
|
|
35902
|
-
secret ? `${name}: active \u2014 ${renderSecret(secret)}` : `${name}: missing, disabled, or empty
|
|
36624
|
+
check ? `${name}: ${check.reason} for ${check.playName}${secret ? ` (${secret.scope})` : ""}` : secret ? `${name}: active metadata \u2014 ${renderSecret(secret)}` : `${name}: missing, disabled, or empty`,
|
|
36625
|
+
scopeHint
|
|
35903
36626
|
]
|
|
35904
36627
|
}
|
|
35905
36628
|
]
|
|
@@ -35907,7 +36630,7 @@ async function handleCheck(nameInput, options) {
|
|
|
35907
36630
|
},
|
|
35908
36631
|
{ json: options.json }
|
|
35909
36632
|
);
|
|
35910
|
-
if (!
|
|
36633
|
+
if (!ok) process.exitCode = 4;
|
|
35911
36634
|
}
|
|
35912
36635
|
async function handleSet2(nameInput, forbidden, options) {
|
|
35913
36636
|
preventShellHistoryLeak(forbidden);
|
|
@@ -35961,6 +36684,7 @@ Notes:
|
|
|
35961
36684
|
Examples:
|
|
35962
36685
|
deepline secrets list
|
|
35963
36686
|
deepline secrets check HUBSPOT_TOKEN
|
|
36687
|
+
deepline secrets check HUBSPOT_TOKEN --play hubspot-sync
|
|
35964
36688
|
deepline secrets set HUBSPOT_TOKEN
|
|
35965
36689
|
printf %s "$HUBSPOT_TOKEN" | deepline secrets set HUBSPOT_TOKEN --value-stdin
|
|
35966
36690
|
deepline secrets set HUBSPOT_TOKEN --from-env HUBSPOT_TOKEN
|
|
@@ -35970,7 +36694,12 @@ Examples:
|
|
|
35970
36694
|
secrets.command("list").description("List secret metadata only.").option("--json", "Emit JSON output").action(async (options) => {
|
|
35971
36695
|
await handleList2(options);
|
|
35972
36696
|
});
|
|
35973
|
-
secrets.command("check").description(
|
|
36697
|
+
secrets.command("check").description(
|
|
36698
|
+
"Check secret metadata, or effective availability with --play."
|
|
36699
|
+
).argument("<name>", "Secret name").option(
|
|
36700
|
+
"--play <name>",
|
|
36701
|
+
"Validate the effective secret for a bare Play name and active version"
|
|
36702
|
+
).option("--json", "Emit JSON output").action(async (name, options) => {
|
|
35974
36703
|
await handleCheck(name, options);
|
|
35975
36704
|
});
|
|
35976
36705
|
secrets.command("set").description("Set or rotate a secret without exposing its value in argv.").argument("<name>", "Secret name").argument("[forbidden...]", "Do not pass secret values here").option("--json", "Emit JSON output").option("--scope <scope>", "Secret scope: org or play", "org").option("--play <name>", "Play name for play-scoped secrets").option("--value-stdin", "Read the value from piped stdin").option("--from-env <name>", "Read the value from an environment variable").option("--from-file <path>", "Read the value from a file").action(
|
|
@@ -36344,6 +37073,20 @@ function classifyNetworkFailure(error) {
|
|
|
36344
37073
|
}
|
|
36345
37074
|
return "network_error";
|
|
36346
37075
|
}
|
|
37076
|
+
function classifyNetworkCauseCategory(error) {
|
|
37077
|
+
switch (classifyNetworkFailure(error)) {
|
|
37078
|
+
case "network_dns_resolution_failed":
|
|
37079
|
+
return "dns";
|
|
37080
|
+
case "network_ssl_error":
|
|
37081
|
+
return "tls";
|
|
37082
|
+
case "network_connection_reset":
|
|
37083
|
+
return "reset";
|
|
37084
|
+
case "network_timeout":
|
|
37085
|
+
return "connect_timeout";
|
|
37086
|
+
default:
|
|
37087
|
+
return "unknown";
|
|
37088
|
+
}
|
|
37089
|
+
}
|
|
36347
37090
|
function isNetworkFailure(error) {
|
|
36348
37091
|
if (!(error instanceof Error)) return false;
|
|
36349
37092
|
if (error instanceof DeeplineError && error.statusCode) return false;
|
|
@@ -36513,6 +37256,7 @@ function buildFailureReport(input2) {
|
|
|
36513
37256
|
});
|
|
36514
37257
|
const code = failureCode({ exitCode: input2.exitCode, error: input2.error });
|
|
36515
37258
|
const errorBody = input2.error === void 0 ? `SDK CLI command exited ${input2.exitCode ?? "unknown"}` : errorMessage3(input2.error);
|
|
37259
|
+
const networkCauseCategory = input2.error !== void 0 && isNetworkFailure(input2.error) ? classifyNetworkCauseCategory(input2.error) : null;
|
|
36516
37260
|
return {
|
|
36517
37261
|
command: sanitizeCommand(input2.argv),
|
|
36518
37262
|
subcommand: subcommandFromArgv(input2.argv),
|
|
@@ -36534,7 +37278,8 @@ function buildFailureReport(input2) {
|
|
|
36534
37278
|
failure_code: code,
|
|
36535
37279
|
failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
|
|
36536
37280
|
duration_ms: durationMs,
|
|
36537
|
-
...input2.exitCode !== null ? { exit_code: input2.exitCode } : {}
|
|
37281
|
+
...input2.exitCode !== null ? { exit_code: input2.exitCode } : {},
|
|
37282
|
+
...networkCauseCategory ? { network_cause_category: networkCauseCategory } : {}
|
|
36538
37283
|
}
|
|
36539
37284
|
};
|
|
36540
37285
|
}
|
|
@@ -38239,6 +38984,9 @@ Examples:
|
|
|
38239
38984
|
});
|
|
38240
38985
|
}
|
|
38241
38986
|
|
|
38987
|
+
// src/cli/commands/settings.ts
|
|
38988
|
+
var import_node_fs24 = require("fs");
|
|
38989
|
+
|
|
38242
38990
|
// src/cli/update-preferences.ts
|
|
38243
38991
|
var import_node_fs21 = require("fs");
|
|
38244
38992
|
var import_node_os14 = require("os");
|
|
@@ -38372,6 +39120,8 @@ var SDK_SIDECAR_CRITICAL_PACKAGE_FILES = [
|
|
|
38372
39120
|
"dist/index.d.ts",
|
|
38373
39121
|
"dist/plays/bundle-play-file.mjs",
|
|
38374
39122
|
"dist/bundling-sources/shared_libs/observability/telemetry.ts",
|
|
39123
|
+
"dist/bundling-sources/shared_libs/integration-contracts/bettercontact/execution-policy.ts",
|
|
39124
|
+
"dist/bundling-sources/shared_libs/integration-contracts/theirstack/execution-policy.ts",
|
|
38375
39125
|
"dist/bundling-sources/shared_libs/play-runtime/backend.ts",
|
|
38376
39126
|
"dist/bundling-sources/shared_libs/plays/bundling/index.ts",
|
|
38377
39127
|
"dist/bundling-sources/shared_libs/product-notifications/contract.ts",
|
|
@@ -39928,21 +40678,104 @@ function displaySlackTarget(target) {
|
|
|
39928
40678
|
function collectEvent(value, previous = []) {
|
|
39929
40679
|
return [...previous, value];
|
|
39930
40680
|
}
|
|
40681
|
+
function collectNotificationTarget(value, previous = []) {
|
|
40682
|
+
return [...previous, value];
|
|
40683
|
+
}
|
|
40684
|
+
async function readNotificationConfigurationChange(source, read = (path, encoding) => (0, import_node_fs24.readFileSync)(path, encoding)) {
|
|
40685
|
+
const label = source === "-" ? "stdin" : source;
|
|
40686
|
+
let text;
|
|
40687
|
+
try {
|
|
40688
|
+
text = await read(source === "-" ? 0 : source, "utf8");
|
|
40689
|
+
} catch (error) {
|
|
40690
|
+
throw new Error(
|
|
40691
|
+
`Could not read notification configuration from ${label}: ${error instanceof Error ? error.message : String(error)}`
|
|
40692
|
+
);
|
|
40693
|
+
}
|
|
40694
|
+
let parsed;
|
|
40695
|
+
try {
|
|
40696
|
+
parsed = JSON.parse(text);
|
|
40697
|
+
} catch (error) {
|
|
40698
|
+
throw new Error(
|
|
40699
|
+
`Notification configuration from ${label} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
40700
|
+
);
|
|
40701
|
+
}
|
|
40702
|
+
if (typeof parsed.expectedWorkspaceVersion !== "number" || !Number.isInteger(parsed.expectedWorkspaceVersion) || !parsed.change || typeof parsed.change !== "object") {
|
|
40703
|
+
throw new Error(
|
|
40704
|
+
`Notification configuration from ${label} must contain an integer expectedWorkspaceVersion and a change object.`
|
|
40705
|
+
);
|
|
40706
|
+
}
|
|
40707
|
+
return {
|
|
40708
|
+
expectedWorkspaceVersion: parsed.expectedWorkspaceVersion,
|
|
40709
|
+
change: parsed.change
|
|
40710
|
+
};
|
|
40711
|
+
}
|
|
39931
40712
|
function registerNotificationCommands(program) {
|
|
39932
|
-
const notifications = program.command("notifications").description("
|
|
40713
|
+
const notifications = program.command("notifications").description("Configure notification groups, destinations, and rules.").addHelpText(
|
|
39933
40714
|
"after",
|
|
39934
40715
|
`
|
|
39935
40716
|
Examples:
|
|
40717
|
+
deepline notifications add oncall --to email:oncall@example.com --to slack:#oncall
|
|
39936
40718
|
deepline notifications events
|
|
39937
40719
|
deepline notifications slack channels --search pipeline
|
|
39938
40720
|
deepline notifications add pipeline-watchdog --to slack:#pipeline-alerts --for play.cron.failed
|
|
39939
40721
|
deepline notifications add owner-alerts --to slack:member:U0123456789 --for play.cron.failed
|
|
39940
40722
|
deepline notifications test pipeline-watchdog
|
|
39941
40723
|
|
|
39942
|
-
|
|
39943
|
-
|
|
40724
|
+
Each named notification is a group. Repeat --to to give it email and Slack
|
|
40725
|
+
destinations. Add rules from the dashboard or notification configuration. The
|
|
40726
|
+
existing one-Slack-target form with --for remains supported and creates the
|
|
40727
|
+
equivalent compatibility group and rules. Slack connections are managed in
|
|
40728
|
+
Dashboard \u2192 Integrations.
|
|
39944
40729
|
`
|
|
39945
40730
|
);
|
|
40731
|
+
const configuration = notifications.command("configuration").description("Read or atomically update notification groups and rules.").addHelpText(
|
|
40732
|
+
"after",
|
|
40733
|
+
`
|
|
40734
|
+
Examples:
|
|
40735
|
+
deepline notifications configuration get --json
|
|
40736
|
+
deepline notifications configuration apply change.json --dry-run --json
|
|
40737
|
+
jq '{expectedWorkspaceVersion: .configuration.workspaceVersion, change: {kind: "delete_group", groupKey: "oncall"}}' current.json | deepline notifications configuration apply - --json
|
|
40738
|
+
`
|
|
40739
|
+
);
|
|
40740
|
+
configuration.command("get").description("Show the effective group-based notification configuration.").option("--json", "Emit JSON output").action(async (options) => {
|
|
40741
|
+
const result = await new DeeplineClient().getNotificationConfiguration();
|
|
40742
|
+
printCommandEnvelope(
|
|
40743
|
+
{
|
|
40744
|
+
...result,
|
|
40745
|
+
render: {
|
|
40746
|
+
sections: [
|
|
40747
|
+
{
|
|
40748
|
+
title: "notification groups",
|
|
40749
|
+
lines: result.configuration.groups.length ? result.configuration.groups.map(
|
|
40750
|
+
(group) => `${group.name}: ${group.enabled ? "active" : "paused"}`
|
|
40751
|
+
) : ["No notification groups are configured."]
|
|
40752
|
+
}
|
|
40753
|
+
]
|
|
40754
|
+
}
|
|
40755
|
+
},
|
|
40756
|
+
{ json: options.json }
|
|
40757
|
+
);
|
|
40758
|
+
});
|
|
40759
|
+
configuration.command("apply").argument(
|
|
40760
|
+
"<file>",
|
|
40761
|
+
"JSON file, or - for stdin, containing expectedWorkspaceVersion and one desired change"
|
|
40762
|
+
).description(
|
|
40763
|
+
"Atomically apply a configuration draft exported by an agent or UI."
|
|
40764
|
+
).option("--dry-run", "Validate and display the file without saving it").option("--json", "Emit JSON output").action(async (file, options) => {
|
|
40765
|
+
const input2 = await readNotificationConfigurationChange(file);
|
|
40766
|
+
if (options.dryRun) {
|
|
40767
|
+
printCommandEnvelope(
|
|
40768
|
+
{ dryRun: true, ...input2 },
|
|
40769
|
+
{ json: options.json }
|
|
40770
|
+
);
|
|
40771
|
+
return;
|
|
40772
|
+
}
|
|
40773
|
+
const result = await new DeeplineClient().changeNotificationConfiguration(
|
|
40774
|
+
input2.expectedWorkspaceVersion,
|
|
40775
|
+
input2.change
|
|
40776
|
+
);
|
|
40777
|
+
printCommandEnvelope(result, { json: options.json });
|
|
40778
|
+
});
|
|
39946
40779
|
notifications.command("events").description("List the Play events available to a notification.").option("--json", "Emit JSON output").action(async (options) => {
|
|
39947
40780
|
const settings = await new DeeplineClient().getNotifications();
|
|
39948
40781
|
printCommandEnvelope(
|
|
@@ -39998,42 +40831,82 @@ chooses the connected Slack channel or member and the events it receives.
|
|
|
39998
40831
|
);
|
|
39999
40832
|
printCommandEnvelope({ notification: rule }, { json: options.json });
|
|
40000
40833
|
});
|
|
40001
|
-
notifications.command("add").argument("<name>", "
|
|
40834
|
+
notifications.command("add").argument("<name>", "Group name, for example oncall").requiredOption(
|
|
40002
40835
|
"--to <target>",
|
|
40003
|
-
"Target
|
|
40836
|
+
"Target; repeat email:name@example.com, slack:#channel, or slack:member:U0123456789",
|
|
40837
|
+
collectNotificationTarget,
|
|
40838
|
+
[]
|
|
40004
40839
|
).option(
|
|
40005
40840
|
"--for <event>",
|
|
40006
|
-
"
|
|
40841
|
+
"Legacy one-Slack-target event ID; repeat for more events",
|
|
40007
40842
|
collectEvent,
|
|
40008
40843
|
[]
|
|
40009
40844
|
).option("--dry-run", "Describe the notification without saving it").option("--json", "Emit JSON output").action(
|
|
40010
40845
|
async (name, options) => {
|
|
40011
|
-
|
|
40012
|
-
|
|
40846
|
+
const result = await new DeeplineClient().createNotificationGroup({
|
|
40847
|
+
name,
|
|
40848
|
+
targets: options.to,
|
|
40849
|
+
legacyEvents: options.for,
|
|
40850
|
+
dryRun: options.dryRun
|
|
40851
|
+
});
|
|
40852
|
+
if (result.mode === "dry_run") {
|
|
40853
|
+
printCommandEnvelope(
|
|
40854
|
+
result.compatibilityMode ? {
|
|
40855
|
+
dryRun: true,
|
|
40856
|
+
name: result.name,
|
|
40857
|
+
target: options.to[0],
|
|
40858
|
+
eventTypes: result.legacyEvents
|
|
40859
|
+
} : {
|
|
40860
|
+
dryRun: true,
|
|
40861
|
+
group: result.name,
|
|
40862
|
+
targets: result.targets,
|
|
40863
|
+
compatibilityMode: false
|
|
40864
|
+
},
|
|
40865
|
+
{ json: options.json }
|
|
40866
|
+
);
|
|
40867
|
+
return;
|
|
40013
40868
|
}
|
|
40014
|
-
|
|
40015
|
-
if (options.dryRun) {
|
|
40869
|
+
if (result.mode === "legacy") {
|
|
40016
40870
|
printCommandEnvelope(
|
|
40017
|
-
{
|
|
40871
|
+
{
|
|
40872
|
+
notification: result.notification,
|
|
40873
|
+
render: {
|
|
40874
|
+
sections: [
|
|
40875
|
+
{
|
|
40876
|
+
title: "notification saved",
|
|
40877
|
+
lines: [name]
|
|
40878
|
+
}
|
|
40879
|
+
],
|
|
40880
|
+
actions: [
|
|
40881
|
+
{
|
|
40882
|
+
label: "Send a test",
|
|
40883
|
+
command: `deepline notifications test ${name}`
|
|
40884
|
+
}
|
|
40885
|
+
]
|
|
40886
|
+
}
|
|
40887
|
+
},
|
|
40018
40888
|
{ json: options.json }
|
|
40019
40889
|
);
|
|
40020
40890
|
return;
|
|
40021
40891
|
}
|
|
40022
|
-
const result = await new DeeplineClient().createNotification({
|
|
40023
|
-
name,
|
|
40024
|
-
provider: "slack",
|
|
40025
|
-
...target,
|
|
40026
|
-
eventTypes: options.for
|
|
40027
|
-
});
|
|
40028
40892
|
printCommandEnvelope(
|
|
40029
40893
|
{
|
|
40030
|
-
|
|
40894
|
+
...result,
|
|
40031
40895
|
render: {
|
|
40032
|
-
sections: [
|
|
40896
|
+
sections: [
|
|
40897
|
+
{
|
|
40898
|
+
title: "notification group saved",
|
|
40899
|
+
lines: [
|
|
40900
|
+
result.group.name,
|
|
40901
|
+
`${result.destinations.length} destination${result.destinations.length === 1 ? "" : "s"}`,
|
|
40902
|
+
"0 rules"
|
|
40903
|
+
]
|
|
40904
|
+
}
|
|
40905
|
+
],
|
|
40033
40906
|
actions: [
|
|
40034
40907
|
{
|
|
40035
|
-
label: "
|
|
40036
|
-
command:
|
|
40908
|
+
label: "View configuration",
|
|
40909
|
+
command: "deepline notifications configuration get"
|
|
40037
40910
|
}
|
|
40038
40911
|
]
|
|
40039
40912
|
}
|
|
@@ -40147,12 +41020,12 @@ chooses the connected Slack channel or member and the events it receives.
|
|
|
40147
41020
|
|
|
40148
41021
|
// src/cli/commands/tools.ts
|
|
40149
41022
|
var import_commander4 = require("commander");
|
|
40150
|
-
var
|
|
41023
|
+
var import_node_fs26 = require("fs");
|
|
40151
41024
|
var import_node_os17 = require("os");
|
|
40152
41025
|
var import_node_path27 = require("path");
|
|
40153
41026
|
|
|
40154
41027
|
// src/tool-output.ts
|
|
40155
|
-
var
|
|
41028
|
+
var import_node_fs25 = require("fs");
|
|
40156
41029
|
var import_node_os16 = require("os");
|
|
40157
41030
|
var import_node_path26 = require("path");
|
|
40158
41031
|
function isPlainObject(value) {
|
|
@@ -40282,18 +41155,18 @@ function projectRowOutput(conversion) {
|
|
|
40282
41155
|
}
|
|
40283
41156
|
function ensureOutputDir() {
|
|
40284
41157
|
const outputDir = (0, import_node_path26.join)((0, import_node_os16.homedir)(), ".local", "share", "deepline", "data");
|
|
40285
|
-
(0,
|
|
41158
|
+
(0, import_node_fs25.mkdirSync)(outputDir, { recursive: true });
|
|
40286
41159
|
return outputDir;
|
|
40287
41160
|
}
|
|
40288
41161
|
function writeJsonOutputFile(payload, stem) {
|
|
40289
41162
|
const outputDir = ensureOutputDir();
|
|
40290
41163
|
const outputPath = (0, import_node_path26.join)(outputDir, `${stem}_${Date.now()}.json`);
|
|
40291
|
-
(0,
|
|
41164
|
+
(0, import_node_fs25.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
40292
41165
|
return outputPath;
|
|
40293
41166
|
}
|
|
40294
41167
|
function writeCsvOutputFile(rows, stem, options) {
|
|
40295
41168
|
const outputPath = options?.outPath ? options.outPath : (0, import_node_path26.join)(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
|
|
40296
|
-
(0,
|
|
41169
|
+
(0, import_node_fs25.mkdirSync)((0, import_node_path26.dirname)(outputPath), { recursive: true });
|
|
40297
41170
|
const columns = columnsForRows(rows);
|
|
40298
41171
|
const escapeCell = (value) => {
|
|
40299
41172
|
const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
|
|
@@ -40302,19 +41175,19 @@ function writeCsvOutputFile(rows, stem, options) {
|
|
|
40302
41175
|
}
|
|
40303
41176
|
return normalized;
|
|
40304
41177
|
};
|
|
40305
|
-
const fd = (0,
|
|
41178
|
+
const fd = (0, import_node_fs25.openSync)(outputPath, "w");
|
|
40306
41179
|
try {
|
|
40307
|
-
(0,
|
|
41180
|
+
(0, import_node_fs25.writeSync)(fd, `${columns.map(escapeCell).join(",")}
|
|
40308
41181
|
`);
|
|
40309
41182
|
for (const row of rows) {
|
|
40310
|
-
(0,
|
|
41183
|
+
(0, import_node_fs25.writeSync)(
|
|
40311
41184
|
fd,
|
|
40312
41185
|
`${columns.map((column) => escapeCell(row[column])).join(",")}
|
|
40313
41186
|
`
|
|
40314
41187
|
);
|
|
40315
41188
|
}
|
|
40316
41189
|
} finally {
|
|
40317
|
-
(0,
|
|
41190
|
+
(0, import_node_fs25.closeSync)(fd);
|
|
40318
41191
|
}
|
|
40319
41192
|
const previewRows = rows.slice(0, 5);
|
|
40320
41193
|
const previewColumns = columns.slice(0, 5);
|
|
@@ -41008,6 +41881,9 @@ async function findPlayForToolId(client2, toolId) {
|
|
|
41008
41881
|
const plays = await client2.searchPlays({ query: requested, compact: true });
|
|
41009
41882
|
return plays.find((play) => playIdentifiers(play).includes(requested)) ?? null;
|
|
41010
41883
|
}
|
|
41884
|
+
function isMissingToolMetadataError(error) {
|
|
41885
|
+
return error instanceof DeeplineError && error.statusCode === 404;
|
|
41886
|
+
}
|
|
41011
41887
|
function playAliasToolErrorMessage(toolId, play) {
|
|
41012
41888
|
const playName = play.reference ?? play.name;
|
|
41013
41889
|
return `${toolId} is a play, not a tool.
|
|
@@ -41289,10 +42165,12 @@ async function getTool(toolId, options = {}) {
|
|
|
41289
42165
|
try {
|
|
41290
42166
|
tool = await client2.getTool(toolId);
|
|
41291
42167
|
} catch (error) {
|
|
41292
|
-
|
|
41293
|
-
|
|
41294
|
-
|
|
41295
|
-
|
|
42168
|
+
if (isMissingToolMetadataError(error)) {
|
|
42169
|
+
const play = await findPlayForToolId(client2, toolId);
|
|
42170
|
+
if (play) {
|
|
42171
|
+
printPlayAliasToolError(toolId, play);
|
|
42172
|
+
return 2;
|
|
42173
|
+
}
|
|
41296
42174
|
}
|
|
41297
42175
|
throw error;
|
|
41298
42176
|
}
|
|
@@ -42266,10 +43144,10 @@ function normalizeOutputFormat(raw) {
|
|
|
42266
43144
|
function resolveAtFilePath(rawPath) {
|
|
42267
43145
|
const trimmed = rawPath.trim();
|
|
42268
43146
|
const resolved = (0, import_node_path27.resolve)(trimmed);
|
|
42269
|
-
if ((0,
|
|
43147
|
+
if ((0, import_node_fs26.existsSync)(resolved)) return resolved;
|
|
42270
43148
|
if (process.platform !== "win32" && trimmed.includes("\\")) {
|
|
42271
43149
|
const normalized = (0, import_node_path27.resolve)(trimmed.replace(/\\/g, "/"));
|
|
42272
|
-
if ((0,
|
|
43150
|
+
if ((0, import_node_fs26.existsSync)(normalized)) return normalized;
|
|
42273
43151
|
}
|
|
42274
43152
|
return resolved;
|
|
42275
43153
|
}
|
|
@@ -42280,7 +43158,7 @@ function readJsonArgument(raw, flagName) {
|
|
|
42280
43158
|
throw new Error(`Invalid ${flagName} value: empty @file path.`);
|
|
42281
43159
|
}
|
|
42282
43160
|
try {
|
|
42283
|
-
return (0,
|
|
43161
|
+
return (0, import_node_fs26.readFileSync)(resolveAtFilePath(filePath), "utf8").replace(
|
|
42284
43162
|
/^\uFEFF/,
|
|
42285
43163
|
""
|
|
42286
43164
|
);
|
|
@@ -42387,8 +43265,8 @@ function starterScriptJson(script) {
|
|
|
42387
43265
|
function seedToolListScript(input2) {
|
|
42388
43266
|
const stem = safeFileStem(input2.toolId);
|
|
42389
43267
|
const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
|
|
42390
|
-
const scriptDir = (0,
|
|
42391
|
-
(0,
|
|
43268
|
+
const scriptDir = (0, import_node_fs26.mkdtempSync)((0, import_node_path27.join)((0, import_node_os17.tmpdir)(), "deepline-workflow-seed-"));
|
|
43269
|
+
(0, import_node_fs26.chmodSync)(scriptDir, 448);
|
|
42392
43270
|
const scriptPath = (0, import_node_path27.join)(scriptDir, fileName);
|
|
42393
43271
|
const projectDir = `deepline/projects/${stem}-workflow`;
|
|
42394
43272
|
const playName = `${stem}-workflow`;
|
|
@@ -42432,7 +43310,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
42432
43310
|
description: ${JSON.stringify(`Seed ${input2.toolId} rows into a Deepline workflow-ready dataset.`)},
|
|
42433
43311
|
});
|
|
42434
43312
|
`;
|
|
42435
|
-
(0,
|
|
43313
|
+
(0, import_node_fs26.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
|
|
42436
43314
|
return {
|
|
42437
43315
|
path: scriptPath,
|
|
42438
43316
|
sourceCode: script,
|
|
@@ -42631,19 +43509,18 @@ async function executeTool(args) {
|
|
|
42631
43509
|
try {
|
|
42632
43510
|
metadata = await client2.getTool(parsed.toolId);
|
|
42633
43511
|
} catch (error) {
|
|
42634
|
-
|
|
42635
|
-
|
|
42636
|
-
if (
|
|
42637
|
-
|
|
42638
|
-
|
|
42639
|
-
|
|
42640
|
-
|
|
42641
|
-
|
|
43512
|
+
if (isMissingToolMetadataError(error)) {
|
|
43513
|
+
const play = await findPlayForToolId(client2, parsed.toolId);
|
|
43514
|
+
if (play) {
|
|
43515
|
+
if (argsWantJson(args)) {
|
|
43516
|
+
printJsonError(
|
|
43517
|
+
new Error(playAliasToolErrorMessage(parsed.toolId, play))
|
|
43518
|
+
);
|
|
43519
|
+
} else {
|
|
43520
|
+
printPlayAliasToolError(parsed.toolId, play);
|
|
43521
|
+
}
|
|
43522
|
+
return 2;
|
|
42642
43523
|
}
|
|
42643
|
-
return 2;
|
|
42644
|
-
}
|
|
42645
|
-
if (error instanceof DeeplineError) {
|
|
42646
|
-
throw error;
|
|
42647
43524
|
}
|
|
42648
43525
|
throw error;
|
|
42649
43526
|
}
|