deepline 0.2.55 → 0.2.56
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 +14 -0
- package/dist/bundling-sources/sdk/src/http.ts +19 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/stream-reconnect.ts +6 -0
- package/dist/bundling-sources/sdk/src/types.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +146 -12
- package/dist/bundling-sources/shared_libs/play-runtime/batch-runtime.ts +6 -3
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1631 -748
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +81 -52
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +146 -6
- package/dist/bundling-sources/shared_libs/play-runtime/gateway-auth-session.ts +56 -22
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +14 -11
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +21 -2
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +81 -21
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +27 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +49 -10
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +96 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +341 -67
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +8 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts +17 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +4 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +17 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +16 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-writer.ts +25 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +80 -1
- package/dist/bundling-sources/shared_libs/security/safe-fetch.ts +9 -0
- package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +85 -48
- package/dist/cli/index.js +409 -51
- package/dist/cli/index.mjs +389 -25
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +29 -2
- package/dist/index.mjs +29 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -185,7 +185,7 @@ function configureProxyFromEnv() {
|
|
|
185
185
|
configureProxyFromEnv();
|
|
186
186
|
|
|
187
187
|
// src/cli/index.ts
|
|
188
|
-
var
|
|
188
|
+
var import_promises9 = require("fs/promises");
|
|
189
189
|
var import_node_path26 = require("path");
|
|
190
190
|
var import_node_os19 = require("os");
|
|
191
191
|
var import_commander4 = require("commander");
|
|
@@ -1044,7 +1044,7 @@ var SDK_RELEASE = {
|
|
|
1044
1044
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
1045
1045
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
1046
1046
|
// release keeps lazy paging semantics independent of row residency.
|
|
1047
|
-
version: "0.2.
|
|
1047
|
+
version: "0.2.56",
|
|
1048
1048
|
contracts: {
|
|
1049
1049
|
api: {
|
|
1050
1050
|
name: "sdk-http-api",
|
|
@@ -1627,9 +1627,26 @@ var HttpClient = class {
|
|
|
1627
1627
|
if (error instanceof AuthError || error instanceof DeeplineError) {
|
|
1628
1628
|
throw error;
|
|
1629
1629
|
}
|
|
1630
|
-
|
|
1630
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
1631
|
+
if (isAbortLikeError(normalized) && options?.signal?.aborted) {
|
|
1632
|
+
throw new DeeplineError(
|
|
1633
|
+
`Stream from ${this.config.baseUrl} was aborted by the caller.`,
|
|
1634
|
+
void 0,
|
|
1635
|
+
"ABORTED"
|
|
1636
|
+
);
|
|
1637
|
+
}
|
|
1638
|
+
lastError = normalized;
|
|
1631
1639
|
}
|
|
1632
1640
|
}
|
|
1641
|
+
if (lastError && isAbortLikeError(lastError)) {
|
|
1642
|
+
throw new DeeplineError(
|
|
1643
|
+
withCoworkNetworkHint(
|
|
1644
|
+
`Unable to stream from ${this.config.baseUrl}. The remote stream was interrupted.`
|
|
1645
|
+
),
|
|
1646
|
+
void 0,
|
|
1647
|
+
"PLAY_STREAM_NETWORK_ABORTED"
|
|
1648
|
+
);
|
|
1649
|
+
}
|
|
1633
1650
|
throw new DeeplineError(
|
|
1634
1651
|
withCoworkNetworkHint(
|
|
1635
1652
|
lastError?.message ? `Unable to stream from ${this.config.baseUrl}. ${lastError.message}` : `Unable to stream from ${this.config.baseUrl}.`
|
|
@@ -1892,6 +1909,9 @@ function streamReconnectDelayMs(attempt) {
|
|
|
1892
1909
|
return Math.max(1, Math.floor(Math.random() * (cappedExponentialMs + 1)));
|
|
1893
1910
|
}
|
|
1894
1911
|
function isTransientPlayStreamError(error) {
|
|
1912
|
+
if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
|
|
1913
|
+
return true;
|
|
1914
|
+
}
|
|
1895
1915
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
1896
1916
|
return error.statusCode >= 500 && error.statusCode < 600;
|
|
1897
1917
|
}
|
|
@@ -2044,6 +2064,7 @@ var RUNTIME_RECEIPT_OUTPUT_MAX_BYTES = 10 * 1024 * 1024;
|
|
|
2044
2064
|
var RUNTIME_RECEIPT_COMPLETION_BUFFER_MAX_BYTES = 32 * 1024 * 1024;
|
|
2045
2065
|
var RUNNER_TERMINAL_PUSH_MAX_BODY_BYTES = 16 * 1024 * 1024;
|
|
2046
2066
|
var RUNTIME_RECEIPT_GATEWAY_BATCH_MAX_BYTES = 12 * 1024 * 1024;
|
|
2067
|
+
var RUNTIME_RECEIPT_WRITER_TARGET_BATCH_BYTES = 4 * 1024 * 1024;
|
|
2047
2068
|
var RUNNER_POST_TERMINAL_DIAGNOSTIC_MAX_BYTES = 64 * 1024;
|
|
2048
2069
|
|
|
2049
2070
|
// ../shared_libs/play-runtime/ledger-safe-payload.ts
|
|
@@ -4626,6 +4647,10 @@ var DeeplineClient = class {
|
|
|
4626
4647
|
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
4627
4648
|
...request.force ? { force: true } : {},
|
|
4628
4649
|
...forceToolRefresh ? { forceToolRefresh: true } : {},
|
|
4650
|
+
...typeof request.maxConcurrentExternalCalls === "number" ? {
|
|
4651
|
+
maxConcurrentExternalCalls: request.maxConcurrentExternalCalls
|
|
4652
|
+
} : {},
|
|
4653
|
+
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
4629
4654
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
4630
4655
|
// Profile selection is the API's job, not the CLI's. The server
|
|
4631
4656
|
// defaults to absurd; callers normally omit this field.
|
|
@@ -4678,6 +4703,8 @@ var DeeplineClient = class {
|
|
|
4678
4703
|
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
4679
4704
|
...request.force ? { force: true } : {},
|
|
4680
4705
|
...forceToolRefresh ? { forceToolRefresh: true } : {},
|
|
4706
|
+
...typeof request.maxConcurrentExternalCalls === "number" ? { maxConcurrentExternalCalls: request.maxConcurrentExternalCalls } : {},
|
|
4707
|
+
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
4681
4708
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
4682
4709
|
...request.profile ? { profile: request.profile } : {},
|
|
4683
4710
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -8758,14 +8785,14 @@ function invoiceDateText(createdAt) {
|
|
|
8758
8785
|
}
|
|
8759
8786
|
function invoiceLine(entry, compact) {
|
|
8760
8787
|
const amount = invoiceAmountText(entry.amount_cents, entry.currency);
|
|
8761
|
-
const
|
|
8788
|
+
const link2 = entry.url ?? "(no link)";
|
|
8762
8789
|
if (compact) {
|
|
8763
8790
|
return [
|
|
8764
8791
|
entry.id,
|
|
8765
8792
|
invoiceDateText(entry.created_at),
|
|
8766
8793
|
amount,
|
|
8767
8794
|
entry.status,
|
|
8768
|
-
|
|
8795
|
+
link2
|
|
8769
8796
|
].join(" | ");
|
|
8770
8797
|
}
|
|
8771
8798
|
return [
|
|
@@ -8773,7 +8800,7 @@ function invoiceLine(entry, compact) {
|
|
|
8773
8800
|
entry.description,
|
|
8774
8801
|
amount,
|
|
8775
8802
|
entry.status,
|
|
8776
|
-
|
|
8803
|
+
link2
|
|
8777
8804
|
].join(" | ");
|
|
8778
8805
|
}
|
|
8779
8806
|
async function handleInvoices(options) {
|
|
@@ -10917,7 +10944,7 @@ Examples:
|
|
|
10917
10944
|
}
|
|
10918
10945
|
|
|
10919
10946
|
// src/cli/commands/enrich.ts
|
|
10920
|
-
var
|
|
10947
|
+
var import_promises6 = require("fs/promises");
|
|
10921
10948
|
var import_node_os10 = require("os");
|
|
10922
10949
|
var import_node_path15 = require("path");
|
|
10923
10950
|
var import_commander2 = require("commander");
|
|
@@ -10925,6 +10952,7 @@ var import_commander2 = require("commander");
|
|
|
10925
10952
|
// src/cli/commands/play.ts
|
|
10926
10953
|
var import_node_crypto6 = require("crypto");
|
|
10927
10954
|
var import_node_fs12 = require("fs");
|
|
10955
|
+
var import_promises5 = require("fs/promises");
|
|
10928
10956
|
var import_node_path14 = require("path");
|
|
10929
10957
|
var import_sync5 = require("csv-parse/sync");
|
|
10930
10958
|
|
|
@@ -17577,6 +17605,31 @@ ${hint}`;
|
|
|
17577
17605
|
});
|
|
17578
17606
|
}
|
|
17579
17607
|
|
|
17608
|
+
// ../shared_libs/play-runtime/governor/policy.ts
|
|
17609
|
+
var DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS = 64;
|
|
17610
|
+
var MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS = 256;
|
|
17611
|
+
var MAX_CONFIGURABLE_CONCURRENT_ROWS = 1e3;
|
|
17612
|
+
function resolveMaxConcurrentExternalCalls(requested) {
|
|
17613
|
+
if (requested === void 0 || requested === null) {
|
|
17614
|
+
return DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS;
|
|
17615
|
+
}
|
|
17616
|
+
if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS) {
|
|
17617
|
+
throw new Error(
|
|
17618
|
+
`maxConcurrentExternalCalls must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.`
|
|
17619
|
+
);
|
|
17620
|
+
}
|
|
17621
|
+
return requested;
|
|
17622
|
+
}
|
|
17623
|
+
function resolveMaxConcurrentRows(requested) {
|
|
17624
|
+
if (requested === void 0 || requested === null) return null;
|
|
17625
|
+
if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_ROWS) {
|
|
17626
|
+
throw new Error(
|
|
17627
|
+
`maxConcurrentRows must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_ROWS}.`
|
|
17628
|
+
);
|
|
17629
|
+
}
|
|
17630
|
+
return requested;
|
|
17631
|
+
}
|
|
17632
|
+
|
|
17580
17633
|
// ../shared_libs/play-runtime/sandbox-runtime-limits.ts
|
|
17581
17634
|
var PLAY_SANDBOX_SIZE_LIMITS = {
|
|
17582
17635
|
standard: {
|
|
@@ -17801,6 +17854,7 @@ function stripLeadingTimestamp(line) {
|
|
|
17801
17854
|
// ../shared_libs/play-runtime/fixture-behavior.ts
|
|
17802
17855
|
var FIXTURE_BEHAVIOR_VERSION = 1;
|
|
17803
17856
|
var FIXTURE_BEHAVIOR_RESPONSE_VERSION = 2;
|
|
17857
|
+
var FIXTURE_BEHAVIOR_REPLAY_VERSION = 3;
|
|
17804
17858
|
var MAX_FIXTURE_RESPONSE_DELAY_SAMPLES = 256;
|
|
17805
17859
|
var MAX_FIXTURE_RESPONSE_DELAY_MS = 8 * 6e4;
|
|
17806
17860
|
var MAX_FIXTURE_RESPONSE_ERROR_MESSAGE_LENGTH = 500;
|
|
@@ -17812,7 +17866,11 @@ function validateFixtureBehavior(value) {
|
|
|
17812
17866
|
return { ok: false, error: "fixtureBehavior must be a JSON object." };
|
|
17813
17867
|
}
|
|
17814
17868
|
const record = value;
|
|
17815
|
-
const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION
|
|
17869
|
+
const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
|
|
17870
|
+
"version",
|
|
17871
|
+
"responseSamples",
|
|
17872
|
+
...record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
|
|
17873
|
+
]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
|
|
17816
17874
|
const unknownKeys = Object.keys(record).filter(
|
|
17817
17875
|
(key) => !supportedKeys.has(key)
|
|
17818
17876
|
);
|
|
@@ -17822,13 +17880,13 @@ function validateFixtureBehavior(value) {
|
|
|
17822
17880
|
error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
|
|
17823
17881
|
};
|
|
17824
17882
|
}
|
|
17825
|
-
if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
|
|
17883
|
+
if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17826
17884
|
return {
|
|
17827
17885
|
ok: false,
|
|
17828
|
-
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}.`
|
|
17886
|
+
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
|
|
17829
17887
|
};
|
|
17830
17888
|
}
|
|
17831
|
-
if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
|
|
17889
|
+
if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17832
17890
|
if (!Array.isArray(record.responseSamples) || record.responseSamples.length === 0 || record.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
17833
17891
|
return {
|
|
17834
17892
|
ok: false,
|
|
@@ -17935,6 +17993,72 @@ function validateFixtureBehavior(value) {
|
|
|
17935
17993
|
...httpError ? { httpError } : {}
|
|
17936
17994
|
});
|
|
17937
17995
|
}
|
|
17996
|
+
let replayBundle;
|
|
17997
|
+
if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17998
|
+
if (!record.replayBundle || typeof record.replayBundle !== "object" || Array.isArray(record.replayBundle)) {
|
|
17999
|
+
return {
|
|
18000
|
+
ok: false,
|
|
18001
|
+
error: "fixtureBehavior.replayBundle must be an object."
|
|
18002
|
+
};
|
|
18003
|
+
}
|
|
18004
|
+
const replay = record.replayBundle;
|
|
18005
|
+
const replayUnknownKeys = Object.keys(replay).filter(
|
|
18006
|
+
(key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
|
|
18007
|
+
);
|
|
18008
|
+
if (replayUnknownKeys.length > 0) {
|
|
18009
|
+
return {
|
|
18010
|
+
ok: false,
|
|
18011
|
+
error: `Unsupported fixtureBehavior.replayBundle field "${replayUnknownKeys[0]}".`
|
|
18012
|
+
};
|
|
18013
|
+
}
|
|
18014
|
+
const digestPattern = /^[a-f0-9]{64}$/;
|
|
18015
|
+
if (typeof replay.bundleId !== "string" || !digestPattern.test(replay.bundleId)) {
|
|
18016
|
+
return {
|
|
18017
|
+
ok: false,
|
|
18018
|
+
error: "fixtureBehavior.replayBundle.bundleId must be a lowercase SHA-256 digest."
|
|
18019
|
+
};
|
|
18020
|
+
}
|
|
18021
|
+
if (typeof replay.manifestSha256 !== "string" || !digestPattern.test(replay.manifestSha256)) {
|
|
18022
|
+
return {
|
|
18023
|
+
ok: false,
|
|
18024
|
+
error: "fixtureBehavior.replayBundle.manifestSha256 must be a lowercase SHA-256 digest."
|
|
18025
|
+
};
|
|
18026
|
+
}
|
|
18027
|
+
let syntheticFallbackToolIds;
|
|
18028
|
+
if (replay.syntheticFallbackToolIds !== void 0) {
|
|
18029
|
+
if (!Array.isArray(replay.syntheticFallbackToolIds) || replay.syntheticFallbackToolIds.length === 0 || replay.syntheticFallbackToolIds.length > 32) {
|
|
18030
|
+
return {
|
|
18031
|
+
ok: false,
|
|
18032
|
+
error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds must contain 1-32 tool ids."
|
|
18033
|
+
};
|
|
18034
|
+
}
|
|
18035
|
+
syntheticFallbackToolIds = [];
|
|
18036
|
+
for (const rawToolId of replay.syntheticFallbackToolIds) {
|
|
18037
|
+
if (typeof rawToolId !== "string" || rawToolId !== rawToolId.trim().toLowerCase() || !/^[a-z0-9][a-z0-9_.-]*$/.test(rawToolId) || rawToolId.length > 250 || syntheticFallbackToolIds.includes(rawToolId)) {
|
|
18038
|
+
return {
|
|
18039
|
+
ok: false,
|
|
18040
|
+
error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds contains an invalid tool id."
|
|
18041
|
+
};
|
|
18042
|
+
}
|
|
18043
|
+
syntheticFallbackToolIds.push(rawToolId);
|
|
18044
|
+
}
|
|
18045
|
+
}
|
|
18046
|
+
replayBundle = {
|
|
18047
|
+
bundleId: replay.bundleId,
|
|
18048
|
+
manifestSha256: replay.manifestSha256,
|
|
18049
|
+
...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
|
|
18050
|
+
};
|
|
18051
|
+
}
|
|
18052
|
+
if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18053
|
+
return {
|
|
18054
|
+
ok: true,
|
|
18055
|
+
behavior: {
|
|
18056
|
+
version: FIXTURE_BEHAVIOR_REPLAY_VERSION,
|
|
18057
|
+
responseSamples: samples2,
|
|
18058
|
+
replayBundle
|
|
18059
|
+
}
|
|
18060
|
+
};
|
|
18061
|
+
}
|
|
17938
18062
|
return {
|
|
17939
18063
|
ok: true,
|
|
17940
18064
|
behavior: {
|
|
@@ -18027,6 +18151,114 @@ var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
18027
18151
|
"--debug-map-latency",
|
|
18028
18152
|
"--debug-fixture-provider-pacing"
|
|
18029
18153
|
]);
|
|
18154
|
+
async function pathExistsIncludingSymlink(path) {
|
|
18155
|
+
try {
|
|
18156
|
+
await (0, import_promises5.lstat)(path);
|
|
18157
|
+
return true;
|
|
18158
|
+
} catch (error) {
|
|
18159
|
+
if (error.code === "ENOENT") {
|
|
18160
|
+
return false;
|
|
18161
|
+
}
|
|
18162
|
+
throw error;
|
|
18163
|
+
}
|
|
18164
|
+
}
|
|
18165
|
+
function runIdFileTempPath(destination) {
|
|
18166
|
+
return (0, import_node_path14.join)(
|
|
18167
|
+
(0, import_node_path14.dirname)(destination),
|
|
18168
|
+
`.${(0, import_node_path14.basename)(destination)}.${process.pid}.${(0, import_node_crypto6.randomUUID)()}.tmp`
|
|
18169
|
+
);
|
|
18170
|
+
}
|
|
18171
|
+
async function removeRunIdTempFile(path) {
|
|
18172
|
+
try {
|
|
18173
|
+
await (0, import_promises5.unlink)(path);
|
|
18174
|
+
} catch (error) {
|
|
18175
|
+
if (error.code !== "ENOENT") {
|
|
18176
|
+
throw error;
|
|
18177
|
+
}
|
|
18178
|
+
}
|
|
18179
|
+
}
|
|
18180
|
+
async function preflightRunIdFile(path) {
|
|
18181
|
+
const destination = (0, import_node_path14.resolve)(path);
|
|
18182
|
+
if (await pathExistsIncludingSymlink(destination)) {
|
|
18183
|
+
throw new Error(
|
|
18184
|
+
`--run-id-file destination already exists: ${destination}. Choose a new path so this run cannot overwrite another run identity.`
|
|
18185
|
+
);
|
|
18186
|
+
}
|
|
18187
|
+
const tempPath = runIdFileTempPath(destination);
|
|
18188
|
+
let handle = null;
|
|
18189
|
+
try {
|
|
18190
|
+
handle = await (0, import_promises5.open)(tempPath, "wx", 384);
|
|
18191
|
+
await handle.sync();
|
|
18192
|
+
} catch (error) {
|
|
18193
|
+
throw new Error(
|
|
18194
|
+
`Cannot write --run-id-file destination ${destination}: ${error instanceof Error ? error.message : String(error)}`
|
|
18195
|
+
);
|
|
18196
|
+
} finally {
|
|
18197
|
+
await handle?.close();
|
|
18198
|
+
await removeRunIdTempFile(tempPath);
|
|
18199
|
+
}
|
|
18200
|
+
return destination;
|
|
18201
|
+
}
|
|
18202
|
+
async function readRunIdFile(destination) {
|
|
18203
|
+
if (!await pathExistsIncludingSymlink(destination)) {
|
|
18204
|
+
return null;
|
|
18205
|
+
}
|
|
18206
|
+
let parsed;
|
|
18207
|
+
try {
|
|
18208
|
+
parsed = JSON.parse(await (0, import_promises5.readFile)(destination, "utf8"));
|
|
18209
|
+
} catch (error) {
|
|
18210
|
+
throw new Error(
|
|
18211
|
+
`--run-id-file destination contains invalid JSON: ${destination}. Refusing to overwrite it (${error instanceof Error ? error.message : String(error)}).`
|
|
18212
|
+
);
|
|
18213
|
+
}
|
|
18214
|
+
if (!parsed || typeof parsed !== "object" || parsed.version !== 1 || typeof parsed.runId !== "string" || !parsed.runId) {
|
|
18215
|
+
throw new Error(
|
|
18216
|
+
`--run-id-file destination has an unsupported identity record: ${destination}. Refusing to overwrite it.`
|
|
18217
|
+
);
|
|
18218
|
+
}
|
|
18219
|
+
return parsed;
|
|
18220
|
+
}
|
|
18221
|
+
async function writePlayRunIdFile(destination, runId) {
|
|
18222
|
+
const existing = await readRunIdFile(destination);
|
|
18223
|
+
if (existing) {
|
|
18224
|
+
if (existing.runId === runId) return;
|
|
18225
|
+
throw new Error(
|
|
18226
|
+
`--run-id-file destination already records run ${existing.runId}; refusing to replace it with ${runId}: ${destination}`
|
|
18227
|
+
);
|
|
18228
|
+
}
|
|
18229
|
+
const tempPath = runIdFileTempPath(destination);
|
|
18230
|
+
let handle = null;
|
|
18231
|
+
try {
|
|
18232
|
+
handle = await (0, import_promises5.open)(tempPath, "wx", 384);
|
|
18233
|
+
await handle.writeFile(
|
|
18234
|
+
`${JSON.stringify({ version: 1, runId })}
|
|
18235
|
+
`,
|
|
18236
|
+
"utf8"
|
|
18237
|
+
);
|
|
18238
|
+
await handle.sync();
|
|
18239
|
+
await handle.close();
|
|
18240
|
+
handle = null;
|
|
18241
|
+
try {
|
|
18242
|
+
await (0, import_promises5.link)(tempPath, destination);
|
|
18243
|
+
const directory = await (0, import_promises5.open)((0, import_node_path14.dirname)(destination), "r");
|
|
18244
|
+
try {
|
|
18245
|
+
await directory.sync();
|
|
18246
|
+
} finally {
|
|
18247
|
+
await directory.close();
|
|
18248
|
+
}
|
|
18249
|
+
} catch (error) {
|
|
18250
|
+
if (error.code !== "EEXIST") throw error;
|
|
18251
|
+
const raced = await readRunIdFile(destination);
|
|
18252
|
+
if (raced?.runId === runId) return;
|
|
18253
|
+
throw new Error(
|
|
18254
|
+
`--run-id-file destination already records run ${raced?.runId ?? "<invalid>"}; refusing to replace it with ${runId}: ${destination}`
|
|
18255
|
+
);
|
|
18256
|
+
}
|
|
18257
|
+
} finally {
|
|
18258
|
+
await handle?.close();
|
|
18259
|
+
await removeRunIdTempFile(tempPath);
|
|
18260
|
+
}
|
|
18261
|
+
}
|
|
18030
18262
|
function traceCliSync(phase, fields, run) {
|
|
18031
18263
|
const startedAt = Date.now();
|
|
18032
18264
|
try {
|
|
@@ -19431,8 +19663,8 @@ function buildPlayDashboardUrl(baseUrl, playName) {
|
|
|
19431
19663
|
const encodedPlayName = encodeURIComponent(playName);
|
|
19432
19664
|
return `${trimmedBase}/dashboard/plays/${encodedPlayName}`;
|
|
19433
19665
|
}
|
|
19434
|
-
function openPlayDashboard(dashboardUrl,
|
|
19435
|
-
if (
|
|
19666
|
+
function openPlayDashboard(dashboardUrl, open2) {
|
|
19667
|
+
if (open2 && dashboardUrl) {
|
|
19436
19668
|
openInBrowser(dashboardUrl);
|
|
19437
19669
|
}
|
|
19438
19670
|
}
|
|
@@ -19468,9 +19700,11 @@ function assertPlayWaitNotTimedOut(input2) {
|
|
|
19468
19700
|
);
|
|
19469
19701
|
}
|
|
19470
19702
|
}
|
|
19703
|
+
var PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS = 15e3;
|
|
19471
19704
|
async function waitForPlayCompletionByStream(input2) {
|
|
19472
19705
|
let lastPhase = null;
|
|
19473
19706
|
let reconnectAttempt = 0;
|
|
19707
|
+
let nextDurableProbeAt = Date.now() + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
|
|
19474
19708
|
const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
|
|
19475
19709
|
const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
|
|
19476
19710
|
const fetchTerminalStatus = async () => {
|
|
@@ -19489,6 +19723,14 @@ async function waitForPlayCompletionByStream(input2) {
|
|
|
19489
19723
|
};
|
|
19490
19724
|
const handleLiveEvent = async (event) => {
|
|
19491
19725
|
assertPlayWaitNotTimedOut({ ...input2, lastPhase });
|
|
19726
|
+
const now = Date.now();
|
|
19727
|
+
if (now >= nextDurableProbeAt) {
|
|
19728
|
+
nextDurableProbeAt = now + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
|
|
19729
|
+
const durableTerminal = await fetchTerminalStatus();
|
|
19730
|
+
if (durableTerminal) {
|
|
19731
|
+
return durableTerminal;
|
|
19732
|
+
}
|
|
19733
|
+
}
|
|
19492
19734
|
const phase = describeLiveEventPhase(event);
|
|
19493
19735
|
if (phase) {
|
|
19494
19736
|
lastPhase = phase;
|
|
@@ -19737,7 +19979,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
19737
19979
|
lastKnownWorkflowId = eventRunId;
|
|
19738
19980
|
firstRunIdMs ??= Date.now() - startedAt;
|
|
19739
19981
|
if (runStartedNow) {
|
|
19740
|
-
input2.onRunStarted?.(eventRunId);
|
|
19982
|
+
await input2.onRunStarted?.(eventRunId);
|
|
19741
19983
|
}
|
|
19742
19984
|
}
|
|
19743
19985
|
if (eventConfirmsPlayRunLaunch(event) && eventRunId === lastKnownWorkflowId) {
|
|
@@ -21016,6 +21258,15 @@ function buildOrdinaryPlayRunCommand(options, resolvedRevisionId) {
|
|
|
21016
21258
|
}
|
|
21017
21259
|
if (options.profile)
|
|
21018
21260
|
parts.push("--profile", shellSingleQuote(options.profile));
|
|
21261
|
+
if (options.maxConcurrentExternalCalls !== null) {
|
|
21262
|
+
parts.push(
|
|
21263
|
+
"--max-concurrent-external-calls",
|
|
21264
|
+
String(options.maxConcurrentExternalCalls)
|
|
21265
|
+
);
|
|
21266
|
+
}
|
|
21267
|
+
if (options.maxConcurrentRows !== null) {
|
|
21268
|
+
parts.push("--max-concurrent-rows", String(options.maxConcurrentRows));
|
|
21269
|
+
}
|
|
21019
21270
|
const pinnedRevisionId = options.target.kind === "name" ? resolvedRevisionId ?? options.revisionId : null;
|
|
21020
21271
|
if (pinnedRevisionId) {
|
|
21021
21272
|
parts.push("--revision-id", shellSingleQuote(pinnedRevisionId));
|
|
@@ -21885,7 +22136,7 @@ function writeStartedPlayRun(input2) {
|
|
|
21885
22136
|
);
|
|
21886
22137
|
}
|
|
21887
22138
|
function parsePlayRunOptions(args) {
|
|
21888
|
-
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--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>] [--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.";
|
|
22139
|
+
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.";
|
|
21889
22140
|
let filePath = null;
|
|
21890
22141
|
let playName = null;
|
|
21891
22142
|
let input2 = null;
|
|
@@ -21896,15 +22147,18 @@ function parsePlayRunOptions(args) {
|
|
|
21896
22147
|
const fullJson = args.includes("--full");
|
|
21897
22148
|
const emitLogs = !jsonOutput || args.includes("--logs");
|
|
21898
22149
|
const force = args.includes("--force");
|
|
21899
|
-
const
|
|
22150
|
+
const open2 = args.includes("--open");
|
|
21900
22151
|
const debugMapLatency = args.includes("--debug-map-latency");
|
|
21901
22152
|
const debugFixtureProviderPacing = args.includes(
|
|
21902
22153
|
"--debug-fixture-provider-pacing"
|
|
21903
22154
|
);
|
|
21904
22155
|
const verboseLogs = args.includes("--logs") || debugMapLatency;
|
|
21905
22156
|
let waitTimeoutMs = null;
|
|
22157
|
+
let maxConcurrentExternalCalls = null;
|
|
22158
|
+
let maxConcurrentRows = null;
|
|
21906
22159
|
let profile = null;
|
|
21907
22160
|
let fixtureBehavior = null;
|
|
22161
|
+
let runIdFile = null;
|
|
21908
22162
|
for (let index = 0; index < args.length; index += 1) {
|
|
21909
22163
|
const arg = args[index];
|
|
21910
22164
|
if (arg === "--file" && args[index + 1]) {
|
|
@@ -21919,6 +22173,23 @@ function parsePlayRunOptions(args) {
|
|
|
21919
22173
|
input2 = parseJsonInput(args[++index]);
|
|
21920
22174
|
continue;
|
|
21921
22175
|
}
|
|
22176
|
+
if (arg === "--run-id-file") {
|
|
22177
|
+
const value = args[index + 1];
|
|
22178
|
+
if (!value || value.startsWith("--")) {
|
|
22179
|
+
throw new Error("--run-id-file requires a destination path.");
|
|
22180
|
+
}
|
|
22181
|
+
runIdFile = value;
|
|
22182
|
+
index += 1;
|
|
22183
|
+
continue;
|
|
22184
|
+
}
|
|
22185
|
+
if (arg.startsWith("--run-id-file=")) {
|
|
22186
|
+
const value = arg.slice("--run-id-file=".length);
|
|
22187
|
+
if (!value) {
|
|
22188
|
+
throw new Error("--run-id-file requires a destination path.");
|
|
22189
|
+
}
|
|
22190
|
+
runIdFile = value;
|
|
22191
|
+
continue;
|
|
22192
|
+
}
|
|
21922
22193
|
if (arg === "--revision-id" && args[index + 1]) {
|
|
21923
22194
|
revisionId = args[++index];
|
|
21924
22195
|
continue;
|
|
@@ -21933,6 +22204,41 @@ function parsePlayRunOptions(args) {
|
|
|
21933
22204
|
index += 1;
|
|
21934
22205
|
continue;
|
|
21935
22206
|
}
|
|
22207
|
+
if (arg === "--max-concurrent-external-calls") {
|
|
22208
|
+
const value = args[index + 1];
|
|
22209
|
+
if (!value || value.startsWith("--")) {
|
|
22210
|
+
throw new Error(
|
|
22211
|
+
"--max-concurrent-external-calls requires a whole number."
|
|
22212
|
+
);
|
|
22213
|
+
}
|
|
22214
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
22215
|
+
throw new Error(
|
|
22216
|
+
"--max-concurrent-external-calls requires a positive whole number."
|
|
22217
|
+
);
|
|
22218
|
+
}
|
|
22219
|
+
maxConcurrentExternalCalls = parsePositiveInteger3(
|
|
22220
|
+
value,
|
|
22221
|
+
"--max-concurrent-external-calls"
|
|
22222
|
+
);
|
|
22223
|
+
resolveMaxConcurrentExternalCalls(maxConcurrentExternalCalls);
|
|
22224
|
+
index += 1;
|
|
22225
|
+
continue;
|
|
22226
|
+
}
|
|
22227
|
+
if (arg === "--max-concurrent-rows") {
|
|
22228
|
+
const value = args[index + 1];
|
|
22229
|
+
if (!value || value.startsWith("--")) {
|
|
22230
|
+
throw new Error("--max-concurrent-rows requires a whole number.");
|
|
22231
|
+
}
|
|
22232
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
22233
|
+
throw new Error(
|
|
22234
|
+
"--max-concurrent-rows requires a positive whole number."
|
|
22235
|
+
);
|
|
22236
|
+
}
|
|
22237
|
+
maxConcurrentRows = parsePositiveInteger3(value, "--max-concurrent-rows");
|
|
22238
|
+
resolveMaxConcurrentRows(maxConcurrentRows);
|
|
22239
|
+
index += 1;
|
|
22240
|
+
continue;
|
|
22241
|
+
}
|
|
21936
22242
|
if (arg === "--fixture-behavior") {
|
|
21937
22243
|
const value = args[index + 1];
|
|
21938
22244
|
if (!value) {
|
|
@@ -22043,11 +22349,14 @@ function parsePlayRunOptions(args) {
|
|
|
22043
22349
|
fullJson,
|
|
22044
22350
|
waitTimeoutMs,
|
|
22045
22351
|
force,
|
|
22046
|
-
|
|
22352
|
+
maxConcurrentExternalCalls,
|
|
22353
|
+
maxConcurrentRows,
|
|
22354
|
+
open: open2,
|
|
22047
22355
|
profile,
|
|
22048
22356
|
debugMapLatency,
|
|
22049
22357
|
debugFixtureProviderPacing,
|
|
22050
|
-
fixtureBehavior
|
|
22358
|
+
fixtureBehavior,
|
|
22359
|
+
runIdFile
|
|
22051
22360
|
};
|
|
22052
22361
|
}
|
|
22053
22362
|
function parsePlayCheckOptions(args) {
|
|
@@ -22730,6 +23039,8 @@ async function handleFileBackedRun(options, hooks) {
|
|
|
22730
23039
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
22731
23040
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
22732
23041
|
...options.force ? { force: true } : {},
|
|
23042
|
+
...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
|
|
23043
|
+
...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
|
|
22733
23044
|
...options.profile ? { profile: options.profile } : {},
|
|
22734
23045
|
...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
|
|
22735
23046
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -22790,6 +23101,7 @@ async function handleFileBackedRun(options, hooks) {
|
|
|
22790
23101
|
throw await normalizePlayStartError(client2, error, playName);
|
|
22791
23102
|
})
|
|
22792
23103
|
);
|
|
23104
|
+
await hooks?.onRunStarted?.(started.workflowId);
|
|
22793
23105
|
const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
|
|
22794
23106
|
openPlayDashboard(resolvedDashboardUrl, options.open);
|
|
22795
23107
|
progress.phase("started run");
|
|
@@ -22910,6 +23222,8 @@ async function handleNamedRun(options, hooks) {
|
|
|
22910
23222
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
22911
23223
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
22912
23224
|
...options.force ? { force: true } : {},
|
|
23225
|
+
...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
|
|
23226
|
+
...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
|
|
22913
23227
|
...options.profile ? { profile: options.profile } : {},
|
|
22914
23228
|
...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
|
|
22915
23229
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -22975,6 +23289,7 @@ async function handleNamedRun(options, hooks) {
|
|
|
22975
23289
|
});
|
|
22976
23290
|
})
|
|
22977
23291
|
);
|
|
23292
|
+
await hooks?.onRunStarted?.(started.workflowId);
|
|
22978
23293
|
const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
|
|
22979
23294
|
openPlayDashboard(resolvedDashboardUrl, options.open);
|
|
22980
23295
|
progress.phase("started run");
|
|
@@ -22991,10 +23306,28 @@ async function handleNamedRun(options, hooks) {
|
|
|
22991
23306
|
return 0;
|
|
22992
23307
|
}
|
|
22993
23308
|
async function handlePlayRun(args, hooks) {
|
|
22994
|
-
const
|
|
23309
|
+
const parsedOptions = parsePlayRunOptions(args);
|
|
23310
|
+
const options = parsedOptions.runIdFile ? {
|
|
23311
|
+
...parsedOptions,
|
|
23312
|
+
runIdFile: await preflightRunIdFile(parsedOptions.runIdFile)
|
|
23313
|
+
} : parsedOptions;
|
|
23314
|
+
const runHooks = options.runIdFile ? {
|
|
23315
|
+
...hooks,
|
|
23316
|
+
onRunStarted: async (runId) => {
|
|
23317
|
+
try {
|
|
23318
|
+
await writePlayRunIdFile(options.runIdFile, runId);
|
|
23319
|
+
} catch (error) {
|
|
23320
|
+
throw new Error(
|
|
23321
|
+
`Run ${runId} was accepted, but its identity could not be persisted to ${options.runIdFile}: ${error instanceof Error ? error.message : String(error)}. Inspect it with 'deepline runs get ${runId} --full --json'; do not submit a replacement run.`,
|
|
23322
|
+
{ cause: error }
|
|
23323
|
+
);
|
|
23324
|
+
}
|
|
23325
|
+
await hooks?.onRunStarted?.(runId);
|
|
23326
|
+
}
|
|
23327
|
+
} : hooks;
|
|
22995
23328
|
if (options.target.kind === "file") {
|
|
22996
23329
|
if (isFileTarget(options.target.path)) {
|
|
22997
|
-
return handleFileBackedRun(options,
|
|
23330
|
+
return handleFileBackedRun(options, runHooks);
|
|
22998
23331
|
}
|
|
22999
23332
|
const resolved = (0, import_node_path14.resolve)(options.target.path);
|
|
23000
23333
|
console.error(`File not found: ${resolved}`);
|
|
@@ -23016,7 +23349,7 @@ async function handlePlayRun(args, hooks) {
|
|
|
23016
23349
|
}
|
|
23017
23350
|
return 1;
|
|
23018
23351
|
}
|
|
23019
|
-
return handleNamedRun(options,
|
|
23352
|
+
return handleNamedRun(options, runHooks);
|
|
23020
23353
|
}
|
|
23021
23354
|
function parseRunIdPositional(args, usage) {
|
|
23022
23355
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -24344,10 +24677,18 @@ Notes:
|
|
|
24344
24677
|
next commands. --watch and --wait are accepted compatibility aliases for the
|
|
24345
24678
|
default behavior. Use --no-wait only when you intentionally want
|
|
24346
24679
|
a fire-and-forget run id.
|
|
24680
|
+
--run-id-file writes the durable run id to a versioned JSON file as soon as
|
|
24681
|
+
the server accepts the run. The destination must not already exist.
|
|
24347
24682
|
The play page URL is printed when the run starts. Pass --open to open it in a browser.
|
|
24348
24683
|
Concurrent runs for the same play are allowed.
|
|
24349
24684
|
--force starts a fresh run graph without refreshing completed provider calls.
|
|
24350
24685
|
It does not cancel active sibling runs.
|
|
24686
|
+
--max-concurrent-external-calls controls the per-run provider-tool/ctx.fetch
|
|
24687
|
+
resident-work ceiling. Default: ${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS}; accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.
|
|
24688
|
+
Provider pacing and sandbox memory limits still apply.
|
|
24689
|
+
--max-concurrent-rows sets the run-wide default and ceiling for live map row
|
|
24690
|
+
resolvers. Accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_ROWS}. The runtime
|
|
24691
|
+
may lower it when source-row size exceeds the active-row memory budget.
|
|
24351
24692
|
This command starts cloud work and may spend Deepline credits through tool calls.
|
|
24352
24693
|
|
|
24353
24694
|
Idempotent execution:
|
|
@@ -24383,8 +24724,10 @@ Idempotent execution:
|
|
|
24383
24724
|
Examples:
|
|
24384
24725
|
deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
|
|
24385
24726
|
deepline plays run long-background-play --no-wait
|
|
24727
|
+
deepline plays run long-background-play --run-id-file ./run-id.json
|
|
24386
24728
|
deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
|
|
24387
24729
|
deepline plays run my.play.ts --profile absurd
|
|
24730
|
+
deepline plays run my.play.ts --max-concurrent-external-calls 20
|
|
24388
24731
|
deepline plays run my.play.ts --input @input.json --json
|
|
24389
24732
|
deepline plays run cto-search.play.ts --limit 5
|
|
24390
24733
|
deepline runs export <run-id> --out output.csv
|
|
@@ -24400,9 +24743,18 @@ Examples:
|
|
|
24400
24743
|
"--fixture-behavior <json>",
|
|
24401
24744
|
"Internal/testing: fixture response behavior JSON object or @file path"
|
|
24402
24745
|
).option("--watch", "Compatibility alias; run waits by default").option("--wait", "Compatibility alias; run waits by default").option("--no-wait", "Start the run and return immediately").option(
|
|
24746
|
+
"--run-id-file <path>",
|
|
24747
|
+
"Atomically write the accepted run id to a new JSON file"
|
|
24748
|
+
).option(
|
|
24403
24749
|
"--logs",
|
|
24404
24750
|
"When output is non-interactive, stream play logs to stderr while waiting"
|
|
24405
|
-
).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
|
|
24751
|
+
).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
|
|
24752
|
+
"--max-concurrent-external-calls <count>",
|
|
24753
|
+
`Concurrent provider-tool and ctx.fetch executions (${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS} default, max ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS})`
|
|
24754
|
+
).option(
|
|
24755
|
+
"--max-concurrent-rows <count>",
|
|
24756
|
+
`Run-wide dataset map row resolver ceiling (max ${MAX_CONFIGURABLE_CONCURRENT_ROWS})`
|
|
24757
|
+
).option("--open", "Open the play page in a browser after the run starts").option(
|
|
24406
24758
|
"--debug-map-latency",
|
|
24407
24759
|
"Internal diagnostics: emit one aggregate latency profile per dataset map"
|
|
24408
24760
|
).option(
|
|
@@ -24441,10 +24793,16 @@ Pass-through input flags:
|
|
|
24441
24793
|
...options.profile ? ["--profile", options.profile] : [],
|
|
24442
24794
|
...options.fixtureBehavior ? ["--fixture-behavior", options.fixtureBehavior] : [],
|
|
24443
24795
|
...options.wait === false ? ["--no-wait"] : [],
|
|
24796
|
+
...options.runIdFile ? ["--run-id-file", options.runIdFile] : [],
|
|
24444
24797
|
...options.watch || options.wait ? ["--watch"] : [],
|
|
24445
24798
|
...options.logs ? ["--logs"] : [],
|
|
24446
24799
|
...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
|
|
24447
24800
|
...options.force ? ["--force"] : [],
|
|
24801
|
+
...options.maxConcurrentExternalCalls ? [
|
|
24802
|
+
"--max-concurrent-external-calls",
|
|
24803
|
+
options.maxConcurrentExternalCalls
|
|
24804
|
+
] : [],
|
|
24805
|
+
...options.maxConcurrentRows ? ["--max-concurrent-rows", options.maxConcurrentRows] : [],
|
|
24448
24806
|
...options.open ? ["--open"] : [],
|
|
24449
24807
|
...options.debugMapLatency ? ["--debug-map-latency"] : [],
|
|
24450
24808
|
...options.debugFixtureProviderPacing ? ["--debug-fixture-provider-pacing"] : [],
|
|
@@ -26833,7 +27191,7 @@ async function readAtFileReference(value, argumentName, strip = true) {
|
|
|
26833
27191
|
throw new Error(`Invalid ${argumentName} value: empty @file path.`);
|
|
26834
27192
|
}
|
|
26835
27193
|
try {
|
|
26836
|
-
const text = await (0,
|
|
27194
|
+
const text = await (0, import_promises6.readFile)(filePath, "utf8");
|
|
26837
27195
|
const normalized = text.replace(/^\uFEFF/, "");
|
|
26838
27196
|
return strip ? normalized.trim() : normalized;
|
|
26839
27197
|
} catch (error) {
|
|
@@ -27131,7 +27489,7 @@ async function buildPlanArgs(args) {
|
|
|
27131
27489
|
async function assertInputCsvExists(inputCsv) {
|
|
27132
27490
|
const path = (0, import_node_path15.resolve)(inputCsv);
|
|
27133
27491
|
try {
|
|
27134
|
-
const info = await (0,
|
|
27492
|
+
const info = await (0, import_promises6.stat)(path);
|
|
27135
27493
|
if (info.isFile()) {
|
|
27136
27494
|
return;
|
|
27137
27495
|
}
|
|
@@ -27152,8 +27510,8 @@ async function assertSafeOutputPath(inputCsv, outputPath) {
|
|
|
27152
27510
|
}
|
|
27153
27511
|
try {
|
|
27154
27512
|
const [inputInfo, outputInfo] = await Promise.all([
|
|
27155
|
-
(0,
|
|
27156
|
-
(0,
|
|
27513
|
+
(0, import_promises6.stat)(input2),
|
|
27514
|
+
(0, import_promises6.stat)(output2)
|
|
27157
27515
|
]);
|
|
27158
27516
|
if (inputInfo.dev === outputInfo.dev && inputInfo.ino === outputInfo.ino) {
|
|
27159
27517
|
throw new Error(
|
|
@@ -27173,7 +27531,7 @@ async function assertSafeOutputPath(inputCsv, outputPath) {
|
|
|
27173
27531
|
}
|
|
27174
27532
|
async function regularFileExists(path) {
|
|
27175
27533
|
try {
|
|
27176
|
-
const info = await (0,
|
|
27534
|
+
const info = await (0, import_promises6.stat)((0, import_node_path15.resolve)(path));
|
|
27177
27535
|
return info.isFile();
|
|
27178
27536
|
} catch (error) {
|
|
27179
27537
|
const code = error && typeof error === "object" ? error.code : void 0;
|
|
@@ -27184,7 +27542,7 @@ async function regularFileExists(path) {
|
|
|
27184
27542
|
}
|
|
27185
27543
|
}
|
|
27186
27544
|
async function readConfig(path) {
|
|
27187
|
-
const source = await (0,
|
|
27545
|
+
const source = await (0, import_promises6.readFile)((0, import_node_path15.resolve)(path), "utf8");
|
|
27188
27546
|
let parsed;
|
|
27189
27547
|
try {
|
|
27190
27548
|
parsed = JSON.parse(source);
|
|
@@ -27605,7 +27963,7 @@ async function writeOutputCsv(outputPath, status, options) {
|
|
|
27605
27963
|
]),
|
|
27606
27964
|
options?.config
|
|
27607
27965
|
);
|
|
27608
|
-
await (0,
|
|
27966
|
+
await (0, import_promises6.writeFile)(
|
|
27609
27967
|
(0, import_node_path15.resolve)(outputPath),
|
|
27610
27968
|
csvStringFromRows(merged.rows, columns),
|
|
27611
27969
|
"utf8"
|
|
@@ -29285,7 +29643,7 @@ async function persistEnrichFailureReport(input2) {
|
|
|
29285
29643
|
}
|
|
29286
29644
|
const stateDir = (0, import_node_path15.join)((0, import_node_os10.homedir)(), ".local", "deepline", "runtime", "state");
|
|
29287
29645
|
const reportPrefix = input2.jobs.length > 0 ? "run-block-failures" : "enrich-issues";
|
|
29288
|
-
await (0,
|
|
29646
|
+
await (0, import_promises6.mkdir)(stateDir, { recursive: true });
|
|
29289
29647
|
const reportPath = (0, import_node_path15.join)(
|
|
29290
29648
|
stateDir,
|
|
29291
29649
|
`${reportPrefix}-${Math.floor(Date.now() / 1e3)}-${process.pid}.json`
|
|
@@ -29311,7 +29669,7 @@ async function persistEnrichFailureReport(input2) {
|
|
|
29311
29669
|
if (input2.rows.rowStart !== null && input2.rows.rowEnd !== null) {
|
|
29312
29670
|
report.rows = { start: input2.rows.rowStart, end: input2.rows.rowEnd };
|
|
29313
29671
|
}
|
|
29314
|
-
await (0,
|
|
29672
|
+
await (0, import_promises6.writeFile)(reportPath, `${JSON.stringify(report, null, 2)}
|
|
29315
29673
|
`, "utf8");
|
|
29316
29674
|
return reportPath;
|
|
29317
29675
|
}
|
|
@@ -30214,13 +30572,13 @@ function registerEnrichCommand(program) {
|
|
|
30214
30572
|
sdkEnrichTelemetryCompleted = true;
|
|
30215
30573
|
await completeSdkEnrichTelemetry(sdkEnrichTelemetry, input2);
|
|
30216
30574
|
};
|
|
30217
|
-
const tempDir = await (0,
|
|
30575
|
+
const tempDir = await (0, import_promises6.mkdtemp)((0, import_node_path15.join)((0, import_node_os10.tmpdir)(), "deepline-enrich-play-"));
|
|
30218
30576
|
await emitSdkEnrichTelemetry(sdkEnrichTelemetry, "enrich_started");
|
|
30219
30577
|
const tempPlay = (0, import_node_path15.join)(tempDir, "deepline-enrich.play.ts");
|
|
30220
30578
|
let inPlaceTempDir = null;
|
|
30221
30579
|
let inPlaceTempOutputPath = null;
|
|
30222
30580
|
const inPlaceFinalOutputPath = options.inPlace ? (0, import_node_path15.resolve)(inputCsv) : null;
|
|
30223
|
-
const inPlaceCommitOutputPath = options.inPlace ? (await (0,
|
|
30581
|
+
const inPlaceCommitOutputPath = options.inPlace ? (await (0, import_promises6.lstat)(inputCsv)).isSymbolicLink() ? await (0, import_promises6.realpath)(inputCsv) : inPlaceFinalOutputPath : null;
|
|
30224
30582
|
const failureReportOutputPath = options.inPlace ? inPlaceFinalOutputPath : null;
|
|
30225
30583
|
const enrichIssueFollowUpOutputPath = options.inPlace && inPlaceFinalOutputPath ? sidecarEnrichRowsExportPath(inPlaceFinalOutputPath) : null;
|
|
30226
30584
|
let activeRunId2 = null;
|
|
@@ -30241,16 +30599,16 @@ function registerEnrichCommand(program) {
|
|
|
30241
30599
|
return;
|
|
30242
30600
|
}
|
|
30243
30601
|
if (inPlaceTempDir) {
|
|
30244
|
-
await (0,
|
|
30602
|
+
await (0, import_promises6.rm)(inPlaceTempDir, { recursive: true, force: true });
|
|
30245
30603
|
}
|
|
30246
|
-
inPlaceTempDir = await (0,
|
|
30604
|
+
inPlaceTempDir = await (0, import_promises6.mkdtemp)(
|
|
30247
30605
|
(0, import_node_path15.join)(
|
|
30248
30606
|
(0, import_node_path15.dirname)(inPlaceCommitOutputPath ?? (0, import_node_path15.resolve)(inputCsv)),
|
|
30249
30607
|
".deepline-enrich-in-place-"
|
|
30250
30608
|
)
|
|
30251
30609
|
);
|
|
30252
30610
|
inPlaceTempOutputPath = (0, import_node_path15.join)(inPlaceTempDir, "output.csv");
|
|
30253
|
-
await (0,
|
|
30611
|
+
await (0, import_promises6.copyFile)((0, import_node_path15.resolve)(inputCsv), inPlaceTempOutputPath);
|
|
30254
30612
|
outputPath = inPlaceTempOutputPath;
|
|
30255
30613
|
};
|
|
30256
30614
|
const commitInPlaceOutput = async (exportResult) => {
|
|
@@ -30258,12 +30616,12 @@ function registerEnrichCommand(program) {
|
|
|
30258
30616
|
return exportResult;
|
|
30259
30617
|
}
|
|
30260
30618
|
const committedTempDir = inPlaceTempDir;
|
|
30261
|
-
await (0,
|
|
30619
|
+
await (0, import_promises6.rename)(inPlaceTempOutputPath, inPlaceCommitOutputPath);
|
|
30262
30620
|
inPlaceTempDir = null;
|
|
30263
30621
|
inPlaceTempOutputPath = null;
|
|
30264
30622
|
outputPath = inPlaceFinalOutputPath;
|
|
30265
30623
|
if (committedTempDir) {
|
|
30266
|
-
await (0,
|
|
30624
|
+
await (0, import_promises6.rm)(committedTempDir, { recursive: true, force: true });
|
|
30267
30625
|
}
|
|
30268
30626
|
if (!exportResult) {
|
|
30269
30627
|
return null;
|
|
@@ -30276,7 +30634,7 @@ function registerEnrichCommand(program) {
|
|
|
30276
30634
|
try {
|
|
30277
30635
|
process.once("SIGINT", onSigint);
|
|
30278
30636
|
process.once("SIGTERM", onSigterm);
|
|
30279
|
-
await (0,
|
|
30637
|
+
await (0, import_promises6.writeFile)(tempPlay, playSource, "utf8");
|
|
30280
30638
|
if (options.inPlace) {
|
|
30281
30639
|
await prepareInPlaceOutput();
|
|
30282
30640
|
}
|
|
@@ -30470,11 +30828,11 @@ function registerEnrichCommand(program) {
|
|
|
30470
30828
|
process.removeListener("SIGINT", onSigint);
|
|
30471
30829
|
process.removeListener("SIGTERM", onSigterm);
|
|
30472
30830
|
if (inPlaceTempDir) {
|
|
30473
|
-
await (0,
|
|
30831
|
+
await (0, import_promises6.rm)(inPlaceTempDir, { recursive: true, force: true });
|
|
30474
30832
|
} else if (inPlaceTempOutputPath) {
|
|
30475
|
-
await (0,
|
|
30833
|
+
await (0, import_promises6.rm)(inPlaceTempOutputPath, { force: true });
|
|
30476
30834
|
}
|
|
30477
|
-
await (0,
|
|
30835
|
+
await (0, import_promises6.rm)(tempDir, { recursive: true, force: true });
|
|
30478
30836
|
}
|
|
30479
30837
|
});
|
|
30480
30838
|
}
|
|
@@ -31366,7 +31724,7 @@ Examples:
|
|
|
31366
31724
|
|
|
31367
31725
|
// src/cli/commands/monitors.ts
|
|
31368
31726
|
var import_node_fs14 = require("fs");
|
|
31369
|
-
var
|
|
31727
|
+
var import_promises7 = require("readline/promises");
|
|
31370
31728
|
var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
|
|
31371
31729
|
function withJsonOption(command) {
|
|
31372
31730
|
return command.option("--json", JSON_OPTION_DESCRIPTION);
|
|
@@ -32135,7 +32493,7 @@ async function handleMonitorsValidate(key, options) {
|
|
|
32135
32493
|
if (result.valid === false) process.exitCode = 7;
|
|
32136
32494
|
}
|
|
32137
32495
|
async function confirmMonitorDelete(key, options) {
|
|
32138
|
-
const rl = (0,
|
|
32496
|
+
const rl = (0, import_promises7.createInterface)({
|
|
32139
32497
|
input: process.stdin,
|
|
32140
32498
|
output: process.stderr
|
|
32141
32499
|
});
|
|
@@ -36156,7 +36514,7 @@ Examples:
|
|
|
36156
36514
|
}
|
|
36157
36515
|
|
|
36158
36516
|
// src/cli/commands/workflow.ts
|
|
36159
|
-
var
|
|
36517
|
+
var import_promises8 = require("fs/promises");
|
|
36160
36518
|
var import_node_path20 = require("path");
|
|
36161
36519
|
|
|
36162
36520
|
// src/cli/workflow-to-play.ts
|
|
@@ -36366,7 +36724,7 @@ function readStatus(payload) {
|
|
|
36366
36724
|
}
|
|
36367
36725
|
async function readJsonOption(payload, file) {
|
|
36368
36726
|
if (file) {
|
|
36369
|
-
const raw = await (0,
|
|
36727
|
+
const raw = await (0, import_promises8.readFile)((0, import_node_path20.resolve)(file), "utf8");
|
|
36370
36728
|
return JSON.parse(raw);
|
|
36371
36729
|
}
|
|
36372
36730
|
if (payload) {
|
|
@@ -36401,8 +36759,8 @@ async function transformOne(api, workflowId, outDir, publish) {
|
|
|
36401
36759
|
{ workflowName: workflow.name, version: revision.version }
|
|
36402
36760
|
);
|
|
36403
36761
|
const file = (0, import_node_path20.join)((0, import_node_path20.resolve)(outDir), `${compiled.playName}.play.ts`);
|
|
36404
|
-
await (0,
|
|
36405
|
-
await (0,
|
|
36762
|
+
await (0, import_promises8.mkdir)((0, import_node_path20.dirname)(file), { recursive: true });
|
|
36763
|
+
await (0, import_promises8.writeFile)(file, compiled.sourceCode, "utf8");
|
|
36406
36764
|
let published = false;
|
|
36407
36765
|
if (publish) {
|
|
36408
36766
|
const code = await handlePlayPublish([file]);
|
|
@@ -40477,10 +40835,10 @@ function topLevelCommandKnown(program, commandName) {
|
|
|
40477
40835
|
);
|
|
40478
40836
|
}
|
|
40479
40837
|
async function runPlayRunnerHealthCheck() {
|
|
40480
|
-
const dir = await (0,
|
|
40838
|
+
const dir = await (0, import_promises9.mkdtemp)((0, import_node_path26.join)((0, import_node_os19.tmpdir)(), "deepline-health-play-"));
|
|
40481
40839
|
const file = (0, import_node_path26.join)(dir, "health-check.play.ts");
|
|
40482
40840
|
try {
|
|
40483
|
-
await (0,
|
|
40841
|
+
await (0, import_promises9.writeFile)(
|
|
40484
40842
|
file,
|
|
40485
40843
|
[
|
|
40486
40844
|
"import { definePlay } from 'deepline';",
|
|
@@ -40529,7 +40887,7 @@ async function runPlayRunnerHealthCheck() {
|
|
|
40529
40887
|
}
|
|
40530
40888
|
};
|
|
40531
40889
|
} finally {
|
|
40532
|
-
await (0,
|
|
40890
|
+
await (0, import_promises9.rm)(dir, { recursive: true, force: true });
|
|
40533
40891
|
}
|
|
40534
40892
|
}
|
|
40535
40893
|
function pickString(value, ...keys) {
|