deepline 0.1.83 → 0.1.88
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/cli/index.js +481 -79
- package/dist/cli/index.mjs +500 -92
- package/dist/index.d.mts +604 -28
- package/dist/index.d.ts +604 -28
- package/dist/index.js +274 -4
- package/dist/index.mjs +269 -4
- package/dist/repo/apps/play-runner-workers/src/dedup-do.ts +1 -0
- package/dist/repo/apps/play-runner-workers/src/entry.ts +345 -72
- package/dist/repo/sdk/src/client.ts +155 -1
- package/dist/repo/sdk/src/http.ts +11 -0
- package/dist/repo/sdk/src/index.ts +35 -1
- package/dist/repo/sdk/src/play.ts +254 -15
- package/dist/repo/sdk/src/plays/harness-stub.ts +2 -1
- package/dist/repo/sdk/src/release.ts +2 -2
- package/dist/repo/sdk/src/types.ts +65 -0
- package/dist/repo/sdk/src/worker-play-entry.ts +6 -3
- package/dist/repo/shared_libs/play-runtime/cell-staleness.ts +179 -7
- package/dist/repo/shared_libs/play-runtime/coordinator-headers.ts +10 -0
- package/dist/repo/shared_libs/play-runtime/execution-plan.ts +3 -3
- package/dist/repo/shared_libs/play-runtime/extractor-targets.ts +106 -0
- package/dist/repo/shared_libs/play-runtime/providers.ts +28 -0
- package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +21 -1
- package/dist/repo/shared_libs/play-runtime/step-program-dataset-builder.ts +96 -6
- package/dist/repo/shared_libs/play-runtime/tool-result.ts +82 -0
- package/dist/repo/shared_libs/plays/bundling/index.ts +23 -16
- package/dist/repo/shared_libs/plays/dataset.ts +2 -0
- package/dist/repo/shared_libs/plays/static-pipeline.ts +133 -24
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -206,10 +206,10 @@ import { join as join2 } from "path";
|
|
|
206
206
|
|
|
207
207
|
// src/release.ts
|
|
208
208
|
var SDK_RELEASE = {
|
|
209
|
-
version: "0.1.
|
|
209
|
+
version: "0.1.88",
|
|
210
210
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
211
211
|
supportPolicy: {
|
|
212
|
-
latest: "0.1.
|
|
212
|
+
latest: "0.1.88",
|
|
213
213
|
minimumSupported: "0.1.53",
|
|
214
214
|
deprecatedBelow: "0.1.53"
|
|
215
215
|
}
|
|
@@ -223,6 +223,7 @@ var SDK_API_CONTRACT = SDK_RELEASE.apiContract;
|
|
|
223
223
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
224
224
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
225
225
|
var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
|
|
226
|
+
var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
|
|
226
227
|
|
|
227
228
|
// src/http.ts
|
|
228
229
|
var MAX_DIAGNOSTIC_HEADER_LENGTH = 120;
|
|
@@ -290,6 +291,10 @@ var HttpClient = class {
|
|
|
290
291
|
if (workerCallbackUrl?.trim()) {
|
|
291
292
|
headers[WORKER_CALLBACK_URL_OVERRIDE_HEADER] = workerCallbackUrl.trim();
|
|
292
293
|
}
|
|
294
|
+
const syntheticRun = typeof process !== "undefined" ? process.env?.DEEPLINE_SYNTHETIC_RUN : void 0;
|
|
295
|
+
if (syntheticRun && syntheticRun.trim() && syntheticRun.trim() !== "0") {
|
|
296
|
+
headers[SYNTHETIC_RUN_HEADER] = "1";
|
|
297
|
+
}
|
|
293
298
|
return headers;
|
|
294
299
|
}
|
|
295
300
|
/**
|
|
@@ -556,7 +561,7 @@ function decodeSseFrame(frame) {
|
|
|
556
561
|
return parsed;
|
|
557
562
|
}
|
|
558
563
|
function sleep(ms) {
|
|
559
|
-
return new Promise((
|
|
564
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
560
565
|
}
|
|
561
566
|
|
|
562
567
|
// src/client.ts
|
|
@@ -566,7 +571,7 @@ var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
|
|
|
566
571
|
var V2_EXECUTE_RESPONSE_CONTRACT = "v2-tool-response";
|
|
567
572
|
var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
|
|
568
573
|
function sleep2(ms) {
|
|
569
|
-
return new Promise((
|
|
574
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
570
575
|
}
|
|
571
576
|
function isTransientCompileManifestError(error) {
|
|
572
577
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
@@ -580,6 +585,21 @@ function isTransientCompileManifestError(error) {
|
|
|
580
585
|
function isRecord(value) {
|
|
581
586
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
582
587
|
}
|
|
588
|
+
function isPrebuiltPlayDescription(play) {
|
|
589
|
+
return play.origin === "prebuilt" || play.ownerType === "deepline";
|
|
590
|
+
}
|
|
591
|
+
function preferPrebuiltPlayDescriptions(plays) {
|
|
592
|
+
const prebuilt = [];
|
|
593
|
+
const owned = [];
|
|
594
|
+
for (const play of plays) {
|
|
595
|
+
if (isPrebuiltPlayDescription(play)) {
|
|
596
|
+
prebuilt.push(play);
|
|
597
|
+
} else {
|
|
598
|
+
owned.push(play);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return [...prebuilt, ...owned];
|
|
602
|
+
}
|
|
583
603
|
function isPlayRunPackage(value) {
|
|
584
604
|
return Boolean(
|
|
585
605
|
value && typeof value === "object" && !Array.isArray(value) && value.kind === "play_run" && value.run && typeof value.run?.id === "string"
|
|
@@ -703,8 +723,14 @@ function playRunStatusFromState(state) {
|
|
|
703
723
|
var DeeplineClient = class {
|
|
704
724
|
http;
|
|
705
725
|
config;
|
|
726
|
+
/** Canonical run lifecycle namespace backed by `/api/v2/runs`. */
|
|
706
727
|
runs;
|
|
707
728
|
/**
|
|
729
|
+
* Create a low-level SDK client.
|
|
730
|
+
*
|
|
731
|
+
* Most callers can omit options and let the SDK resolve auth/config from
|
|
732
|
+
* environment variables and CLI-managed credentials.
|
|
733
|
+
*
|
|
708
734
|
* @param options - Optional overrides for API key, base URL, timeout, and retries.
|
|
709
735
|
* @throws {@link ConfigError} if no API key can be resolved from any source.
|
|
710
736
|
*/
|
|
@@ -806,12 +832,19 @@ var DeeplineClient = class {
|
|
|
806
832
|
// ——————————————————————————————————————————————————————————
|
|
807
833
|
// Secrets
|
|
808
834
|
// ——————————————————————————————————————————————————————————
|
|
835
|
+
/** List secret metadata visible to the current workspace. */
|
|
809
836
|
async listSecrets() {
|
|
810
837
|
const response = await this.http.get(
|
|
811
838
|
"/api/v2/secrets"
|
|
812
839
|
);
|
|
813
840
|
return Array.isArray(response.secrets) ? response.secrets : [];
|
|
814
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* Check whether a named secret exists, is active, and has a stored value.
|
|
844
|
+
*
|
|
845
|
+
* @param name - Secret name. It is normalized to uppercase before lookup.
|
|
846
|
+
* @returns Matching active secret metadata, or `null`.
|
|
847
|
+
*/
|
|
815
848
|
async checkSecret(name) {
|
|
816
849
|
const normalized = name.trim().toUpperCase();
|
|
817
850
|
const secrets = await this.listSecrets();
|
|
@@ -924,9 +957,21 @@ var DeeplineClient = class {
|
|
|
924
957
|
headers
|
|
925
958
|
);
|
|
926
959
|
}
|
|
960
|
+
/**
|
|
961
|
+
* Back-compatible alias for {@link executeTool}.
|
|
962
|
+
*
|
|
963
|
+
* Retained for callers that still use the older raw naming while the response
|
|
964
|
+
* envelope remains the same.
|
|
965
|
+
*/
|
|
927
966
|
async executeToolRaw(toolId, input2, options) {
|
|
928
967
|
return this.executeTool(toolId, input2, options);
|
|
929
968
|
}
|
|
969
|
+
/**
|
|
970
|
+
* Run a bounded SQL query against the customer data plane.
|
|
971
|
+
*
|
|
972
|
+
* Use this from trusted backend or agent contexts only. The API enforces
|
|
973
|
+
* workspace scoping and row limits.
|
|
974
|
+
*/
|
|
930
975
|
async queryCustomerDb(input2) {
|
|
931
976
|
return this.http.post("/api/v2/db/query", {
|
|
932
977
|
sql: input2.sql,
|
|
@@ -998,6 +1043,17 @@ var DeeplineClient = class {
|
|
|
998
1043
|
);
|
|
999
1044
|
return normalizePlayRunStart(response);
|
|
1000
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Start a play run and stream live runtime events from the same request.
|
|
1048
|
+
*
|
|
1049
|
+
* Use this when a caller wants low-level event handling instead of submitting
|
|
1050
|
+
* first and then connecting to `streamPlayRunEvents(runId)`.
|
|
1051
|
+
*
|
|
1052
|
+
* @param request - Play run configuration.
|
|
1053
|
+
* @param options - Optional streaming options.
|
|
1054
|
+
* @param options.signal - Optional abort signal for the streaming request.
|
|
1055
|
+
* @returns Async stream of play-scoped live events.
|
|
1056
|
+
*/
|
|
1001
1057
|
async *startPlayRunStream(request, options) {
|
|
1002
1058
|
const body = {
|
|
1003
1059
|
...request.name ? { name: request.name } : {},
|
|
@@ -1050,6 +1106,12 @@ var DeeplineClient = class {
|
|
|
1050
1106
|
compilerManifest
|
|
1051
1107
|
});
|
|
1052
1108
|
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Register multiple bundled play artifacts in one request.
|
|
1111
|
+
*
|
|
1112
|
+
* Used by packaging and prebuilt publication flows. Each artifact is compiled
|
|
1113
|
+
* first when a compiler manifest is not already supplied.
|
|
1114
|
+
*/
|
|
1053
1115
|
async registerPlayArtifacts(artifacts) {
|
|
1054
1116
|
const compiledArtifacts = await Promise.all(
|
|
1055
1117
|
artifacts.map(async (artifact) => ({
|
|
@@ -1066,6 +1128,13 @@ var DeeplineClient = class {
|
|
|
1066
1128
|
artifacts: compiledArtifacts
|
|
1067
1129
|
});
|
|
1068
1130
|
}
|
|
1131
|
+
/**
|
|
1132
|
+
* Compile a bundled play artifact into the server-side compiler manifest.
|
|
1133
|
+
*
|
|
1134
|
+
* The manifest records imports, trigger bindings, static pipeline shape, and
|
|
1135
|
+
* runtime metadata needed before a play artifact can be checked, registered,
|
|
1136
|
+
* or run.
|
|
1137
|
+
*/
|
|
1069
1138
|
async compilePlayManifest(input2) {
|
|
1070
1139
|
const retryDelays = COMPILE_MANIFEST_RETRY_DELAYS_MS.slice(
|
|
1071
1140
|
0,
|
|
@@ -1094,9 +1163,21 @@ var DeeplineClient = class {
|
|
|
1094
1163
|
async checkPlayArtifact(input2) {
|
|
1095
1164
|
return this.http.post("/api/v2/plays/check", input2);
|
|
1096
1165
|
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Compile legacy enrich command arguments into a runtime plan.
|
|
1168
|
+
*
|
|
1169
|
+
* This is primarily used by CLI compatibility paths that translate older
|
|
1170
|
+
* enrichment commands onto the play runtime.
|
|
1171
|
+
*/
|
|
1097
1172
|
async compileEnrichPlan(input2) {
|
|
1098
1173
|
return this.http.post("/api/v2/enrich/compile", input2);
|
|
1099
1174
|
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Register an already-bundled play artifact and start a run from it.
|
|
1177
|
+
*
|
|
1178
|
+
* This is the low-level file-backed run path used by SDK/CLI packaging
|
|
1179
|
+
* wrappers after local bundling has produced the runtime artifact.
|
|
1180
|
+
*/
|
|
1100
1181
|
async startPlayRunFromBundle(input2) {
|
|
1101
1182
|
const compilerManifest = input2.compilerManifest ?? await this.compilePlayManifest({
|
|
1102
1183
|
name: input2.name,
|
|
@@ -1254,6 +1335,12 @@ var DeeplineClient = class {
|
|
|
1254
1335
|
const response = await this.http.postFormData("/api/v2/plays/files/stage", buildFormData);
|
|
1255
1336
|
return response.files;
|
|
1256
1337
|
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Resolve staged play files by content hash without uploading bytes.
|
|
1340
|
+
*
|
|
1341
|
+
* Missing files are returned so callers can upload only the files the server
|
|
1342
|
+
* does not already have.
|
|
1343
|
+
*/
|
|
1257
1344
|
async resolveStagedPlayFiles(files) {
|
|
1258
1345
|
return this.http.post("/api/v2/plays/files/stage", { files });
|
|
1259
1346
|
}
|
|
@@ -1470,6 +1557,12 @@ var DeeplineClient = class {
|
|
|
1470
1557
|
entries
|
|
1471
1558
|
};
|
|
1472
1559
|
}
|
|
1560
|
+
/**
|
|
1561
|
+
* Export persisted runtime-sheet rows for a play dataset/table namespace.
|
|
1562
|
+
*
|
|
1563
|
+
* This is the SDK form of exporting `ctx.dataset(...).run()` output for a
|
|
1564
|
+
* specific play and optional run id.
|
|
1565
|
+
*/
|
|
1473
1566
|
async getPlaySheetRows(input2) {
|
|
1474
1567
|
const params = new URLSearchParams({
|
|
1475
1568
|
tableNamespace: input2.tableNamespace,
|
|
@@ -1498,6 +1591,12 @@ var DeeplineClient = class {
|
|
|
1498
1591
|
options?.reason ? { reason: options.reason } : {}
|
|
1499
1592
|
);
|
|
1500
1593
|
}
|
|
1594
|
+
/**
|
|
1595
|
+
* List callable plays visible to the workspace.
|
|
1596
|
+
*
|
|
1597
|
+
* Pass `origin: "prebuilt"` for Deepline-managed prebuilts or
|
|
1598
|
+
* `origin: "owned"` for org-owned plays.
|
|
1599
|
+
*/
|
|
1501
1600
|
async listPlays(options) {
|
|
1502
1601
|
const params = new URLSearchParams();
|
|
1503
1602
|
if (options?.origin) params.set("origin", options.origin);
|
|
@@ -1512,15 +1611,32 @@ var DeeplineClient = class {
|
|
|
1512
1611
|
);
|
|
1513
1612
|
return response.plays ?? [];
|
|
1514
1613
|
}
|
|
1614
|
+
/**
|
|
1615
|
+
* Search callable plays and return compact play descriptions.
|
|
1616
|
+
*
|
|
1617
|
+
* Prebuilt plays are preferred by default because they have maintained
|
|
1618
|
+
* contracts and stable run behavior.
|
|
1619
|
+
*/
|
|
1515
1620
|
async searchPlays(options) {
|
|
1516
1621
|
const params = new URLSearchParams();
|
|
1517
1622
|
params.set("search", options.query.trim());
|
|
1623
|
+
const scope = options.scope ?? "prebuilt";
|
|
1624
|
+
if (scope !== "all") {
|
|
1625
|
+
params.set("origin", scope);
|
|
1626
|
+
}
|
|
1518
1627
|
const response = await this.http.get(
|
|
1519
1628
|
`/api/v2/plays?${params.toString()}`
|
|
1520
1629
|
);
|
|
1521
|
-
|
|
1630
|
+
const plays = (response.plays ?? []).map(
|
|
1522
1631
|
(play) => this.summarizePlayListItem(play, options)
|
|
1523
1632
|
);
|
|
1633
|
+
if (scope === "prebuilt") {
|
|
1634
|
+
return plays.filter(isPrebuiltPlayDescription);
|
|
1635
|
+
}
|
|
1636
|
+
if (scope === "owned") {
|
|
1637
|
+
return plays.filter((play) => !isPrebuiltPlayDescription(play));
|
|
1638
|
+
}
|
|
1639
|
+
return preferPrebuiltPlayDescriptions(plays);
|
|
1524
1640
|
}
|
|
1525
1641
|
/**
|
|
1526
1642
|
* Get the full definition and state of a named play.
|
|
@@ -1543,6 +1659,12 @@ var DeeplineClient = class {
|
|
|
1543
1659
|
const encodedName = encodeURIComponent(name);
|
|
1544
1660
|
return this.http.get(`/api/v2/plays/${encodedName}`);
|
|
1545
1661
|
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Get a normalized play description suitable for agents and CLIs.
|
|
1664
|
+
*
|
|
1665
|
+
* The description includes runnable examples, input/output summaries, clone
|
|
1666
|
+
* guidance, revision state, and latest run metadata when available.
|
|
1667
|
+
*/
|
|
1546
1668
|
async describePlay(name, options) {
|
|
1547
1669
|
const detail = await this.getPlay(name);
|
|
1548
1670
|
return this.summarizePlayDetail(detail, options);
|
|
@@ -2125,6 +2247,9 @@ function readCsvRows(csvPath) {
|
|
|
2125
2247
|
function csvStringFromRows(rows, columns) {
|
|
2126
2248
|
return stringify(rows, {
|
|
2127
2249
|
header: true,
|
|
2250
|
+
cast: {
|
|
2251
|
+
boolean: (value) => value ? "true" : "false"
|
|
2252
|
+
},
|
|
2128
2253
|
...columns?.length ? { columns } : {}
|
|
2129
2254
|
});
|
|
2130
2255
|
}
|
|
@@ -2406,7 +2531,7 @@ function buildCandidateUrls2(url) {
|
|
|
2406
2531
|
}
|
|
2407
2532
|
}
|
|
2408
2533
|
function sleep3(ms) {
|
|
2409
|
-
return new Promise((
|
|
2534
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
2410
2535
|
}
|
|
2411
2536
|
function printDeeplineLogo() {
|
|
2412
2537
|
if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
|
|
@@ -4674,7 +4799,12 @@ function readPackageVersionFromPackageJson(packageJsonPath, packageName) {
|
|
|
4674
4799
|
return null;
|
|
4675
4800
|
}
|
|
4676
4801
|
function findPackageJsonPathFrom(startDir, packageName) {
|
|
4677
|
-
|
|
4802
|
+
if (!isAbsolute(startDir)) {
|
|
4803
|
+
throw new Error(
|
|
4804
|
+
`Package resolution requires an absolute start directory, got ${startDir}`
|
|
4805
|
+
);
|
|
4806
|
+
}
|
|
4807
|
+
let current = startDir;
|
|
4678
4808
|
while (true) {
|
|
4679
4809
|
const packageJsonPath = join4(
|
|
4680
4810
|
current,
|
|
@@ -4694,17 +4824,15 @@ function findPackageJsonPathFrom(startDir, packageName) {
|
|
|
4694
4824
|
}
|
|
4695
4825
|
function findPackageJsonPath(packageName, fromFile, adapter) {
|
|
4696
4826
|
const startDirs = [
|
|
4697
|
-
dirname5(fromFile),
|
|
4698
|
-
adapter.projectRoot,
|
|
4699
|
-
dirname5(adapter.sdkPackageJson)
|
|
4700
|
-
process.cwd()
|
|
4827
|
+
resolve6(dirname5(fromFile)),
|
|
4828
|
+
resolve6(adapter.projectRoot),
|
|
4829
|
+
resolve6(dirname5(adapter.sdkPackageJson))
|
|
4701
4830
|
];
|
|
4702
4831
|
const seen = /* @__PURE__ */ new Set();
|
|
4703
4832
|
for (const startDir of startDirs) {
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
const packageJsonPath = findPackageJsonPathFrom(normalized, packageName);
|
|
4833
|
+
if (seen.has(startDir)) continue;
|
|
4834
|
+
seen.add(startDir);
|
|
4835
|
+
const packageJsonPath = findPackageJsonPathFrom(startDir, packageName);
|
|
4708
4836
|
if (packageJsonPath) return packageJsonPath;
|
|
4709
4837
|
}
|
|
4710
4838
|
const adapterNodeModulesPackageJson = join4(
|
|
@@ -5162,13 +5290,13 @@ async function writeArtifactCache(artifact, adapter) {
|
|
|
5162
5290
|
"utf-8"
|
|
5163
5291
|
);
|
|
5164
5292
|
}
|
|
5165
|
-
function normalizeSourceMapForRuntime(sourceMapText) {
|
|
5293
|
+
function normalizeSourceMapForRuntime(sourceMapText, projectRoot) {
|
|
5166
5294
|
const parsed = JSON.parse(sourceMapText);
|
|
5167
5295
|
parsed.sources = (parsed.sources ?? []).map((sourcePath) => {
|
|
5168
5296
|
if (sourcePath.startsWith("data:") || sourcePath.startsWith("node:") || sourcePath.startsWith("/") || /^[a-zA-Z]+:\/\//.test(sourcePath)) {
|
|
5169
5297
|
return sourcePath;
|
|
5170
5298
|
}
|
|
5171
|
-
return
|
|
5299
|
+
return join4(projectRoot, sourcePath);
|
|
5172
5300
|
});
|
|
5173
5301
|
parsed.sourceRoot = void 0;
|
|
5174
5302
|
return JSON.stringify(parsed);
|
|
@@ -5434,7 +5562,10 @@ workers-harness:${harnessFingerprint}`
|
|
|
5434
5562
|
};
|
|
5435
5563
|
}
|
|
5436
5564
|
const { bundledCode, sourceMapText, outputExtension } = buildOutcome;
|
|
5437
|
-
const normalizedSourceMap = normalizeSourceMapForRuntime(
|
|
5565
|
+
const normalizedSourceMap = normalizeSourceMapForRuntime(
|
|
5566
|
+
sourceMapText,
|
|
5567
|
+
resolve6(adapter.projectRoot)
|
|
5568
|
+
);
|
|
5438
5569
|
const virtualBaseName = exportName === "default" ? basename(absolutePath).replace(/\.[^.]+$/, "") : `${basename(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
|
|
5439
5570
|
const virtualFilename = `/virtual/deepline-plays/${analysis.graphHash}/${virtualBaseName}.${outputExtension}`;
|
|
5440
5571
|
const executableCode = `${bundledCode}
|
|
@@ -5508,12 +5639,16 @@ var PLAY_DEDUP_BACKENDS = {
|
|
|
5508
5639
|
var PLAY_SCHEDULER_BACKENDS = {
|
|
5509
5640
|
temporal: "temporal",
|
|
5510
5641
|
cfWorkflows: "cf-workflows",
|
|
5642
|
+
postgres: "postgres",
|
|
5511
5643
|
inProcess: "in-process"
|
|
5512
5644
|
};
|
|
5513
5645
|
|
|
5514
5646
|
// ../shared_libs/play-runtime/providers.ts
|
|
5515
5647
|
var PLAY_RUNTIME_PROVIDER_IDS = {
|
|
5516
5648
|
workersEdge: "workers_edge",
|
|
5649
|
+
postgresFast: "postgres_fast",
|
|
5650
|
+
postgresFastSandbox: "postgres_fast_sandbox",
|
|
5651
|
+
postgresFastWorkers: "postgres_fast_workers",
|
|
5517
5652
|
local: "local"
|
|
5518
5653
|
};
|
|
5519
5654
|
var PLAY_RUNTIME_PROVIDERS = {
|
|
@@ -5525,6 +5660,30 @@ var PLAY_RUNTIME_PROVIDERS = {
|
|
|
5525
5660
|
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
5526
5661
|
label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
|
|
5527
5662
|
},
|
|
5663
|
+
postgres_fast: {
|
|
5664
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFast,
|
|
5665
|
+
scheduler: PLAY_SCHEDULER_BACKENDS.postgres,
|
|
5666
|
+
runner: PLAY_RUNTIME_BACKENDS.daytona,
|
|
5667
|
+
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
5668
|
+
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
5669
|
+
label: "Experimental Postgres Scheduler + warm sandbox runner + DO dedup"
|
|
5670
|
+
},
|
|
5671
|
+
postgres_fast_sandbox: {
|
|
5672
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFastSandbox,
|
|
5673
|
+
scheduler: PLAY_SCHEDULER_BACKENDS.postgres,
|
|
5674
|
+
runner: PLAY_RUNTIME_BACKENDS.daytona,
|
|
5675
|
+
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
5676
|
+
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
5677
|
+
label: "Experimental Postgres Scheduler + warm sandbox runner + DO dedup"
|
|
5678
|
+
},
|
|
5679
|
+
postgres_fast_workers: {
|
|
5680
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFastWorkers,
|
|
5681
|
+
scheduler: PLAY_SCHEDULER_BACKENDS.postgres,
|
|
5682
|
+
runner: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
|
|
5683
|
+
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
5684
|
+
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
5685
|
+
label: "Experimental Postgres Scheduler + Queue/DO-woken Workers + DO dedup"
|
|
5686
|
+
},
|
|
5528
5687
|
local: {
|
|
5529
5688
|
id: PLAY_RUNTIME_PROVIDER_IDS.local,
|
|
5530
5689
|
scheduler: PLAY_SCHEDULER_BACKENDS.temporal,
|
|
@@ -7814,7 +7973,7 @@ function traceCliSync(phase, fields, run) {
|
|
|
7814
7973
|
}
|
|
7815
7974
|
}
|
|
7816
7975
|
function sleep4(ms) {
|
|
7817
|
-
return new Promise((
|
|
7976
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
7818
7977
|
}
|
|
7819
7978
|
function parseReferencedPlayTarget2(target) {
|
|
7820
7979
|
const trimmed = target.trim();
|
|
@@ -8152,9 +8311,10 @@ function formatUnresolvedPackagedFiles(filePath, unresolvedFileReferences) {
|
|
|
8152
8311
|
const details = unresolvedFileReferences.map((unresolved) => `${unresolved.sourceFragment}: ${unresolved.message}`).join("; ");
|
|
8153
8312
|
return `Failed to package local ctx.csv(...) files in ${filePath}: ${details}`;
|
|
8154
8313
|
}
|
|
8155
|
-
async function collectBundledPlayGraph(entryFile) {
|
|
8314
|
+
async function collectBundledPlayGraph(entryFile, profile = null) {
|
|
8156
8315
|
const nodes = /* @__PURE__ */ new Map();
|
|
8157
8316
|
const visiting = /* @__PURE__ */ new Set();
|
|
8317
|
+
const artifactKind = resolveExecutionProfile(profile).artifactKind;
|
|
8158
8318
|
const visit = async (filePath) => {
|
|
8159
8319
|
const absolutePath = normalizePlayPath(filePath);
|
|
8160
8320
|
const cached = nodes.get(absolutePath);
|
|
@@ -8169,7 +8329,7 @@ async function collectBundledPlayGraph(entryFile) {
|
|
|
8169
8329
|
visiting.add(absolutePath);
|
|
8170
8330
|
try {
|
|
8171
8331
|
const bundleResult = await bundlePlayFile2(absolutePath, {
|
|
8172
|
-
target:
|
|
8332
|
+
target: artifactKind
|
|
8173
8333
|
});
|
|
8174
8334
|
if (bundleResult.success === false) {
|
|
8175
8335
|
throw new Error(
|
|
@@ -8284,7 +8444,8 @@ function formatTimestamp(value) {
|
|
|
8284
8444
|
return date.toISOString();
|
|
8285
8445
|
}
|
|
8286
8446
|
function formatRunLine(run) {
|
|
8287
|
-
|
|
8447
|
+
const credits = typeof run.billingTotalCredits === "number" && Number.isFinite(run.billingTotalCredits) ? `${formatCreditAmount(run.billingTotalCredits)} credits` : "\u2014";
|
|
8448
|
+
return `${run.workflowId} ${run.status} ${formatTimestamp(run.startTime)} ${credits}`;
|
|
8288
8449
|
}
|
|
8289
8450
|
function isTransientPlayStreamError(error) {
|
|
8290
8451
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
@@ -8331,6 +8492,8 @@ var TERMINAL_PLAY_STATUSES2 = /* @__PURE__ */ new Set([
|
|
|
8331
8492
|
"cancelled"
|
|
8332
8493
|
]);
|
|
8333
8494
|
var PLAY_START_TRANSIENT_RETRY_DELAYS_MS = [500, 1500];
|
|
8495
|
+
var PLAY_PROGRESS_HEARTBEAT_INTERVAL_MS = 15e3;
|
|
8496
|
+
var PLAY_STATUS_HEARTBEAT_INTERVAL_MS = 15e3;
|
|
8334
8497
|
function getEventPayload(event) {
|
|
8335
8498
|
return event.payload && typeof event.payload === "object" ? event.payload : {};
|
|
8336
8499
|
}
|
|
@@ -8391,6 +8554,7 @@ function extractTableNamespaceFromLiveEvent(event) {
|
|
|
8391
8554
|
const payload = getEventPayload(event);
|
|
8392
8555
|
const candidates = [
|
|
8393
8556
|
payload.artifactTableNamespace,
|
|
8557
|
+
payload.activeArtifactTableNamespace,
|
|
8394
8558
|
payload.tableNamespace,
|
|
8395
8559
|
payload.mapNodeId
|
|
8396
8560
|
];
|
|
@@ -8469,6 +8633,20 @@ function formatProgressCounts(input2) {
|
|
|
8469
8633
|
const failed = typeof input2.failed === "number" && Number.isFinite(input2.failed) && input2.failed > 0 ? `, failed ${formatInteger(input2.failed)}` : "";
|
|
8470
8634
|
return `${formatInteger(completed)}/${formatInteger(total)} (${percent}%)${failed}`;
|
|
8471
8635
|
}
|
|
8636
|
+
function formatProgressMessageSuffix(input2) {
|
|
8637
|
+
const message = typeof input2.message === "string" ? input2.message.trim() : "";
|
|
8638
|
+
if (!message) {
|
|
8639
|
+
return "";
|
|
8640
|
+
}
|
|
8641
|
+
const completed = typeof input2.completed === "number" && Number.isFinite(input2.completed) ? input2.completed : null;
|
|
8642
|
+
if (/^[\d,]+\s*\/\s*[\d,]+\s+rows processed$/i.test(message)) {
|
|
8643
|
+
return "";
|
|
8644
|
+
}
|
|
8645
|
+
if (completed !== null && completed > 0 && /rows?\s+queued\b/i.test(message)) {
|
|
8646
|
+
return "";
|
|
8647
|
+
}
|
|
8648
|
+
return ` - ${message}`;
|
|
8649
|
+
}
|
|
8472
8650
|
function getProgressLinesFromLiveEvent(event) {
|
|
8473
8651
|
const payload = getEventPayload(event);
|
|
8474
8652
|
if (event.type === "play.step.progress") {
|
|
@@ -8478,7 +8656,13 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
8478
8656
|
failed: payload.failed
|
|
8479
8657
|
});
|
|
8480
8658
|
if (!counts) return [];
|
|
8481
|
-
|
|
8659
|
+
const messageSuffix = formatProgressMessageSuffix({
|
|
8660
|
+
message: payload.message,
|
|
8661
|
+
completed: payload.completed
|
|
8662
|
+
});
|
|
8663
|
+
return [
|
|
8664
|
+
`progress ${formatProgressLabel(payload.stepId)}: ${counts}${messageSuffix}`
|
|
8665
|
+
];
|
|
8482
8666
|
}
|
|
8483
8667
|
if (event.type !== "play.run.snapshot" && event.type !== "play.run.final_status") {
|
|
8484
8668
|
return [];
|
|
@@ -8502,22 +8686,69 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
8502
8686
|
if (!counts) {
|
|
8503
8687
|
continue;
|
|
8504
8688
|
}
|
|
8689
|
+
const messageSuffix = formatProgressMessageSuffix({
|
|
8690
|
+
message: progress.message,
|
|
8691
|
+
completed: progress.completed
|
|
8692
|
+
});
|
|
8505
8693
|
lines.push(
|
|
8506
|
-
`progress ${formatProgressLabel(record.nodeId ?? progress.artifactTableNamespace)}: ${counts}`
|
|
8694
|
+
`progress ${formatProgressLabel(record.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
|
|
8507
8695
|
);
|
|
8508
8696
|
}
|
|
8509
8697
|
return lines;
|
|
8510
8698
|
}
|
|
8699
|
+
function shouldPrintPlayProgressLine(input2) {
|
|
8700
|
+
if (!input2.signature) {
|
|
8701
|
+
return false;
|
|
8702
|
+
}
|
|
8703
|
+
return input2.lastProgressSignature !== input2.signature || input2.nowMs - input2.lastProgressHeartbeatAt >= PLAY_PROGRESS_HEARTBEAT_INTERVAL_MS;
|
|
8704
|
+
}
|
|
8511
8705
|
function printPlayProgressLines(input2) {
|
|
8512
8706
|
for (const line of input2.lines) {
|
|
8513
8707
|
const signature = line.trim();
|
|
8514
|
-
|
|
8708
|
+
const now = Date.now();
|
|
8709
|
+
if (!shouldPrintPlayProgressLine({
|
|
8710
|
+
signature,
|
|
8711
|
+
lastProgressSignature: input2.state.lastProgressSignature,
|
|
8712
|
+
lastProgressHeartbeatAt: input2.state.lastProgressHeartbeatAt,
|
|
8713
|
+
nowMs: now
|
|
8714
|
+
})) {
|
|
8515
8715
|
continue;
|
|
8516
8716
|
}
|
|
8517
8717
|
input2.state.lastProgressSignature = signature;
|
|
8718
|
+
input2.state.lastProgressHeartbeatAt = now;
|
|
8518
8719
|
input2.progress.writeLine(line);
|
|
8519
8720
|
}
|
|
8520
8721
|
}
|
|
8722
|
+
function getRunningHeartbeatLine(input2) {
|
|
8723
|
+
const status = getStatusFromLiveEvent(input2.event);
|
|
8724
|
+
if (status !== "queued" && status !== "running" && status !== "waiting") {
|
|
8725
|
+
return null;
|
|
8726
|
+
}
|
|
8727
|
+
const tableNamespace = extractTableNamespaceFromLiveEvent(input2.event);
|
|
8728
|
+
const target = tableNamespace ? formatProgressLabel(tableNamespace) : input2.playName;
|
|
8729
|
+
if (status === "queued") {
|
|
8730
|
+
return `queued ${target}: waiting for worker capacity`;
|
|
8731
|
+
}
|
|
8732
|
+
if (status === "waiting") {
|
|
8733
|
+
return `waiting ${target}: waiting on external work`;
|
|
8734
|
+
}
|
|
8735
|
+
return `running ${target}: still processing`;
|
|
8736
|
+
}
|
|
8737
|
+
function printPlayStatusHeartbeat(input2) {
|
|
8738
|
+
const now = Date.now();
|
|
8739
|
+
if (now - input2.state.lastStatusHeartbeatAt < PLAY_STATUS_HEARTBEAT_INTERVAL_MS) {
|
|
8740
|
+
return;
|
|
8741
|
+
}
|
|
8742
|
+
const line = getRunningHeartbeatLine({
|
|
8743
|
+
event: input2.event,
|
|
8744
|
+
playName: input2.playName
|
|
8745
|
+
});
|
|
8746
|
+
if (!line) {
|
|
8747
|
+
return;
|
|
8748
|
+
}
|
|
8749
|
+
input2.state.lastStatusHeartbeatAt = now;
|
|
8750
|
+
input2.progress.writeLine(line);
|
|
8751
|
+
}
|
|
8521
8752
|
function buildPlayDashboardUrl(baseUrl, playName) {
|
|
8522
8753
|
const trimmedBase = baseUrl.replace(/\/$/, "");
|
|
8523
8754
|
const encodedPlayName = encodeURIComponent(playName);
|
|
@@ -8600,11 +8831,20 @@ async function waitForPlayCompletionByStream(input2) {
|
|
|
8600
8831
|
progress: input2.progress
|
|
8601
8832
|
});
|
|
8602
8833
|
if (!input2.jsonOutput) {
|
|
8834
|
+
const progressLines = getProgressLinesFromLiveEvent(event);
|
|
8603
8835
|
printPlayProgressLines({
|
|
8604
|
-
lines:
|
|
8836
|
+
lines: progressLines,
|
|
8605
8837
|
state: input2.state,
|
|
8606
8838
|
progress: input2.progress
|
|
8607
8839
|
});
|
|
8840
|
+
if (progressLines.length === 0) {
|
|
8841
|
+
printPlayStatusHeartbeat({
|
|
8842
|
+
event,
|
|
8843
|
+
playName: input2.playName,
|
|
8844
|
+
state: input2.state,
|
|
8845
|
+
progress: input2.progress
|
|
8846
|
+
});
|
|
8847
|
+
}
|
|
8608
8848
|
}
|
|
8609
8849
|
const finalStatus = getFinalStatusFromLiveEvent(event);
|
|
8610
8850
|
if (finalStatus) {
|
|
@@ -8682,7 +8922,9 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
8682
8922
|
const state = {
|
|
8683
8923
|
lastLogIndex: 0,
|
|
8684
8924
|
emittedRunnerStarted: false,
|
|
8685
|
-
lastProgressSignature: null
|
|
8925
|
+
lastProgressSignature: null,
|
|
8926
|
+
lastProgressHeartbeatAt: 0,
|
|
8927
|
+
lastStatusHeartbeatAt: 0
|
|
8686
8928
|
};
|
|
8687
8929
|
const controller = new AbortController();
|
|
8688
8930
|
let timedOut = false;
|
|
@@ -8723,7 +8965,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
8723
8965
|
dashboardUrl,
|
|
8724
8966
|
noOpen: input2.noOpen
|
|
8725
8967
|
});
|
|
8726
|
-
input2.progress.phase(
|
|
8968
|
+
input2.progress.phase("running");
|
|
8727
8969
|
emittedDashboardUrl = true;
|
|
8728
8970
|
}
|
|
8729
8971
|
assertPlayWaitNotTimedOut({
|
|
@@ -8754,11 +8996,20 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
8754
8996
|
progress: input2.progress
|
|
8755
8997
|
});
|
|
8756
8998
|
if (!input2.jsonOutput) {
|
|
8999
|
+
const progressLines = getProgressLinesFromLiveEvent(event);
|
|
8757
9000
|
printPlayProgressLines({
|
|
8758
|
-
lines:
|
|
9001
|
+
lines: progressLines,
|
|
8759
9002
|
state,
|
|
8760
9003
|
progress: input2.progress
|
|
8761
9004
|
});
|
|
9005
|
+
if (progressLines.length === 0) {
|
|
9006
|
+
printPlayStatusHeartbeat({
|
|
9007
|
+
event,
|
|
9008
|
+
playName: input2.playName,
|
|
9009
|
+
state,
|
|
9010
|
+
progress: input2.progress
|
|
9011
|
+
});
|
|
9012
|
+
}
|
|
8762
9013
|
}
|
|
8763
9014
|
const finalStatus = getFinalStatusFromLiveEvent(event);
|
|
8764
9015
|
if (finalStatus) {
|
|
@@ -9358,6 +9609,17 @@ function getPlayRunPackage(status) {
|
|
|
9358
9609
|
const packaged = status.package;
|
|
9359
9610
|
return isPlayRunPackageValue(packaged) ? packaged : null;
|
|
9360
9611
|
}
|
|
9612
|
+
function withTerminalPlayIdentity(status, playName) {
|
|
9613
|
+
if (!playName.trim() || getPlayRunPackage(status)) {
|
|
9614
|
+
return status;
|
|
9615
|
+
}
|
|
9616
|
+
const record = status;
|
|
9617
|
+
const hasIdentity = typeof record.playName === "string" && record.playName.trim().length > 0 || typeof record.name === "string" && record.name.trim().length > 0 || Boolean(getStringField(record.run, "playName"));
|
|
9618
|
+
if (hasIdentity) {
|
|
9619
|
+
return status;
|
|
9620
|
+
}
|
|
9621
|
+
return { ...status, playName };
|
|
9622
|
+
}
|
|
9361
9623
|
function compactPlayStatus(status) {
|
|
9362
9624
|
const packaged = getPlayRunPackage(status);
|
|
9363
9625
|
if (packaged) {
|
|
@@ -9534,6 +9796,9 @@ function actionToCommand(action) {
|
|
|
9534
9796
|
if (record.kind === "deepline_run_inspect" && typeof record.runId === "string") {
|
|
9535
9797
|
return `deepline runs get ${record.runId} --json`;
|
|
9536
9798
|
}
|
|
9799
|
+
if (record.kind === "deepline_run_billing" && typeof record.runId === "string") {
|
|
9800
|
+
return `deepline runs get ${record.runId} --full --json | jq '.billing'`;
|
|
9801
|
+
}
|
|
9537
9802
|
if (record.kind === "deepline_run_export" && typeof record.runId === "string" && typeof record.datasetPath === "string") {
|
|
9538
9803
|
return `deepline runs export ${record.runId} --dataset ${shellSingleQuote(
|
|
9539
9804
|
record.datasetPath
|
|
@@ -9566,6 +9831,12 @@ function buildRunPackageTextLines(packaged) {
|
|
|
9566
9831
|
if (playName) {
|
|
9567
9832
|
lines.push(` play: ${playName}`);
|
|
9568
9833
|
}
|
|
9834
|
+
const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
|
|
9835
|
+
const billingCommand = actionToCommand(next.billing);
|
|
9836
|
+
if (billingCommand) {
|
|
9837
|
+
const costState = status === "completed" || status === "failed" || status === "cancelled" ? "finalizing" : "pending";
|
|
9838
|
+
lines.push(` cost: ${costState}`);
|
|
9839
|
+
}
|
|
9569
9840
|
for (const step of readRecordArray(packaged.steps).slice(0, 8)) {
|
|
9570
9841
|
const id = typeof step.id === "string" ? step.id : "step";
|
|
9571
9842
|
const kind = typeof step.kind === "string" ? step.kind : "step";
|
|
@@ -9582,12 +9853,12 @@ function buildRunPackageTextLines(packaged) {
|
|
|
9582
9853
|
);
|
|
9583
9854
|
}
|
|
9584
9855
|
}
|
|
9585
|
-
const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
|
|
9586
9856
|
const datasetActions = readFirstDatasetActions(packaged);
|
|
9587
9857
|
const inspectCommand = actionToCommand(next.inspect);
|
|
9588
9858
|
const queryCommand = actionToCommand(next.query) ?? actionToCommand(datasetActions.query);
|
|
9589
9859
|
const exportCommand = actionToCommand(next.export) ?? actionToCommand(datasetActions.exportCsv);
|
|
9590
9860
|
if (inspectCommand) lines.push(` inspect: ${inspectCommand}`);
|
|
9861
|
+
if (billingCommand) lines.push(` billing: ${billingCommand}`);
|
|
9591
9862
|
if (queryCommand) lines.push(` query: ${queryCommand}`);
|
|
9592
9863
|
if (exportCommand) lines.push(` export CSV: ${exportCommand}`);
|
|
9593
9864
|
return lines;
|
|
@@ -10136,7 +10407,7 @@ function writeStartedPlayRun(input2) {
|
|
|
10136
10407
|
);
|
|
10137
10408
|
}
|
|
10138
10409
|
function parsePlayRunOptions(args) {
|
|
10139
|
-
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotency, tool call id, and ctx.dataset guidance.";
|
|
10410
|
+
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotency, tool call id, and ctx.dataset guidance.";
|
|
10140
10411
|
let filePath = null;
|
|
10141
10412
|
let playName = null;
|
|
10142
10413
|
let input2 = null;
|
|
@@ -10149,6 +10420,7 @@ function parsePlayRunOptions(args) {
|
|
|
10149
10420
|
const force = args.includes("--force");
|
|
10150
10421
|
const noOpen = args.includes("--no-open");
|
|
10151
10422
|
let waitTimeoutMs = null;
|
|
10423
|
+
let profile = null;
|
|
10152
10424
|
for (let index = 0; index < args.length; index += 1) {
|
|
10153
10425
|
const arg = args[index];
|
|
10154
10426
|
if (arg === "--file" && args[index + 1]) {
|
|
@@ -10167,6 +10439,16 @@ function parsePlayRunOptions(args) {
|
|
|
10167
10439
|
revisionId = args[++index];
|
|
10168
10440
|
continue;
|
|
10169
10441
|
}
|
|
10442
|
+
if (arg === "--profile") {
|
|
10443
|
+
const value = args[index + 1];
|
|
10444
|
+
if (!value) {
|
|
10445
|
+
throw new Error("--profile requires an execution profile id.");
|
|
10446
|
+
}
|
|
10447
|
+
profile = value.trim();
|
|
10448
|
+
resolveExecutionProfile(profile);
|
|
10449
|
+
index += 1;
|
|
10450
|
+
continue;
|
|
10451
|
+
}
|
|
10170
10452
|
if (arg === "--live") {
|
|
10171
10453
|
revisionSelector = "live";
|
|
10172
10454
|
continue;
|
|
@@ -10254,7 +10536,8 @@ function parsePlayRunOptions(args) {
|
|
|
10254
10536
|
fullJson,
|
|
10255
10537
|
waitTimeoutMs,
|
|
10256
10538
|
force,
|
|
10257
|
-
noOpen
|
|
10539
|
+
noOpen,
|
|
10540
|
+
profile
|
|
10258
10541
|
};
|
|
10259
10542
|
}
|
|
10260
10543
|
function parsePlayCheckOptions(args) {
|
|
@@ -10531,7 +10814,7 @@ async function handleFileBackedRun(options) {
|
|
|
10531
10814
|
graph = await traceCliSpan(
|
|
10532
10815
|
"cli.play_file_bundle_graph",
|
|
10533
10816
|
{ targetKind: "file" },
|
|
10534
|
-
() => collectBundledPlayGraph(absolutePlayPath)
|
|
10817
|
+
() => collectBundledPlayGraph(absolutePlayPath, options.profile)
|
|
10535
10818
|
);
|
|
10536
10819
|
await traceCliSpan(
|
|
10537
10820
|
"cli.play_file_compile_manifests",
|
|
@@ -10591,7 +10874,8 @@ async function handleFileBackedRun(options) {
|
|
|
10591
10874
|
...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
|
|
10592
10875
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
10593
10876
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
10594
|
-
...options.force ? { force: true } : {}
|
|
10877
|
+
...options.force ? { force: true } : {},
|
|
10878
|
+
...options.profile ? { profile: options.profile } : {}
|
|
10595
10879
|
};
|
|
10596
10880
|
if (options.watch) {
|
|
10597
10881
|
progress.phase("starting run");
|
|
@@ -10616,11 +10900,14 @@ async function handleFileBackedRun(options) {
|
|
|
10616
10900
|
} else {
|
|
10617
10901
|
progress.fail();
|
|
10618
10902
|
}
|
|
10619
|
-
const outputStatus =
|
|
10620
|
-
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10903
|
+
const outputStatus = withTerminalPlayIdentity(
|
|
10904
|
+
await resolvePlayRunOutputStatus({
|
|
10905
|
+
client,
|
|
10906
|
+
status: finalStatus,
|
|
10907
|
+
fullJson: options.fullJson
|
|
10908
|
+
}),
|
|
10909
|
+
playName
|
|
10910
|
+
);
|
|
10624
10911
|
traceCliSync(
|
|
10625
10912
|
"cli.play_write_result",
|
|
10626
10913
|
{ targetKind: "file", playName },
|
|
@@ -10643,7 +10930,7 @@ async function handleFileBackedRun(options) {
|
|
|
10643
10930
|
dashboardUrl: resolvedDashboardUrl,
|
|
10644
10931
|
noOpen: options.noOpen
|
|
10645
10932
|
});
|
|
10646
|
-
progress.phase(
|
|
10933
|
+
progress.phase("started run");
|
|
10647
10934
|
progress.complete();
|
|
10648
10935
|
writeStartedPlayRun({
|
|
10649
10936
|
runId: started.workflowId,
|
|
@@ -10737,7 +11024,8 @@ async function handleNamedRun(options) {
|
|
|
10737
11024
|
...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
|
|
10738
11025
|
...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
|
|
10739
11026
|
...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
|
|
10740
|
-
...options.force ? { force: true } : {}
|
|
11027
|
+
...options.force ? { force: true } : {},
|
|
11028
|
+
...options.profile ? { profile: options.profile } : {}
|
|
10741
11029
|
};
|
|
10742
11030
|
if (options.watch) {
|
|
10743
11031
|
progress.phase("starting run");
|
|
@@ -10762,11 +11050,14 @@ async function handleNamedRun(options) {
|
|
|
10762
11050
|
} else {
|
|
10763
11051
|
progress.fail();
|
|
10764
11052
|
}
|
|
10765
|
-
const outputStatus =
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
11053
|
+
const outputStatus = withTerminalPlayIdentity(
|
|
11054
|
+
await resolvePlayRunOutputStatus({
|
|
11055
|
+
client,
|
|
11056
|
+
status: finalStatus,
|
|
11057
|
+
fullJson: options.fullJson
|
|
11058
|
+
}),
|
|
11059
|
+
playName
|
|
11060
|
+
);
|
|
10770
11061
|
traceCliSync(
|
|
10771
11062
|
"cli.play_write_result",
|
|
10772
11063
|
{ targetKind: "name", playName },
|
|
@@ -10789,7 +11080,7 @@ async function handleNamedRun(options) {
|
|
|
10789
11080
|
dashboardUrl: resolvedDashboardUrl,
|
|
10790
11081
|
noOpen: options.noOpen
|
|
10791
11082
|
});
|
|
10792
|
-
progress.phase(
|
|
11083
|
+
progress.phase("started run");
|
|
10793
11084
|
progress.complete();
|
|
10794
11085
|
writeStartedPlayRun({
|
|
10795
11086
|
runId: started.workflowId,
|
|
@@ -10901,10 +11192,12 @@ async function handleRunsList(args) {
|
|
|
10901
11192
|
startedAt: run.startTime,
|
|
10902
11193
|
finishedAt: run.closeTime,
|
|
10903
11194
|
executionTime: run.executionTime,
|
|
11195
|
+
billingTotalCredits: run.billingTotalCredits,
|
|
11196
|
+
billingMaxCreditsPerRun: run.billingMaxCreditsPerRun,
|
|
10904
11197
|
playName: run.memo?.playName ?? playName
|
|
10905
11198
|
}));
|
|
10906
11199
|
const lines = runs.length === 0 ? [`No runs found for ${playName}.`] : runs.map(
|
|
10907
|
-
(run) => `${run.runId} ${run.status} ${formatTimestamp(run.startedAt)}`
|
|
11200
|
+
(run) => `${run.runId} ${run.status} ${formatTimestamp(run.startedAt)} ${typeof run.billingTotalCredits === "number" && Number.isFinite(run.billingTotalCredits) ? `${formatCreditAmount(run.billingTotalCredits)} credits` : "\u2014"}`
|
|
10908
11201
|
);
|
|
10909
11202
|
printCommandEnvelope(
|
|
10910
11203
|
{
|
|
@@ -11275,16 +11568,19 @@ function parsePlaySearchOptions(args) {
|
|
|
11275
11568
|
const query = args[0]?.trim();
|
|
11276
11569
|
if (!query) {
|
|
11277
11570
|
throw new Error(
|
|
11278
|
-
"Usage: deepline plays search <query> [--compact] [--json]"
|
|
11571
|
+
"Usage: deepline plays search <query> [--all] [--compact] [--json]"
|
|
11279
11572
|
);
|
|
11280
11573
|
}
|
|
11281
11574
|
return {
|
|
11282
11575
|
query,
|
|
11283
11576
|
jsonOutput: argsWantJson(args),
|
|
11284
11577
|
compact: args.includes("--compact"),
|
|
11285
|
-
|
|
11578
|
+
scope: args.includes("--all") && !args.includes("--prebuilt") ? "all" : "prebuilt"
|
|
11286
11579
|
};
|
|
11287
11580
|
}
|
|
11581
|
+
function playSearchDisclaimer(scope) {
|
|
11582
|
+
return scope === "all" ? "Prebuilt-first search: Deepline-managed prebuilts are trusted, robust plays with maintained contracts, so they are listed before plays you created. Use created-play results only when you are specifically looking for one." : "Prebuilt-first search: Deepline-managed prebuilts are trusted, robust plays with maintained contracts. Plays you created are omitted by default; add --all only when you are specifically looking for one.";
|
|
11583
|
+
}
|
|
11288
11584
|
function printPlayDescription(play) {
|
|
11289
11585
|
const reference = formatPlayListReference(play);
|
|
11290
11586
|
const labels = [
|
|
@@ -11426,19 +11722,26 @@ async function handlePlaySearch(args) {
|
|
|
11426
11722
|
return 1;
|
|
11427
11723
|
}
|
|
11428
11724
|
const client = new DeeplineClient();
|
|
11429
|
-
const plays =
|
|
11725
|
+
const plays = await client.searchPlays({
|
|
11430
11726
|
query: options.query,
|
|
11431
|
-
compact: options.compact
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
);
|
|
11727
|
+
compact: options.compact,
|
|
11728
|
+
scope: options.scope
|
|
11729
|
+
});
|
|
11730
|
+
const disclaimer = playSearchDisclaimer(options.scope);
|
|
11435
11731
|
if (options.jsonOutput) {
|
|
11436
|
-
const jsonPlays = options.
|
|
11732
|
+
const jsonPlays = options.scope === "prebuilt" ? plays.map((play) => ({
|
|
11437
11733
|
...play,
|
|
11438
11734
|
inputSchema: compactPlaySchema(play.inputSchema)
|
|
11439
11735
|
})) : plays;
|
|
11440
11736
|
process.stdout.write(
|
|
11441
11737
|
`${JSON.stringify({
|
|
11738
|
+
disclaimer,
|
|
11739
|
+
search_policy: {
|
|
11740
|
+
default_scope: "prebuilt",
|
|
11741
|
+
included_origins: options.scope === "all" ? ["prebuilt", "owned"] : ["prebuilt"],
|
|
11742
|
+
owned_plays_omitted: options.scope === "prebuilt",
|
|
11743
|
+
include_owned_flag: "--all"
|
|
11744
|
+
},
|
|
11442
11745
|
plays: jsonPlays,
|
|
11443
11746
|
total: jsonPlays.length,
|
|
11444
11747
|
truncated: false
|
|
@@ -11447,21 +11750,23 @@ async function handlePlaySearch(args) {
|
|
|
11447
11750
|
);
|
|
11448
11751
|
return 0;
|
|
11449
11752
|
}
|
|
11450
|
-
const displayPlays = options.
|
|
11753
|
+
const displayPlays = options.scope === "prebuilt" ? plays.slice(0, 5) : plays;
|
|
11754
|
+
process.stdout.write(`${disclaimer}
|
|
11755
|
+
`);
|
|
11451
11756
|
process.stdout.write(
|
|
11452
|
-
`${plays.length} plays found${options.
|
|
11757
|
+
`${plays.length} plays found${options.scope === "prebuilt" && plays.length > displayPlays.length ? `; showing top ${displayPlays.length}` : ""}:
|
|
11453
11758
|
|
|
11454
11759
|
`
|
|
11455
11760
|
);
|
|
11456
11761
|
for (const play of displayPlays) {
|
|
11457
|
-
if (options.
|
|
11762
|
+
if (options.scope === "prebuilt") {
|
|
11458
11763
|
printCompactPlaySearchResult(play);
|
|
11459
11764
|
} else {
|
|
11460
11765
|
printPlayDescription(play);
|
|
11461
11766
|
}
|
|
11462
11767
|
console.log("");
|
|
11463
11768
|
}
|
|
11464
|
-
if (options.
|
|
11769
|
+
if (options.scope === "prebuilt" && plays.length > displayPlays.length) {
|
|
11465
11770
|
console.log("Use --json for the full machine-readable result set.");
|
|
11466
11771
|
}
|
|
11467
11772
|
return 0;
|
|
@@ -11825,6 +12130,9 @@ Examples:
|
|
|
11825
12130
|
).option("--file <path>", "Local play file to run").option("--name <name>", "Saved play name to run").option("-i, --input <json>", "Input JSON object or @file path").option("--live", "Run the current live revision explicitly").option("--latest", "Run the newest saved revision, even if it is not live").option(
|
|
11826
12131
|
"--revision-id <id>",
|
|
11827
12132
|
"Run a specific saved revision instead of the live revision"
|
|
12133
|
+
).option(
|
|
12134
|
+
"--profile <id>",
|
|
12135
|
+
"Internal/testing: override the execution profile for this run"
|
|
11828
12136
|
).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(
|
|
11829
12137
|
"--logs",
|
|
11830
12138
|
"When output is non-interactive, stream play logs to stderr while waiting"
|
|
@@ -11858,6 +12166,7 @@ Pass-through input flags:
|
|
|
11858
12166
|
...options.live ? ["--live"] : [],
|
|
11859
12167
|
...options.latest ? ["--latest"] : [],
|
|
11860
12168
|
...options.revisionId ? ["--revision-id", options.revisionId] : [],
|
|
12169
|
+
...options.profile ? ["--profile", options.profile] : [],
|
|
11861
12170
|
...options.wait === false ? ["--no-wait"] : [],
|
|
11862
12171
|
...options.watch || options.wait ? ["--watch"] : [],
|
|
11863
12172
|
...options.logs ? ["--logs"] : [],
|
|
@@ -11911,18 +12220,26 @@ Examples:
|
|
|
11911
12220
|
...options.json ? ["--json"] : []
|
|
11912
12221
|
]);
|
|
11913
12222
|
});
|
|
11914
|
-
const addPlaySearchCommand = (command) => command.description("Search
|
|
12223
|
+
const addPlaySearchCommand = (command) => command.description("Search Deepline prebuilt plays by task.").option(
|
|
12224
|
+
"--prebuilt",
|
|
12225
|
+
"Only show Deepline-managed prebuilt plays (default)"
|
|
12226
|
+
).option(
|
|
12227
|
+
"--all",
|
|
12228
|
+
"Also include plays you created after Deepline-managed prebuilts"
|
|
12229
|
+
).addHelpText(
|
|
11915
12230
|
"after",
|
|
11916
12231
|
`
|
|
11917
12232
|
Notes:
|
|
11918
|
-
Ranked discovery for workflows.
|
|
11919
|
-
|
|
11920
|
-
|
|
12233
|
+
Ranked discovery for workflows. Search defaults to Deepline-managed prebuilts
|
|
12234
|
+
because they are trusted, robust plays with maintained contracts. Use describe
|
|
12235
|
+
on a result before running it.
|
|
12236
|
+
Add --all only when you are specifically looking for a play you created.
|
|
11921
12237
|
The grep alias is the same ranked retrieval surface with a more literal name
|
|
11922
12238
|
for agents that are filtering the play registry.
|
|
11923
12239
|
|
|
11924
12240
|
Examples:
|
|
11925
12241
|
deepline plays search email
|
|
12242
|
+
deepline plays search email --all
|
|
11926
12243
|
deepline plays grep "linkedin to email" --compact --json
|
|
11927
12244
|
deepline plays describe person-linkedin-to-email --json
|
|
11928
12245
|
`
|
|
@@ -11930,6 +12247,7 @@ Examples:
|
|
|
11930
12247
|
process.exitCode = await handlePlaySearch([
|
|
11931
12248
|
query,
|
|
11932
12249
|
...options.prebuilt ? ["--prebuilt"] : [],
|
|
12250
|
+
...options.all ? ["--all"] : [],
|
|
11933
12251
|
...options.compact ? ["--compact"] : [],
|
|
11934
12252
|
...options.json ? ["--json"] : []
|
|
11935
12253
|
]);
|
|
@@ -13697,7 +14015,7 @@ async function readHiddenLine(prompt) {
|
|
|
13697
14015
|
if (typeof input.setRawMode === "function") input.setRawMode(true);
|
|
13698
14016
|
let value = "";
|
|
13699
14017
|
input.resume();
|
|
13700
|
-
return await new Promise((
|
|
14018
|
+
return await new Promise((resolve14, reject) => {
|
|
13701
14019
|
let settled = false;
|
|
13702
14020
|
const cleanup = () => {
|
|
13703
14021
|
input.off("data", onData);
|
|
@@ -13712,7 +14030,7 @@ async function readHiddenLine(prompt) {
|
|
|
13712
14030
|
settled = true;
|
|
13713
14031
|
output.write("\n");
|
|
13714
14032
|
cleanup();
|
|
13715
|
-
|
|
14033
|
+
resolve14(line);
|
|
13716
14034
|
};
|
|
13717
14035
|
const fail = (error) => {
|
|
13718
14036
|
if (settled) return;
|
|
@@ -13884,9 +14202,15 @@ Examples:
|
|
|
13884
14202
|
|
|
13885
14203
|
// src/cli/commands/tools.ts
|
|
13886
14204
|
import { Option } from "commander";
|
|
13887
|
-
import {
|
|
14205
|
+
import {
|
|
14206
|
+
chmodSync,
|
|
14207
|
+
existsSync as existsSync8,
|
|
14208
|
+
mkdtempSync,
|
|
14209
|
+
readFileSync as readFileSync7,
|
|
14210
|
+
writeFileSync as writeFileSync9
|
|
14211
|
+
} from "fs";
|
|
13888
14212
|
import { tmpdir as tmpdir4 } from "os";
|
|
13889
|
-
import { join as join10 } from "path";
|
|
14213
|
+
import { join as join10, resolve as resolve12 } from "path";
|
|
13890
14214
|
|
|
13891
14215
|
// src/tool-output.ts
|
|
13892
14216
|
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync8 } from "fs";
|
|
@@ -14477,7 +14801,13 @@ Examples:
|
|
|
14477
14801
|
).option(
|
|
14478
14802
|
"--json [payload]",
|
|
14479
14803
|
"Emit JSON output. Use `--input` or `--payload` for passing JSON params."
|
|
14480
|
-
).option(
|
|
14804
|
+
).option(
|
|
14805
|
+
"--input <payload>",
|
|
14806
|
+
"Merge a JSON object or @file path into the tool params"
|
|
14807
|
+
).option(
|
|
14808
|
+
"--payload <payload>",
|
|
14809
|
+
"Merge a JSON object or @file path into the tool params"
|
|
14810
|
+
).option(
|
|
14481
14811
|
"--output-format <format>",
|
|
14482
14812
|
"Output format: auto, csv, csv_file, json, or json_file"
|
|
14483
14813
|
).option(
|
|
@@ -15048,6 +15378,57 @@ function normalizeOutputFormat(raw) {
|
|
|
15048
15378
|
throw new Error(`Invalid value for --output-format: ${raw}`);
|
|
15049
15379
|
}
|
|
15050
15380
|
}
|
|
15381
|
+
function resolveAtFilePath(rawPath) {
|
|
15382
|
+
const trimmed = rawPath.trim();
|
|
15383
|
+
const resolved = resolve12(trimmed);
|
|
15384
|
+
if (existsSync8(resolved)) return resolved;
|
|
15385
|
+
if (process.platform !== "win32" && trimmed.includes("\\")) {
|
|
15386
|
+
const normalized = resolve12(trimmed.replace(/\\/g, "/"));
|
|
15387
|
+
if (existsSync8(normalized)) return normalized;
|
|
15388
|
+
}
|
|
15389
|
+
return resolved;
|
|
15390
|
+
}
|
|
15391
|
+
function readJsonArgument(raw, flagName) {
|
|
15392
|
+
if (!raw.startsWith("@")) return raw.replace(/^\uFEFF/, "");
|
|
15393
|
+
const filePath = raw.slice(1).trim();
|
|
15394
|
+
if (!filePath) {
|
|
15395
|
+
throw new Error(`Invalid ${flagName} value: empty @file path.`);
|
|
15396
|
+
}
|
|
15397
|
+
try {
|
|
15398
|
+
return readFileSync7(resolveAtFilePath(filePath), "utf8").replace(
|
|
15399
|
+
/^\uFEFF/,
|
|
15400
|
+
""
|
|
15401
|
+
);
|
|
15402
|
+
} catch (error) {
|
|
15403
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15404
|
+
throw new Error(
|
|
15405
|
+
`Failed to read ${flagName} file '${filePath}': ${message}`
|
|
15406
|
+
);
|
|
15407
|
+
}
|
|
15408
|
+
}
|
|
15409
|
+
function invalidJsonError(flagName, message) {
|
|
15410
|
+
const error = new Error(
|
|
15411
|
+
`Invalid JSON in ${flagName}: ${message}`
|
|
15412
|
+
);
|
|
15413
|
+
error.code = "INVALID_JSON";
|
|
15414
|
+
return error;
|
|
15415
|
+
}
|
|
15416
|
+
function parseJsonObjectArgument(raw, flagName) {
|
|
15417
|
+
let parsed;
|
|
15418
|
+
try {
|
|
15419
|
+
parsed = JSON.parse(readJsonArgument(raw, flagName));
|
|
15420
|
+
} catch (error) {
|
|
15421
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15422
|
+
if (message.startsWith("Failed to read ") || message.startsWith("Invalid ")) {
|
|
15423
|
+
throw error;
|
|
15424
|
+
}
|
|
15425
|
+
throw invalidJsonError(flagName, message);
|
|
15426
|
+
}
|
|
15427
|
+
if (!isRecord5(parsed)) {
|
|
15428
|
+
throw invalidJsonError(flagName, "expected an object.");
|
|
15429
|
+
}
|
|
15430
|
+
return parsed;
|
|
15431
|
+
}
|
|
15051
15432
|
function parseExecuteOptions(args) {
|
|
15052
15433
|
const toolId = args[0];
|
|
15053
15434
|
if (!toolId) {
|
|
@@ -15070,12 +15451,15 @@ function parseExecuteOptions(args) {
|
|
|
15070
15451
|
const next = args[index + 1];
|
|
15071
15452
|
outputFormat = "json";
|
|
15072
15453
|
if (next && !next.startsWith("--")) {
|
|
15073
|
-
Object.assign(
|
|
15454
|
+
Object.assign(
|
|
15455
|
+
params,
|
|
15456
|
+
parseJsonObjectArgument(args[++index], "--json")
|
|
15457
|
+
);
|
|
15074
15458
|
}
|
|
15075
15459
|
continue;
|
|
15076
15460
|
}
|
|
15077
15461
|
if ((arg === "--input" || arg === "--payload") && args[index + 1]) {
|
|
15078
|
-
Object.assign(params,
|
|
15462
|
+
Object.assign(params, parseJsonObjectArgument(args[++index], arg));
|
|
15079
15463
|
continue;
|
|
15080
15464
|
}
|
|
15081
15465
|
if (arg === "--output-format" && args[index + 1]) {
|
|
@@ -15395,8 +15779,8 @@ async function executeTool(args) {
|
|
|
15395
15779
|
|
|
15396
15780
|
// src/cli/commands/update.ts
|
|
15397
15781
|
import { spawn } from "child_process";
|
|
15398
|
-
import { existsSync as
|
|
15399
|
-
import { dirname as dirname9, join as join11, resolve as
|
|
15782
|
+
import { existsSync as existsSync9 } from "fs";
|
|
15783
|
+
import { dirname as dirname9, join as join11, resolve as resolve13 } from "path";
|
|
15400
15784
|
function posixShellQuote(value) {
|
|
15401
15785
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
15402
15786
|
}
|
|
@@ -15415,9 +15799,9 @@ function buildSourceUpdateCommand(sourceRoot) {
|
|
|
15415
15799
|
return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
|
|
15416
15800
|
}
|
|
15417
15801
|
function findRepoBackedSdkRoot(startPath) {
|
|
15418
|
-
let current =
|
|
15802
|
+
let current = resolve13(startPath);
|
|
15419
15803
|
while (true) {
|
|
15420
|
-
if (
|
|
15804
|
+
if (existsSync9(join11(current, "sdk", "package.json")) && existsSync9(join11(current, "sdk", "bin", "deepline-dev.ts"))) {
|
|
15421
15805
|
return current;
|
|
15422
15806
|
}
|
|
15423
15807
|
const parent = dirname9(current);
|
|
@@ -15426,7 +15810,7 @@ function findRepoBackedSdkRoot(startPath) {
|
|
|
15426
15810
|
}
|
|
15427
15811
|
}
|
|
15428
15812
|
function resolveUpdatePlan() {
|
|
15429
|
-
const entrypoint = process.argv[1] ?
|
|
15813
|
+
const entrypoint = process.argv[1] ? resolve13(process.argv[1]) : "";
|
|
15430
15814
|
const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname9(entrypoint)) : null;
|
|
15431
15815
|
if (sourceRoot) {
|
|
15432
15816
|
return {
|
|
@@ -15660,7 +16044,7 @@ function commandCompatibilityHint(currentFamily, commandName, baseUrl) {
|
|
|
15660
16044
|
lines.push(
|
|
15661
16045
|
"",
|
|
15662
16046
|
" To stay on the SDK CLI, install the SDK agent skill:",
|
|
15663
|
-
` ${skillsInstallCommand(baseUrl, "deepline-
|
|
16047
|
+
` ${skillsInstallCommand(baseUrl, "deepline-plays")}`,
|
|
15664
16048
|
" To use the legacy Python CLI instead:",
|
|
15665
16049
|
` ${legacyPythonInstallCommand(baseUrl)}`,
|
|
15666
16050
|
" `deepline update` updates this SDK CLI, but it will not switch CLI families."
|
|
@@ -15673,7 +16057,7 @@ function commandCompatibilityHint(currentFamily, commandName, baseUrl) {
|
|
|
15673
16057
|
"",
|
|
15674
16058
|
" To use SDK commands, install the SDK CLI and SDK agent skill:",
|
|
15675
16059
|
` ${sdkNpmGlobalInstallCommand()}`,
|
|
15676
|
-
` ${skillsInstallCommand(baseUrl, "deepline-
|
|
16060
|
+
` ${skillsInstallCommand(baseUrl, "deepline-plays")}`,
|
|
15677
16061
|
" `deepline update` updates this Python CLI and its skills, but it will not switch CLI families."
|
|
15678
16062
|
);
|
|
15679
16063
|
if (compatibility.python_alternative) {
|
|
@@ -15691,22 +16075,39 @@ function unknownCommandNameFromMessage(message) {
|
|
|
15691
16075
|
// src/cli/skills-sync.ts
|
|
15692
16076
|
import { spawn as spawn2, spawnSync } from "child_process";
|
|
15693
16077
|
import {
|
|
15694
|
-
existsSync as
|
|
16078
|
+
existsSync as existsSync10,
|
|
15695
16079
|
mkdirSync as mkdirSync5,
|
|
15696
16080
|
readdirSync as readdirSync2,
|
|
15697
|
-
readFileSync as
|
|
16081
|
+
readFileSync as readFileSync8,
|
|
15698
16082
|
statSync as statSync2,
|
|
15699
16083
|
writeFileSync as writeFileSync10
|
|
15700
16084
|
} from "fs";
|
|
15701
16085
|
import { homedir as homedir6 } from "os";
|
|
15702
16086
|
import { dirname as dirname10, join as join12 } from "path";
|
|
15703
16087
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
15704
|
-
var SDK_SKILL_NAME = "deepline-
|
|
16088
|
+
var SDK_SKILL_NAME = "deepline-plays";
|
|
15705
16089
|
var attemptedSync = false;
|
|
15706
16090
|
function shouldSkipSkillsSync() {
|
|
15707
16091
|
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
15708
16092
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
15709
16093
|
}
|
|
16094
|
+
function activePluginSkillsDir() {
|
|
16095
|
+
const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
|
|
16096
|
+
if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
|
|
16097
|
+
return "";
|
|
16098
|
+
}
|
|
16099
|
+
const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
|
|
16100
|
+
return dir && existsSync10(dir) ? dir : "";
|
|
16101
|
+
}
|
|
16102
|
+
function readPluginSkillsVersion() {
|
|
16103
|
+
const dir = activePluginSkillsDir();
|
|
16104
|
+
if (!dir) return "";
|
|
16105
|
+
try {
|
|
16106
|
+
return readFileSync8(join12(dir, ".version"), "utf-8").trim();
|
|
16107
|
+
} catch {
|
|
16108
|
+
return "";
|
|
16109
|
+
}
|
|
16110
|
+
}
|
|
15710
16111
|
function sdkSkillsVersionPath(baseUrl) {
|
|
15711
16112
|
const home = process.env.HOME?.trim() || homedir6();
|
|
15712
16113
|
return join12(
|
|
@@ -15719,10 +16120,12 @@ function sdkSkillsVersionPath(baseUrl) {
|
|
|
15719
16120
|
);
|
|
15720
16121
|
}
|
|
15721
16122
|
function readLocalSkillsVersion(baseUrl) {
|
|
16123
|
+
const pluginVersion = readPluginSkillsVersion();
|
|
16124
|
+
if (pluginVersion) return pluginVersion;
|
|
15722
16125
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
15723
|
-
if (!
|
|
16126
|
+
if (!existsSync10(path)) return "";
|
|
15724
16127
|
try {
|
|
15725
|
-
return
|
|
16128
|
+
return readFileSync8(path, "utf-8").trim();
|
|
15726
16129
|
} catch {
|
|
15727
16130
|
return "";
|
|
15728
16131
|
}
|
|
@@ -15735,7 +16138,8 @@ function writeLocalSkillsVersion(baseUrl, version) {
|
|
|
15735
16138
|
}
|
|
15736
16139
|
function installedSdkSkillHasStalePositionalExecuteExamples() {
|
|
15737
16140
|
const home = process.env.HOME?.trim() || homedir6();
|
|
15738
|
-
const
|
|
16141
|
+
const pluginSkillsDir = activePluginSkillsDir();
|
|
16142
|
+
const roots = pluginSkillsDir ? [join12(pluginSkillsDir, SDK_SKILL_NAME)] : [
|
|
15739
16143
|
join12(home, ".claude", "skills", SDK_SKILL_NAME),
|
|
15740
16144
|
join12(home, ".agents", "skills", SDK_SKILL_NAME)
|
|
15741
16145
|
];
|
|
@@ -15755,14 +16159,14 @@ function installedSdkSkillHasStalePositionalExecuteExamples() {
|
|
|
15755
16159
|
continue;
|
|
15756
16160
|
}
|
|
15757
16161
|
if (!entry.endsWith(".md")) continue;
|
|
15758
|
-
const text =
|
|
16162
|
+
const text = readFileSync8(path, "utf-8");
|
|
15759
16163
|
if (staleMarkers.some((marker) => text.includes(marker))) return true;
|
|
15760
16164
|
}
|
|
15761
16165
|
return false;
|
|
15762
16166
|
};
|
|
15763
16167
|
for (const root of roots) {
|
|
15764
16168
|
try {
|
|
15765
|
-
if (
|
|
16169
|
+
if (existsSync10(root) && scan(root)) return true;
|
|
15766
16170
|
} catch {
|
|
15767
16171
|
continue;
|
|
15768
16172
|
}
|
|
@@ -15834,7 +16238,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
15834
16238
|
return [npxInstall];
|
|
15835
16239
|
}
|
|
15836
16240
|
function runOneSkillsInstall(install) {
|
|
15837
|
-
return new Promise((
|
|
16241
|
+
return new Promise((resolve14) => {
|
|
15838
16242
|
const child = spawn2(install.command, install.args, {
|
|
15839
16243
|
stdio: ["ignore", "ignore", "pipe"],
|
|
15840
16244
|
env: process.env
|
|
@@ -15844,7 +16248,7 @@ function runOneSkillsInstall(install) {
|
|
|
15844
16248
|
stderr += chunk.toString("utf-8");
|
|
15845
16249
|
});
|
|
15846
16250
|
child.on("error", (error) => {
|
|
15847
|
-
|
|
16251
|
+
resolve14({
|
|
15848
16252
|
ok: false,
|
|
15849
16253
|
detail: `failed to start ${install.command}: ${error.message}`,
|
|
15850
16254
|
manualCommand: install.manualCommand
|
|
@@ -15852,11 +16256,11 @@ function runOneSkillsInstall(install) {
|
|
|
15852
16256
|
});
|
|
15853
16257
|
child.on("close", (code) => {
|
|
15854
16258
|
if (code === 0) {
|
|
15855
|
-
|
|
16259
|
+
resolve14({ ok: true, detail: "", manualCommand: install.manualCommand });
|
|
15856
16260
|
return;
|
|
15857
16261
|
}
|
|
15858
16262
|
const detail = stderr.trim();
|
|
15859
|
-
|
|
16263
|
+
resolve14({
|
|
15860
16264
|
ok: false,
|
|
15861
16265
|
detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
|
|
15862
16266
|
manualCommand: install.manualCommand
|
|
@@ -15893,18 +16297,22 @@ function writeSdkSkillsStatusLine(line) {
|
|
|
15893
16297
|
async function syncSdkSkillsIfNeeded(baseUrl) {
|
|
15894
16298
|
if (attemptedSync || shouldSkipSkillsSync()) return;
|
|
15895
16299
|
attemptedSync = true;
|
|
16300
|
+
const usingPluginSkills = Boolean(activePluginSkillsDir());
|
|
15896
16301
|
const localVersion = readLocalSkillsVersion(baseUrl);
|
|
15897
16302
|
const update = await fetchSkillsUpdate(baseUrl, localVersion);
|
|
15898
16303
|
const hasStaleInstalledSkill = installedSdkSkillHasStalePositionalExecuteExamples();
|
|
16304
|
+
if (usingPluginSkills) {
|
|
16305
|
+
return;
|
|
16306
|
+
}
|
|
15899
16307
|
if (!update?.needsUpdate && !hasStaleInstalledSkill || !update?.remoteVersion) {
|
|
15900
16308
|
return;
|
|
15901
16309
|
}
|
|
15902
|
-
writeSdkSkillsStatusLine("SDK skills changed; syncing deepline-
|
|
16310
|
+
writeSdkSkillsStatusLine("SDK skills changed; syncing deepline-plays skill...");
|
|
15903
16311
|
const installed = await runSkillsInstall(baseUrl);
|
|
15904
16312
|
if (!installed) return;
|
|
15905
16313
|
if (installedSdkSkillHasStalePositionalExecuteExamples()) {
|
|
15906
16314
|
process.stderr.write(
|
|
15907
|
-
"SDK skills sync completed, but installed deepline-
|
|
16315
|
+
"SDK skills sync completed, but installed deepline-plays docs still contain stale positional ctx.tools.execute examples.\n"
|
|
15908
16316
|
);
|
|
15909
16317
|
return;
|
|
15910
16318
|
}
|