deepline 0.2.55 → 0.2.57
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/plays/docflow.ts +113 -14
- package/dist/bundling-sources/shared_libs/plays/play-exports.ts +53 -4
- 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 +429 -54
- package/dist/cli/index.mjs +409 -28
- package/dist/{compiler-manifest-Bl8kmLx9.d.mts → compiler-manifest-TgaC4DeD.d.mts} +13 -0
- package/dist/{compiler-manifest-Bl8kmLx9.d.ts → compiler-manifest-TgaC4DeD.d.ts} +13 -0
- package/dist/index.d.mts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +29 -2
- package/dist/index.mjs +29 -2
- package/dist/install-integrity.json +2 -2
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/plays/bundle-play-file.mjs +78 -18
- 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.57",
|
|
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
|
|
|
@@ -16617,6 +16645,12 @@ function isDefinePlayCall(node) {
|
|
|
16617
16645
|
}
|
|
16618
16646
|
return false;
|
|
16619
16647
|
}
|
|
16648
|
+
function definePlayName(node) {
|
|
16649
|
+
const expression = unwrapStaticExpression(node);
|
|
16650
|
+
if (!expression || expression.type !== "CallExpression") return null;
|
|
16651
|
+
const first = astArray(expression.arguments)[0] ?? null;
|
|
16652
|
+
return first?.type === "Literal" && typeof first.value === "string" ? first.value : null;
|
|
16653
|
+
}
|
|
16620
16654
|
function listPlayFileExports(sourceCode) {
|
|
16621
16655
|
const ast = parsePlaySourceForAnalysis(sourceCode);
|
|
16622
16656
|
if (!ast) return null;
|
|
@@ -16666,13 +16700,24 @@ function listPlayFileExports(sourceCode) {
|
|
|
16666
16700
|
if (defaultIsPlay) {
|
|
16667
16701
|
const aliases = defaultLocalName ? [...namedExports.entries()].filter(([, local]) => local === defaultLocalName).map(([exported]) => exported) : [];
|
|
16668
16702
|
if (defaultLocalName) aliasedLocals.add(defaultLocalName);
|
|
16669
|
-
exports2.push({
|
|
16703
|
+
exports2.push({
|
|
16704
|
+
name: PLAY_DEFAULT_EXPORT,
|
|
16705
|
+
aliases,
|
|
16706
|
+
playName: definePlayName(
|
|
16707
|
+
defaultLocalName ? declarations.get(defaultLocalName) ?? null : defaultExpression
|
|
16708
|
+
)
|
|
16709
|
+
});
|
|
16670
16710
|
}
|
|
16671
16711
|
for (const [exportedName, localName] of namedExports) {
|
|
16672
16712
|
if (exportedName === PLAY_DEFAULT_EXPORT) continue;
|
|
16673
16713
|
if (aliasedLocals.has(localName)) continue;
|
|
16674
|
-
|
|
16675
|
-
|
|
16714
|
+
const declaration = declarations.get(localName) ?? null;
|
|
16715
|
+
if (!isDefinePlayCall(declaration)) continue;
|
|
16716
|
+
exports2.push({
|
|
16717
|
+
name: exportedName,
|
|
16718
|
+
aliases: [],
|
|
16719
|
+
playName: definePlayName(declaration)
|
|
16720
|
+
});
|
|
16676
16721
|
}
|
|
16677
16722
|
return exports2;
|
|
16678
16723
|
}
|
|
@@ -17577,6 +17622,31 @@ ${hint}`;
|
|
|
17577
17622
|
});
|
|
17578
17623
|
}
|
|
17579
17624
|
|
|
17625
|
+
// ../shared_libs/play-runtime/governor/policy.ts
|
|
17626
|
+
var DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS = 64;
|
|
17627
|
+
var MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS = 256;
|
|
17628
|
+
var MAX_CONFIGURABLE_CONCURRENT_ROWS = 1e3;
|
|
17629
|
+
function resolveMaxConcurrentExternalCalls(requested) {
|
|
17630
|
+
if (requested === void 0 || requested === null) {
|
|
17631
|
+
return DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS;
|
|
17632
|
+
}
|
|
17633
|
+
if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS) {
|
|
17634
|
+
throw new Error(
|
|
17635
|
+
`maxConcurrentExternalCalls must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.`
|
|
17636
|
+
);
|
|
17637
|
+
}
|
|
17638
|
+
return requested;
|
|
17639
|
+
}
|
|
17640
|
+
function resolveMaxConcurrentRows(requested) {
|
|
17641
|
+
if (requested === void 0 || requested === null) return null;
|
|
17642
|
+
if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_ROWS) {
|
|
17643
|
+
throw new Error(
|
|
17644
|
+
`maxConcurrentRows must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_ROWS}.`
|
|
17645
|
+
);
|
|
17646
|
+
}
|
|
17647
|
+
return requested;
|
|
17648
|
+
}
|
|
17649
|
+
|
|
17580
17650
|
// ../shared_libs/play-runtime/sandbox-runtime-limits.ts
|
|
17581
17651
|
var PLAY_SANDBOX_SIZE_LIMITS = {
|
|
17582
17652
|
standard: {
|
|
@@ -17801,6 +17871,7 @@ function stripLeadingTimestamp(line) {
|
|
|
17801
17871
|
// ../shared_libs/play-runtime/fixture-behavior.ts
|
|
17802
17872
|
var FIXTURE_BEHAVIOR_VERSION = 1;
|
|
17803
17873
|
var FIXTURE_BEHAVIOR_RESPONSE_VERSION = 2;
|
|
17874
|
+
var FIXTURE_BEHAVIOR_REPLAY_VERSION = 3;
|
|
17804
17875
|
var MAX_FIXTURE_RESPONSE_DELAY_SAMPLES = 256;
|
|
17805
17876
|
var MAX_FIXTURE_RESPONSE_DELAY_MS = 8 * 6e4;
|
|
17806
17877
|
var MAX_FIXTURE_RESPONSE_ERROR_MESSAGE_LENGTH = 500;
|
|
@@ -17812,7 +17883,11 @@ function validateFixtureBehavior(value) {
|
|
|
17812
17883
|
return { ok: false, error: "fixtureBehavior must be a JSON object." };
|
|
17813
17884
|
}
|
|
17814
17885
|
const record = value;
|
|
17815
|
-
const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION
|
|
17886
|
+
const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
|
|
17887
|
+
"version",
|
|
17888
|
+
"responseSamples",
|
|
17889
|
+
...record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
|
|
17890
|
+
]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
|
|
17816
17891
|
const unknownKeys = Object.keys(record).filter(
|
|
17817
17892
|
(key) => !supportedKeys.has(key)
|
|
17818
17893
|
);
|
|
@@ -17822,13 +17897,13 @@ function validateFixtureBehavior(value) {
|
|
|
17822
17897
|
error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
|
|
17823
17898
|
};
|
|
17824
17899
|
}
|
|
17825
|
-
if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
|
|
17900
|
+
if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17826
17901
|
return {
|
|
17827
17902
|
ok: false,
|
|
17828
|
-
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}.`
|
|
17903
|
+
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
|
|
17829
17904
|
};
|
|
17830
17905
|
}
|
|
17831
|
-
if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
|
|
17906
|
+
if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17832
17907
|
if (!Array.isArray(record.responseSamples) || record.responseSamples.length === 0 || record.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
17833
17908
|
return {
|
|
17834
17909
|
ok: false,
|
|
@@ -17935,6 +18010,72 @@ function validateFixtureBehavior(value) {
|
|
|
17935
18010
|
...httpError ? { httpError } : {}
|
|
17936
18011
|
});
|
|
17937
18012
|
}
|
|
18013
|
+
let replayBundle;
|
|
18014
|
+
if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18015
|
+
if (!record.replayBundle || typeof record.replayBundle !== "object" || Array.isArray(record.replayBundle)) {
|
|
18016
|
+
return {
|
|
18017
|
+
ok: false,
|
|
18018
|
+
error: "fixtureBehavior.replayBundle must be an object."
|
|
18019
|
+
};
|
|
18020
|
+
}
|
|
18021
|
+
const replay = record.replayBundle;
|
|
18022
|
+
const replayUnknownKeys = Object.keys(replay).filter(
|
|
18023
|
+
(key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
|
|
18024
|
+
);
|
|
18025
|
+
if (replayUnknownKeys.length > 0) {
|
|
18026
|
+
return {
|
|
18027
|
+
ok: false,
|
|
18028
|
+
error: `Unsupported fixtureBehavior.replayBundle field "${replayUnknownKeys[0]}".`
|
|
18029
|
+
};
|
|
18030
|
+
}
|
|
18031
|
+
const digestPattern = /^[a-f0-9]{64}$/;
|
|
18032
|
+
if (typeof replay.bundleId !== "string" || !digestPattern.test(replay.bundleId)) {
|
|
18033
|
+
return {
|
|
18034
|
+
ok: false,
|
|
18035
|
+
error: "fixtureBehavior.replayBundle.bundleId must be a lowercase SHA-256 digest."
|
|
18036
|
+
};
|
|
18037
|
+
}
|
|
18038
|
+
if (typeof replay.manifestSha256 !== "string" || !digestPattern.test(replay.manifestSha256)) {
|
|
18039
|
+
return {
|
|
18040
|
+
ok: false,
|
|
18041
|
+
error: "fixtureBehavior.replayBundle.manifestSha256 must be a lowercase SHA-256 digest."
|
|
18042
|
+
};
|
|
18043
|
+
}
|
|
18044
|
+
let syntheticFallbackToolIds;
|
|
18045
|
+
if (replay.syntheticFallbackToolIds !== void 0) {
|
|
18046
|
+
if (!Array.isArray(replay.syntheticFallbackToolIds) || replay.syntheticFallbackToolIds.length === 0 || replay.syntheticFallbackToolIds.length > 32) {
|
|
18047
|
+
return {
|
|
18048
|
+
ok: false,
|
|
18049
|
+
error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds must contain 1-32 tool ids."
|
|
18050
|
+
};
|
|
18051
|
+
}
|
|
18052
|
+
syntheticFallbackToolIds = [];
|
|
18053
|
+
for (const rawToolId of replay.syntheticFallbackToolIds) {
|
|
18054
|
+
if (typeof rawToolId !== "string" || rawToolId !== rawToolId.trim().toLowerCase() || !/^[a-z0-9][a-z0-9_.-]*$/.test(rawToolId) || rawToolId.length > 250 || syntheticFallbackToolIds.includes(rawToolId)) {
|
|
18055
|
+
return {
|
|
18056
|
+
ok: false,
|
|
18057
|
+
error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds contains an invalid tool id."
|
|
18058
|
+
};
|
|
18059
|
+
}
|
|
18060
|
+
syntheticFallbackToolIds.push(rawToolId);
|
|
18061
|
+
}
|
|
18062
|
+
}
|
|
18063
|
+
replayBundle = {
|
|
18064
|
+
bundleId: replay.bundleId,
|
|
18065
|
+
manifestSha256: replay.manifestSha256,
|
|
18066
|
+
...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
|
|
18067
|
+
};
|
|
18068
|
+
}
|
|
18069
|
+
if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18070
|
+
return {
|
|
18071
|
+
ok: true,
|
|
18072
|
+
behavior: {
|
|
18073
|
+
version: FIXTURE_BEHAVIOR_REPLAY_VERSION,
|
|
18074
|
+
responseSamples: samples2,
|
|
18075
|
+
replayBundle
|
|
18076
|
+
}
|
|
18077
|
+
};
|
|
18078
|
+
}
|
|
17938
18079
|
return {
|
|
17939
18080
|
ok: true,
|
|
17940
18081
|
behavior: {
|
|
@@ -18027,6 +18168,114 @@ var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
18027
18168
|
"--debug-map-latency",
|
|
18028
18169
|
"--debug-fixture-provider-pacing"
|
|
18029
18170
|
]);
|
|
18171
|
+
async function pathExistsIncludingSymlink(path) {
|
|
18172
|
+
try {
|
|
18173
|
+
await (0, import_promises5.lstat)(path);
|
|
18174
|
+
return true;
|
|
18175
|
+
} catch (error) {
|
|
18176
|
+
if (error.code === "ENOENT") {
|
|
18177
|
+
return false;
|
|
18178
|
+
}
|
|
18179
|
+
throw error;
|
|
18180
|
+
}
|
|
18181
|
+
}
|
|
18182
|
+
function runIdFileTempPath(destination) {
|
|
18183
|
+
return (0, import_node_path14.join)(
|
|
18184
|
+
(0, import_node_path14.dirname)(destination),
|
|
18185
|
+
`.${(0, import_node_path14.basename)(destination)}.${process.pid}.${(0, import_node_crypto6.randomUUID)()}.tmp`
|
|
18186
|
+
);
|
|
18187
|
+
}
|
|
18188
|
+
async function removeRunIdTempFile(path) {
|
|
18189
|
+
try {
|
|
18190
|
+
await (0, import_promises5.unlink)(path);
|
|
18191
|
+
} catch (error) {
|
|
18192
|
+
if (error.code !== "ENOENT") {
|
|
18193
|
+
throw error;
|
|
18194
|
+
}
|
|
18195
|
+
}
|
|
18196
|
+
}
|
|
18197
|
+
async function preflightRunIdFile(path) {
|
|
18198
|
+
const destination = (0, import_node_path14.resolve)(path);
|
|
18199
|
+
if (await pathExistsIncludingSymlink(destination)) {
|
|
18200
|
+
throw new Error(
|
|
18201
|
+
`--run-id-file destination already exists: ${destination}. Choose a new path so this run cannot overwrite another run identity.`
|
|
18202
|
+
);
|
|
18203
|
+
}
|
|
18204
|
+
const tempPath = runIdFileTempPath(destination);
|
|
18205
|
+
let handle = null;
|
|
18206
|
+
try {
|
|
18207
|
+
handle = await (0, import_promises5.open)(tempPath, "wx", 384);
|
|
18208
|
+
await handle.sync();
|
|
18209
|
+
} catch (error) {
|
|
18210
|
+
throw new Error(
|
|
18211
|
+
`Cannot write --run-id-file destination ${destination}: ${error instanceof Error ? error.message : String(error)}`
|
|
18212
|
+
);
|
|
18213
|
+
} finally {
|
|
18214
|
+
await handle?.close();
|
|
18215
|
+
await removeRunIdTempFile(tempPath);
|
|
18216
|
+
}
|
|
18217
|
+
return destination;
|
|
18218
|
+
}
|
|
18219
|
+
async function readRunIdFile(destination) {
|
|
18220
|
+
if (!await pathExistsIncludingSymlink(destination)) {
|
|
18221
|
+
return null;
|
|
18222
|
+
}
|
|
18223
|
+
let parsed;
|
|
18224
|
+
try {
|
|
18225
|
+
parsed = JSON.parse(await (0, import_promises5.readFile)(destination, "utf8"));
|
|
18226
|
+
} catch (error) {
|
|
18227
|
+
throw new Error(
|
|
18228
|
+
`--run-id-file destination contains invalid JSON: ${destination}. Refusing to overwrite it (${error instanceof Error ? error.message : String(error)}).`
|
|
18229
|
+
);
|
|
18230
|
+
}
|
|
18231
|
+
if (!parsed || typeof parsed !== "object" || parsed.version !== 1 || typeof parsed.runId !== "string" || !parsed.runId) {
|
|
18232
|
+
throw new Error(
|
|
18233
|
+
`--run-id-file destination has an unsupported identity record: ${destination}. Refusing to overwrite it.`
|
|
18234
|
+
);
|
|
18235
|
+
}
|
|
18236
|
+
return parsed;
|
|
18237
|
+
}
|
|
18238
|
+
async function writePlayRunIdFile(destination, runId) {
|
|
18239
|
+
const existing = await readRunIdFile(destination);
|
|
18240
|
+
if (existing) {
|
|
18241
|
+
if (existing.runId === runId) return;
|
|
18242
|
+
throw new Error(
|
|
18243
|
+
`--run-id-file destination already records run ${existing.runId}; refusing to replace it with ${runId}: ${destination}`
|
|
18244
|
+
);
|
|
18245
|
+
}
|
|
18246
|
+
const tempPath = runIdFileTempPath(destination);
|
|
18247
|
+
let handle = null;
|
|
18248
|
+
try {
|
|
18249
|
+
handle = await (0, import_promises5.open)(tempPath, "wx", 384);
|
|
18250
|
+
await handle.writeFile(
|
|
18251
|
+
`${JSON.stringify({ version: 1, runId })}
|
|
18252
|
+
`,
|
|
18253
|
+
"utf8"
|
|
18254
|
+
);
|
|
18255
|
+
await handle.sync();
|
|
18256
|
+
await handle.close();
|
|
18257
|
+
handle = null;
|
|
18258
|
+
try {
|
|
18259
|
+
await (0, import_promises5.link)(tempPath, destination);
|
|
18260
|
+
const directory = await (0, import_promises5.open)((0, import_node_path14.dirname)(destination), "r");
|
|
18261
|
+
try {
|
|
18262
|
+
await directory.sync();
|
|
18263
|
+
} finally {
|
|
18264
|
+
await directory.close();
|
|
18265
|
+
}
|
|
18266
|
+
} catch (error) {
|
|
18267
|
+
if (error.code !== "EEXIST") throw error;
|
|
18268
|
+
const raced = await readRunIdFile(destination);
|
|
18269
|
+
if (raced?.runId === runId) return;
|
|
18270
|
+
throw new Error(
|
|
18271
|
+
`--run-id-file destination already records run ${raced?.runId ?? "<invalid>"}; refusing to replace it with ${runId}: ${destination}`
|
|
18272
|
+
);
|
|
18273
|
+
}
|
|
18274
|
+
} finally {
|
|
18275
|
+
await handle?.close();
|
|
18276
|
+
await removeRunIdTempFile(tempPath);
|
|
18277
|
+
}
|
|
18278
|
+
}
|
|
18030
18279
|
function traceCliSync(phase, fields, run) {
|
|
18031
18280
|
const startedAt = Date.now();
|
|
18032
18281
|
try {
|
|
@@ -19431,8 +19680,8 @@ function buildPlayDashboardUrl(baseUrl, playName) {
|
|
|
19431
19680
|
const encodedPlayName = encodeURIComponent(playName);
|
|
19432
19681
|
return `${trimmedBase}/dashboard/plays/${encodedPlayName}`;
|
|
19433
19682
|
}
|
|
19434
|
-
function openPlayDashboard(dashboardUrl,
|
|
19435
|
-
if (
|
|
19683
|
+
function openPlayDashboard(dashboardUrl, open2) {
|
|
19684
|
+
if (open2 && dashboardUrl) {
|
|
19436
19685
|
openInBrowser(dashboardUrl);
|
|
19437
19686
|
}
|
|
19438
19687
|
}
|
|
@@ -19468,9 +19717,11 @@ function assertPlayWaitNotTimedOut(input2) {
|
|
|
19468
19717
|
);
|
|
19469
19718
|
}
|
|
19470
19719
|
}
|
|
19720
|
+
var PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS = 15e3;
|
|
19471
19721
|
async function waitForPlayCompletionByStream(input2) {
|
|
19472
19722
|
let lastPhase = null;
|
|
19473
19723
|
let reconnectAttempt = 0;
|
|
19724
|
+
let nextDurableProbeAt = Date.now() + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
|
|
19474
19725
|
const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
|
|
19475
19726
|
const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
|
|
19476
19727
|
const fetchTerminalStatus = async () => {
|
|
@@ -19489,6 +19740,14 @@ async function waitForPlayCompletionByStream(input2) {
|
|
|
19489
19740
|
};
|
|
19490
19741
|
const handleLiveEvent = async (event) => {
|
|
19491
19742
|
assertPlayWaitNotTimedOut({ ...input2, lastPhase });
|
|
19743
|
+
const now = Date.now();
|
|
19744
|
+
if (now >= nextDurableProbeAt) {
|
|
19745
|
+
nextDurableProbeAt = now + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
|
|
19746
|
+
const durableTerminal = await fetchTerminalStatus();
|
|
19747
|
+
if (durableTerminal) {
|
|
19748
|
+
return durableTerminal;
|
|
19749
|
+
}
|
|
19750
|
+
}
|
|
19492
19751
|
const phase = describeLiveEventPhase(event);
|
|
19493
19752
|
if (phase) {
|
|
19494
19753
|
lastPhase = phase;
|
|
@@ -19737,7 +19996,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
19737
19996
|
lastKnownWorkflowId = eventRunId;
|
|
19738
19997
|
firstRunIdMs ??= Date.now() - startedAt;
|
|
19739
19998
|
if (runStartedNow) {
|
|
19740
|
-
input2.onRunStarted?.(eventRunId);
|
|
19999
|
+
await input2.onRunStarted?.(eventRunId);
|
|
19741
20000
|
}
|
|
19742
20001
|
}
|
|
19743
20002
|
if (eventConfirmsPlayRunLaunch(event) && eventRunId === lastKnownWorkflowId) {
|
|
@@ -21016,6 +21275,15 @@ function buildOrdinaryPlayRunCommand(options, resolvedRevisionId) {
|
|
|
21016
21275
|
}
|
|
21017
21276
|
if (options.profile)
|
|
21018
21277
|
parts.push("--profile", shellSingleQuote(options.profile));
|
|
21278
|
+
if (options.maxConcurrentExternalCalls !== null) {
|
|
21279
|
+
parts.push(
|
|
21280
|
+
"--max-concurrent-external-calls",
|
|
21281
|
+
String(options.maxConcurrentExternalCalls)
|
|
21282
|
+
);
|
|
21283
|
+
}
|
|
21284
|
+
if (options.maxConcurrentRows !== null) {
|
|
21285
|
+
parts.push("--max-concurrent-rows", String(options.maxConcurrentRows));
|
|
21286
|
+
}
|
|
21019
21287
|
const pinnedRevisionId = options.target.kind === "name" ? resolvedRevisionId ?? options.revisionId : null;
|
|
21020
21288
|
if (pinnedRevisionId) {
|
|
21021
21289
|
parts.push("--revision-id", shellSingleQuote(pinnedRevisionId));
|
|
@@ -21885,7 +22153,7 @@ function writeStartedPlayRun(input2) {
|
|
|
21885
22153
|
);
|
|
21886
22154
|
}
|
|
21887
22155
|
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.";
|
|
22156
|
+
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
22157
|
let filePath = null;
|
|
21890
22158
|
let playName = null;
|
|
21891
22159
|
let input2 = null;
|
|
@@ -21896,15 +22164,18 @@ function parsePlayRunOptions(args) {
|
|
|
21896
22164
|
const fullJson = args.includes("--full");
|
|
21897
22165
|
const emitLogs = !jsonOutput || args.includes("--logs");
|
|
21898
22166
|
const force = args.includes("--force");
|
|
21899
|
-
const
|
|
22167
|
+
const open2 = args.includes("--open");
|
|
21900
22168
|
const debugMapLatency = args.includes("--debug-map-latency");
|
|
21901
22169
|
const debugFixtureProviderPacing = args.includes(
|
|
21902
22170
|
"--debug-fixture-provider-pacing"
|
|
21903
22171
|
);
|
|
21904
22172
|
const verboseLogs = args.includes("--logs") || debugMapLatency;
|
|
21905
22173
|
let waitTimeoutMs = null;
|
|
22174
|
+
let maxConcurrentExternalCalls = null;
|
|
22175
|
+
let maxConcurrentRows = null;
|
|
21906
22176
|
let profile = null;
|
|
21907
22177
|
let fixtureBehavior = null;
|
|
22178
|
+
let runIdFile = null;
|
|
21908
22179
|
for (let index = 0; index < args.length; index += 1) {
|
|
21909
22180
|
const arg = args[index];
|
|
21910
22181
|
if (arg === "--file" && args[index + 1]) {
|
|
@@ -21919,6 +22190,23 @@ function parsePlayRunOptions(args) {
|
|
|
21919
22190
|
input2 = parseJsonInput(args[++index]);
|
|
21920
22191
|
continue;
|
|
21921
22192
|
}
|
|
22193
|
+
if (arg === "--run-id-file") {
|
|
22194
|
+
const value = args[index + 1];
|
|
22195
|
+
if (!value || value.startsWith("--")) {
|
|
22196
|
+
throw new Error("--run-id-file requires a destination path.");
|
|
22197
|
+
}
|
|
22198
|
+
runIdFile = value;
|
|
22199
|
+
index += 1;
|
|
22200
|
+
continue;
|
|
22201
|
+
}
|
|
22202
|
+
if (arg.startsWith("--run-id-file=")) {
|
|
22203
|
+
const value = arg.slice("--run-id-file=".length);
|
|
22204
|
+
if (!value) {
|
|
22205
|
+
throw new Error("--run-id-file requires a destination path.");
|
|
22206
|
+
}
|
|
22207
|
+
runIdFile = value;
|
|
22208
|
+
continue;
|
|
22209
|
+
}
|
|
21922
22210
|
if (arg === "--revision-id" && args[index + 1]) {
|
|
21923
22211
|
revisionId = args[++index];
|
|
21924
22212
|
continue;
|
|
@@ -21933,6 +22221,41 @@ function parsePlayRunOptions(args) {
|
|
|
21933
22221
|
index += 1;
|
|
21934
22222
|
continue;
|
|
21935
22223
|
}
|
|
22224
|
+
if (arg === "--max-concurrent-external-calls") {
|
|
22225
|
+
const value = args[index + 1];
|
|
22226
|
+
if (!value || value.startsWith("--")) {
|
|
22227
|
+
throw new Error(
|
|
22228
|
+
"--max-concurrent-external-calls requires a whole number."
|
|
22229
|
+
);
|
|
22230
|
+
}
|
|
22231
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
22232
|
+
throw new Error(
|
|
22233
|
+
"--max-concurrent-external-calls requires a positive whole number."
|
|
22234
|
+
);
|
|
22235
|
+
}
|
|
22236
|
+
maxConcurrentExternalCalls = parsePositiveInteger3(
|
|
22237
|
+
value,
|
|
22238
|
+
"--max-concurrent-external-calls"
|
|
22239
|
+
);
|
|
22240
|
+
resolveMaxConcurrentExternalCalls(maxConcurrentExternalCalls);
|
|
22241
|
+
index += 1;
|
|
22242
|
+
continue;
|
|
22243
|
+
}
|
|
22244
|
+
if (arg === "--max-concurrent-rows") {
|
|
22245
|
+
const value = args[index + 1];
|
|
22246
|
+
if (!value || value.startsWith("--")) {
|
|
22247
|
+
throw new Error("--max-concurrent-rows requires a whole number.");
|
|
22248
|
+
}
|
|
22249
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
22250
|
+
throw new Error(
|
|
22251
|
+
"--max-concurrent-rows requires a positive whole number."
|
|
22252
|
+
);
|
|
22253
|
+
}
|
|
22254
|
+
maxConcurrentRows = parsePositiveInteger3(value, "--max-concurrent-rows");
|
|
22255
|
+
resolveMaxConcurrentRows(maxConcurrentRows);
|
|
22256
|
+
index += 1;
|
|
22257
|
+
continue;
|
|
22258
|
+
}
|
|
21936
22259
|
if (arg === "--fixture-behavior") {
|
|
21937
22260
|
const value = args[index + 1];
|
|
21938
22261
|
if (!value) {
|
|
@@ -22043,11 +22366,14 @@ function parsePlayRunOptions(args) {
|
|
|
22043
22366
|
fullJson,
|
|
22044
22367
|
waitTimeoutMs,
|
|
22045
22368
|
force,
|
|
22046
|
-
|
|
22369
|
+
maxConcurrentExternalCalls,
|
|
22370
|
+
maxConcurrentRows,
|
|
22371
|
+
open: open2,
|
|
22047
22372
|
profile,
|
|
22048
22373
|
debugMapLatency,
|
|
22049
22374
|
debugFixtureProviderPacing,
|
|
22050
|
-
fixtureBehavior
|
|
22375
|
+
fixtureBehavior,
|
|
22376
|
+
runIdFile
|
|
22051
22377
|
};
|
|
22052
22378
|
}
|
|
22053
22379
|
function parsePlayCheckOptions(args) {
|
|
@@ -22730,6 +23056,8 @@ async function handleFileBackedRun(options, hooks) {
|
|
|
22730
23056
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
22731
23057
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
22732
23058
|
...options.force ? { force: true } : {},
|
|
23059
|
+
...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
|
|
23060
|
+
...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
|
|
22733
23061
|
...options.profile ? { profile: options.profile } : {},
|
|
22734
23062
|
...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
|
|
22735
23063
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -22790,6 +23118,7 @@ async function handleFileBackedRun(options, hooks) {
|
|
|
22790
23118
|
throw await normalizePlayStartError(client2, error, playName);
|
|
22791
23119
|
})
|
|
22792
23120
|
);
|
|
23121
|
+
await hooks?.onRunStarted?.(started.workflowId);
|
|
22793
23122
|
const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
|
|
22794
23123
|
openPlayDashboard(resolvedDashboardUrl, options.open);
|
|
22795
23124
|
progress.phase("started run");
|
|
@@ -22910,6 +23239,8 @@ async function handleNamedRun(options, hooks) {
|
|
|
22910
23239
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
22911
23240
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
22912
23241
|
...options.force ? { force: true } : {},
|
|
23242
|
+
...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
|
|
23243
|
+
...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
|
|
22913
23244
|
...options.profile ? { profile: options.profile } : {},
|
|
22914
23245
|
...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
|
|
22915
23246
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -22975,6 +23306,7 @@ async function handleNamedRun(options, hooks) {
|
|
|
22975
23306
|
});
|
|
22976
23307
|
})
|
|
22977
23308
|
);
|
|
23309
|
+
await hooks?.onRunStarted?.(started.workflowId);
|
|
22978
23310
|
const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
|
|
22979
23311
|
openPlayDashboard(resolvedDashboardUrl, options.open);
|
|
22980
23312
|
progress.phase("started run");
|
|
@@ -22991,10 +23323,28 @@ async function handleNamedRun(options, hooks) {
|
|
|
22991
23323
|
return 0;
|
|
22992
23324
|
}
|
|
22993
23325
|
async function handlePlayRun(args, hooks) {
|
|
22994
|
-
const
|
|
23326
|
+
const parsedOptions = parsePlayRunOptions(args);
|
|
23327
|
+
const options = parsedOptions.runIdFile ? {
|
|
23328
|
+
...parsedOptions,
|
|
23329
|
+
runIdFile: await preflightRunIdFile(parsedOptions.runIdFile)
|
|
23330
|
+
} : parsedOptions;
|
|
23331
|
+
const runHooks = options.runIdFile ? {
|
|
23332
|
+
...hooks,
|
|
23333
|
+
onRunStarted: async (runId) => {
|
|
23334
|
+
try {
|
|
23335
|
+
await writePlayRunIdFile(options.runIdFile, runId);
|
|
23336
|
+
} catch (error) {
|
|
23337
|
+
throw new Error(
|
|
23338
|
+
`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.`,
|
|
23339
|
+
{ cause: error }
|
|
23340
|
+
);
|
|
23341
|
+
}
|
|
23342
|
+
await hooks?.onRunStarted?.(runId);
|
|
23343
|
+
}
|
|
23344
|
+
} : hooks;
|
|
22995
23345
|
if (options.target.kind === "file") {
|
|
22996
23346
|
if (isFileTarget(options.target.path)) {
|
|
22997
|
-
return handleFileBackedRun(options,
|
|
23347
|
+
return handleFileBackedRun(options, runHooks);
|
|
22998
23348
|
}
|
|
22999
23349
|
const resolved = (0, import_node_path14.resolve)(options.target.path);
|
|
23000
23350
|
console.error(`File not found: ${resolved}`);
|
|
@@ -23016,7 +23366,7 @@ async function handlePlayRun(args, hooks) {
|
|
|
23016
23366
|
}
|
|
23017
23367
|
return 1;
|
|
23018
23368
|
}
|
|
23019
|
-
return handleNamedRun(options,
|
|
23369
|
+
return handleNamedRun(options, runHooks);
|
|
23020
23370
|
}
|
|
23021
23371
|
function parseRunIdPositional(args, usage) {
|
|
23022
23372
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -24344,10 +24694,18 @@ Notes:
|
|
|
24344
24694
|
next commands. --watch and --wait are accepted compatibility aliases for the
|
|
24345
24695
|
default behavior. Use --no-wait only when you intentionally want
|
|
24346
24696
|
a fire-and-forget run id.
|
|
24697
|
+
--run-id-file writes the durable run id to a versioned JSON file as soon as
|
|
24698
|
+
the server accepts the run. The destination must not already exist.
|
|
24347
24699
|
The play page URL is printed when the run starts. Pass --open to open it in a browser.
|
|
24348
24700
|
Concurrent runs for the same play are allowed.
|
|
24349
24701
|
--force starts a fresh run graph without refreshing completed provider calls.
|
|
24350
24702
|
It does not cancel active sibling runs.
|
|
24703
|
+
--max-concurrent-external-calls controls the per-run provider-tool/ctx.fetch
|
|
24704
|
+
resident-work ceiling. Default: ${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS}; accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.
|
|
24705
|
+
Provider pacing and sandbox memory limits still apply.
|
|
24706
|
+
--max-concurrent-rows sets the run-wide default and ceiling for live map row
|
|
24707
|
+
resolvers. Accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_ROWS}. The runtime
|
|
24708
|
+
may lower it when source-row size exceeds the active-row memory budget.
|
|
24351
24709
|
This command starts cloud work and may spend Deepline credits through tool calls.
|
|
24352
24710
|
|
|
24353
24711
|
Idempotent execution:
|
|
@@ -24383,8 +24741,10 @@ Idempotent execution:
|
|
|
24383
24741
|
Examples:
|
|
24384
24742
|
deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
|
|
24385
24743
|
deepline plays run long-background-play --no-wait
|
|
24744
|
+
deepline plays run long-background-play --run-id-file ./run-id.json
|
|
24386
24745
|
deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
|
|
24387
24746
|
deepline plays run my.play.ts --profile absurd
|
|
24747
|
+
deepline plays run my.play.ts --max-concurrent-external-calls 20
|
|
24388
24748
|
deepline plays run my.play.ts --input @input.json --json
|
|
24389
24749
|
deepline plays run cto-search.play.ts --limit 5
|
|
24390
24750
|
deepline runs export <run-id> --out output.csv
|
|
@@ -24400,9 +24760,18 @@ Examples:
|
|
|
24400
24760
|
"--fixture-behavior <json>",
|
|
24401
24761
|
"Internal/testing: fixture response behavior JSON object or @file path"
|
|
24402
24762
|
).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(
|
|
24763
|
+
"--run-id-file <path>",
|
|
24764
|
+
"Atomically write the accepted run id to a new JSON file"
|
|
24765
|
+
).option(
|
|
24403
24766
|
"--logs",
|
|
24404
24767
|
"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(
|
|
24768
|
+
).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
|
|
24769
|
+
"--max-concurrent-external-calls <count>",
|
|
24770
|
+
`Concurrent provider-tool and ctx.fetch executions (${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS} default, max ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS})`
|
|
24771
|
+
).option(
|
|
24772
|
+
"--max-concurrent-rows <count>",
|
|
24773
|
+
`Run-wide dataset map row resolver ceiling (max ${MAX_CONFIGURABLE_CONCURRENT_ROWS})`
|
|
24774
|
+
).option("--open", "Open the play page in a browser after the run starts").option(
|
|
24406
24775
|
"--debug-map-latency",
|
|
24407
24776
|
"Internal diagnostics: emit one aggregate latency profile per dataset map"
|
|
24408
24777
|
).option(
|
|
@@ -24441,10 +24810,16 @@ Pass-through input flags:
|
|
|
24441
24810
|
...options.profile ? ["--profile", options.profile] : [],
|
|
24442
24811
|
...options.fixtureBehavior ? ["--fixture-behavior", options.fixtureBehavior] : [],
|
|
24443
24812
|
...options.wait === false ? ["--no-wait"] : [],
|
|
24813
|
+
...options.runIdFile ? ["--run-id-file", options.runIdFile] : [],
|
|
24444
24814
|
...options.watch || options.wait ? ["--watch"] : [],
|
|
24445
24815
|
...options.logs ? ["--logs"] : [],
|
|
24446
24816
|
...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
|
|
24447
24817
|
...options.force ? ["--force"] : [],
|
|
24818
|
+
...options.maxConcurrentExternalCalls ? [
|
|
24819
|
+
"--max-concurrent-external-calls",
|
|
24820
|
+
options.maxConcurrentExternalCalls
|
|
24821
|
+
] : [],
|
|
24822
|
+
...options.maxConcurrentRows ? ["--max-concurrent-rows", options.maxConcurrentRows] : [],
|
|
24448
24823
|
...options.open ? ["--open"] : [],
|
|
24449
24824
|
...options.debugMapLatency ? ["--debug-map-latency"] : [],
|
|
24450
24825
|
...options.debugFixtureProviderPacing ? ["--debug-fixture-provider-pacing"] : [],
|
|
@@ -26833,7 +27208,7 @@ async function readAtFileReference(value, argumentName, strip = true) {
|
|
|
26833
27208
|
throw new Error(`Invalid ${argumentName} value: empty @file path.`);
|
|
26834
27209
|
}
|
|
26835
27210
|
try {
|
|
26836
|
-
const text = await (0,
|
|
27211
|
+
const text = await (0, import_promises6.readFile)(filePath, "utf8");
|
|
26837
27212
|
const normalized = text.replace(/^\uFEFF/, "");
|
|
26838
27213
|
return strip ? normalized.trim() : normalized;
|
|
26839
27214
|
} catch (error) {
|
|
@@ -27131,7 +27506,7 @@ async function buildPlanArgs(args) {
|
|
|
27131
27506
|
async function assertInputCsvExists(inputCsv) {
|
|
27132
27507
|
const path = (0, import_node_path15.resolve)(inputCsv);
|
|
27133
27508
|
try {
|
|
27134
|
-
const info = await (0,
|
|
27509
|
+
const info = await (0, import_promises6.stat)(path);
|
|
27135
27510
|
if (info.isFile()) {
|
|
27136
27511
|
return;
|
|
27137
27512
|
}
|
|
@@ -27152,8 +27527,8 @@ async function assertSafeOutputPath(inputCsv, outputPath) {
|
|
|
27152
27527
|
}
|
|
27153
27528
|
try {
|
|
27154
27529
|
const [inputInfo, outputInfo] = await Promise.all([
|
|
27155
|
-
(0,
|
|
27156
|
-
(0,
|
|
27530
|
+
(0, import_promises6.stat)(input2),
|
|
27531
|
+
(0, import_promises6.stat)(output2)
|
|
27157
27532
|
]);
|
|
27158
27533
|
if (inputInfo.dev === outputInfo.dev && inputInfo.ino === outputInfo.ino) {
|
|
27159
27534
|
throw new Error(
|
|
@@ -27173,7 +27548,7 @@ async function assertSafeOutputPath(inputCsv, outputPath) {
|
|
|
27173
27548
|
}
|
|
27174
27549
|
async function regularFileExists(path) {
|
|
27175
27550
|
try {
|
|
27176
|
-
const info = await (0,
|
|
27551
|
+
const info = await (0, import_promises6.stat)((0, import_node_path15.resolve)(path));
|
|
27177
27552
|
return info.isFile();
|
|
27178
27553
|
} catch (error) {
|
|
27179
27554
|
const code = error && typeof error === "object" ? error.code : void 0;
|
|
@@ -27184,7 +27559,7 @@ async function regularFileExists(path) {
|
|
|
27184
27559
|
}
|
|
27185
27560
|
}
|
|
27186
27561
|
async function readConfig(path) {
|
|
27187
|
-
const source = await (0,
|
|
27562
|
+
const source = await (0, import_promises6.readFile)((0, import_node_path15.resolve)(path), "utf8");
|
|
27188
27563
|
let parsed;
|
|
27189
27564
|
try {
|
|
27190
27565
|
parsed = JSON.parse(source);
|
|
@@ -27605,7 +27980,7 @@ async function writeOutputCsv(outputPath, status, options) {
|
|
|
27605
27980
|
]),
|
|
27606
27981
|
options?.config
|
|
27607
27982
|
);
|
|
27608
|
-
await (0,
|
|
27983
|
+
await (0, import_promises6.writeFile)(
|
|
27609
27984
|
(0, import_node_path15.resolve)(outputPath),
|
|
27610
27985
|
csvStringFromRows(merged.rows, columns),
|
|
27611
27986
|
"utf8"
|
|
@@ -29285,7 +29660,7 @@ async function persistEnrichFailureReport(input2) {
|
|
|
29285
29660
|
}
|
|
29286
29661
|
const stateDir = (0, import_node_path15.join)((0, import_node_os10.homedir)(), ".local", "deepline", "runtime", "state");
|
|
29287
29662
|
const reportPrefix = input2.jobs.length > 0 ? "run-block-failures" : "enrich-issues";
|
|
29288
|
-
await (0,
|
|
29663
|
+
await (0, import_promises6.mkdir)(stateDir, { recursive: true });
|
|
29289
29664
|
const reportPath = (0, import_node_path15.join)(
|
|
29290
29665
|
stateDir,
|
|
29291
29666
|
`${reportPrefix}-${Math.floor(Date.now() / 1e3)}-${process.pid}.json`
|
|
@@ -29311,7 +29686,7 @@ async function persistEnrichFailureReport(input2) {
|
|
|
29311
29686
|
if (input2.rows.rowStart !== null && input2.rows.rowEnd !== null) {
|
|
29312
29687
|
report.rows = { start: input2.rows.rowStart, end: input2.rows.rowEnd };
|
|
29313
29688
|
}
|
|
29314
|
-
await (0,
|
|
29689
|
+
await (0, import_promises6.writeFile)(reportPath, `${JSON.stringify(report, null, 2)}
|
|
29315
29690
|
`, "utf8");
|
|
29316
29691
|
return reportPath;
|
|
29317
29692
|
}
|
|
@@ -30214,13 +30589,13 @@ function registerEnrichCommand(program) {
|
|
|
30214
30589
|
sdkEnrichTelemetryCompleted = true;
|
|
30215
30590
|
await completeSdkEnrichTelemetry(sdkEnrichTelemetry, input2);
|
|
30216
30591
|
};
|
|
30217
|
-
const tempDir = await (0,
|
|
30592
|
+
const tempDir = await (0, import_promises6.mkdtemp)((0, import_node_path15.join)((0, import_node_os10.tmpdir)(), "deepline-enrich-play-"));
|
|
30218
30593
|
await emitSdkEnrichTelemetry(sdkEnrichTelemetry, "enrich_started");
|
|
30219
30594
|
const tempPlay = (0, import_node_path15.join)(tempDir, "deepline-enrich.play.ts");
|
|
30220
30595
|
let inPlaceTempDir = null;
|
|
30221
30596
|
let inPlaceTempOutputPath = null;
|
|
30222
30597
|
const inPlaceFinalOutputPath = options.inPlace ? (0, import_node_path15.resolve)(inputCsv) : null;
|
|
30223
|
-
const inPlaceCommitOutputPath = options.inPlace ? (await (0,
|
|
30598
|
+
const inPlaceCommitOutputPath = options.inPlace ? (await (0, import_promises6.lstat)(inputCsv)).isSymbolicLink() ? await (0, import_promises6.realpath)(inputCsv) : inPlaceFinalOutputPath : null;
|
|
30224
30599
|
const failureReportOutputPath = options.inPlace ? inPlaceFinalOutputPath : null;
|
|
30225
30600
|
const enrichIssueFollowUpOutputPath = options.inPlace && inPlaceFinalOutputPath ? sidecarEnrichRowsExportPath(inPlaceFinalOutputPath) : null;
|
|
30226
30601
|
let activeRunId2 = null;
|
|
@@ -30241,16 +30616,16 @@ function registerEnrichCommand(program) {
|
|
|
30241
30616
|
return;
|
|
30242
30617
|
}
|
|
30243
30618
|
if (inPlaceTempDir) {
|
|
30244
|
-
await (0,
|
|
30619
|
+
await (0, import_promises6.rm)(inPlaceTempDir, { recursive: true, force: true });
|
|
30245
30620
|
}
|
|
30246
|
-
inPlaceTempDir = await (0,
|
|
30621
|
+
inPlaceTempDir = await (0, import_promises6.mkdtemp)(
|
|
30247
30622
|
(0, import_node_path15.join)(
|
|
30248
30623
|
(0, import_node_path15.dirname)(inPlaceCommitOutputPath ?? (0, import_node_path15.resolve)(inputCsv)),
|
|
30249
30624
|
".deepline-enrich-in-place-"
|
|
30250
30625
|
)
|
|
30251
30626
|
);
|
|
30252
30627
|
inPlaceTempOutputPath = (0, import_node_path15.join)(inPlaceTempDir, "output.csv");
|
|
30253
|
-
await (0,
|
|
30628
|
+
await (0, import_promises6.copyFile)((0, import_node_path15.resolve)(inputCsv), inPlaceTempOutputPath);
|
|
30254
30629
|
outputPath = inPlaceTempOutputPath;
|
|
30255
30630
|
};
|
|
30256
30631
|
const commitInPlaceOutput = async (exportResult) => {
|
|
@@ -30258,12 +30633,12 @@ function registerEnrichCommand(program) {
|
|
|
30258
30633
|
return exportResult;
|
|
30259
30634
|
}
|
|
30260
30635
|
const committedTempDir = inPlaceTempDir;
|
|
30261
|
-
await (0,
|
|
30636
|
+
await (0, import_promises6.rename)(inPlaceTempOutputPath, inPlaceCommitOutputPath);
|
|
30262
30637
|
inPlaceTempDir = null;
|
|
30263
30638
|
inPlaceTempOutputPath = null;
|
|
30264
30639
|
outputPath = inPlaceFinalOutputPath;
|
|
30265
30640
|
if (committedTempDir) {
|
|
30266
|
-
await (0,
|
|
30641
|
+
await (0, import_promises6.rm)(committedTempDir, { recursive: true, force: true });
|
|
30267
30642
|
}
|
|
30268
30643
|
if (!exportResult) {
|
|
30269
30644
|
return null;
|
|
@@ -30276,7 +30651,7 @@ function registerEnrichCommand(program) {
|
|
|
30276
30651
|
try {
|
|
30277
30652
|
process.once("SIGINT", onSigint);
|
|
30278
30653
|
process.once("SIGTERM", onSigterm);
|
|
30279
|
-
await (0,
|
|
30654
|
+
await (0, import_promises6.writeFile)(tempPlay, playSource, "utf8");
|
|
30280
30655
|
if (options.inPlace) {
|
|
30281
30656
|
await prepareInPlaceOutput();
|
|
30282
30657
|
}
|
|
@@ -30470,11 +30845,11 @@ function registerEnrichCommand(program) {
|
|
|
30470
30845
|
process.removeListener("SIGINT", onSigint);
|
|
30471
30846
|
process.removeListener("SIGTERM", onSigterm);
|
|
30472
30847
|
if (inPlaceTempDir) {
|
|
30473
|
-
await (0,
|
|
30848
|
+
await (0, import_promises6.rm)(inPlaceTempDir, { recursive: true, force: true });
|
|
30474
30849
|
} else if (inPlaceTempOutputPath) {
|
|
30475
|
-
await (0,
|
|
30850
|
+
await (0, import_promises6.rm)(inPlaceTempOutputPath, { force: true });
|
|
30476
30851
|
}
|
|
30477
|
-
await (0,
|
|
30852
|
+
await (0, import_promises6.rm)(tempDir, { recursive: true, force: true });
|
|
30478
30853
|
}
|
|
30479
30854
|
});
|
|
30480
30855
|
}
|
|
@@ -31366,7 +31741,7 @@ Examples:
|
|
|
31366
31741
|
|
|
31367
31742
|
// src/cli/commands/monitors.ts
|
|
31368
31743
|
var import_node_fs14 = require("fs");
|
|
31369
|
-
var
|
|
31744
|
+
var import_promises7 = require("readline/promises");
|
|
31370
31745
|
var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
|
|
31371
31746
|
function withJsonOption(command) {
|
|
31372
31747
|
return command.option("--json", JSON_OPTION_DESCRIPTION);
|
|
@@ -32135,7 +32510,7 @@ async function handleMonitorsValidate(key, options) {
|
|
|
32135
32510
|
if (result.valid === false) process.exitCode = 7;
|
|
32136
32511
|
}
|
|
32137
32512
|
async function confirmMonitorDelete(key, options) {
|
|
32138
|
-
const rl = (0,
|
|
32513
|
+
const rl = (0, import_promises7.createInterface)({
|
|
32139
32514
|
input: process.stdin,
|
|
32140
32515
|
output: process.stderr
|
|
32141
32516
|
});
|
|
@@ -36156,7 +36531,7 @@ Examples:
|
|
|
36156
36531
|
}
|
|
36157
36532
|
|
|
36158
36533
|
// src/cli/commands/workflow.ts
|
|
36159
|
-
var
|
|
36534
|
+
var import_promises8 = require("fs/promises");
|
|
36160
36535
|
var import_node_path20 = require("path");
|
|
36161
36536
|
|
|
36162
36537
|
// src/cli/workflow-to-play.ts
|
|
@@ -36366,7 +36741,7 @@ function readStatus(payload) {
|
|
|
36366
36741
|
}
|
|
36367
36742
|
async function readJsonOption(payload, file) {
|
|
36368
36743
|
if (file) {
|
|
36369
|
-
const raw = await (0,
|
|
36744
|
+
const raw = await (0, import_promises8.readFile)((0, import_node_path20.resolve)(file), "utf8");
|
|
36370
36745
|
return JSON.parse(raw);
|
|
36371
36746
|
}
|
|
36372
36747
|
if (payload) {
|
|
@@ -36401,8 +36776,8 @@ async function transformOne(api, workflowId, outDir, publish) {
|
|
|
36401
36776
|
{ workflowName: workflow.name, version: revision.version }
|
|
36402
36777
|
);
|
|
36403
36778
|
const file = (0, import_node_path20.join)((0, import_node_path20.resolve)(outDir), `${compiled.playName}.play.ts`);
|
|
36404
|
-
await (0,
|
|
36405
|
-
await (0,
|
|
36779
|
+
await (0, import_promises8.mkdir)((0, import_node_path20.dirname)(file), { recursive: true });
|
|
36780
|
+
await (0, import_promises8.writeFile)(file, compiled.sourceCode, "utf8");
|
|
36406
36781
|
let published = false;
|
|
36407
36782
|
if (publish) {
|
|
36408
36783
|
const code = await handlePlayPublish([file]);
|
|
@@ -40477,10 +40852,10 @@ function topLevelCommandKnown(program, commandName) {
|
|
|
40477
40852
|
);
|
|
40478
40853
|
}
|
|
40479
40854
|
async function runPlayRunnerHealthCheck() {
|
|
40480
|
-
const dir = await (0,
|
|
40855
|
+
const dir = await (0, import_promises9.mkdtemp)((0, import_node_path26.join)((0, import_node_os19.tmpdir)(), "deepline-health-play-"));
|
|
40481
40856
|
const file = (0, import_node_path26.join)(dir, "health-check.play.ts");
|
|
40482
40857
|
try {
|
|
40483
|
-
await (0,
|
|
40858
|
+
await (0, import_promises9.writeFile)(
|
|
40484
40859
|
file,
|
|
40485
40860
|
[
|
|
40486
40861
|
"import { definePlay } from 'deepline';",
|
|
@@ -40529,7 +40904,7 @@ async function runPlayRunnerHealthCheck() {
|
|
|
40529
40904
|
}
|
|
40530
40905
|
};
|
|
40531
40906
|
} finally {
|
|
40532
|
-
await (0,
|
|
40907
|
+
await (0, import_promises9.rm)(dir, { recursive: true, force: true });
|
|
40533
40908
|
}
|
|
40534
40909
|
}
|
|
40535
40910
|
function pickString(value, ...keys) {
|