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.mjs
CHANGED
|
@@ -1030,7 +1030,7 @@ var SDK_RELEASE = {
|
|
|
1030
1030
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
1031
1031
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
1032
1032
|
// release keeps lazy paging semantics independent of row residency.
|
|
1033
|
-
version: "0.2.
|
|
1033
|
+
version: "0.2.57",
|
|
1034
1034
|
contracts: {
|
|
1035
1035
|
api: {
|
|
1036
1036
|
name: "sdk-http-api",
|
|
@@ -1613,9 +1613,26 @@ var HttpClient = class {
|
|
|
1613
1613
|
if (error instanceof AuthError || error instanceof DeeplineError) {
|
|
1614
1614
|
throw error;
|
|
1615
1615
|
}
|
|
1616
|
-
|
|
1616
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
1617
|
+
if (isAbortLikeError(normalized) && options?.signal?.aborted) {
|
|
1618
|
+
throw new DeeplineError(
|
|
1619
|
+
`Stream from ${this.config.baseUrl} was aborted by the caller.`,
|
|
1620
|
+
void 0,
|
|
1621
|
+
"ABORTED"
|
|
1622
|
+
);
|
|
1623
|
+
}
|
|
1624
|
+
lastError = normalized;
|
|
1617
1625
|
}
|
|
1618
1626
|
}
|
|
1627
|
+
if (lastError && isAbortLikeError(lastError)) {
|
|
1628
|
+
throw new DeeplineError(
|
|
1629
|
+
withCoworkNetworkHint(
|
|
1630
|
+
`Unable to stream from ${this.config.baseUrl}. The remote stream was interrupted.`
|
|
1631
|
+
),
|
|
1632
|
+
void 0,
|
|
1633
|
+
"PLAY_STREAM_NETWORK_ABORTED"
|
|
1634
|
+
);
|
|
1635
|
+
}
|
|
1619
1636
|
throw new DeeplineError(
|
|
1620
1637
|
withCoworkNetworkHint(
|
|
1621
1638
|
lastError?.message ? `Unable to stream from ${this.config.baseUrl}. ${lastError.message}` : `Unable to stream from ${this.config.baseUrl}.`
|
|
@@ -1878,6 +1895,9 @@ function streamReconnectDelayMs(attempt) {
|
|
|
1878
1895
|
return Math.max(1, Math.floor(Math.random() * (cappedExponentialMs + 1)));
|
|
1879
1896
|
}
|
|
1880
1897
|
function isTransientPlayStreamError(error) {
|
|
1898
|
+
if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
|
|
1899
|
+
return true;
|
|
1900
|
+
}
|
|
1881
1901
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
1882
1902
|
return error.statusCode >= 500 && error.statusCode < 600;
|
|
1883
1903
|
}
|
|
@@ -2030,6 +2050,7 @@ var RUNTIME_RECEIPT_OUTPUT_MAX_BYTES = 10 * 1024 * 1024;
|
|
|
2030
2050
|
var RUNTIME_RECEIPT_COMPLETION_BUFFER_MAX_BYTES = 32 * 1024 * 1024;
|
|
2031
2051
|
var RUNNER_TERMINAL_PUSH_MAX_BODY_BYTES = 16 * 1024 * 1024;
|
|
2032
2052
|
var RUNTIME_RECEIPT_GATEWAY_BATCH_MAX_BYTES = 12 * 1024 * 1024;
|
|
2053
|
+
var RUNTIME_RECEIPT_WRITER_TARGET_BATCH_BYTES = 4 * 1024 * 1024;
|
|
2033
2054
|
var RUNNER_POST_TERMINAL_DIAGNOSTIC_MAX_BYTES = 64 * 1024;
|
|
2034
2055
|
|
|
2035
2056
|
// ../shared_libs/play-runtime/ledger-safe-payload.ts
|
|
@@ -4612,6 +4633,10 @@ var DeeplineClient = class {
|
|
|
4612
4633
|
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
4613
4634
|
...request.force ? { force: true } : {},
|
|
4614
4635
|
...forceToolRefresh ? { forceToolRefresh: true } : {},
|
|
4636
|
+
...typeof request.maxConcurrentExternalCalls === "number" ? {
|
|
4637
|
+
maxConcurrentExternalCalls: request.maxConcurrentExternalCalls
|
|
4638
|
+
} : {},
|
|
4639
|
+
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
4615
4640
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
4616
4641
|
// Profile selection is the API's job, not the CLI's. The server
|
|
4617
4642
|
// defaults to absurd; callers normally omit this field.
|
|
@@ -4664,6 +4689,8 @@ var DeeplineClient = class {
|
|
|
4664
4689
|
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
4665
4690
|
...request.force ? { force: true } : {},
|
|
4666
4691
|
...forceToolRefresh ? { forceToolRefresh: true } : {},
|
|
4692
|
+
...typeof request.maxConcurrentExternalCalls === "number" ? { maxConcurrentExternalCalls: request.maxConcurrentExternalCalls } : {},
|
|
4693
|
+
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
4667
4694
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
4668
4695
|
...request.profile ? { profile: request.profile } : {},
|
|
4669
4696
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -8756,14 +8783,14 @@ function invoiceDateText(createdAt) {
|
|
|
8756
8783
|
}
|
|
8757
8784
|
function invoiceLine(entry, compact) {
|
|
8758
8785
|
const amount = invoiceAmountText(entry.amount_cents, entry.currency);
|
|
8759
|
-
const
|
|
8786
|
+
const link2 = entry.url ?? "(no link)";
|
|
8760
8787
|
if (compact) {
|
|
8761
8788
|
return [
|
|
8762
8789
|
entry.id,
|
|
8763
8790
|
invoiceDateText(entry.created_at),
|
|
8764
8791
|
amount,
|
|
8765
8792
|
entry.status,
|
|
8766
|
-
|
|
8793
|
+
link2
|
|
8767
8794
|
].join(" | ");
|
|
8768
8795
|
}
|
|
8769
8796
|
return [
|
|
@@ -8771,7 +8798,7 @@ function invoiceLine(entry, compact) {
|
|
|
8771
8798
|
entry.description,
|
|
8772
8799
|
amount,
|
|
8773
8800
|
entry.status,
|
|
8774
|
-
|
|
8801
|
+
link2
|
|
8775
8802
|
].join(" | ");
|
|
8776
8803
|
}
|
|
8777
8804
|
async function handleInvoices(options) {
|
|
@@ -10925,7 +10952,7 @@ Examples:
|
|
|
10925
10952
|
// src/cli/commands/enrich.ts
|
|
10926
10953
|
import {
|
|
10927
10954
|
copyFile,
|
|
10928
|
-
lstat,
|
|
10955
|
+
lstat as lstat2,
|
|
10929
10956
|
mkdir as mkdir4,
|
|
10930
10957
|
mkdtemp,
|
|
10931
10958
|
readFile as readFile3,
|
|
@@ -10940,7 +10967,7 @@ import { basename as basename4, dirname as dirname10, extname as extname3, join
|
|
|
10940
10967
|
import { Option } from "commander";
|
|
10941
10968
|
|
|
10942
10969
|
// src/cli/commands/play.ts
|
|
10943
|
-
import { createHash as createHash4 } from "crypto";
|
|
10970
|
+
import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
|
|
10944
10971
|
import {
|
|
10945
10972
|
existsSync as existsSync9,
|
|
10946
10973
|
readFileSync as readFileSync8,
|
|
@@ -10949,6 +10976,13 @@ import {
|
|
|
10949
10976
|
statSync as statSync3,
|
|
10950
10977
|
writeFileSync as writeFileSync9
|
|
10951
10978
|
} from "fs";
|
|
10979
|
+
import {
|
|
10980
|
+
lstat,
|
|
10981
|
+
link,
|
|
10982
|
+
open,
|
|
10983
|
+
readFile as readFileAsync,
|
|
10984
|
+
unlink
|
|
10985
|
+
} from "fs/promises";
|
|
10952
10986
|
import { basename as basename3, dirname as dirname9, join as join10, resolve as resolve11 } from "path";
|
|
10953
10987
|
import { parse as parseCsvSync2 } from "csv-parse/sync";
|
|
10954
10988
|
|
|
@@ -16656,6 +16690,12 @@ function isDefinePlayCall(node) {
|
|
|
16656
16690
|
}
|
|
16657
16691
|
return false;
|
|
16658
16692
|
}
|
|
16693
|
+
function definePlayName(node) {
|
|
16694
|
+
const expression = unwrapStaticExpression(node);
|
|
16695
|
+
if (!expression || expression.type !== "CallExpression") return null;
|
|
16696
|
+
const first = astArray(expression.arguments)[0] ?? null;
|
|
16697
|
+
return first?.type === "Literal" && typeof first.value === "string" ? first.value : null;
|
|
16698
|
+
}
|
|
16659
16699
|
function listPlayFileExports(sourceCode) {
|
|
16660
16700
|
const ast = parsePlaySourceForAnalysis(sourceCode);
|
|
16661
16701
|
if (!ast) return null;
|
|
@@ -16705,13 +16745,24 @@ function listPlayFileExports(sourceCode) {
|
|
|
16705
16745
|
if (defaultIsPlay) {
|
|
16706
16746
|
const aliases = defaultLocalName ? [...namedExports.entries()].filter(([, local]) => local === defaultLocalName).map(([exported]) => exported) : [];
|
|
16707
16747
|
if (defaultLocalName) aliasedLocals.add(defaultLocalName);
|
|
16708
|
-
exports.push({
|
|
16748
|
+
exports.push({
|
|
16749
|
+
name: PLAY_DEFAULT_EXPORT,
|
|
16750
|
+
aliases,
|
|
16751
|
+
playName: definePlayName(
|
|
16752
|
+
defaultLocalName ? declarations.get(defaultLocalName) ?? null : defaultExpression
|
|
16753
|
+
)
|
|
16754
|
+
});
|
|
16709
16755
|
}
|
|
16710
16756
|
for (const [exportedName, localName] of namedExports) {
|
|
16711
16757
|
if (exportedName === PLAY_DEFAULT_EXPORT) continue;
|
|
16712
16758
|
if (aliasedLocals.has(localName)) continue;
|
|
16713
|
-
|
|
16714
|
-
|
|
16759
|
+
const declaration = declarations.get(localName) ?? null;
|
|
16760
|
+
if (!isDefinePlayCall(declaration)) continue;
|
|
16761
|
+
exports.push({
|
|
16762
|
+
name: exportedName,
|
|
16763
|
+
aliases: [],
|
|
16764
|
+
playName: definePlayName(declaration)
|
|
16765
|
+
});
|
|
16715
16766
|
}
|
|
16716
16767
|
return exports;
|
|
16717
16768
|
}
|
|
@@ -17623,6 +17674,31 @@ ${hint}`;
|
|
|
17623
17674
|
});
|
|
17624
17675
|
}
|
|
17625
17676
|
|
|
17677
|
+
// ../shared_libs/play-runtime/governor/policy.ts
|
|
17678
|
+
var DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS = 64;
|
|
17679
|
+
var MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS = 256;
|
|
17680
|
+
var MAX_CONFIGURABLE_CONCURRENT_ROWS = 1e3;
|
|
17681
|
+
function resolveMaxConcurrentExternalCalls(requested) {
|
|
17682
|
+
if (requested === void 0 || requested === null) {
|
|
17683
|
+
return DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS;
|
|
17684
|
+
}
|
|
17685
|
+
if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS) {
|
|
17686
|
+
throw new Error(
|
|
17687
|
+
`maxConcurrentExternalCalls must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.`
|
|
17688
|
+
);
|
|
17689
|
+
}
|
|
17690
|
+
return requested;
|
|
17691
|
+
}
|
|
17692
|
+
function resolveMaxConcurrentRows(requested) {
|
|
17693
|
+
if (requested === void 0 || requested === null) return null;
|
|
17694
|
+
if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_ROWS) {
|
|
17695
|
+
throw new Error(
|
|
17696
|
+
`maxConcurrentRows must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_ROWS}.`
|
|
17697
|
+
);
|
|
17698
|
+
}
|
|
17699
|
+
return requested;
|
|
17700
|
+
}
|
|
17701
|
+
|
|
17626
17702
|
// ../shared_libs/play-runtime/sandbox-runtime-limits.ts
|
|
17627
17703
|
var PLAY_SANDBOX_SIZE_LIMITS = {
|
|
17628
17704
|
standard: {
|
|
@@ -17847,6 +17923,7 @@ function stripLeadingTimestamp(line) {
|
|
|
17847
17923
|
// ../shared_libs/play-runtime/fixture-behavior.ts
|
|
17848
17924
|
var FIXTURE_BEHAVIOR_VERSION = 1;
|
|
17849
17925
|
var FIXTURE_BEHAVIOR_RESPONSE_VERSION = 2;
|
|
17926
|
+
var FIXTURE_BEHAVIOR_REPLAY_VERSION = 3;
|
|
17850
17927
|
var MAX_FIXTURE_RESPONSE_DELAY_SAMPLES = 256;
|
|
17851
17928
|
var MAX_FIXTURE_RESPONSE_DELAY_MS = 8 * 6e4;
|
|
17852
17929
|
var MAX_FIXTURE_RESPONSE_ERROR_MESSAGE_LENGTH = 500;
|
|
@@ -17858,7 +17935,11 @@ function validateFixtureBehavior(value) {
|
|
|
17858
17935
|
return { ok: false, error: "fixtureBehavior must be a JSON object." };
|
|
17859
17936
|
}
|
|
17860
17937
|
const record = value;
|
|
17861
|
-
const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION
|
|
17938
|
+
const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
|
|
17939
|
+
"version",
|
|
17940
|
+
"responseSamples",
|
|
17941
|
+
...record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
|
|
17942
|
+
]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
|
|
17862
17943
|
const unknownKeys = Object.keys(record).filter(
|
|
17863
17944
|
(key) => !supportedKeys.has(key)
|
|
17864
17945
|
);
|
|
@@ -17868,13 +17949,13 @@ function validateFixtureBehavior(value) {
|
|
|
17868
17949
|
error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
|
|
17869
17950
|
};
|
|
17870
17951
|
}
|
|
17871
|
-
if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
|
|
17952
|
+
if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17872
17953
|
return {
|
|
17873
17954
|
ok: false,
|
|
17874
|
-
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}.`
|
|
17955
|
+
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
|
|
17875
17956
|
};
|
|
17876
17957
|
}
|
|
17877
|
-
if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
|
|
17958
|
+
if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17878
17959
|
if (!Array.isArray(record.responseSamples) || record.responseSamples.length === 0 || record.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
17879
17960
|
return {
|
|
17880
17961
|
ok: false,
|
|
@@ -17981,6 +18062,72 @@ function validateFixtureBehavior(value) {
|
|
|
17981
18062
|
...httpError ? { httpError } : {}
|
|
17982
18063
|
});
|
|
17983
18064
|
}
|
|
18065
|
+
let replayBundle;
|
|
18066
|
+
if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18067
|
+
if (!record.replayBundle || typeof record.replayBundle !== "object" || Array.isArray(record.replayBundle)) {
|
|
18068
|
+
return {
|
|
18069
|
+
ok: false,
|
|
18070
|
+
error: "fixtureBehavior.replayBundle must be an object."
|
|
18071
|
+
};
|
|
18072
|
+
}
|
|
18073
|
+
const replay = record.replayBundle;
|
|
18074
|
+
const replayUnknownKeys = Object.keys(replay).filter(
|
|
18075
|
+
(key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
|
|
18076
|
+
);
|
|
18077
|
+
if (replayUnknownKeys.length > 0) {
|
|
18078
|
+
return {
|
|
18079
|
+
ok: false,
|
|
18080
|
+
error: `Unsupported fixtureBehavior.replayBundle field "${replayUnknownKeys[0]}".`
|
|
18081
|
+
};
|
|
18082
|
+
}
|
|
18083
|
+
const digestPattern = /^[a-f0-9]{64}$/;
|
|
18084
|
+
if (typeof replay.bundleId !== "string" || !digestPattern.test(replay.bundleId)) {
|
|
18085
|
+
return {
|
|
18086
|
+
ok: false,
|
|
18087
|
+
error: "fixtureBehavior.replayBundle.bundleId must be a lowercase SHA-256 digest."
|
|
18088
|
+
};
|
|
18089
|
+
}
|
|
18090
|
+
if (typeof replay.manifestSha256 !== "string" || !digestPattern.test(replay.manifestSha256)) {
|
|
18091
|
+
return {
|
|
18092
|
+
ok: false,
|
|
18093
|
+
error: "fixtureBehavior.replayBundle.manifestSha256 must be a lowercase SHA-256 digest."
|
|
18094
|
+
};
|
|
18095
|
+
}
|
|
18096
|
+
let syntheticFallbackToolIds;
|
|
18097
|
+
if (replay.syntheticFallbackToolIds !== void 0) {
|
|
18098
|
+
if (!Array.isArray(replay.syntheticFallbackToolIds) || replay.syntheticFallbackToolIds.length === 0 || replay.syntheticFallbackToolIds.length > 32) {
|
|
18099
|
+
return {
|
|
18100
|
+
ok: false,
|
|
18101
|
+
error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds must contain 1-32 tool ids."
|
|
18102
|
+
};
|
|
18103
|
+
}
|
|
18104
|
+
syntheticFallbackToolIds = [];
|
|
18105
|
+
for (const rawToolId of replay.syntheticFallbackToolIds) {
|
|
18106
|
+
if (typeof rawToolId !== "string" || rawToolId !== rawToolId.trim().toLowerCase() || !/^[a-z0-9][a-z0-9_.-]*$/.test(rawToolId) || rawToolId.length > 250 || syntheticFallbackToolIds.includes(rawToolId)) {
|
|
18107
|
+
return {
|
|
18108
|
+
ok: false,
|
|
18109
|
+
error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds contains an invalid tool id."
|
|
18110
|
+
};
|
|
18111
|
+
}
|
|
18112
|
+
syntheticFallbackToolIds.push(rawToolId);
|
|
18113
|
+
}
|
|
18114
|
+
}
|
|
18115
|
+
replayBundle = {
|
|
18116
|
+
bundleId: replay.bundleId,
|
|
18117
|
+
manifestSha256: replay.manifestSha256,
|
|
18118
|
+
...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
|
|
18119
|
+
};
|
|
18120
|
+
}
|
|
18121
|
+
if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18122
|
+
return {
|
|
18123
|
+
ok: true,
|
|
18124
|
+
behavior: {
|
|
18125
|
+
version: FIXTURE_BEHAVIOR_REPLAY_VERSION,
|
|
18126
|
+
responseSamples: samples2,
|
|
18127
|
+
replayBundle
|
|
18128
|
+
}
|
|
18129
|
+
};
|
|
18130
|
+
}
|
|
17984
18131
|
return {
|
|
17985
18132
|
ok: true,
|
|
17986
18133
|
behavior: {
|
|
@@ -18073,6 +18220,114 @@ var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
18073
18220
|
"--debug-map-latency",
|
|
18074
18221
|
"--debug-fixture-provider-pacing"
|
|
18075
18222
|
]);
|
|
18223
|
+
async function pathExistsIncludingSymlink(path) {
|
|
18224
|
+
try {
|
|
18225
|
+
await lstat(path);
|
|
18226
|
+
return true;
|
|
18227
|
+
} catch (error) {
|
|
18228
|
+
if (error.code === "ENOENT") {
|
|
18229
|
+
return false;
|
|
18230
|
+
}
|
|
18231
|
+
throw error;
|
|
18232
|
+
}
|
|
18233
|
+
}
|
|
18234
|
+
function runIdFileTempPath(destination) {
|
|
18235
|
+
return join10(
|
|
18236
|
+
dirname9(destination),
|
|
18237
|
+
`.${basename3(destination)}.${process.pid}.${randomUUID3()}.tmp`
|
|
18238
|
+
);
|
|
18239
|
+
}
|
|
18240
|
+
async function removeRunIdTempFile(path) {
|
|
18241
|
+
try {
|
|
18242
|
+
await unlink(path);
|
|
18243
|
+
} catch (error) {
|
|
18244
|
+
if (error.code !== "ENOENT") {
|
|
18245
|
+
throw error;
|
|
18246
|
+
}
|
|
18247
|
+
}
|
|
18248
|
+
}
|
|
18249
|
+
async function preflightRunIdFile(path) {
|
|
18250
|
+
const destination = resolve11(path);
|
|
18251
|
+
if (await pathExistsIncludingSymlink(destination)) {
|
|
18252
|
+
throw new Error(
|
|
18253
|
+
`--run-id-file destination already exists: ${destination}. Choose a new path so this run cannot overwrite another run identity.`
|
|
18254
|
+
);
|
|
18255
|
+
}
|
|
18256
|
+
const tempPath = runIdFileTempPath(destination);
|
|
18257
|
+
let handle = null;
|
|
18258
|
+
try {
|
|
18259
|
+
handle = await open(tempPath, "wx", 384);
|
|
18260
|
+
await handle.sync();
|
|
18261
|
+
} catch (error) {
|
|
18262
|
+
throw new Error(
|
|
18263
|
+
`Cannot write --run-id-file destination ${destination}: ${error instanceof Error ? error.message : String(error)}`
|
|
18264
|
+
);
|
|
18265
|
+
} finally {
|
|
18266
|
+
await handle?.close();
|
|
18267
|
+
await removeRunIdTempFile(tempPath);
|
|
18268
|
+
}
|
|
18269
|
+
return destination;
|
|
18270
|
+
}
|
|
18271
|
+
async function readRunIdFile(destination) {
|
|
18272
|
+
if (!await pathExistsIncludingSymlink(destination)) {
|
|
18273
|
+
return null;
|
|
18274
|
+
}
|
|
18275
|
+
let parsed;
|
|
18276
|
+
try {
|
|
18277
|
+
parsed = JSON.parse(await readFileAsync(destination, "utf8"));
|
|
18278
|
+
} catch (error) {
|
|
18279
|
+
throw new Error(
|
|
18280
|
+
`--run-id-file destination contains invalid JSON: ${destination}. Refusing to overwrite it (${error instanceof Error ? error.message : String(error)}).`
|
|
18281
|
+
);
|
|
18282
|
+
}
|
|
18283
|
+
if (!parsed || typeof parsed !== "object" || parsed.version !== 1 || typeof parsed.runId !== "string" || !parsed.runId) {
|
|
18284
|
+
throw new Error(
|
|
18285
|
+
`--run-id-file destination has an unsupported identity record: ${destination}. Refusing to overwrite it.`
|
|
18286
|
+
);
|
|
18287
|
+
}
|
|
18288
|
+
return parsed;
|
|
18289
|
+
}
|
|
18290
|
+
async function writePlayRunIdFile(destination, runId) {
|
|
18291
|
+
const existing = await readRunIdFile(destination);
|
|
18292
|
+
if (existing) {
|
|
18293
|
+
if (existing.runId === runId) return;
|
|
18294
|
+
throw new Error(
|
|
18295
|
+
`--run-id-file destination already records run ${existing.runId}; refusing to replace it with ${runId}: ${destination}`
|
|
18296
|
+
);
|
|
18297
|
+
}
|
|
18298
|
+
const tempPath = runIdFileTempPath(destination);
|
|
18299
|
+
let handle = null;
|
|
18300
|
+
try {
|
|
18301
|
+
handle = await open(tempPath, "wx", 384);
|
|
18302
|
+
await handle.writeFile(
|
|
18303
|
+
`${JSON.stringify({ version: 1, runId })}
|
|
18304
|
+
`,
|
|
18305
|
+
"utf8"
|
|
18306
|
+
);
|
|
18307
|
+
await handle.sync();
|
|
18308
|
+
await handle.close();
|
|
18309
|
+
handle = null;
|
|
18310
|
+
try {
|
|
18311
|
+
await link(tempPath, destination);
|
|
18312
|
+
const directory = await open(dirname9(destination), "r");
|
|
18313
|
+
try {
|
|
18314
|
+
await directory.sync();
|
|
18315
|
+
} finally {
|
|
18316
|
+
await directory.close();
|
|
18317
|
+
}
|
|
18318
|
+
} catch (error) {
|
|
18319
|
+
if (error.code !== "EEXIST") throw error;
|
|
18320
|
+
const raced = await readRunIdFile(destination);
|
|
18321
|
+
if (raced?.runId === runId) return;
|
|
18322
|
+
throw new Error(
|
|
18323
|
+
`--run-id-file destination already records run ${raced?.runId ?? "<invalid>"}; refusing to replace it with ${runId}: ${destination}`
|
|
18324
|
+
);
|
|
18325
|
+
}
|
|
18326
|
+
} finally {
|
|
18327
|
+
await handle?.close();
|
|
18328
|
+
await removeRunIdTempFile(tempPath);
|
|
18329
|
+
}
|
|
18330
|
+
}
|
|
18076
18331
|
function traceCliSync(phase, fields, run) {
|
|
18077
18332
|
const startedAt = Date.now();
|
|
18078
18333
|
try {
|
|
@@ -19477,8 +19732,8 @@ function buildPlayDashboardUrl(baseUrl, playName) {
|
|
|
19477
19732
|
const encodedPlayName = encodeURIComponent(playName);
|
|
19478
19733
|
return `${trimmedBase}/dashboard/plays/${encodedPlayName}`;
|
|
19479
19734
|
}
|
|
19480
|
-
function openPlayDashboard(dashboardUrl,
|
|
19481
|
-
if (
|
|
19735
|
+
function openPlayDashboard(dashboardUrl, open2) {
|
|
19736
|
+
if (open2 && dashboardUrl) {
|
|
19482
19737
|
openInBrowser(dashboardUrl);
|
|
19483
19738
|
}
|
|
19484
19739
|
}
|
|
@@ -19514,9 +19769,11 @@ function assertPlayWaitNotTimedOut(input2) {
|
|
|
19514
19769
|
);
|
|
19515
19770
|
}
|
|
19516
19771
|
}
|
|
19772
|
+
var PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS = 15e3;
|
|
19517
19773
|
async function waitForPlayCompletionByStream(input2) {
|
|
19518
19774
|
let lastPhase = null;
|
|
19519
19775
|
let reconnectAttempt = 0;
|
|
19776
|
+
let nextDurableProbeAt = Date.now() + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
|
|
19520
19777
|
const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
|
|
19521
19778
|
const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
|
|
19522
19779
|
const fetchTerminalStatus = async () => {
|
|
@@ -19535,6 +19792,14 @@ async function waitForPlayCompletionByStream(input2) {
|
|
|
19535
19792
|
};
|
|
19536
19793
|
const handleLiveEvent = async (event) => {
|
|
19537
19794
|
assertPlayWaitNotTimedOut({ ...input2, lastPhase });
|
|
19795
|
+
const now = Date.now();
|
|
19796
|
+
if (now >= nextDurableProbeAt) {
|
|
19797
|
+
nextDurableProbeAt = now + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
|
|
19798
|
+
const durableTerminal = await fetchTerminalStatus();
|
|
19799
|
+
if (durableTerminal) {
|
|
19800
|
+
return durableTerminal;
|
|
19801
|
+
}
|
|
19802
|
+
}
|
|
19538
19803
|
const phase = describeLiveEventPhase(event);
|
|
19539
19804
|
if (phase) {
|
|
19540
19805
|
lastPhase = phase;
|
|
@@ -19783,7 +20048,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
19783
20048
|
lastKnownWorkflowId = eventRunId;
|
|
19784
20049
|
firstRunIdMs ??= Date.now() - startedAt;
|
|
19785
20050
|
if (runStartedNow) {
|
|
19786
|
-
input2.onRunStarted?.(eventRunId);
|
|
20051
|
+
await input2.onRunStarted?.(eventRunId);
|
|
19787
20052
|
}
|
|
19788
20053
|
}
|
|
19789
20054
|
if (eventConfirmsPlayRunLaunch(event) && eventRunId === lastKnownWorkflowId) {
|
|
@@ -21062,6 +21327,15 @@ function buildOrdinaryPlayRunCommand(options, resolvedRevisionId) {
|
|
|
21062
21327
|
}
|
|
21063
21328
|
if (options.profile)
|
|
21064
21329
|
parts.push("--profile", shellSingleQuote(options.profile));
|
|
21330
|
+
if (options.maxConcurrentExternalCalls !== null) {
|
|
21331
|
+
parts.push(
|
|
21332
|
+
"--max-concurrent-external-calls",
|
|
21333
|
+
String(options.maxConcurrentExternalCalls)
|
|
21334
|
+
);
|
|
21335
|
+
}
|
|
21336
|
+
if (options.maxConcurrentRows !== null) {
|
|
21337
|
+
parts.push("--max-concurrent-rows", String(options.maxConcurrentRows));
|
|
21338
|
+
}
|
|
21065
21339
|
const pinnedRevisionId = options.target.kind === "name" ? resolvedRevisionId ?? options.revisionId : null;
|
|
21066
21340
|
if (pinnedRevisionId) {
|
|
21067
21341
|
parts.push("--revision-id", shellSingleQuote(pinnedRevisionId));
|
|
@@ -21931,7 +22205,7 @@ function writeStartedPlayRun(input2) {
|
|
|
21931
22205
|
);
|
|
21932
22206
|
}
|
|
21933
22207
|
function parsePlayRunOptions(args) {
|
|
21934
|
-
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.";
|
|
22208
|
+
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.";
|
|
21935
22209
|
let filePath = null;
|
|
21936
22210
|
let playName = null;
|
|
21937
22211
|
let input2 = null;
|
|
@@ -21942,15 +22216,18 @@ function parsePlayRunOptions(args) {
|
|
|
21942
22216
|
const fullJson = args.includes("--full");
|
|
21943
22217
|
const emitLogs = !jsonOutput || args.includes("--logs");
|
|
21944
22218
|
const force = args.includes("--force");
|
|
21945
|
-
const
|
|
22219
|
+
const open2 = args.includes("--open");
|
|
21946
22220
|
const debugMapLatency = args.includes("--debug-map-latency");
|
|
21947
22221
|
const debugFixtureProviderPacing = args.includes(
|
|
21948
22222
|
"--debug-fixture-provider-pacing"
|
|
21949
22223
|
);
|
|
21950
22224
|
const verboseLogs = args.includes("--logs") || debugMapLatency;
|
|
21951
22225
|
let waitTimeoutMs = null;
|
|
22226
|
+
let maxConcurrentExternalCalls = null;
|
|
22227
|
+
let maxConcurrentRows = null;
|
|
21952
22228
|
let profile = null;
|
|
21953
22229
|
let fixtureBehavior = null;
|
|
22230
|
+
let runIdFile = null;
|
|
21954
22231
|
for (let index = 0; index < args.length; index += 1) {
|
|
21955
22232
|
const arg = args[index];
|
|
21956
22233
|
if (arg === "--file" && args[index + 1]) {
|
|
@@ -21965,6 +22242,23 @@ function parsePlayRunOptions(args) {
|
|
|
21965
22242
|
input2 = parseJsonInput(args[++index]);
|
|
21966
22243
|
continue;
|
|
21967
22244
|
}
|
|
22245
|
+
if (arg === "--run-id-file") {
|
|
22246
|
+
const value = args[index + 1];
|
|
22247
|
+
if (!value || value.startsWith("--")) {
|
|
22248
|
+
throw new Error("--run-id-file requires a destination path.");
|
|
22249
|
+
}
|
|
22250
|
+
runIdFile = value;
|
|
22251
|
+
index += 1;
|
|
22252
|
+
continue;
|
|
22253
|
+
}
|
|
22254
|
+
if (arg.startsWith("--run-id-file=")) {
|
|
22255
|
+
const value = arg.slice("--run-id-file=".length);
|
|
22256
|
+
if (!value) {
|
|
22257
|
+
throw new Error("--run-id-file requires a destination path.");
|
|
22258
|
+
}
|
|
22259
|
+
runIdFile = value;
|
|
22260
|
+
continue;
|
|
22261
|
+
}
|
|
21968
22262
|
if (arg === "--revision-id" && args[index + 1]) {
|
|
21969
22263
|
revisionId = args[++index];
|
|
21970
22264
|
continue;
|
|
@@ -21979,6 +22273,41 @@ function parsePlayRunOptions(args) {
|
|
|
21979
22273
|
index += 1;
|
|
21980
22274
|
continue;
|
|
21981
22275
|
}
|
|
22276
|
+
if (arg === "--max-concurrent-external-calls") {
|
|
22277
|
+
const value = args[index + 1];
|
|
22278
|
+
if (!value || value.startsWith("--")) {
|
|
22279
|
+
throw new Error(
|
|
22280
|
+
"--max-concurrent-external-calls requires a whole number."
|
|
22281
|
+
);
|
|
22282
|
+
}
|
|
22283
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
22284
|
+
throw new Error(
|
|
22285
|
+
"--max-concurrent-external-calls requires a positive whole number."
|
|
22286
|
+
);
|
|
22287
|
+
}
|
|
22288
|
+
maxConcurrentExternalCalls = parsePositiveInteger3(
|
|
22289
|
+
value,
|
|
22290
|
+
"--max-concurrent-external-calls"
|
|
22291
|
+
);
|
|
22292
|
+
resolveMaxConcurrentExternalCalls(maxConcurrentExternalCalls);
|
|
22293
|
+
index += 1;
|
|
22294
|
+
continue;
|
|
22295
|
+
}
|
|
22296
|
+
if (arg === "--max-concurrent-rows") {
|
|
22297
|
+
const value = args[index + 1];
|
|
22298
|
+
if (!value || value.startsWith("--")) {
|
|
22299
|
+
throw new Error("--max-concurrent-rows requires a whole number.");
|
|
22300
|
+
}
|
|
22301
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
22302
|
+
throw new Error(
|
|
22303
|
+
"--max-concurrent-rows requires a positive whole number."
|
|
22304
|
+
);
|
|
22305
|
+
}
|
|
22306
|
+
maxConcurrentRows = parsePositiveInteger3(value, "--max-concurrent-rows");
|
|
22307
|
+
resolveMaxConcurrentRows(maxConcurrentRows);
|
|
22308
|
+
index += 1;
|
|
22309
|
+
continue;
|
|
22310
|
+
}
|
|
21982
22311
|
if (arg === "--fixture-behavior") {
|
|
21983
22312
|
const value = args[index + 1];
|
|
21984
22313
|
if (!value) {
|
|
@@ -22089,11 +22418,14 @@ function parsePlayRunOptions(args) {
|
|
|
22089
22418
|
fullJson,
|
|
22090
22419
|
waitTimeoutMs,
|
|
22091
22420
|
force,
|
|
22092
|
-
|
|
22421
|
+
maxConcurrentExternalCalls,
|
|
22422
|
+
maxConcurrentRows,
|
|
22423
|
+
open: open2,
|
|
22093
22424
|
profile,
|
|
22094
22425
|
debugMapLatency,
|
|
22095
22426
|
debugFixtureProviderPacing,
|
|
22096
|
-
fixtureBehavior
|
|
22427
|
+
fixtureBehavior,
|
|
22428
|
+
runIdFile
|
|
22097
22429
|
};
|
|
22098
22430
|
}
|
|
22099
22431
|
function parsePlayCheckOptions(args) {
|
|
@@ -22776,6 +23108,8 @@ async function handleFileBackedRun(options, hooks) {
|
|
|
22776
23108
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
22777
23109
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
22778
23110
|
...options.force ? { force: true } : {},
|
|
23111
|
+
...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
|
|
23112
|
+
...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
|
|
22779
23113
|
...options.profile ? { profile: options.profile } : {},
|
|
22780
23114
|
...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
|
|
22781
23115
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -22836,6 +23170,7 @@ async function handleFileBackedRun(options, hooks) {
|
|
|
22836
23170
|
throw await normalizePlayStartError(client2, error, playName);
|
|
22837
23171
|
})
|
|
22838
23172
|
);
|
|
23173
|
+
await hooks?.onRunStarted?.(started.workflowId);
|
|
22839
23174
|
const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
|
|
22840
23175
|
openPlayDashboard(resolvedDashboardUrl, options.open);
|
|
22841
23176
|
progress.phase("started run");
|
|
@@ -22956,6 +23291,8 @@ async function handleNamedRun(options, hooks) {
|
|
|
22956
23291
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
22957
23292
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
22958
23293
|
...options.force ? { force: true } : {},
|
|
23294
|
+
...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
|
|
23295
|
+
...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
|
|
22959
23296
|
...options.profile ? { profile: options.profile } : {},
|
|
22960
23297
|
...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
|
|
22961
23298
|
...integrationMode ? { integrationMode } : {},
|
|
@@ -23021,6 +23358,7 @@ async function handleNamedRun(options, hooks) {
|
|
|
23021
23358
|
});
|
|
23022
23359
|
})
|
|
23023
23360
|
);
|
|
23361
|
+
await hooks?.onRunStarted?.(started.workflowId);
|
|
23024
23362
|
const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
|
|
23025
23363
|
openPlayDashboard(resolvedDashboardUrl, options.open);
|
|
23026
23364
|
progress.phase("started run");
|
|
@@ -23037,10 +23375,28 @@ async function handleNamedRun(options, hooks) {
|
|
|
23037
23375
|
return 0;
|
|
23038
23376
|
}
|
|
23039
23377
|
async function handlePlayRun(args, hooks) {
|
|
23040
|
-
const
|
|
23378
|
+
const parsedOptions = parsePlayRunOptions(args);
|
|
23379
|
+
const options = parsedOptions.runIdFile ? {
|
|
23380
|
+
...parsedOptions,
|
|
23381
|
+
runIdFile: await preflightRunIdFile(parsedOptions.runIdFile)
|
|
23382
|
+
} : parsedOptions;
|
|
23383
|
+
const runHooks = options.runIdFile ? {
|
|
23384
|
+
...hooks,
|
|
23385
|
+
onRunStarted: async (runId) => {
|
|
23386
|
+
try {
|
|
23387
|
+
await writePlayRunIdFile(options.runIdFile, runId);
|
|
23388
|
+
} catch (error) {
|
|
23389
|
+
throw new Error(
|
|
23390
|
+
`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.`,
|
|
23391
|
+
{ cause: error }
|
|
23392
|
+
);
|
|
23393
|
+
}
|
|
23394
|
+
await hooks?.onRunStarted?.(runId);
|
|
23395
|
+
}
|
|
23396
|
+
} : hooks;
|
|
23041
23397
|
if (options.target.kind === "file") {
|
|
23042
23398
|
if (isFileTarget(options.target.path)) {
|
|
23043
|
-
return handleFileBackedRun(options,
|
|
23399
|
+
return handleFileBackedRun(options, runHooks);
|
|
23044
23400
|
}
|
|
23045
23401
|
const resolved = resolve11(options.target.path);
|
|
23046
23402
|
console.error(`File not found: ${resolved}`);
|
|
@@ -23062,7 +23418,7 @@ async function handlePlayRun(args, hooks) {
|
|
|
23062
23418
|
}
|
|
23063
23419
|
return 1;
|
|
23064
23420
|
}
|
|
23065
|
-
return handleNamedRun(options,
|
|
23421
|
+
return handleNamedRun(options, runHooks);
|
|
23066
23422
|
}
|
|
23067
23423
|
function parseRunIdPositional(args, usage) {
|
|
23068
23424
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -24390,10 +24746,18 @@ Notes:
|
|
|
24390
24746
|
next commands. --watch and --wait are accepted compatibility aliases for the
|
|
24391
24747
|
default behavior. Use --no-wait only when you intentionally want
|
|
24392
24748
|
a fire-and-forget run id.
|
|
24749
|
+
--run-id-file writes the durable run id to a versioned JSON file as soon as
|
|
24750
|
+
the server accepts the run. The destination must not already exist.
|
|
24393
24751
|
The play page URL is printed when the run starts. Pass --open to open it in a browser.
|
|
24394
24752
|
Concurrent runs for the same play are allowed.
|
|
24395
24753
|
--force starts a fresh run graph without refreshing completed provider calls.
|
|
24396
24754
|
It does not cancel active sibling runs.
|
|
24755
|
+
--max-concurrent-external-calls controls the per-run provider-tool/ctx.fetch
|
|
24756
|
+
resident-work ceiling. Default: ${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS}; accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.
|
|
24757
|
+
Provider pacing and sandbox memory limits still apply.
|
|
24758
|
+
--max-concurrent-rows sets the run-wide default and ceiling for live map row
|
|
24759
|
+
resolvers. Accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_ROWS}. The runtime
|
|
24760
|
+
may lower it when source-row size exceeds the active-row memory budget.
|
|
24397
24761
|
This command starts cloud work and may spend Deepline credits through tool calls.
|
|
24398
24762
|
|
|
24399
24763
|
Idempotent execution:
|
|
@@ -24429,8 +24793,10 @@ Idempotent execution:
|
|
|
24429
24793
|
Examples:
|
|
24430
24794
|
deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
|
|
24431
24795
|
deepline plays run long-background-play --no-wait
|
|
24796
|
+
deepline plays run long-background-play --run-id-file ./run-id.json
|
|
24432
24797
|
deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
|
|
24433
24798
|
deepline plays run my.play.ts --profile absurd
|
|
24799
|
+
deepline plays run my.play.ts --max-concurrent-external-calls 20
|
|
24434
24800
|
deepline plays run my.play.ts --input @input.json --json
|
|
24435
24801
|
deepline plays run cto-search.play.ts --limit 5
|
|
24436
24802
|
deepline runs export <run-id> --out output.csv
|
|
@@ -24446,9 +24812,18 @@ Examples:
|
|
|
24446
24812
|
"--fixture-behavior <json>",
|
|
24447
24813
|
"Internal/testing: fixture response behavior JSON object or @file path"
|
|
24448
24814
|
).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(
|
|
24815
|
+
"--run-id-file <path>",
|
|
24816
|
+
"Atomically write the accepted run id to a new JSON file"
|
|
24817
|
+
).option(
|
|
24449
24818
|
"--logs",
|
|
24450
24819
|
"When output is non-interactive, stream play logs to stderr while waiting"
|
|
24451
|
-
).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
|
|
24820
|
+
).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
|
|
24821
|
+
"--max-concurrent-external-calls <count>",
|
|
24822
|
+
`Concurrent provider-tool and ctx.fetch executions (${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS} default, max ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS})`
|
|
24823
|
+
).option(
|
|
24824
|
+
"--max-concurrent-rows <count>",
|
|
24825
|
+
`Run-wide dataset map row resolver ceiling (max ${MAX_CONFIGURABLE_CONCURRENT_ROWS})`
|
|
24826
|
+
).option("--open", "Open the play page in a browser after the run starts").option(
|
|
24452
24827
|
"--debug-map-latency",
|
|
24453
24828
|
"Internal diagnostics: emit one aggregate latency profile per dataset map"
|
|
24454
24829
|
).option(
|
|
@@ -24487,10 +24862,16 @@ Pass-through input flags:
|
|
|
24487
24862
|
...options.profile ? ["--profile", options.profile] : [],
|
|
24488
24863
|
...options.fixtureBehavior ? ["--fixture-behavior", options.fixtureBehavior] : [],
|
|
24489
24864
|
...options.wait === false ? ["--no-wait"] : [],
|
|
24865
|
+
...options.runIdFile ? ["--run-id-file", options.runIdFile] : [],
|
|
24490
24866
|
...options.watch || options.wait ? ["--watch"] : [],
|
|
24491
24867
|
...options.logs ? ["--logs"] : [],
|
|
24492
24868
|
...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
|
|
24493
24869
|
...options.force ? ["--force"] : [],
|
|
24870
|
+
...options.maxConcurrentExternalCalls ? [
|
|
24871
|
+
"--max-concurrent-external-calls",
|
|
24872
|
+
options.maxConcurrentExternalCalls
|
|
24873
|
+
] : [],
|
|
24874
|
+
...options.maxConcurrentRows ? ["--max-concurrent-rows", options.maxConcurrentRows] : [],
|
|
24494
24875
|
...options.open ? ["--open"] : [],
|
|
24495
24876
|
...options.debugMapLatency ? ["--debug-map-latency"] : [],
|
|
24496
24877
|
...options.debugFixtureProviderPacing ? ["--debug-fixture-provider-pacing"] : [],
|
|
@@ -30266,7 +30647,7 @@ function registerEnrichCommand(program) {
|
|
|
30266
30647
|
let inPlaceTempDir = null;
|
|
30267
30648
|
let inPlaceTempOutputPath = null;
|
|
30268
30649
|
const inPlaceFinalOutputPath = options.inPlace ? resolve12(inputCsv) : null;
|
|
30269
|
-
const inPlaceCommitOutputPath = options.inPlace ? (await
|
|
30650
|
+
const inPlaceCommitOutputPath = options.inPlace ? (await lstat2(inputCsv)).isSymbolicLink() ? await realpath2(inputCsv) : inPlaceFinalOutputPath : null;
|
|
30270
30651
|
const failureReportOutputPath = options.inPlace ? inPlaceFinalOutputPath : null;
|
|
30271
30652
|
const enrichIssueFollowUpOutputPath = options.inPlace && inPlaceFinalOutputPath ? sidecarEnrichRowsExportPath(inPlaceFinalOutputPath) : null;
|
|
30272
30653
|
let activeRunId2 = null;
|
|
@@ -30581,7 +30962,7 @@ import {
|
|
|
30581
30962
|
import { homedir as homedir8, platform } from "os";
|
|
30582
30963
|
import { basename as basename5, dirname as dirname11, join as join12, resolve as resolve13 } from "path";
|
|
30583
30964
|
import { gzipSync } from "zlib";
|
|
30584
|
-
import { randomUUID as
|
|
30965
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
30585
30966
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
30586
30967
|
var UUID_IN_TEXT_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
|
|
30587
30968
|
var MAX_SESSION_UPLOAD_BYTES = 35e5;
|
|
@@ -30980,7 +31361,7 @@ async function uploadPayload(path, payload) {
|
|
|
30980
31361
|
return await http.post(path, payload);
|
|
30981
31362
|
}
|
|
30982
31363
|
async function uploadChunkedSessions(sessions, options) {
|
|
30983
|
-
const uploadId =
|
|
31364
|
+
const uploadId = randomUUID4();
|
|
30984
31365
|
for (const session of sessions) {
|
|
30985
31366
|
const bytes = Buffer.from(session.encodedContent, "base64");
|
|
30986
31367
|
const chunks = [];
|