deepline 0.1.85 → 0.1.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +419 -70
- package/dist/cli/index.mjs +438 -83
- package/dist/index.d.mts +442 -60
- package/dist/index.d.ts +442 -60
- package/dist/index.js +161 -4
- package/dist/index.mjs +161 -4
- package/dist/repo/apps/play-runner-workers/src/dedup-do.ts +1 -0
- package/dist/repo/apps/play-runner-workers/src/entry.ts +276 -192
- 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 +24 -1
- package/dist/repo/sdk/src/play.ts +198 -15
- package/dist/repo/sdk/src/release.ts +2 -2
- package/dist/repo/sdk/src/types.ts +61 -0
- package/dist/repo/sdk/src/worker-play-entry.ts +6 -3
- package/dist/repo/shared_libs/play-runtime/cell-staleness.ts +23 -0
- package/dist/repo/shared_libs/play-runtime/coordinator-headers.ts +10 -0
- package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +10 -1
- package/dist/repo/shared_libs/play-runtime/tool-result.ts +202 -12
- 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/row-identity.ts +14 -8
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -229,10 +229,10 @@ var import_node_path2 = require("path");
|
|
|
229
229
|
|
|
230
230
|
// src/release.ts
|
|
231
231
|
var SDK_RELEASE = {
|
|
232
|
-
version: "0.1.
|
|
232
|
+
version: "0.1.89",
|
|
233
233
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
234
234
|
supportPolicy: {
|
|
235
|
-
latest: "0.1.
|
|
235
|
+
latest: "0.1.89",
|
|
236
236
|
minimumSupported: "0.1.53",
|
|
237
237
|
deprecatedBelow: "0.1.53"
|
|
238
238
|
}
|
|
@@ -246,6 +246,7 @@ var SDK_API_CONTRACT = SDK_RELEASE.apiContract;
|
|
|
246
246
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
247
247
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
248
248
|
var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
|
|
249
|
+
var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
|
|
249
250
|
|
|
250
251
|
// src/http.ts
|
|
251
252
|
var MAX_DIAGNOSTIC_HEADER_LENGTH = 120;
|
|
@@ -313,6 +314,10 @@ var HttpClient = class {
|
|
|
313
314
|
if (workerCallbackUrl?.trim()) {
|
|
314
315
|
headers[WORKER_CALLBACK_URL_OVERRIDE_HEADER] = workerCallbackUrl.trim();
|
|
315
316
|
}
|
|
317
|
+
const syntheticRun = typeof process !== "undefined" ? process.env?.DEEPLINE_SYNTHETIC_RUN : void 0;
|
|
318
|
+
if (syntheticRun && syntheticRun.trim() && syntheticRun.trim() !== "0") {
|
|
319
|
+
headers[SYNTHETIC_RUN_HEADER] = "1";
|
|
320
|
+
}
|
|
316
321
|
return headers;
|
|
317
322
|
}
|
|
318
323
|
/**
|
|
@@ -579,7 +584,7 @@ function decodeSseFrame(frame) {
|
|
|
579
584
|
return parsed;
|
|
580
585
|
}
|
|
581
586
|
function sleep(ms) {
|
|
582
|
-
return new Promise((
|
|
587
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
583
588
|
}
|
|
584
589
|
|
|
585
590
|
// src/client.ts
|
|
@@ -589,7 +594,7 @@ var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
|
|
|
589
594
|
var V2_EXECUTE_RESPONSE_CONTRACT = "v2-tool-response";
|
|
590
595
|
var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
|
|
591
596
|
function sleep2(ms) {
|
|
592
|
-
return new Promise((
|
|
597
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
593
598
|
}
|
|
594
599
|
function isTransientCompileManifestError(error) {
|
|
595
600
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
@@ -603,6 +608,21 @@ function isTransientCompileManifestError(error) {
|
|
|
603
608
|
function isRecord(value) {
|
|
604
609
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
605
610
|
}
|
|
611
|
+
function isPrebuiltPlayDescription(play) {
|
|
612
|
+
return play.origin === "prebuilt" || play.ownerType === "deepline";
|
|
613
|
+
}
|
|
614
|
+
function preferPrebuiltPlayDescriptions(plays) {
|
|
615
|
+
const prebuilt = [];
|
|
616
|
+
const owned = [];
|
|
617
|
+
for (const play of plays) {
|
|
618
|
+
if (isPrebuiltPlayDescription(play)) {
|
|
619
|
+
prebuilt.push(play);
|
|
620
|
+
} else {
|
|
621
|
+
owned.push(play);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return [...prebuilt, ...owned];
|
|
625
|
+
}
|
|
606
626
|
function isPlayRunPackage(value) {
|
|
607
627
|
return Boolean(
|
|
608
628
|
value && typeof value === "object" && !Array.isArray(value) && value.kind === "play_run" && value.run && typeof value.run?.id === "string"
|
|
@@ -726,8 +746,14 @@ function playRunStatusFromState(state) {
|
|
|
726
746
|
var DeeplineClient = class {
|
|
727
747
|
http;
|
|
728
748
|
config;
|
|
749
|
+
/** Canonical run lifecycle namespace backed by `/api/v2/runs`. */
|
|
729
750
|
runs;
|
|
730
751
|
/**
|
|
752
|
+
* Create a low-level SDK client.
|
|
753
|
+
*
|
|
754
|
+
* Most callers can omit options and let the SDK resolve auth/config from
|
|
755
|
+
* environment variables and CLI-managed credentials.
|
|
756
|
+
*
|
|
731
757
|
* @param options - Optional overrides for API key, base URL, timeout, and retries.
|
|
732
758
|
* @throws {@link ConfigError} if no API key can be resolved from any source.
|
|
733
759
|
*/
|
|
@@ -829,12 +855,19 @@ var DeeplineClient = class {
|
|
|
829
855
|
// ——————————————————————————————————————————————————————————
|
|
830
856
|
// Secrets
|
|
831
857
|
// ——————————————————————————————————————————————————————————
|
|
858
|
+
/** List secret metadata visible to the current workspace. */
|
|
832
859
|
async listSecrets() {
|
|
833
860
|
const response = await this.http.get(
|
|
834
861
|
"/api/v2/secrets"
|
|
835
862
|
);
|
|
836
863
|
return Array.isArray(response.secrets) ? response.secrets : [];
|
|
837
864
|
}
|
|
865
|
+
/**
|
|
866
|
+
* Check whether a named secret exists, is active, and has a stored value.
|
|
867
|
+
*
|
|
868
|
+
* @param name - Secret name. It is normalized to uppercase before lookup.
|
|
869
|
+
* @returns Matching active secret metadata, or `null`.
|
|
870
|
+
*/
|
|
838
871
|
async checkSecret(name) {
|
|
839
872
|
const normalized = name.trim().toUpperCase();
|
|
840
873
|
const secrets = await this.listSecrets();
|
|
@@ -947,9 +980,21 @@ var DeeplineClient = class {
|
|
|
947
980
|
headers
|
|
948
981
|
);
|
|
949
982
|
}
|
|
983
|
+
/**
|
|
984
|
+
* Back-compatible alias for {@link executeTool}.
|
|
985
|
+
*
|
|
986
|
+
* Retained for callers that still use the older raw naming while the response
|
|
987
|
+
* envelope remains the same.
|
|
988
|
+
*/
|
|
950
989
|
async executeToolRaw(toolId, input2, options) {
|
|
951
990
|
return this.executeTool(toolId, input2, options);
|
|
952
991
|
}
|
|
992
|
+
/**
|
|
993
|
+
* Run a bounded SQL query against the customer data plane.
|
|
994
|
+
*
|
|
995
|
+
* Use this from trusted backend or agent contexts only. The API enforces
|
|
996
|
+
* workspace scoping and row limits.
|
|
997
|
+
*/
|
|
953
998
|
async queryCustomerDb(input2) {
|
|
954
999
|
return this.http.post("/api/v2/db/query", {
|
|
955
1000
|
sql: input2.sql,
|
|
@@ -1021,6 +1066,17 @@ var DeeplineClient = class {
|
|
|
1021
1066
|
);
|
|
1022
1067
|
return normalizePlayRunStart(response);
|
|
1023
1068
|
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Start a play run and stream live runtime events from the same request.
|
|
1071
|
+
*
|
|
1072
|
+
* Use this when a caller wants low-level event handling instead of submitting
|
|
1073
|
+
* first and then connecting to `streamPlayRunEvents(runId)`.
|
|
1074
|
+
*
|
|
1075
|
+
* @param request - Play run configuration.
|
|
1076
|
+
* @param options - Optional streaming options.
|
|
1077
|
+
* @param options.signal - Optional abort signal for the streaming request.
|
|
1078
|
+
* @returns Async stream of play-scoped live events.
|
|
1079
|
+
*/
|
|
1024
1080
|
async *startPlayRunStream(request, options) {
|
|
1025
1081
|
const body = {
|
|
1026
1082
|
...request.name ? { name: request.name } : {},
|
|
@@ -1073,6 +1129,12 @@ var DeeplineClient = class {
|
|
|
1073
1129
|
compilerManifest
|
|
1074
1130
|
});
|
|
1075
1131
|
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Register multiple bundled play artifacts in one request.
|
|
1134
|
+
*
|
|
1135
|
+
* Used by packaging and prebuilt publication flows. Each artifact is compiled
|
|
1136
|
+
* first when a compiler manifest is not already supplied.
|
|
1137
|
+
*/
|
|
1076
1138
|
async registerPlayArtifacts(artifacts) {
|
|
1077
1139
|
const compiledArtifacts = await Promise.all(
|
|
1078
1140
|
artifacts.map(async (artifact) => ({
|
|
@@ -1089,6 +1151,13 @@ var DeeplineClient = class {
|
|
|
1089
1151
|
artifacts: compiledArtifacts
|
|
1090
1152
|
});
|
|
1091
1153
|
}
|
|
1154
|
+
/**
|
|
1155
|
+
* Compile a bundled play artifact into the server-side compiler manifest.
|
|
1156
|
+
*
|
|
1157
|
+
* The manifest records imports, trigger bindings, static pipeline shape, and
|
|
1158
|
+
* runtime metadata needed before a play artifact can be checked, registered,
|
|
1159
|
+
* or run.
|
|
1160
|
+
*/
|
|
1092
1161
|
async compilePlayManifest(input2) {
|
|
1093
1162
|
const retryDelays = COMPILE_MANIFEST_RETRY_DELAYS_MS.slice(
|
|
1094
1163
|
0,
|
|
@@ -1117,9 +1186,21 @@ var DeeplineClient = class {
|
|
|
1117
1186
|
async checkPlayArtifact(input2) {
|
|
1118
1187
|
return this.http.post("/api/v2/plays/check", input2);
|
|
1119
1188
|
}
|
|
1189
|
+
/**
|
|
1190
|
+
* Compile legacy enrich command arguments into a runtime plan.
|
|
1191
|
+
*
|
|
1192
|
+
* This is primarily used by CLI compatibility paths that translate older
|
|
1193
|
+
* enrichment commands onto the play runtime.
|
|
1194
|
+
*/
|
|
1120
1195
|
async compileEnrichPlan(input2) {
|
|
1121
1196
|
return this.http.post("/api/v2/enrich/compile", input2);
|
|
1122
1197
|
}
|
|
1198
|
+
/**
|
|
1199
|
+
* Register an already-bundled play artifact and start a run from it.
|
|
1200
|
+
*
|
|
1201
|
+
* This is the low-level file-backed run path used by SDK/CLI packaging
|
|
1202
|
+
* wrappers after local bundling has produced the runtime artifact.
|
|
1203
|
+
*/
|
|
1123
1204
|
async startPlayRunFromBundle(input2) {
|
|
1124
1205
|
const compilerManifest = input2.compilerManifest ?? await this.compilePlayManifest({
|
|
1125
1206
|
name: input2.name,
|
|
@@ -1277,6 +1358,12 @@ var DeeplineClient = class {
|
|
|
1277
1358
|
const response = await this.http.postFormData("/api/v2/plays/files/stage", buildFormData);
|
|
1278
1359
|
return response.files;
|
|
1279
1360
|
}
|
|
1361
|
+
/**
|
|
1362
|
+
* Resolve staged play files by content hash without uploading bytes.
|
|
1363
|
+
*
|
|
1364
|
+
* Missing files are returned so callers can upload only the files the server
|
|
1365
|
+
* does not already have.
|
|
1366
|
+
*/
|
|
1280
1367
|
async resolveStagedPlayFiles(files) {
|
|
1281
1368
|
return this.http.post("/api/v2/plays/files/stage", { files });
|
|
1282
1369
|
}
|
|
@@ -1493,6 +1580,12 @@ var DeeplineClient = class {
|
|
|
1493
1580
|
entries
|
|
1494
1581
|
};
|
|
1495
1582
|
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Export persisted runtime-sheet rows for a play dataset/table namespace.
|
|
1585
|
+
*
|
|
1586
|
+
* This is the SDK form of exporting `ctx.dataset(...).run()` output for a
|
|
1587
|
+
* specific play and optional run id.
|
|
1588
|
+
*/
|
|
1496
1589
|
async getPlaySheetRows(input2) {
|
|
1497
1590
|
const params = new URLSearchParams({
|
|
1498
1591
|
tableNamespace: input2.tableNamespace,
|
|
@@ -1521,6 +1614,12 @@ var DeeplineClient = class {
|
|
|
1521
1614
|
options?.reason ? { reason: options.reason } : {}
|
|
1522
1615
|
);
|
|
1523
1616
|
}
|
|
1617
|
+
/**
|
|
1618
|
+
* List callable plays visible to the workspace.
|
|
1619
|
+
*
|
|
1620
|
+
* Pass `origin: "prebuilt"` for Deepline-managed prebuilts or
|
|
1621
|
+
* `origin: "owned"` for org-owned plays.
|
|
1622
|
+
*/
|
|
1524
1623
|
async listPlays(options) {
|
|
1525
1624
|
const params = new URLSearchParams();
|
|
1526
1625
|
if (options?.origin) params.set("origin", options.origin);
|
|
@@ -1535,15 +1634,32 @@ var DeeplineClient = class {
|
|
|
1535
1634
|
);
|
|
1536
1635
|
return response.plays ?? [];
|
|
1537
1636
|
}
|
|
1637
|
+
/**
|
|
1638
|
+
* Search callable plays and return compact play descriptions.
|
|
1639
|
+
*
|
|
1640
|
+
* Prebuilt plays are preferred by default because they have maintained
|
|
1641
|
+
* contracts and stable run behavior.
|
|
1642
|
+
*/
|
|
1538
1643
|
async searchPlays(options) {
|
|
1539
1644
|
const params = new URLSearchParams();
|
|
1540
1645
|
params.set("search", options.query.trim());
|
|
1646
|
+
const scope = options.scope ?? "prebuilt";
|
|
1647
|
+
if (scope !== "all") {
|
|
1648
|
+
params.set("origin", scope);
|
|
1649
|
+
}
|
|
1541
1650
|
const response = await this.http.get(
|
|
1542
1651
|
`/api/v2/plays?${params.toString()}`
|
|
1543
1652
|
);
|
|
1544
|
-
|
|
1653
|
+
const plays = (response.plays ?? []).map(
|
|
1545
1654
|
(play) => this.summarizePlayListItem(play, options)
|
|
1546
1655
|
);
|
|
1656
|
+
if (scope === "prebuilt") {
|
|
1657
|
+
return plays.filter(isPrebuiltPlayDescription);
|
|
1658
|
+
}
|
|
1659
|
+
if (scope === "owned") {
|
|
1660
|
+
return plays.filter((play) => !isPrebuiltPlayDescription(play));
|
|
1661
|
+
}
|
|
1662
|
+
return preferPrebuiltPlayDescriptions(plays);
|
|
1547
1663
|
}
|
|
1548
1664
|
/**
|
|
1549
1665
|
* Get the full definition and state of a named play.
|
|
@@ -1566,6 +1682,12 @@ var DeeplineClient = class {
|
|
|
1566
1682
|
const encodedName = encodeURIComponent(name);
|
|
1567
1683
|
return this.http.get(`/api/v2/plays/${encodedName}`);
|
|
1568
1684
|
}
|
|
1685
|
+
/**
|
|
1686
|
+
* Get a normalized play description suitable for agents and CLIs.
|
|
1687
|
+
*
|
|
1688
|
+
* The description includes runnable examples, input/output summaries, clone
|
|
1689
|
+
* guidance, revision state, and latest run metadata when available.
|
|
1690
|
+
*/
|
|
1569
1691
|
async describePlay(name, options) {
|
|
1570
1692
|
const detail = await this.getPlay(name);
|
|
1571
1693
|
return this.summarizePlayDetail(detail, options);
|
|
@@ -2420,7 +2542,7 @@ function buildCandidateUrls2(url) {
|
|
|
2420
2542
|
}
|
|
2421
2543
|
}
|
|
2422
2544
|
function sleep3(ms) {
|
|
2423
|
-
return new Promise((
|
|
2545
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
2424
2546
|
}
|
|
2425
2547
|
function printDeeplineLogo() {
|
|
2426
2548
|
if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
|
|
@@ -4675,7 +4797,12 @@ function readPackageVersionFromPackageJson(packageJsonPath, packageName) {
|
|
|
4675
4797
|
return null;
|
|
4676
4798
|
}
|
|
4677
4799
|
function findPackageJsonPathFrom(startDir, packageName) {
|
|
4678
|
-
|
|
4800
|
+
if (!(0, import_node_path8.isAbsolute)(startDir)) {
|
|
4801
|
+
throw new Error(
|
|
4802
|
+
`Package resolution requires an absolute start directory, got ${startDir}`
|
|
4803
|
+
);
|
|
4804
|
+
}
|
|
4805
|
+
let current = startDir;
|
|
4679
4806
|
while (true) {
|
|
4680
4807
|
const packageJsonPath = (0, import_node_path8.join)(
|
|
4681
4808
|
current,
|
|
@@ -4695,17 +4822,15 @@ function findPackageJsonPathFrom(startDir, packageName) {
|
|
|
4695
4822
|
}
|
|
4696
4823
|
function findPackageJsonPath(packageName, fromFile, adapter) {
|
|
4697
4824
|
const startDirs = [
|
|
4698
|
-
(0, import_node_path8.dirname)(fromFile),
|
|
4699
|
-
adapter.projectRoot,
|
|
4700
|
-
(0, import_node_path8.dirname)(adapter.sdkPackageJson)
|
|
4701
|
-
process.cwd()
|
|
4825
|
+
(0, import_node_path8.resolve)((0, import_node_path8.dirname)(fromFile)),
|
|
4826
|
+
(0, import_node_path8.resolve)(adapter.projectRoot),
|
|
4827
|
+
(0, import_node_path8.resolve)((0, import_node_path8.dirname)(adapter.sdkPackageJson))
|
|
4702
4828
|
];
|
|
4703
4829
|
const seen = /* @__PURE__ */ new Set();
|
|
4704
4830
|
for (const startDir of startDirs) {
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
const packageJsonPath = findPackageJsonPathFrom(normalized, packageName);
|
|
4831
|
+
if (seen.has(startDir)) continue;
|
|
4832
|
+
seen.add(startDir);
|
|
4833
|
+
const packageJsonPath = findPackageJsonPathFrom(startDir, packageName);
|
|
4709
4834
|
if (packageJsonPath) return packageJsonPath;
|
|
4710
4835
|
}
|
|
4711
4836
|
const adapterNodeModulesPackageJson = (0, import_node_path8.join)(
|
|
@@ -5163,13 +5288,13 @@ async function writeArtifactCache(artifact, adapter) {
|
|
|
5163
5288
|
"utf-8"
|
|
5164
5289
|
);
|
|
5165
5290
|
}
|
|
5166
|
-
function normalizeSourceMapForRuntime(sourceMapText) {
|
|
5291
|
+
function normalizeSourceMapForRuntime(sourceMapText, projectRoot) {
|
|
5167
5292
|
const parsed = JSON.parse(sourceMapText);
|
|
5168
5293
|
parsed.sources = (parsed.sources ?? []).map((sourcePath) => {
|
|
5169
5294
|
if (sourcePath.startsWith("data:") || sourcePath.startsWith("node:") || sourcePath.startsWith("/") || /^[a-zA-Z]+:\/\//.test(sourcePath)) {
|
|
5170
5295
|
return sourcePath;
|
|
5171
5296
|
}
|
|
5172
|
-
return (0, import_node_path8.
|
|
5297
|
+
return (0, import_node_path8.join)(projectRoot, sourcePath);
|
|
5173
5298
|
});
|
|
5174
5299
|
parsed.sourceRoot = void 0;
|
|
5175
5300
|
return JSON.stringify(parsed);
|
|
@@ -5435,7 +5560,10 @@ workers-harness:${harnessFingerprint}`
|
|
|
5435
5560
|
};
|
|
5436
5561
|
}
|
|
5437
5562
|
const { bundledCode, sourceMapText, outputExtension } = buildOutcome;
|
|
5438
|
-
const normalizedSourceMap = normalizeSourceMapForRuntime(
|
|
5563
|
+
const normalizedSourceMap = normalizeSourceMapForRuntime(
|
|
5564
|
+
sourceMapText,
|
|
5565
|
+
(0, import_node_path8.resolve)(adapter.projectRoot)
|
|
5566
|
+
);
|
|
5439
5567
|
const virtualBaseName = exportName === "default" ? (0, import_node_path8.basename)(absolutePath).replace(/\.[^.]+$/, "") : `${(0, import_node_path8.basename)(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
|
|
5440
5568
|
const virtualFilename = `/virtual/deepline-plays/${analysis.graphHash}/${virtualBaseName}.${outputExtension}`;
|
|
5441
5569
|
const executableCode = `${bundledCode}
|
|
@@ -7836,7 +7964,7 @@ function traceCliSync(phase, fields, run) {
|
|
|
7836
7964
|
}
|
|
7837
7965
|
}
|
|
7838
7966
|
function sleep4(ms) {
|
|
7839
|
-
return new Promise((
|
|
7967
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
7840
7968
|
}
|
|
7841
7969
|
function parseReferencedPlayTarget2(target) {
|
|
7842
7970
|
const trimmed = target.trim();
|
|
@@ -8355,6 +8483,8 @@ var TERMINAL_PLAY_STATUSES2 = /* @__PURE__ */ new Set([
|
|
|
8355
8483
|
"cancelled"
|
|
8356
8484
|
]);
|
|
8357
8485
|
var PLAY_START_TRANSIENT_RETRY_DELAYS_MS = [500, 1500];
|
|
8486
|
+
var PLAY_PROGRESS_HEARTBEAT_INTERVAL_MS = 15e3;
|
|
8487
|
+
var PLAY_STATUS_HEARTBEAT_INTERVAL_MS = 15e3;
|
|
8358
8488
|
function getEventPayload(event) {
|
|
8359
8489
|
return event.payload && typeof event.payload === "object" ? event.payload : {};
|
|
8360
8490
|
}
|
|
@@ -8415,6 +8545,7 @@ function extractTableNamespaceFromLiveEvent(event) {
|
|
|
8415
8545
|
const payload = getEventPayload(event);
|
|
8416
8546
|
const candidates = [
|
|
8417
8547
|
payload.artifactTableNamespace,
|
|
8548
|
+
payload.activeArtifactTableNamespace,
|
|
8418
8549
|
payload.tableNamespace,
|
|
8419
8550
|
payload.mapNodeId
|
|
8420
8551
|
];
|
|
@@ -8493,6 +8624,20 @@ function formatProgressCounts(input2) {
|
|
|
8493
8624
|
const failed = typeof input2.failed === "number" && Number.isFinite(input2.failed) && input2.failed > 0 ? `, failed ${formatInteger(input2.failed)}` : "";
|
|
8494
8625
|
return `${formatInteger(completed)}/${formatInteger(total)} (${percent}%)${failed}`;
|
|
8495
8626
|
}
|
|
8627
|
+
function formatProgressMessageSuffix(input2) {
|
|
8628
|
+
const message = typeof input2.message === "string" ? input2.message.trim() : "";
|
|
8629
|
+
if (!message) {
|
|
8630
|
+
return "";
|
|
8631
|
+
}
|
|
8632
|
+
const completed = typeof input2.completed === "number" && Number.isFinite(input2.completed) ? input2.completed : null;
|
|
8633
|
+
if (/^[\d,]+\s*\/\s*[\d,]+\s+rows processed$/i.test(message)) {
|
|
8634
|
+
return "";
|
|
8635
|
+
}
|
|
8636
|
+
if (completed !== null && completed > 0 && /rows?\s+queued\b/i.test(message)) {
|
|
8637
|
+
return "";
|
|
8638
|
+
}
|
|
8639
|
+
return ` - ${message}`;
|
|
8640
|
+
}
|
|
8496
8641
|
function getProgressLinesFromLiveEvent(event) {
|
|
8497
8642
|
const payload = getEventPayload(event);
|
|
8498
8643
|
if (event.type === "play.step.progress") {
|
|
@@ -8502,7 +8647,13 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
8502
8647
|
failed: payload.failed
|
|
8503
8648
|
});
|
|
8504
8649
|
if (!counts) return [];
|
|
8505
|
-
|
|
8650
|
+
const messageSuffix = formatProgressMessageSuffix({
|
|
8651
|
+
message: payload.message,
|
|
8652
|
+
completed: payload.completed
|
|
8653
|
+
});
|
|
8654
|
+
return [
|
|
8655
|
+
`progress ${formatProgressLabel(payload.stepId)}: ${counts}${messageSuffix}`
|
|
8656
|
+
];
|
|
8506
8657
|
}
|
|
8507
8658
|
if (event.type !== "play.run.snapshot" && event.type !== "play.run.final_status") {
|
|
8508
8659
|
return [];
|
|
@@ -8526,22 +8677,69 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
8526
8677
|
if (!counts) {
|
|
8527
8678
|
continue;
|
|
8528
8679
|
}
|
|
8680
|
+
const messageSuffix = formatProgressMessageSuffix({
|
|
8681
|
+
message: progress.message,
|
|
8682
|
+
completed: progress.completed
|
|
8683
|
+
});
|
|
8529
8684
|
lines.push(
|
|
8530
|
-
`progress ${formatProgressLabel(record.nodeId ?? progress.artifactTableNamespace)}: ${counts}`
|
|
8685
|
+
`progress ${formatProgressLabel(record.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
|
|
8531
8686
|
);
|
|
8532
8687
|
}
|
|
8533
8688
|
return lines;
|
|
8534
8689
|
}
|
|
8690
|
+
function shouldPrintPlayProgressLine(input2) {
|
|
8691
|
+
if (!input2.signature) {
|
|
8692
|
+
return false;
|
|
8693
|
+
}
|
|
8694
|
+
return input2.lastProgressSignature !== input2.signature || input2.nowMs - input2.lastProgressHeartbeatAt >= PLAY_PROGRESS_HEARTBEAT_INTERVAL_MS;
|
|
8695
|
+
}
|
|
8535
8696
|
function printPlayProgressLines(input2) {
|
|
8536
8697
|
for (const line of input2.lines) {
|
|
8537
8698
|
const signature = line.trim();
|
|
8538
|
-
|
|
8699
|
+
const now = Date.now();
|
|
8700
|
+
if (!shouldPrintPlayProgressLine({
|
|
8701
|
+
signature,
|
|
8702
|
+
lastProgressSignature: input2.state.lastProgressSignature,
|
|
8703
|
+
lastProgressHeartbeatAt: input2.state.lastProgressHeartbeatAt,
|
|
8704
|
+
nowMs: now
|
|
8705
|
+
})) {
|
|
8539
8706
|
continue;
|
|
8540
8707
|
}
|
|
8541
8708
|
input2.state.lastProgressSignature = signature;
|
|
8709
|
+
input2.state.lastProgressHeartbeatAt = now;
|
|
8542
8710
|
input2.progress.writeLine(line);
|
|
8543
8711
|
}
|
|
8544
8712
|
}
|
|
8713
|
+
function getRunningHeartbeatLine(input2) {
|
|
8714
|
+
const status = getStatusFromLiveEvent(input2.event);
|
|
8715
|
+
if (status !== "queued" && status !== "running" && status !== "waiting") {
|
|
8716
|
+
return null;
|
|
8717
|
+
}
|
|
8718
|
+
const tableNamespace = extractTableNamespaceFromLiveEvent(input2.event);
|
|
8719
|
+
const target = tableNamespace ? formatProgressLabel(tableNamespace) : input2.playName;
|
|
8720
|
+
if (status === "queued") {
|
|
8721
|
+
return `queued ${target}: waiting for worker capacity`;
|
|
8722
|
+
}
|
|
8723
|
+
if (status === "waiting") {
|
|
8724
|
+
return `waiting ${target}: waiting on external work`;
|
|
8725
|
+
}
|
|
8726
|
+
return `running ${target}: still processing`;
|
|
8727
|
+
}
|
|
8728
|
+
function printPlayStatusHeartbeat(input2) {
|
|
8729
|
+
const now = Date.now();
|
|
8730
|
+
if (now - input2.state.lastStatusHeartbeatAt < PLAY_STATUS_HEARTBEAT_INTERVAL_MS) {
|
|
8731
|
+
return;
|
|
8732
|
+
}
|
|
8733
|
+
const line = getRunningHeartbeatLine({
|
|
8734
|
+
event: input2.event,
|
|
8735
|
+
playName: input2.playName
|
|
8736
|
+
});
|
|
8737
|
+
if (!line) {
|
|
8738
|
+
return;
|
|
8739
|
+
}
|
|
8740
|
+
input2.state.lastStatusHeartbeatAt = now;
|
|
8741
|
+
input2.progress.writeLine(line);
|
|
8742
|
+
}
|
|
8545
8743
|
function buildPlayDashboardUrl(baseUrl, playName) {
|
|
8546
8744
|
const trimmedBase = baseUrl.replace(/\/$/, "");
|
|
8547
8745
|
const encodedPlayName = encodeURIComponent(playName);
|
|
@@ -8624,11 +8822,20 @@ async function waitForPlayCompletionByStream(input2) {
|
|
|
8624
8822
|
progress: input2.progress
|
|
8625
8823
|
});
|
|
8626
8824
|
if (!input2.jsonOutput) {
|
|
8825
|
+
const progressLines = getProgressLinesFromLiveEvent(event);
|
|
8627
8826
|
printPlayProgressLines({
|
|
8628
|
-
lines:
|
|
8827
|
+
lines: progressLines,
|
|
8629
8828
|
state: input2.state,
|
|
8630
8829
|
progress: input2.progress
|
|
8631
8830
|
});
|
|
8831
|
+
if (progressLines.length === 0) {
|
|
8832
|
+
printPlayStatusHeartbeat({
|
|
8833
|
+
event,
|
|
8834
|
+
playName: input2.playName,
|
|
8835
|
+
state: input2.state,
|
|
8836
|
+
progress: input2.progress
|
|
8837
|
+
});
|
|
8838
|
+
}
|
|
8632
8839
|
}
|
|
8633
8840
|
const finalStatus = getFinalStatusFromLiveEvent(event);
|
|
8634
8841
|
if (finalStatus) {
|
|
@@ -8706,7 +8913,9 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
8706
8913
|
const state = {
|
|
8707
8914
|
lastLogIndex: 0,
|
|
8708
8915
|
emittedRunnerStarted: false,
|
|
8709
|
-
lastProgressSignature: null
|
|
8916
|
+
lastProgressSignature: null,
|
|
8917
|
+
lastProgressHeartbeatAt: 0,
|
|
8918
|
+
lastStatusHeartbeatAt: 0
|
|
8710
8919
|
};
|
|
8711
8920
|
const controller = new AbortController();
|
|
8712
8921
|
let timedOut = false;
|
|
@@ -8747,7 +8956,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
8747
8956
|
dashboardUrl,
|
|
8748
8957
|
noOpen: input2.noOpen
|
|
8749
8958
|
});
|
|
8750
|
-
input2.progress.phase(
|
|
8959
|
+
input2.progress.phase("running");
|
|
8751
8960
|
emittedDashboardUrl = true;
|
|
8752
8961
|
}
|
|
8753
8962
|
assertPlayWaitNotTimedOut({
|
|
@@ -8778,11 +8987,20 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
8778
8987
|
progress: input2.progress
|
|
8779
8988
|
});
|
|
8780
8989
|
if (!input2.jsonOutput) {
|
|
8990
|
+
const progressLines = getProgressLinesFromLiveEvent(event);
|
|
8781
8991
|
printPlayProgressLines({
|
|
8782
|
-
lines:
|
|
8992
|
+
lines: progressLines,
|
|
8783
8993
|
state,
|
|
8784
8994
|
progress: input2.progress
|
|
8785
8995
|
});
|
|
8996
|
+
if (progressLines.length === 0) {
|
|
8997
|
+
printPlayStatusHeartbeat({
|
|
8998
|
+
event,
|
|
8999
|
+
playName: input2.playName,
|
|
9000
|
+
state,
|
|
9001
|
+
progress: input2.progress
|
|
9002
|
+
});
|
|
9003
|
+
}
|
|
8786
9004
|
}
|
|
8787
9005
|
const finalStatus = getFinalStatusFromLiveEvent(event);
|
|
8788
9006
|
if (finalStatus) {
|
|
@@ -9382,6 +9600,17 @@ function getPlayRunPackage(status) {
|
|
|
9382
9600
|
const packaged = status.package;
|
|
9383
9601
|
return isPlayRunPackageValue(packaged) ? packaged : null;
|
|
9384
9602
|
}
|
|
9603
|
+
function withTerminalPlayIdentity(status, playName) {
|
|
9604
|
+
if (!playName.trim() || getPlayRunPackage(status)) {
|
|
9605
|
+
return status;
|
|
9606
|
+
}
|
|
9607
|
+
const record = status;
|
|
9608
|
+
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"));
|
|
9609
|
+
if (hasIdentity) {
|
|
9610
|
+
return status;
|
|
9611
|
+
}
|
|
9612
|
+
return { ...status, playName };
|
|
9613
|
+
}
|
|
9385
9614
|
function compactPlayStatus(status) {
|
|
9386
9615
|
const packaged = getPlayRunPackage(status);
|
|
9387
9616
|
if (packaged) {
|
|
@@ -9558,6 +9787,9 @@ function actionToCommand(action) {
|
|
|
9558
9787
|
if (record.kind === "deepline_run_inspect" && typeof record.runId === "string") {
|
|
9559
9788
|
return `deepline runs get ${record.runId} --json`;
|
|
9560
9789
|
}
|
|
9790
|
+
if (record.kind === "deepline_run_billing" && typeof record.runId === "string") {
|
|
9791
|
+
return `deepline runs get ${record.runId} --full --json | jq '.billing'`;
|
|
9792
|
+
}
|
|
9561
9793
|
if (record.kind === "deepline_run_export" && typeof record.runId === "string" && typeof record.datasetPath === "string") {
|
|
9562
9794
|
return `deepline runs export ${record.runId} --dataset ${shellSingleQuote(
|
|
9563
9795
|
record.datasetPath
|
|
@@ -9590,6 +9822,12 @@ function buildRunPackageTextLines(packaged) {
|
|
|
9590
9822
|
if (playName) {
|
|
9591
9823
|
lines.push(` play: ${playName}`);
|
|
9592
9824
|
}
|
|
9825
|
+
const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
|
|
9826
|
+
const billingCommand = actionToCommand(next.billing);
|
|
9827
|
+
if (billingCommand) {
|
|
9828
|
+
const costState = status === "completed" || status === "failed" || status === "cancelled" ? "finalizing" : "pending";
|
|
9829
|
+
lines.push(` cost: ${costState}`);
|
|
9830
|
+
}
|
|
9593
9831
|
for (const step of readRecordArray(packaged.steps).slice(0, 8)) {
|
|
9594
9832
|
const id = typeof step.id === "string" ? step.id : "step";
|
|
9595
9833
|
const kind = typeof step.kind === "string" ? step.kind : "step";
|
|
@@ -9606,12 +9844,12 @@ function buildRunPackageTextLines(packaged) {
|
|
|
9606
9844
|
);
|
|
9607
9845
|
}
|
|
9608
9846
|
}
|
|
9609
|
-
const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
|
|
9610
9847
|
const datasetActions = readFirstDatasetActions(packaged);
|
|
9611
9848
|
const inspectCommand = actionToCommand(next.inspect);
|
|
9612
9849
|
const queryCommand = actionToCommand(next.query) ?? actionToCommand(datasetActions.query);
|
|
9613
9850
|
const exportCommand = actionToCommand(next.export) ?? actionToCommand(datasetActions.exportCsv);
|
|
9614
9851
|
if (inspectCommand) lines.push(` inspect: ${inspectCommand}`);
|
|
9852
|
+
if (billingCommand) lines.push(` billing: ${billingCommand}`);
|
|
9615
9853
|
if (queryCommand) lines.push(` query: ${queryCommand}`);
|
|
9616
9854
|
if (exportCommand) lines.push(` export CSV: ${exportCommand}`);
|
|
9617
9855
|
return lines;
|
|
@@ -10653,11 +10891,14 @@ async function handleFileBackedRun(options) {
|
|
|
10653
10891
|
} else {
|
|
10654
10892
|
progress.fail();
|
|
10655
10893
|
}
|
|
10656
|
-
const outputStatus =
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10894
|
+
const outputStatus = withTerminalPlayIdentity(
|
|
10895
|
+
await resolvePlayRunOutputStatus({
|
|
10896
|
+
client,
|
|
10897
|
+
status: finalStatus,
|
|
10898
|
+
fullJson: options.fullJson
|
|
10899
|
+
}),
|
|
10900
|
+
playName
|
|
10901
|
+
);
|
|
10661
10902
|
traceCliSync(
|
|
10662
10903
|
"cli.play_write_result",
|
|
10663
10904
|
{ targetKind: "file", playName },
|
|
@@ -10680,7 +10921,7 @@ async function handleFileBackedRun(options) {
|
|
|
10680
10921
|
dashboardUrl: resolvedDashboardUrl,
|
|
10681
10922
|
noOpen: options.noOpen
|
|
10682
10923
|
});
|
|
10683
|
-
progress.phase(
|
|
10924
|
+
progress.phase("started run");
|
|
10684
10925
|
progress.complete();
|
|
10685
10926
|
writeStartedPlayRun({
|
|
10686
10927
|
runId: started.workflowId,
|
|
@@ -10800,11 +11041,14 @@ async function handleNamedRun(options) {
|
|
|
10800
11041
|
} else {
|
|
10801
11042
|
progress.fail();
|
|
10802
11043
|
}
|
|
10803
|
-
const outputStatus =
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
11044
|
+
const outputStatus = withTerminalPlayIdentity(
|
|
11045
|
+
await resolvePlayRunOutputStatus({
|
|
11046
|
+
client,
|
|
11047
|
+
status: finalStatus,
|
|
11048
|
+
fullJson: options.fullJson
|
|
11049
|
+
}),
|
|
11050
|
+
playName
|
|
11051
|
+
);
|
|
10808
11052
|
traceCliSync(
|
|
10809
11053
|
"cli.play_write_result",
|
|
10810
11054
|
{ targetKind: "name", playName },
|
|
@@ -10827,7 +11071,7 @@ async function handleNamedRun(options) {
|
|
|
10827
11071
|
dashboardUrl: resolvedDashboardUrl,
|
|
10828
11072
|
noOpen: options.noOpen
|
|
10829
11073
|
});
|
|
10830
|
-
progress.phase(
|
|
11074
|
+
progress.phase("started run");
|
|
10831
11075
|
progress.complete();
|
|
10832
11076
|
writeStartedPlayRun({
|
|
10833
11077
|
runId: started.workflowId,
|
|
@@ -11315,16 +11559,19 @@ function parsePlaySearchOptions(args) {
|
|
|
11315
11559
|
const query = args[0]?.trim();
|
|
11316
11560
|
if (!query) {
|
|
11317
11561
|
throw new Error(
|
|
11318
|
-
"Usage: deepline plays search <query> [--compact] [--json]"
|
|
11562
|
+
"Usage: deepline plays search <query> [--all] [--compact] [--json]"
|
|
11319
11563
|
);
|
|
11320
11564
|
}
|
|
11321
11565
|
return {
|
|
11322
11566
|
query,
|
|
11323
11567
|
jsonOutput: argsWantJson(args),
|
|
11324
11568
|
compact: args.includes("--compact"),
|
|
11325
|
-
|
|
11569
|
+
scope: args.includes("--all") && !args.includes("--prebuilt") ? "all" : "prebuilt"
|
|
11326
11570
|
};
|
|
11327
11571
|
}
|
|
11572
|
+
function playSearchDisclaimer(scope) {
|
|
11573
|
+
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.";
|
|
11574
|
+
}
|
|
11328
11575
|
function printPlayDescription(play) {
|
|
11329
11576
|
const reference = formatPlayListReference(play);
|
|
11330
11577
|
const labels = [
|
|
@@ -11466,19 +11713,26 @@ async function handlePlaySearch(args) {
|
|
|
11466
11713
|
return 1;
|
|
11467
11714
|
}
|
|
11468
11715
|
const client = new DeeplineClient();
|
|
11469
|
-
const plays =
|
|
11716
|
+
const plays = await client.searchPlays({
|
|
11470
11717
|
query: options.query,
|
|
11471
|
-
compact: options.compact
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
);
|
|
11718
|
+
compact: options.compact,
|
|
11719
|
+
scope: options.scope
|
|
11720
|
+
});
|
|
11721
|
+
const disclaimer = playSearchDisclaimer(options.scope);
|
|
11475
11722
|
if (options.jsonOutput) {
|
|
11476
|
-
const jsonPlays = options.
|
|
11723
|
+
const jsonPlays = options.scope === "prebuilt" ? plays.map((play) => ({
|
|
11477
11724
|
...play,
|
|
11478
11725
|
inputSchema: compactPlaySchema(play.inputSchema)
|
|
11479
11726
|
})) : plays;
|
|
11480
11727
|
process.stdout.write(
|
|
11481
11728
|
`${JSON.stringify({
|
|
11729
|
+
disclaimer,
|
|
11730
|
+
search_policy: {
|
|
11731
|
+
default_scope: "prebuilt",
|
|
11732
|
+
included_origins: options.scope === "all" ? ["prebuilt", "owned"] : ["prebuilt"],
|
|
11733
|
+
owned_plays_omitted: options.scope === "prebuilt",
|
|
11734
|
+
include_owned_flag: "--all"
|
|
11735
|
+
},
|
|
11482
11736
|
plays: jsonPlays,
|
|
11483
11737
|
total: jsonPlays.length,
|
|
11484
11738
|
truncated: false
|
|
@@ -11487,21 +11741,23 @@ async function handlePlaySearch(args) {
|
|
|
11487
11741
|
);
|
|
11488
11742
|
return 0;
|
|
11489
11743
|
}
|
|
11490
|
-
const displayPlays = options.
|
|
11744
|
+
const displayPlays = options.scope === "prebuilt" ? plays.slice(0, 5) : plays;
|
|
11745
|
+
process.stdout.write(`${disclaimer}
|
|
11746
|
+
`);
|
|
11491
11747
|
process.stdout.write(
|
|
11492
|
-
`${plays.length} plays found${options.
|
|
11748
|
+
`${plays.length} plays found${options.scope === "prebuilt" && plays.length > displayPlays.length ? `; showing top ${displayPlays.length}` : ""}:
|
|
11493
11749
|
|
|
11494
11750
|
`
|
|
11495
11751
|
);
|
|
11496
11752
|
for (const play of displayPlays) {
|
|
11497
|
-
if (options.
|
|
11753
|
+
if (options.scope === "prebuilt") {
|
|
11498
11754
|
printCompactPlaySearchResult(play);
|
|
11499
11755
|
} else {
|
|
11500
11756
|
printPlayDescription(play);
|
|
11501
11757
|
}
|
|
11502
11758
|
console.log("");
|
|
11503
11759
|
}
|
|
11504
|
-
if (options.
|
|
11760
|
+
if (options.scope === "prebuilt" && plays.length > displayPlays.length) {
|
|
11505
11761
|
console.log("Use --json for the full machine-readable result set.");
|
|
11506
11762
|
}
|
|
11507
11763
|
return 0;
|
|
@@ -11955,18 +12211,26 @@ Examples:
|
|
|
11955
12211
|
...options.json ? ["--json"] : []
|
|
11956
12212
|
]);
|
|
11957
12213
|
});
|
|
11958
|
-
const addPlaySearchCommand = (command) => command.description("Search
|
|
12214
|
+
const addPlaySearchCommand = (command) => command.description("Search Deepline prebuilt plays by task.").option(
|
|
12215
|
+
"--prebuilt",
|
|
12216
|
+
"Only show Deepline-managed prebuilt plays (default)"
|
|
12217
|
+
).option(
|
|
12218
|
+
"--all",
|
|
12219
|
+
"Also include plays you created after Deepline-managed prebuilts"
|
|
12220
|
+
).addHelpText(
|
|
11959
12221
|
"after",
|
|
11960
12222
|
`
|
|
11961
12223
|
Notes:
|
|
11962
|
-
Ranked discovery for workflows.
|
|
11963
|
-
|
|
11964
|
-
|
|
12224
|
+
Ranked discovery for workflows. Search defaults to Deepline-managed prebuilts
|
|
12225
|
+
because they are trusted, robust plays with maintained contracts. Use describe
|
|
12226
|
+
on a result before running it.
|
|
12227
|
+
Add --all only when you are specifically looking for a play you created.
|
|
11965
12228
|
The grep alias is the same ranked retrieval surface with a more literal name
|
|
11966
12229
|
for agents that are filtering the play registry.
|
|
11967
12230
|
|
|
11968
12231
|
Examples:
|
|
11969
12232
|
deepline plays search email
|
|
12233
|
+
deepline plays search email --all
|
|
11970
12234
|
deepline plays grep "linkedin to email" --compact --json
|
|
11971
12235
|
deepline plays describe person-linkedin-to-email --json
|
|
11972
12236
|
`
|
|
@@ -11974,6 +12238,7 @@ Examples:
|
|
|
11974
12238
|
process.exitCode = await handlePlaySearch([
|
|
11975
12239
|
query,
|
|
11976
12240
|
...options.prebuilt ? ["--prebuilt"] : [],
|
|
12241
|
+
...options.all ? ["--all"] : [],
|
|
11977
12242
|
...options.compact ? ["--compact"] : [],
|
|
11978
12243
|
...options.json ? ["--json"] : []
|
|
11979
12244
|
]);
|
|
@@ -13741,7 +14006,7 @@ async function readHiddenLine(prompt) {
|
|
|
13741
14006
|
if (typeof import_node_process.stdin.setRawMode === "function") import_node_process.stdin.setRawMode(true);
|
|
13742
14007
|
let value = "";
|
|
13743
14008
|
import_node_process.stdin.resume();
|
|
13744
|
-
return await new Promise((
|
|
14009
|
+
return await new Promise((resolve14, reject) => {
|
|
13745
14010
|
let settled = false;
|
|
13746
14011
|
const cleanup = () => {
|
|
13747
14012
|
import_node_process.stdin.off("data", onData);
|
|
@@ -13756,7 +14021,7 @@ async function readHiddenLine(prompt) {
|
|
|
13756
14021
|
settled = true;
|
|
13757
14022
|
import_node_process.stdout.write("\n");
|
|
13758
14023
|
cleanup();
|
|
13759
|
-
|
|
14024
|
+
resolve14(line);
|
|
13760
14025
|
};
|
|
13761
14026
|
const fail = (error) => {
|
|
13762
14027
|
if (settled) return;
|
|
@@ -14521,7 +14786,13 @@ Examples:
|
|
|
14521
14786
|
).option(
|
|
14522
14787
|
"--json [payload]",
|
|
14523
14788
|
"Emit JSON output. Use `--input` or `--payload` for passing JSON params."
|
|
14524
|
-
).option(
|
|
14789
|
+
).option(
|
|
14790
|
+
"--input <payload>",
|
|
14791
|
+
"Merge a JSON object or @file path into the tool params"
|
|
14792
|
+
).option(
|
|
14793
|
+
"--payload <payload>",
|
|
14794
|
+
"Merge a JSON object or @file path into the tool params"
|
|
14795
|
+
).option(
|
|
14525
14796
|
"--output-format <format>",
|
|
14526
14797
|
"Output format: auto, csv, csv_file, json, or json_file"
|
|
14527
14798
|
).option(
|
|
@@ -15092,6 +15363,57 @@ function normalizeOutputFormat(raw) {
|
|
|
15092
15363
|
throw new Error(`Invalid value for --output-format: ${raw}`);
|
|
15093
15364
|
}
|
|
15094
15365
|
}
|
|
15366
|
+
function resolveAtFilePath(rawPath) {
|
|
15367
|
+
const trimmed = rawPath.trim();
|
|
15368
|
+
const resolved = (0, import_node_path15.resolve)(trimmed);
|
|
15369
|
+
if ((0, import_node_fs12.existsSync)(resolved)) return resolved;
|
|
15370
|
+
if (process.platform !== "win32" && trimmed.includes("\\")) {
|
|
15371
|
+
const normalized = (0, import_node_path15.resolve)(trimmed.replace(/\\/g, "/"));
|
|
15372
|
+
if ((0, import_node_fs12.existsSync)(normalized)) return normalized;
|
|
15373
|
+
}
|
|
15374
|
+
return resolved;
|
|
15375
|
+
}
|
|
15376
|
+
function readJsonArgument(raw, flagName) {
|
|
15377
|
+
if (!raw.startsWith("@")) return raw.replace(/^\uFEFF/, "");
|
|
15378
|
+
const filePath = raw.slice(1).trim();
|
|
15379
|
+
if (!filePath) {
|
|
15380
|
+
throw new Error(`Invalid ${flagName} value: empty @file path.`);
|
|
15381
|
+
}
|
|
15382
|
+
try {
|
|
15383
|
+
return (0, import_node_fs12.readFileSync)(resolveAtFilePath(filePath), "utf8").replace(
|
|
15384
|
+
/^\uFEFF/,
|
|
15385
|
+
""
|
|
15386
|
+
);
|
|
15387
|
+
} catch (error) {
|
|
15388
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15389
|
+
throw new Error(
|
|
15390
|
+
`Failed to read ${flagName} file '${filePath}': ${message}`
|
|
15391
|
+
);
|
|
15392
|
+
}
|
|
15393
|
+
}
|
|
15394
|
+
function invalidJsonError(flagName, message) {
|
|
15395
|
+
const error = new Error(
|
|
15396
|
+
`Invalid JSON in ${flagName}: ${message}`
|
|
15397
|
+
);
|
|
15398
|
+
error.code = "INVALID_JSON";
|
|
15399
|
+
return error;
|
|
15400
|
+
}
|
|
15401
|
+
function parseJsonObjectArgument(raw, flagName) {
|
|
15402
|
+
let parsed;
|
|
15403
|
+
try {
|
|
15404
|
+
parsed = JSON.parse(readJsonArgument(raw, flagName));
|
|
15405
|
+
} catch (error) {
|
|
15406
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15407
|
+
if (message.startsWith("Failed to read ") || message.startsWith("Invalid ")) {
|
|
15408
|
+
throw error;
|
|
15409
|
+
}
|
|
15410
|
+
throw invalidJsonError(flagName, message);
|
|
15411
|
+
}
|
|
15412
|
+
if (!isRecord5(parsed)) {
|
|
15413
|
+
throw invalidJsonError(flagName, "expected an object.");
|
|
15414
|
+
}
|
|
15415
|
+
return parsed;
|
|
15416
|
+
}
|
|
15095
15417
|
function parseExecuteOptions(args) {
|
|
15096
15418
|
const toolId = args[0];
|
|
15097
15419
|
if (!toolId) {
|
|
@@ -15114,12 +15436,15 @@ function parseExecuteOptions(args) {
|
|
|
15114
15436
|
const next = args[index + 1];
|
|
15115
15437
|
outputFormat = "json";
|
|
15116
15438
|
if (next && !next.startsWith("--")) {
|
|
15117
|
-
Object.assign(
|
|
15439
|
+
Object.assign(
|
|
15440
|
+
params,
|
|
15441
|
+
parseJsonObjectArgument(args[++index], "--json")
|
|
15442
|
+
);
|
|
15118
15443
|
}
|
|
15119
15444
|
continue;
|
|
15120
15445
|
}
|
|
15121
15446
|
if ((arg === "--input" || arg === "--payload") && args[index + 1]) {
|
|
15122
|
-
Object.assign(params,
|
|
15447
|
+
Object.assign(params, parseJsonObjectArgument(args[++index], arg));
|
|
15123
15448
|
continue;
|
|
15124
15449
|
}
|
|
15125
15450
|
if (arg === "--output-format" && args[index + 1]) {
|
|
@@ -15704,7 +16029,7 @@ function commandCompatibilityHint(currentFamily, commandName, baseUrl) {
|
|
|
15704
16029
|
lines.push(
|
|
15705
16030
|
"",
|
|
15706
16031
|
" To stay on the SDK CLI, install the SDK agent skill:",
|
|
15707
|
-
` ${skillsInstallCommand(baseUrl, "deepline-
|
|
16032
|
+
` ${skillsInstallCommand(baseUrl, "deepline-plays")}`,
|
|
15708
16033
|
" To use the legacy Python CLI instead:",
|
|
15709
16034
|
` ${legacyPythonInstallCommand(baseUrl)}`,
|
|
15710
16035
|
" `deepline update` updates this SDK CLI, but it will not switch CLI families."
|
|
@@ -15717,7 +16042,7 @@ function commandCompatibilityHint(currentFamily, commandName, baseUrl) {
|
|
|
15717
16042
|
"",
|
|
15718
16043
|
" To use SDK commands, install the SDK CLI and SDK agent skill:",
|
|
15719
16044
|
` ${sdkNpmGlobalInstallCommand()}`,
|
|
15720
|
-
` ${skillsInstallCommand(baseUrl, "deepline-
|
|
16045
|
+
` ${skillsInstallCommand(baseUrl, "deepline-plays")}`,
|
|
15721
16046
|
" `deepline update` updates this Python CLI and its skills, but it will not switch CLI families."
|
|
15722
16047
|
);
|
|
15723
16048
|
if (compatibility.python_alternative) {
|
|
@@ -15738,12 +16063,29 @@ var import_node_fs14 = require("fs");
|
|
|
15738
16063
|
var import_node_os10 = require("os");
|
|
15739
16064
|
var import_node_path17 = require("path");
|
|
15740
16065
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
15741
|
-
var SDK_SKILL_NAME = "deepline-
|
|
16066
|
+
var SDK_SKILL_NAME = "deepline-plays";
|
|
15742
16067
|
var attemptedSync = false;
|
|
15743
16068
|
function shouldSkipSkillsSync() {
|
|
15744
16069
|
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
15745
16070
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
15746
16071
|
}
|
|
16072
|
+
function activePluginSkillsDir() {
|
|
16073
|
+
const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
|
|
16074
|
+
if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
|
|
16075
|
+
return "";
|
|
16076
|
+
}
|
|
16077
|
+
const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
|
|
16078
|
+
return dir && (0, import_node_fs14.existsSync)(dir) ? dir : "";
|
|
16079
|
+
}
|
|
16080
|
+
function readPluginSkillsVersion() {
|
|
16081
|
+
const dir = activePluginSkillsDir();
|
|
16082
|
+
if (!dir) return "";
|
|
16083
|
+
try {
|
|
16084
|
+
return (0, import_node_fs14.readFileSync)((0, import_node_path17.join)(dir, ".version"), "utf-8").trim();
|
|
16085
|
+
} catch {
|
|
16086
|
+
return "";
|
|
16087
|
+
}
|
|
16088
|
+
}
|
|
15747
16089
|
function sdkSkillsVersionPath(baseUrl) {
|
|
15748
16090
|
const home = process.env.HOME?.trim() || (0, import_node_os10.homedir)();
|
|
15749
16091
|
return (0, import_node_path17.join)(
|
|
@@ -15756,6 +16098,8 @@ function sdkSkillsVersionPath(baseUrl) {
|
|
|
15756
16098
|
);
|
|
15757
16099
|
}
|
|
15758
16100
|
function readLocalSkillsVersion(baseUrl) {
|
|
16101
|
+
const pluginVersion = readPluginSkillsVersion();
|
|
16102
|
+
if (pluginVersion) return pluginVersion;
|
|
15759
16103
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
15760
16104
|
if (!(0, import_node_fs14.existsSync)(path)) return "";
|
|
15761
16105
|
try {
|
|
@@ -15772,7 +16116,8 @@ function writeLocalSkillsVersion(baseUrl, version) {
|
|
|
15772
16116
|
}
|
|
15773
16117
|
function installedSdkSkillHasStalePositionalExecuteExamples() {
|
|
15774
16118
|
const home = process.env.HOME?.trim() || (0, import_node_os10.homedir)();
|
|
15775
|
-
const
|
|
16119
|
+
const pluginSkillsDir = activePluginSkillsDir();
|
|
16120
|
+
const roots = pluginSkillsDir ? [(0, import_node_path17.join)(pluginSkillsDir, SDK_SKILL_NAME)] : [
|
|
15776
16121
|
(0, import_node_path17.join)(home, ".claude", "skills", SDK_SKILL_NAME),
|
|
15777
16122
|
(0, import_node_path17.join)(home, ".agents", "skills", SDK_SKILL_NAME)
|
|
15778
16123
|
];
|
|
@@ -15871,7 +16216,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
15871
16216
|
return [npxInstall];
|
|
15872
16217
|
}
|
|
15873
16218
|
function runOneSkillsInstall(install) {
|
|
15874
|
-
return new Promise((
|
|
16219
|
+
return new Promise((resolve14) => {
|
|
15875
16220
|
const child = (0, import_node_child_process2.spawn)(install.command, install.args, {
|
|
15876
16221
|
stdio: ["ignore", "ignore", "pipe"],
|
|
15877
16222
|
env: process.env
|
|
@@ -15881,7 +16226,7 @@ function runOneSkillsInstall(install) {
|
|
|
15881
16226
|
stderr += chunk.toString("utf-8");
|
|
15882
16227
|
});
|
|
15883
16228
|
child.on("error", (error) => {
|
|
15884
|
-
|
|
16229
|
+
resolve14({
|
|
15885
16230
|
ok: false,
|
|
15886
16231
|
detail: `failed to start ${install.command}: ${error.message}`,
|
|
15887
16232
|
manualCommand: install.manualCommand
|
|
@@ -15889,11 +16234,11 @@ function runOneSkillsInstall(install) {
|
|
|
15889
16234
|
});
|
|
15890
16235
|
child.on("close", (code) => {
|
|
15891
16236
|
if (code === 0) {
|
|
15892
|
-
|
|
16237
|
+
resolve14({ ok: true, detail: "", manualCommand: install.manualCommand });
|
|
15893
16238
|
return;
|
|
15894
16239
|
}
|
|
15895
16240
|
const detail = stderr.trim();
|
|
15896
|
-
|
|
16241
|
+
resolve14({
|
|
15897
16242
|
ok: false,
|
|
15898
16243
|
detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
|
|
15899
16244
|
manualCommand: install.manualCommand
|
|
@@ -15930,18 +16275,22 @@ function writeSdkSkillsStatusLine(line) {
|
|
|
15930
16275
|
async function syncSdkSkillsIfNeeded(baseUrl) {
|
|
15931
16276
|
if (attemptedSync || shouldSkipSkillsSync()) return;
|
|
15932
16277
|
attemptedSync = true;
|
|
16278
|
+
const usingPluginSkills = Boolean(activePluginSkillsDir());
|
|
15933
16279
|
const localVersion = readLocalSkillsVersion(baseUrl);
|
|
15934
16280
|
const update = await fetchSkillsUpdate(baseUrl, localVersion);
|
|
15935
16281
|
const hasStaleInstalledSkill = installedSdkSkillHasStalePositionalExecuteExamples();
|
|
16282
|
+
if (usingPluginSkills) {
|
|
16283
|
+
return;
|
|
16284
|
+
}
|
|
15936
16285
|
if (!update?.needsUpdate && !hasStaleInstalledSkill || !update?.remoteVersion) {
|
|
15937
16286
|
return;
|
|
15938
16287
|
}
|
|
15939
|
-
writeSdkSkillsStatusLine("SDK skills changed; syncing deepline-
|
|
16288
|
+
writeSdkSkillsStatusLine("SDK skills changed; syncing deepline-plays skill...");
|
|
15940
16289
|
const installed = await runSkillsInstall(baseUrl);
|
|
15941
16290
|
if (!installed) return;
|
|
15942
16291
|
if (installedSdkSkillHasStalePositionalExecuteExamples()) {
|
|
15943
16292
|
process.stderr.write(
|
|
15944
|
-
"SDK skills sync completed, but installed deepline-
|
|
16293
|
+
"SDK skills sync completed, but installed deepline-plays docs still contain stale positional ctx.tools.execute examples.\n"
|
|
15945
16294
|
);
|
|
15946
16295
|
return;
|
|
15947
16296
|
}
|