deepline 0.3.213 → 0.3.214
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/client.ts +122 -32
- package/dist/bundling-sources/sdk/src/compat.ts +2 -0
- package/dist/bundling-sources/sdk/src/deployment-protection.ts +19 -0
- package/dist/bundling-sources/sdk/src/http.ts +3 -7
- package/dist/bundling-sources/sdk/src/index.ts +7 -0
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +25 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +18 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +33 -7
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +11 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +53 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +187 -6
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +12 -3
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +5 -2
- package/dist/bundling-sources/shared_libs/plays/settings-contract.ts +176 -0
- package/dist/cli/index.js +560 -92
- package/dist/cli/index.mjs +560 -92
- package/dist/index.d.mts +165 -3
- package/dist/index.d.ts +165 -3
- package/dist/index.js +67 -35
- package/dist/index.mjs +67 -35
- package/dist/install-integrity.json +2 -0
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +3 -2
package/dist/cli/index.mjs
CHANGED
|
@@ -3046,7 +3046,7 @@ var SDK_RELEASE = {
|
|
|
3046
3046
|
// getters keep their established compatibility behavior.
|
|
3047
3047
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3048
3048
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3049
|
-
version: "0.3.
|
|
3049
|
+
version: "0.3.214",
|
|
3050
3050
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
3051
3051
|
packageCapabilities: {
|
|
3052
3052
|
updatePreferences: 1
|
|
@@ -3367,6 +3367,22 @@ function writeSdkSkillsLocalVersion(baseUrl, version, agents) {
|
|
|
3367
3367
|
return complete;
|
|
3368
3368
|
}
|
|
3369
3369
|
|
|
3370
|
+
// src/deployment-protection.ts
|
|
3371
|
+
function deploymentProtectionHeaders() {
|
|
3372
|
+
const token = typeof process !== "undefined" ? process.env?.VERCEL_PROTECTION_BYPASS_TOKEN : void 0;
|
|
3373
|
+
return token ? { "x-vercel-protection-bypass": token } : {};
|
|
3374
|
+
}
|
|
3375
|
+
var fetchWithDeploymentProtection = (input2, init) => {
|
|
3376
|
+
const headers = new Headers(
|
|
3377
|
+
input2 instanceof Request ? input2.headers : void 0
|
|
3378
|
+
);
|
|
3379
|
+
new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
|
|
3380
|
+
for (const [name, value] of Object.entries(deploymentProtectionHeaders())) {
|
|
3381
|
+
headers.set(name, value);
|
|
3382
|
+
}
|
|
3383
|
+
return fetch(input2, { ...init, headers });
|
|
3384
|
+
};
|
|
3385
|
+
|
|
3370
3386
|
// ../play-runtime/coordinator-headers.ts
|
|
3371
3387
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
3372
3388
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
@@ -3749,16 +3765,13 @@ var HttpClient = class {
|
|
|
3749
3765
|
"X-Deepline-SDK-Version": SDK_VERSION,
|
|
3750
3766
|
"X-Deepline-API-Contract": SDK_API_CONTRACT,
|
|
3751
3767
|
"X-Deepline-Run-Result-Shape": "canonical",
|
|
3752
|
-
...extra
|
|
3768
|
+
...extra,
|
|
3769
|
+
...deploymentProtectionHeaders()
|
|
3753
3770
|
};
|
|
3754
3771
|
const skillsVersion = this.readSkillsVersionHeader();
|
|
3755
3772
|
if (skillsVersion) {
|
|
3756
3773
|
headers["X-Deepline-Skills-Version"] = skillsVersion;
|
|
3757
3774
|
}
|
|
3758
|
-
const bypassToken = typeof process !== "undefined" ? process.env?.VERCEL_PROTECTION_BYPASS_TOKEN : void 0;
|
|
3759
|
-
if (bypassToken) {
|
|
3760
|
-
headers["x-vercel-protection-bypass"] = bypassToken;
|
|
3761
|
-
}
|
|
3762
3775
|
const playArtifactR2Prefix = typeof process !== "undefined" ? process.env?.DEEPLINE_PLAY_ARTIFACT_R2_PREFIX : void 0;
|
|
3763
3776
|
if (playArtifactR2Prefix) {
|
|
3764
3777
|
headers["x-deepline-play-artifact-r2-prefix"] = playArtifactR2Prefix;
|
|
@@ -4887,13 +4900,13 @@ function previewValue(value, input2) {
|
|
|
4887
4900
|
([, descriptor]) => descriptor.enumerable
|
|
4888
4901
|
);
|
|
4889
4902
|
const selected = entries.slice(0, DOCFLOW_NODE_IO_LIMITS.maxObjectFields);
|
|
4890
|
-
const
|
|
4903
|
+
const fields2 = {};
|
|
4891
4904
|
for (const [key, descriptor] of selected) {
|
|
4892
4905
|
const safeKey = truncateUtf8(
|
|
4893
4906
|
ledgerSafeDocflowPreviewKey(input2.redactor.redactString(key)),
|
|
4894
4907
|
DOCFLOW_NODE_IO_LIMITS.maxStringBytes
|
|
4895
4908
|
);
|
|
4896
|
-
|
|
4909
|
+
fields2[safeKey] = "value" in descriptor ? previewValue(descriptor.value, {
|
|
4897
4910
|
...input2,
|
|
4898
4911
|
depth: input2.depth + 1,
|
|
4899
4912
|
key
|
|
@@ -4901,7 +4914,7 @@ function previewValue(value, input2) {
|
|
|
4901
4914
|
}
|
|
4902
4915
|
return {
|
|
4903
4916
|
kind: "object",
|
|
4904
|
-
fields,
|
|
4917
|
+
fields: fields2,
|
|
4905
4918
|
totalFields: entries.length,
|
|
4906
4919
|
...entries.length > selected.length ? { truncated: true } : {}
|
|
4907
4920
|
};
|
|
@@ -5010,20 +5023,20 @@ function normalizePreview(value, depth) {
|
|
|
5010
5023
|
};
|
|
5011
5024
|
}
|
|
5012
5025
|
if (value.kind === "object" && isRecord3(value.fields)) {
|
|
5013
|
-
const
|
|
5026
|
+
const fields2 = {};
|
|
5014
5027
|
for (const [key, field] of Object.entries(value.fields).slice(
|
|
5015
5028
|
0,
|
|
5016
5029
|
DOCFLOW_NODE_IO_LIMITS.maxObjectFields
|
|
5017
5030
|
)) {
|
|
5018
5031
|
const normalized = normalizePreview(field, depth + 1);
|
|
5019
|
-
if (normalized)
|
|
5032
|
+
if (normalized) fields2[ledgerSafeDocflowPreviewKey(key)] = normalized;
|
|
5020
5033
|
}
|
|
5021
|
-
const totalFields = typeof value.totalFields === "number" && Number.isFinite(value.totalFields) ? Math.max(Object.keys(
|
|
5034
|
+
const totalFields = typeof value.totalFields === "number" && Number.isFinite(value.totalFields) ? Math.max(Object.keys(fields2).length, Math.floor(value.totalFields)) : Object.keys(fields2).length;
|
|
5022
5035
|
return {
|
|
5023
5036
|
kind: "object",
|
|
5024
|
-
fields,
|
|
5037
|
+
fields: fields2,
|
|
5025
5038
|
totalFields,
|
|
5026
|
-
...value.truncated === true || totalFields > Object.keys(
|
|
5039
|
+
...value.truncated === true || totalFields > Object.keys(fields2).length ? { truncated: true } : {}
|
|
5027
5040
|
};
|
|
5028
5041
|
}
|
|
5029
5042
|
return null;
|
|
@@ -7035,10 +7048,19 @@ function normalizePlayStatus(raw) {
|
|
|
7035
7048
|
);
|
|
7036
7049
|
}
|
|
7037
7050
|
const runId = typeof raw.runId === "string" ? raw.runId : typeof raw.workflowId === "string" ? raw.workflowId : packageRun?.id ?? "";
|
|
7051
|
+
const legacyOverview = runPackage?.overview ?? raw.overview;
|
|
7052
|
+
const runStatus = runPackage?.runStatus ?? raw.runStatus;
|
|
7038
7053
|
return {
|
|
7039
7054
|
...raw,
|
|
7040
7055
|
runId,
|
|
7041
|
-
...
|
|
7056
|
+
...isRecord7(legacyOverview) ? {
|
|
7057
|
+
overview: legacyOverview
|
|
7058
|
+
} : {},
|
|
7059
|
+
...isRecord7(runStatus) ? { runStatus } : {},
|
|
7060
|
+
...runPackage ? {
|
|
7061
|
+
package: runPackage,
|
|
7062
|
+
outputs: runPackage.outputs
|
|
7063
|
+
} : {},
|
|
7042
7064
|
status
|
|
7043
7065
|
};
|
|
7044
7066
|
}
|
|
@@ -7220,18 +7242,6 @@ function playRunResultFromStatus(status, startedAt, fallbackRunId) {
|
|
|
7220
7242
|
error: status.progress?.error ?? (status.status !== "completed" ? status.status : void 0)
|
|
7221
7243
|
};
|
|
7222
7244
|
}
|
|
7223
|
-
function playRunStatusFromState(state) {
|
|
7224
|
-
return {
|
|
7225
|
-
runId: state.runId,
|
|
7226
|
-
status: state.status,
|
|
7227
|
-
progress: {
|
|
7228
|
-
status: state.status,
|
|
7229
|
-
logs: state.logs,
|
|
7230
|
-
...state.error ? { error: state.error } : {}
|
|
7231
|
-
},
|
|
7232
|
-
..."result" in state ? { result: state.result } : {}
|
|
7233
|
-
};
|
|
7234
|
-
}
|
|
7235
7245
|
var DeeplineClient = class _DeeplineClient {
|
|
7236
7246
|
http;
|
|
7237
7247
|
config;
|
|
@@ -7374,14 +7384,14 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
7374
7384
|
}
|
|
7375
7385
|
compactSchema(schema) {
|
|
7376
7386
|
if (!schema) return null;
|
|
7377
|
-
const
|
|
7387
|
+
const fields2 = Array.isArray(schema.fields) ? schema.fields.map(
|
|
7378
7388
|
(field) => field && typeof field === "object" ? {
|
|
7379
7389
|
name: String(field.name ?? ""),
|
|
7380
7390
|
type: field.type ?? void 0,
|
|
7381
7391
|
required: field.required ?? void 0
|
|
7382
7392
|
} : null
|
|
7383
7393
|
).filter((field) => Boolean(field?.name)) : [];
|
|
7384
|
-
return
|
|
7394
|
+
return fields2.length > 0 ? { fields: fields2 } : schema;
|
|
7385
7395
|
}
|
|
7386
7396
|
schemaMetadata(schema, key) {
|
|
7387
7397
|
if (!isRecord7(schema)) return null;
|
|
@@ -7568,6 +7578,12 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
7568
7578
|
options.includeSearchDebug ? "true" : "false"
|
|
7569
7579
|
);
|
|
7570
7580
|
params.set("search_mode", options.searchMode ?? "v2");
|
|
7581
|
+
if (options.limit !== void 0) {
|
|
7582
|
+
params.set("limit", String(options.limit));
|
|
7583
|
+
}
|
|
7584
|
+
if (options.offset !== void 0) {
|
|
7585
|
+
params.set("offset", String(options.offset));
|
|
7586
|
+
}
|
|
7571
7587
|
if (options.categories?.trim()) {
|
|
7572
7588
|
params.set("categories", options.categories.trim());
|
|
7573
7589
|
}
|
|
@@ -8629,9 +8645,18 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8629
8645
|
}
|
|
8630
8646
|
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
8631
8647
|
const response = await this.http.get(
|
|
8632
|
-
`/api/v2/runs/${encodeURIComponent(runId)}${query}
|
|
8648
|
+
`/api/v2/runs/${encodeURIComponent(runId)}${query}`,
|
|
8649
|
+
{ headers: { "x-deepline-run-status": "1" } }
|
|
8633
8650
|
);
|
|
8651
|
+
const responseRunStatus = isPlayRunPackage(response) ? response.runStatus : isPlayRunPackage(response.package) ? response.package.runStatus : response.runStatus;
|
|
8652
|
+
const responseOverview = isPlayRunPackage(response) ? response.overview : isPlayRunPackage(response.package) ? response.package.overview : response.overview;
|
|
8634
8653
|
const status = normalizePlayStatus(response);
|
|
8654
|
+
if (isRecord7(responseRunStatus)) {
|
|
8655
|
+
status.runStatus = responseRunStatus;
|
|
8656
|
+
}
|
|
8657
|
+
if (isRecord7(responseOverview)) {
|
|
8658
|
+
status.overview = responseOverview;
|
|
8659
|
+
}
|
|
8635
8660
|
if (options?.failedLogs !== true || status.status !== "failed") {
|
|
8636
8661
|
return status;
|
|
8637
8662
|
}
|
|
@@ -8672,7 +8697,10 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8672
8697
|
}
|
|
8673
8698
|
};
|
|
8674
8699
|
}
|
|
8675
|
-
/**
|
|
8700
|
+
/** Fetch only the legacy scalar lifecycle status for a run.
|
|
8701
|
+
*
|
|
8702
|
+
* @deprecated Use `client.runs.get(runId)` for the canonical run read.
|
|
8703
|
+
*/
|
|
8676
8704
|
async getRunLifecycleStatus(runId) {
|
|
8677
8705
|
const response = await this.http.get(
|
|
8678
8706
|
`/api/v2/runs/${encodeURIComponent(runId)}/status`
|
|
@@ -8848,9 +8876,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8848
8876
|
if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
|
|
8849
8877
|
continue;
|
|
8850
8878
|
}
|
|
8851
|
-
return await this.getRunStatus(status.runId || runId)
|
|
8852
|
-
() => state.latest ?? playRunStatusFromState(state)
|
|
8853
|
-
);
|
|
8879
|
+
return await this.getRunStatus(status.runId || runId);
|
|
8854
8880
|
}
|
|
8855
8881
|
if (options?.signal?.aborted) {
|
|
8856
8882
|
throw new DeeplineError("Run observation aborted.", void 0, "ABORTED");
|
|
@@ -8901,6 +8927,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8901
8927
|
for (; ; ) {
|
|
8902
8928
|
const connectedAt = Date.now();
|
|
8903
8929
|
let sawEvent = false;
|
|
8930
|
+
let terminalRunId = null;
|
|
8904
8931
|
let endedReason = "stream window ended before a terminal event";
|
|
8905
8932
|
try {
|
|
8906
8933
|
for await (const event of this.streamPlayRunEvents(runId, {
|
|
@@ -8913,9 +8940,8 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8913
8940
|
if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
|
|
8914
8941
|
continue;
|
|
8915
8942
|
}
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
);
|
|
8943
|
+
terminalRunId = status.runId || runId;
|
|
8944
|
+
break;
|
|
8919
8945
|
}
|
|
8920
8946
|
} catch (error) {
|
|
8921
8947
|
if (options?.signal?.aborted || !isTransientPlayStreamError(error)) {
|
|
@@ -8923,15 +8949,11 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8923
8949
|
}
|
|
8924
8950
|
endedReason = error instanceof Error ? error.message : String(error);
|
|
8925
8951
|
}
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
refreshed = await this.getRunStatus(runId);
|
|
8929
|
-
} catch (error) {
|
|
8930
|
-
if (!isTransientPlayStreamError(error)) {
|
|
8931
|
-
throw error;
|
|
8932
|
-
}
|
|
8952
|
+
if (terminalRunId) {
|
|
8953
|
+
return await this.getRunStatus(terminalRunId);
|
|
8933
8954
|
}
|
|
8934
|
-
|
|
8955
|
+
const refreshed = await this.getRunStatus(runId);
|
|
8956
|
+
if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
|
|
8935
8957
|
return refreshed;
|
|
8936
8958
|
}
|
|
8937
8959
|
if (sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
|
|
@@ -9220,6 +9242,26 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
9220
9242
|
hasMore: Boolean(response.pagination?.hasMore ?? response.hasMore)
|
|
9221
9243
|
};
|
|
9222
9244
|
}
|
|
9245
|
+
/** Read definition-level settings, independently of code revisions. */
|
|
9246
|
+
async getPlaySettings(playName) {
|
|
9247
|
+
return this.http.get(
|
|
9248
|
+
`/api/v2/plays/${encodeURIComponent(playName)}/settings`
|
|
9249
|
+
);
|
|
9250
|
+
}
|
|
9251
|
+
/** Retry-safe field patch; omitted fields retain their current value. */
|
|
9252
|
+
async updatePlaySettings(playName, patch) {
|
|
9253
|
+
return this.http.patch(
|
|
9254
|
+
`/api/v2/plays/${encodeURIComponent(playName)}/settings`,
|
|
9255
|
+
patch
|
|
9256
|
+
);
|
|
9257
|
+
}
|
|
9258
|
+
/** List one bounded page of existing Play locations; continue with cursor. */
|
|
9259
|
+
async listPlaySettingsPaths(options = {}) {
|
|
9260
|
+
const query = new URLSearchParams();
|
|
9261
|
+
for (const [key, value] of Object.entries(options))
|
|
9262
|
+
if (value !== void 0) query.set(key, String(value));
|
|
9263
|
+
return this.http.get(`/api/v2/plays/settings/paths?${query}`);
|
|
9264
|
+
}
|
|
9223
9265
|
/** Set whether an org-owned Play sorts before unpinned Plays. */
|
|
9224
9266
|
async setPlayPinned(playName, pinned) {
|
|
9225
9267
|
return this.http.post(`/api/v2/plays/${encodeURIComponent(playName)}/pin`, {
|
|
@@ -10837,6 +10879,7 @@ async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
|
10837
10879
|
const response = await fetch(url, {
|
|
10838
10880
|
method: "GET",
|
|
10839
10881
|
headers: {
|
|
10882
|
+
...deploymentProtectionHeaders(),
|
|
10840
10883
|
"User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
|
|
10841
10884
|
"X-Deepline-SDK-Version": SDK_VERSION,
|
|
10842
10885
|
"X-Deepline-API-Major": String(SDK_API_MAJOR),
|
|
@@ -11713,8 +11756,8 @@ function resolvePendingAuthClaimForResume(baseUrl, requestedScope) {
|
|
|
11713
11756
|
const claim = readPendingAuthClaim(baseUrl, requestedScope);
|
|
11714
11757
|
return { claim, scope: claim?.scope ?? requestedScope };
|
|
11715
11758
|
}
|
|
11716
|
-
const
|
|
11717
|
-
if (
|
|
11759
|
+
const folder2 = readPendingAuthClaim(baseUrl, "folder");
|
|
11760
|
+
if (folder2) return { claim: folder2, scope: folder2.scope };
|
|
11718
11761
|
const global = readPendingAuthClaim(baseUrl, "global");
|
|
11719
11762
|
return { claim: global, scope: global?.scope ?? "global" };
|
|
11720
11763
|
}
|
|
@@ -15917,6 +15960,332 @@ import { homedir as homedir6, tmpdir as tmpdir5 } from "os";
|
|
|
15917
15960
|
import { basename as basename4, dirname as dirname11, extname as extname3, join as join14, resolve as resolve13 } from "path";
|
|
15918
15961
|
import { Option as Option2 } from "commander";
|
|
15919
15962
|
|
|
15963
|
+
// ../plays/settings-contract.ts
|
|
15964
|
+
import { z } from "zod";
|
|
15965
|
+
function formatPlaySettingsError(error) {
|
|
15966
|
+
if (error instanceof z.ZodError)
|
|
15967
|
+
return [...new Set(error.issues.map((issue) => issue.message))].join(" ");
|
|
15968
|
+
return error instanceof Error ? error.message : String(error);
|
|
15969
|
+
}
|
|
15970
|
+
var PLAY_LOCATION_ROOTS = [
|
|
15971
|
+
{
|
|
15972
|
+
value: "person",
|
|
15973
|
+
label: "Personal",
|
|
15974
|
+
description: "The creator\u2019s personal root, displayed as their name followed by \u201C\u2019s team\u201D."
|
|
15975
|
+
},
|
|
15976
|
+
{
|
|
15977
|
+
value: "team",
|
|
15978
|
+
label: "Team library",
|
|
15979
|
+
description: "The shared team library. Publishing moves personal locations here, keeping their folders."
|
|
15980
|
+
}
|
|
15981
|
+
];
|
|
15982
|
+
var folder = z.string().min(1).max(128).refine(
|
|
15983
|
+
(value) => value === value.trim() && value !== "." && value !== ".." && !/[\\/\u0000-\u001f\u007f]/u.test(value),
|
|
15984
|
+
"Folder names must be trimmed, cannot be . or .., and cannot contain slashes or control characters."
|
|
15985
|
+
);
|
|
15986
|
+
var playPathSchema = z.union([
|
|
15987
|
+
z.null(),
|
|
15988
|
+
z.object({
|
|
15989
|
+
root: z.enum(["person", "team"]),
|
|
15990
|
+
folders: z.array(folder).max(16).default([])
|
|
15991
|
+
}).strict()
|
|
15992
|
+
]).transform(
|
|
15993
|
+
(path) => path?.root === "person" && path.folders.length === 0 ? null : path
|
|
15994
|
+
);
|
|
15995
|
+
function parsePlayPath(value) {
|
|
15996
|
+
const [root, ...parts] = value.split("/");
|
|
15997
|
+
if (!PLAY_LOCATION_ROOTS.some((option) => option.value === root)) {
|
|
15998
|
+
throw new Error(
|
|
15999
|
+
"Path must start with person or team. Example: person/Research/ICP."
|
|
16000
|
+
);
|
|
16001
|
+
}
|
|
16002
|
+
let folders;
|
|
16003
|
+
try {
|
|
16004
|
+
folders = parts.map(decodeURIComponent);
|
|
16005
|
+
} catch {
|
|
16006
|
+
throw new Error(
|
|
16007
|
+
"Path contains an invalid percent escape. Encode a literal % as %25."
|
|
16008
|
+
);
|
|
16009
|
+
}
|
|
16010
|
+
return playPathSchema.parse({ root, folders });
|
|
16011
|
+
}
|
|
16012
|
+
function formatPlayPath(path) {
|
|
16013
|
+
return path === null ? "person" : [path.root, ...path.folders.map(encodeURIComponent)].join("/");
|
|
16014
|
+
}
|
|
16015
|
+
function personalPlayRootLabel(ownerName) {
|
|
16016
|
+
const name = ownerName?.trim();
|
|
16017
|
+
return name ? `${name.split(/\s+/)[0]}\u2019s team` : "Personal";
|
|
16018
|
+
}
|
|
16019
|
+
function displayPlayPath(path, ownerName) {
|
|
16020
|
+
return [
|
|
16021
|
+
path?.root === "team" ? "Team library" : personalPlayRootLabel(ownerName),
|
|
16022
|
+
...path?.folders ?? []
|
|
16023
|
+
].join(" / ");
|
|
16024
|
+
}
|
|
16025
|
+
var PLAY_SETTING_FIELDS = {
|
|
16026
|
+
path: {
|
|
16027
|
+
schema: playPathSchema.default(null).describe(
|
|
16028
|
+
"Play location. Null means the creator\u2019s personal root. Publishing moves it into Team library, preserving folders."
|
|
16029
|
+
),
|
|
16030
|
+
label: "Location",
|
|
16031
|
+
description: "Organize this Play in the creator\u2019s personal root or Team library. Publishing moves it to Team library and keeps its folders. Workspace sharing permissions apply in both roots.",
|
|
16032
|
+
get defaultValue() {
|
|
16033
|
+
return this.schema.parse(void 0);
|
|
16034
|
+
},
|
|
16035
|
+
cli: {
|
|
16036
|
+
valueSyntax: "person[/folder/\u2026] | team[/folder/\u2026] | null",
|
|
16037
|
+
examples: [
|
|
16038
|
+
"person",
|
|
16039
|
+
"person/Research/ICP",
|
|
16040
|
+
"team",
|
|
16041
|
+
"team/Research",
|
|
16042
|
+
"null"
|
|
16043
|
+
],
|
|
16044
|
+
parse: (value) => value === "null" ? null : parsePlayPath(value),
|
|
16045
|
+
format: formatPlayPath
|
|
16046
|
+
},
|
|
16047
|
+
ui: { control: "play-location-picker" }
|
|
16048
|
+
}
|
|
16049
|
+
};
|
|
16050
|
+
var playSettingsSchema = z.object(
|
|
16051
|
+
Object.fromEntries(
|
|
16052
|
+
Object.entries(PLAY_SETTING_FIELDS).map(([key, field]) => [
|
|
16053
|
+
key,
|
|
16054
|
+
field.schema
|
|
16055
|
+
])
|
|
16056
|
+
)
|
|
16057
|
+
).passthrough();
|
|
16058
|
+
var playSettingsPatchSchema = z.object(
|
|
16059
|
+
Object.fromEntries(
|
|
16060
|
+
Object.entries(PLAY_SETTING_FIELDS).map(([key, field]) => [
|
|
16061
|
+
key,
|
|
16062
|
+
field.schema.unwrap().optional()
|
|
16063
|
+
])
|
|
16064
|
+
)
|
|
16065
|
+
).strict().refine(
|
|
16066
|
+
(patch) => Object.keys(patch).length > 0,
|
|
16067
|
+
"Supply at least one setting."
|
|
16068
|
+
);
|
|
16069
|
+
function parsePlaySettings(value) {
|
|
16070
|
+
return playSettingsSchema.parse(value);
|
|
16071
|
+
}
|
|
16072
|
+
var DEFAULT_PLAY_SETTINGS = parsePlaySettings({});
|
|
16073
|
+
|
|
16074
|
+
// src/cli/commands/plays-settings.ts
|
|
16075
|
+
var fields = Object.entries(PLAY_SETTING_FIELDS);
|
|
16076
|
+
var help = `
|
|
16077
|
+
Settings live on the Play definition. Edits preserve code revisions.
|
|
16078
|
+
New Plays start at person (the creator\u2019s personal root, e.g. Chirag\u2019s team).
|
|
16079
|
+
Publishing moves a Play into team and keeps its folders. Workspace sharing
|
|
16080
|
+
permissions apply in both roots. Folder paths are independent of your cwd.
|
|
16081
|
+
|
|
16082
|
+
Setting names and values:
|
|
16083
|
+
${fields.map(([key, field]) => ` ${key}: ${field.schema.description}
|
|
16084
|
+
Values: ${field.cli.valueSyntax}
|
|
16085
|
+
Default: ${JSON.stringify(field.defaultValue)} (${field.cli.format(field.defaultValue)})`).join("\n")}
|
|
16086
|
+
|
|
16087
|
+
Roots:
|
|
16088
|
+
${PLAY_LOCATION_ROOTS.map((root) => ` ${root.value}: ${root.description}`).join("\n")}
|
|
16089
|
+
|
|
16090
|
+
Examples:
|
|
16091
|
+
deepline plays settings describe --name path --json
|
|
16092
|
+
deepline plays settings get --play company-research --json
|
|
16093
|
+
deepline plays settings get --play company-research --name path
|
|
16094
|
+
deepline plays settings set --play company-research --name path --value person/Research/ICP
|
|
16095
|
+
deepline plays settings set --play company-research --name path --value team/Research
|
|
16096
|
+
deepline plays settings reset --play company-research --name path
|
|
16097
|
+
deepline plays settings paths --root team --json
|
|
16098
|
+
|
|
16099
|
+
Quote values containing spaces. Use percent escapes for literal % characters.
|
|
16100
|
+
`;
|
|
16101
|
+
function resolveField(key, command) {
|
|
16102
|
+
const entry = fields.find(([name]) => name === key);
|
|
16103
|
+
if (!entry)
|
|
16104
|
+
command.error(
|
|
16105
|
+
`Unknown --name ${JSON.stringify(key)}. Available settings: ${fields.map(([name]) => name).join(", ")}. Run deepline plays settings describe.`,
|
|
16106
|
+
{ exitCode: 2 }
|
|
16107
|
+
);
|
|
16108
|
+
return entry[1];
|
|
16109
|
+
}
|
|
16110
|
+
function printSettings(result, json2, name) {
|
|
16111
|
+
const selected = fields.filter(([key]) => !name || key === name);
|
|
16112
|
+
printCommandEnvelope(
|
|
16113
|
+
{
|
|
16114
|
+
...result,
|
|
16115
|
+
settings: Object.fromEntries(
|
|
16116
|
+
selected.map(([key]) => [
|
|
16117
|
+
key,
|
|
16118
|
+
result.settings[key]
|
|
16119
|
+
])
|
|
16120
|
+
),
|
|
16121
|
+
render: {
|
|
16122
|
+
sections: [
|
|
16123
|
+
{
|
|
16124
|
+
title: "Play settings",
|
|
16125
|
+
lines: selected.map(
|
|
16126
|
+
([key, field]) => `${field.label}: ${key === "path" ? displayPlayPath(result.settings.path, result.ownerName) : field.cli.format(result.settings[key])} (${field.cli.format(result.settings[key])})`
|
|
16127
|
+
)
|
|
16128
|
+
}
|
|
16129
|
+
]
|
|
16130
|
+
}
|
|
16131
|
+
},
|
|
16132
|
+
{ json: json2 }
|
|
16133
|
+
);
|
|
16134
|
+
}
|
|
16135
|
+
function registerPlaySettingsCommands(plays) {
|
|
16136
|
+
const settings = plays.command("settings").description("Read and change Play settings by name and value.").exitOverride((error) => {
|
|
16137
|
+
if (error.exitCode !== 0) error.exitCode = 2;
|
|
16138
|
+
throw error;
|
|
16139
|
+
}).addHelpText("after", help);
|
|
16140
|
+
settings.command("describe").usage("[--name <setting>] [options]").description(
|
|
16141
|
+
"List setting names, values, examples and defaults; no authentication required."
|
|
16142
|
+
).option(
|
|
16143
|
+
"--name <setting>",
|
|
16144
|
+
`Describe one setting. Available: ${fields.map(([key]) => key).join(", ")}`
|
|
16145
|
+
).option("--json", "Emit JSON; automatic when piped").addHelpText("after", help).action((options, command) => {
|
|
16146
|
+
if (options.name !== void 0) resolveField(options.name, command);
|
|
16147
|
+
const descriptions = fields.filter(([name]) => !options.name || options.name === name).map(([name, field]) => ({
|
|
16148
|
+
key: name,
|
|
16149
|
+
label: field.label,
|
|
16150
|
+
description: field.schema.description ?? field.description,
|
|
16151
|
+
default: field.defaultValue,
|
|
16152
|
+
defaultText: field.cli.format(field.defaultValue),
|
|
16153
|
+
valueSyntax: field.cli.valueSyntax,
|
|
16154
|
+
examples: field.cli.examples
|
|
16155
|
+
}));
|
|
16156
|
+
printCommandEnvelope(
|
|
16157
|
+
{
|
|
16158
|
+
fields: descriptions,
|
|
16159
|
+
render: {
|
|
16160
|
+
sections: descriptions.map((field) => ({
|
|
16161
|
+
title: field.key,
|
|
16162
|
+
lines: [
|
|
16163
|
+
field.description,
|
|
16164
|
+
`Values: ${field.valueSyntax}`,
|
|
16165
|
+
`Default: ${JSON.stringify(field.default)} (${field.defaultText})`,
|
|
16166
|
+
`Examples: ${field.examples.join(", ")}`
|
|
16167
|
+
]
|
|
16168
|
+
}))
|
|
16169
|
+
}
|
|
16170
|
+
},
|
|
16171
|
+
{ json: options.json }
|
|
16172
|
+
);
|
|
16173
|
+
});
|
|
16174
|
+
settings.command("get").usage("--play <play> [--name <setting>] [options]").description("Read all settings, or one setting selected with --name.").requiredOption("--play <play>", "Play to read").option(
|
|
16175
|
+
"--name <setting>",
|
|
16176
|
+
`Read one setting. Available: ${fields.map(([key]) => key).join(", ")}`
|
|
16177
|
+
).option("--json", "Emit JSON; automatic when piped").addHelpText("after", help).action(
|
|
16178
|
+
async (options, command) => {
|
|
16179
|
+
if (options.name !== void 0) resolveField(options.name, command);
|
|
16180
|
+
printSettings(
|
|
16181
|
+
await new DeeplineClient().getPlaySettings(options.play),
|
|
16182
|
+
options.json,
|
|
16183
|
+
options.name
|
|
16184
|
+
);
|
|
16185
|
+
}
|
|
16186
|
+
);
|
|
16187
|
+
const set = settings.command("set").usage("--play <play> --name <setting> --value <value> [options]").requiredOption("--play <play>", "Play to update").requiredOption(
|
|
16188
|
+
"--name <setting>",
|
|
16189
|
+
`Setting name. Available: ${fields.map(([key]) => key).join(", ")}`
|
|
16190
|
+
).requiredOption(
|
|
16191
|
+
"--value <value>",
|
|
16192
|
+
"New value; see settings describe --name <setting>"
|
|
16193
|
+
).description("Set one setting without creating or publishing a revision.");
|
|
16194
|
+
const reset = settings.command("reset").usage("--play <play> --name <setting> [options]").requiredOption("--play <play>", "Play to update").requiredOption(
|
|
16195
|
+
"--name <setting>",
|
|
16196
|
+
`Setting name. Available: ${fields.map(([key]) => key).join(", ")}`
|
|
16197
|
+
).description("Reset one setting to its schema default.");
|
|
16198
|
+
const change = async (command, play, key, value, options, resetting) => {
|
|
16199
|
+
const field = resolveField(key, command);
|
|
16200
|
+
let patch;
|
|
16201
|
+
try {
|
|
16202
|
+
patch = playSettingsPatchSchema.parse({
|
|
16203
|
+
[key]: resetting ? field.defaultValue : field.cli.parse(value)
|
|
16204
|
+
});
|
|
16205
|
+
} catch (error) {
|
|
16206
|
+
command.error(
|
|
16207
|
+
`Invalid --value for --name ${key}: ${formatPlaySettingsError(error)} Values: ${field.cli.valueSyntax}.`,
|
|
16208
|
+
{ exitCode: 2 }
|
|
16209
|
+
);
|
|
16210
|
+
}
|
|
16211
|
+
if (options.dryRun) {
|
|
16212
|
+
printCommandEnvelope(
|
|
16213
|
+
{
|
|
16214
|
+
dryRun: true,
|
|
16215
|
+
play,
|
|
16216
|
+
patch,
|
|
16217
|
+
render: {
|
|
16218
|
+
sections: [
|
|
16219
|
+
{
|
|
16220
|
+
title: "Planned settings patch",
|
|
16221
|
+
lines: Object.entries(patch).map(
|
|
16222
|
+
([name, setting]) => `${name}: ${JSON.stringify(setting)}`
|
|
16223
|
+
)
|
|
16224
|
+
}
|
|
16225
|
+
]
|
|
16226
|
+
}
|
|
16227
|
+
},
|
|
16228
|
+
{ json: options.json }
|
|
16229
|
+
);
|
|
16230
|
+
return;
|
|
16231
|
+
}
|
|
16232
|
+
printSettings(
|
|
16233
|
+
await new DeeplineClient().updatePlaySettings(play, patch),
|
|
16234
|
+
options.json
|
|
16235
|
+
);
|
|
16236
|
+
};
|
|
16237
|
+
for (const [command, resetting] of [
|
|
16238
|
+
[set, false],
|
|
16239
|
+
[reset, true]
|
|
16240
|
+
])
|
|
16241
|
+
command.option("--dry-run", "Show the patch without changing settings").option("--json", "Emit JSON; automatic when piped").addHelpText("after", help).action(
|
|
16242
|
+
(options) => change(
|
|
16243
|
+
command,
|
|
16244
|
+
options.play,
|
|
16245
|
+
options.name,
|
|
16246
|
+
options.value,
|
|
16247
|
+
options,
|
|
16248
|
+
resetting
|
|
16249
|
+
)
|
|
16250
|
+
);
|
|
16251
|
+
settings.command("paths").description("List existing locations (one bounded page).").option("--root <person|team>", "Filter by root").option("--limit <n>", "Plays to inspect, 1\u2013100", "50").option("--cursor <cursor>", "Continue from a previous page").option("--json", "Emit JSON; automatic when piped").addHelpText("after", help).action(
|
|
16252
|
+
async (options, command) => {
|
|
16253
|
+
const limit = Number(options.limit);
|
|
16254
|
+
if (options.root !== void 0 && options.root !== "person" && options.root !== "team" || !Number.isInteger(limit) || limit < 1 || limit > 100)
|
|
16255
|
+
command.error(
|
|
16256
|
+
"--root must be person or team; --limit must be 1\u2013100.",
|
|
16257
|
+
{ exitCode: 2 }
|
|
16258
|
+
);
|
|
16259
|
+
const page = await new DeeplineClient().listPlaySettingsPaths({
|
|
16260
|
+
root: options.root,
|
|
16261
|
+
limit,
|
|
16262
|
+
cursor: options.cursor
|
|
16263
|
+
});
|
|
16264
|
+
const nextCommand = page.hasMore ? `deepline plays settings paths --cursor '${page.cursor}'${options.root ? ` --root ${options.root}` : ""} --json` : null;
|
|
16265
|
+
printCommandEnvelope(
|
|
16266
|
+
{
|
|
16267
|
+
...page,
|
|
16268
|
+
nextCommand,
|
|
16269
|
+
render: {
|
|
16270
|
+
sections: [
|
|
16271
|
+
{
|
|
16272
|
+
title: "Play locations",
|
|
16273
|
+
lines: [
|
|
16274
|
+
...page.paths.map(
|
|
16275
|
+
(item) => `${displayPlayPath(item.path, item.ownerName)} (${formatPlayPath(item.path)}) \u2014 ${item.playName}`
|
|
16276
|
+
),
|
|
16277
|
+
...nextCommand ? [`More: ${nextCommand}`] : []
|
|
16278
|
+
]
|
|
16279
|
+
}
|
|
16280
|
+
]
|
|
16281
|
+
}
|
|
16282
|
+
},
|
|
16283
|
+
{ json: options.json }
|
|
16284
|
+
);
|
|
16285
|
+
}
|
|
16286
|
+
);
|
|
16287
|
+
}
|
|
16288
|
+
|
|
15920
16289
|
// src/cli/commands/play.ts
|
|
15921
16290
|
import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
|
|
15922
16291
|
import {
|
|
@@ -16560,8 +16929,8 @@ function readCsvHeaderFields(csvPath, sample) {
|
|
|
16560
16929
|
skip_empty_lines: false
|
|
16561
16930
|
});
|
|
16562
16931
|
const firstRecord = Array.isArray(records) ? records[0] : null;
|
|
16563
|
-
const
|
|
16564
|
-
const uniqueFields = [...new Set(
|
|
16932
|
+
const fields2 = Array.isArray(firstRecord) ? firstRecord.map((field) => String(field ?? "").trim()).filter(Boolean) : [];
|
|
16933
|
+
const uniqueFields = [...new Set(fields2)];
|
|
16565
16934
|
if (uniqueFields.length === 0) {
|
|
16566
16935
|
throw new PlayBootstrapUsageError(
|
|
16567
16936
|
`Could not read a header row from --from csv:${csvPath}.`
|
|
@@ -17650,6 +18019,45 @@ Examples:
|
|
|
17650
18019
|
});
|
|
17651
18020
|
}
|
|
17652
18021
|
|
|
18022
|
+
// src/cli/commands/plays/run-history.ts
|
|
18023
|
+
async function handleRunsHistory(options) {
|
|
18024
|
+
const query = new URLSearchParams();
|
|
18025
|
+
if (options.cursor) query.set("cursor", options.cursor);
|
|
18026
|
+
if (options.org) query.set("orgId", options.org);
|
|
18027
|
+
if (options.limit !== void 0) {
|
|
18028
|
+
const limit = Number(options.limit);
|
|
18029
|
+
if (!/^\d+$/.test(options.limit) || !Number.isSafeInteger(limit) || limit < 1) {
|
|
18030
|
+
throw new Error("--limit must be a positive integer.");
|
|
18031
|
+
}
|
|
18032
|
+
query.set("limit", String(limit));
|
|
18033
|
+
}
|
|
18034
|
+
const search = query.toString();
|
|
18035
|
+
const page = await new HttpClient(resolveConfig()).get(
|
|
18036
|
+
`/api/v2/dashboard/runs-history${search ? `?${search}` : ""}`
|
|
18037
|
+
);
|
|
18038
|
+
const lines = page.runs.map(
|
|
18039
|
+
(run) => `${run.workflowName} \xB7 ${run.status} \xB7 ${run.runId}`
|
|
18040
|
+
);
|
|
18041
|
+
if (lines.length === 0) lines.push("No runs found on this page.");
|
|
18042
|
+
if (page.hasMore) lines.push(`Next cursor: ${page.nextCursor}`);
|
|
18043
|
+
printCommandEnvelope(
|
|
18044
|
+
{ ...page, render: { sections: [{ title: "Run history", lines }] } },
|
|
18045
|
+
options.json ? { json: true } : {}
|
|
18046
|
+
);
|
|
18047
|
+
}
|
|
18048
|
+
function registerRunHistoryCommand(runs) {
|
|
18049
|
+
runs.command("history").description("Page workspace run history.").option(
|
|
18050
|
+
"--cursor <cursor>",
|
|
18051
|
+
"Opaque nextCursor returned by the previous page"
|
|
18052
|
+
).option("--limit <count>", "Maximum runs on this page").option(
|
|
18053
|
+
"--org <id>",
|
|
18054
|
+
"Workspace ID (must match the authenticated workspace)"
|
|
18055
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").addHelpText(
|
|
18056
|
+
"after",
|
|
18057
|
+
"\nUse the opaque --cursor returned by the previous page to continue.\n\nExample:\n deepline runs history --limit 100 --json\n"
|
|
18058
|
+
).action(handleRunsHistory);
|
|
18059
|
+
}
|
|
18060
|
+
|
|
17653
18061
|
// src/plays/bundle-play-file.ts
|
|
17654
18062
|
import { tmpdir as tmpdir3 } from "os";
|
|
17655
18063
|
import { dirname as dirname9, join as join9, resolve as resolve10 } from "path";
|
|
@@ -20554,7 +20962,7 @@ function recordCliTrace(event) {
|
|
|
20554
20962
|
process.stderr.write(`[cli-trace] ${JSON.stringify(payload)}
|
|
20555
20963
|
`);
|
|
20556
20964
|
}
|
|
20557
|
-
async function traceCliSpan(phase,
|
|
20965
|
+
async function traceCliSpan(phase, fields2, run) {
|
|
20558
20966
|
if (!isCliTraceEnabled()) {
|
|
20559
20967
|
return run();
|
|
20560
20968
|
}
|
|
@@ -20565,7 +20973,7 @@ async function traceCliSpan(phase, fields, run) {
|
|
|
20565
20973
|
phase,
|
|
20566
20974
|
ms: Date.now() - startedAt,
|
|
20567
20975
|
ok: true,
|
|
20568
|
-
...
|
|
20976
|
+
...fields2
|
|
20569
20977
|
});
|
|
20570
20978
|
return result;
|
|
20571
20979
|
} catch (error) {
|
|
@@ -20574,7 +20982,7 @@ async function traceCliSpan(phase, fields, run) {
|
|
|
20574
20982
|
ms: Date.now() - startedAt,
|
|
20575
20983
|
ok: false,
|
|
20576
20984
|
error: error instanceof Error ? error.message : String(error),
|
|
20577
|
-
...
|
|
20985
|
+
...fields2
|
|
20578
20986
|
});
|
|
20579
20987
|
throw error;
|
|
20580
20988
|
}
|
|
@@ -22418,6 +22826,7 @@ async function handlePlaysDeploy(directory, options) {
|
|
|
22418
22826
|
},
|
|
22419
22827
|
{
|
|
22420
22828
|
bundle: bundleDeployPlayFile,
|
|
22829
|
+
fetchImpl: fetchWithDeploymentProtection,
|
|
22421
22830
|
// The plays are already here: "opening" the source is naming it.
|
|
22422
22831
|
openSource: async () => ({
|
|
22423
22832
|
open: async () => ({ repoRoot: root })
|
|
@@ -23129,7 +23538,7 @@ async function writePlayRunIdFile(destination, runId, options = {}) {
|
|
|
23129
23538
|
await removeRunIdTempFile(tempPath);
|
|
23130
23539
|
}
|
|
23131
23540
|
}
|
|
23132
|
-
function traceCliSync(phase,
|
|
23541
|
+
function traceCliSync(phase, fields2, run) {
|
|
23133
23542
|
const startedAt = Date.now();
|
|
23134
23543
|
try {
|
|
23135
23544
|
const result = run();
|
|
@@ -23137,7 +23546,7 @@ function traceCliSync(phase, fields, run) {
|
|
|
23137
23546
|
phase,
|
|
23138
23547
|
ms: Date.now() - startedAt,
|
|
23139
23548
|
ok: true,
|
|
23140
|
-
...
|
|
23549
|
+
...fields2
|
|
23141
23550
|
});
|
|
23142
23551
|
return result;
|
|
23143
23552
|
} catch (error) {
|
|
@@ -23146,7 +23555,7 @@ function traceCliSync(phase, fields, run) {
|
|
|
23146
23555
|
ms: Date.now() - startedAt,
|
|
23147
23556
|
ok: false,
|
|
23148
23557
|
error: error instanceof Error ? error.message : String(error),
|
|
23149
|
-
...
|
|
23558
|
+
...fields2
|
|
23150
23559
|
});
|
|
23151
23560
|
throw error;
|
|
23152
23561
|
}
|
|
@@ -24470,7 +24879,8 @@ function formatProgressCounts(input2) {
|
|
|
24470
24879
|
Math.min(100, Math.round(completed / total * 100))
|
|
24471
24880
|
);
|
|
24472
24881
|
const failed = typeof input2.failed === "number" && Number.isFinite(input2.failed) && input2.failed > 0 ? `, failed ${formatInteger(input2.failed)}` : "";
|
|
24473
|
-
|
|
24882
|
+
const completedLabel = typeof input2.failed === "number" ? "successful " : "";
|
|
24883
|
+
return `${completedLabel}${formatInteger(completed)}/${formatInteger(total)} (${percent}%)${failed}`;
|
|
24474
24884
|
}
|
|
24475
24885
|
function formatProgressMessageSuffix(input2) {
|
|
24476
24886
|
const message = typeof input2.message === "string" ? input2.message.trim() : "";
|
|
@@ -25356,8 +25766,8 @@ function formatPlayLogLine(rawLine, status, state) {
|
|
|
25356
25766
|
if (!logLevelReaches("info", state.logLevel ?? "info")) {
|
|
25357
25767
|
return null;
|
|
25358
25768
|
}
|
|
25359
|
-
const [, rows,
|
|
25360
|
-
return `${prefix}map ${sourceLabelForNamespace(namespace)}: ${formatInteger(Number(rows))} rows, ${
|
|
25769
|
+
const [, rows, fields2, namespace, cached, pending] = mapStart;
|
|
25770
|
+
return `${prefix}map ${sourceLabelForNamespace(namespace)}: ${formatInteger(Number(rows))} rows, ${fields2} fields, ${formatInteger(Number(cached))} cached, ${formatInteger(Number(pending))} pending`;
|
|
25361
25771
|
}
|
|
25362
25772
|
const mapDone = message.match(
|
|
25363
25773
|
/^Map completed: (\d+) results \((\d+) executed, (\d+) already satisfied\)$/
|
|
@@ -26411,6 +26821,54 @@ function buildRunActivityTextLines(run) {
|
|
|
26411
26821
|
if (observedAt) lines.push(` observed: ${observedAt}`);
|
|
26412
26822
|
return lines;
|
|
26413
26823
|
}
|
|
26824
|
+
function formatObservedRunCounter(value) {
|
|
26825
|
+
const counter = readRecord(value);
|
|
26826
|
+
const count = counter?.value;
|
|
26827
|
+
if (typeof count !== "number" || !Number.isSafeInteger(count) || count < 0) {
|
|
26828
|
+
return "unknown";
|
|
26829
|
+
}
|
|
26830
|
+
return counter?.confirmed === true ? formatInteger(count) : `${formatInteger(count)} observed`;
|
|
26831
|
+
}
|
|
26832
|
+
function buildRunStatusEvidenceTextLines(packaged) {
|
|
26833
|
+
const evidence = readRecord(packaged.runStatus);
|
|
26834
|
+
if (!evidence || evidence.available !== true) return [];
|
|
26835
|
+
const calls = readRecord(evidence.calls);
|
|
26836
|
+
const lines = [];
|
|
26837
|
+
if (calls) {
|
|
26838
|
+
lines.push(
|
|
26839
|
+
` calls: ${formatObservedRunCounter(calls.logicalCalls)} logical, ${formatObservedRunCounter(calls.toolDispatches)} tool dispatches, ${formatObservedRunCounter(calls.provider429s)} provider 429s`
|
|
26840
|
+
);
|
|
26841
|
+
}
|
|
26842
|
+
const source = readRecord(evidence.source);
|
|
26843
|
+
if (source?.aligned === false) {
|
|
26844
|
+
lines.push(
|
|
26845
|
+
` consistency: run snapshot event ${String(source.runSnapshotLedgerNextSeq)} and progress event ${String(source.ledgerNextSeq)} differ; retry this read to align them`
|
|
26846
|
+
);
|
|
26847
|
+
}
|
|
26848
|
+
const focus = readRecord(evidence.focusStep);
|
|
26849
|
+
const rows = readRecord(focus?.rows);
|
|
26850
|
+
if (focus) {
|
|
26851
|
+
const id = typeof focus.id === "string" && focus.id.trim() ? focus.id.trim() : "unknown step";
|
|
26852
|
+
const label = typeof focus.label === "string" && focus.label.trim() ? ` (${focus.label.trim()})` : "";
|
|
26853
|
+
const state = typeof focus.status === "string" && focus.status.trim() ? `: ${focus.status.trim()}` : "";
|
|
26854
|
+
const rowCounts = rows ? `; rows ${formatObservedRunCounter({ value: rows.succeeded, confirmed: true })} succeeded, ${formatObservedRunCounter({ value: rows.failed, confirmed: true })} failed, ${formatObservedRunCounter({ value: rows.total, confirmed: true })} total` : "";
|
|
26855
|
+
lines.push(` current step: ${id}${label}${state}${rowCounts}`);
|
|
26856
|
+
}
|
|
26857
|
+
return lines;
|
|
26858
|
+
}
|
|
26859
|
+
function buildRecentRunLogTextLines(packaged) {
|
|
26860
|
+
const logs = readRecord(packaged.logs);
|
|
26861
|
+
const tail = Array.isArray(logs?.tail) ? logs.tail.filter((line) => typeof line === "string") : [];
|
|
26862
|
+
if (tail.length === 0) return [];
|
|
26863
|
+
const visible = tail.slice(-5);
|
|
26864
|
+
const total = typeof logs?.totalCount === "number" && Number.isFinite(logs.totalCount) ? ` of ${formatInteger(logs.totalCount)}` : "";
|
|
26865
|
+
const lines = [` recent logs: showing ${visible.length}${total}`];
|
|
26866
|
+
lines.push(...visible.map((line) => ` ${line}`));
|
|
26867
|
+
if (logs?.truncated === true) {
|
|
26868
|
+
lines.push(" older log lines were truncated by the retention cap");
|
|
26869
|
+
}
|
|
26870
|
+
return lines;
|
|
26871
|
+
}
|
|
26414
26872
|
function buildRunPackageTextLines(packaged) {
|
|
26415
26873
|
const run = readRunPackageRun(packaged);
|
|
26416
26874
|
const runId = typeof run.id === "string" ? run.id : "unknown";
|
|
@@ -26480,6 +26938,8 @@ function buildRunPackageTextLines(packaged) {
|
|
|
26480
26938
|
if (!isRuntimeLimitCheckpoint) {
|
|
26481
26939
|
lines.push(...buildRunActivityTextLines(run));
|
|
26482
26940
|
}
|
|
26941
|
+
lines.push(...buildRunStatusEvidenceTextLines(packaged));
|
|
26942
|
+
lines.push(...buildRecentRunLogTextLines(packaged));
|
|
26483
26943
|
lines.push(...formatPackageValueOutputLines(packaged));
|
|
26484
26944
|
lines.push(
|
|
26485
26945
|
...formatPackageDatasetActionLines(packaged, {
|
|
@@ -26487,12 +26947,7 @@ function buildRunPackageTextLines(packaged) {
|
|
|
26487
26947
|
})
|
|
26488
26948
|
);
|
|
26489
26949
|
const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
|
|
26490
|
-
const billingCommand = actionToCommand(next.billing);
|
|
26491
26950
|
const logsCommand = actionToCommand(next.logs);
|
|
26492
|
-
if (billingCommand) {
|
|
26493
|
-
const costState = status === "completed" || status === "failed" || status === "cancelled" ? "settles asynchronously \u2014 run the billing command below for totals" : "pending";
|
|
26494
|
-
lines.push(` cost: ${costState}`);
|
|
26495
|
-
}
|
|
26496
26951
|
for (const step of isRuntimeLimitCheckpoint ? [] : readRecordArray(packaged.steps).slice(0, 8)) {
|
|
26497
26952
|
const id = typeof step.id === "string" ? step.id : "step";
|
|
26498
26953
|
const kind = typeof step.kind === "string" ? step.kind : "step";
|
|
@@ -26522,7 +26977,6 @@ function buildRunPackageTextLines(packaged) {
|
|
|
26522
26977
|
` ${isRuntimeTimeout ? "full run details" : "full result"}: ${fullResultCommand}`
|
|
26523
26978
|
);
|
|
26524
26979
|
if (logsCommand) lines.push(` logs: ${logsCommand}`);
|
|
26525
|
-
if (billingCommand) lines.push(` billing: ${billingCommand}`);
|
|
26526
26980
|
if (legacyExportCommand) {
|
|
26527
26981
|
lines.push(` export CSV: ${legacyExportCommand}`);
|
|
26528
26982
|
}
|
|
@@ -30117,8 +30571,8 @@ function printPlayDescription(play) {
|
|
|
30117
30571
|
}
|
|
30118
30572
|
}
|
|
30119
30573
|
function inputFieldNames(schema) {
|
|
30120
|
-
const
|
|
30121
|
-
return
|
|
30574
|
+
const fields2 = Array.isArray(schema?.fields) ? schema.fields : [];
|
|
30575
|
+
return fields2.map(
|
|
30122
30576
|
(field) => field && typeof field === "object" ? String(field.name ?? "").trim() : ""
|
|
30123
30577
|
).filter(Boolean);
|
|
30124
30578
|
}
|
|
@@ -30135,9 +30589,9 @@ function printCompactPlaySearchResult(play) {
|
|
|
30135
30589
|
if (aliases) {
|
|
30136
30590
|
console.log(` Aliases: ${aliases}`);
|
|
30137
30591
|
}
|
|
30138
|
-
const
|
|
30139
|
-
if (
|
|
30140
|
-
console.log(` Inputs: ${
|
|
30592
|
+
const fields2 = inputFieldNames(play.inputSchema);
|
|
30593
|
+
if (fields2.length > 0) {
|
|
30594
|
+
console.log(` Inputs: ${fields2.join(", ")}`);
|
|
30141
30595
|
} else if (play.inputSchema) {
|
|
30142
30596
|
console.log(" Inputs: see describe");
|
|
30143
30597
|
}
|
|
@@ -30146,14 +30600,14 @@ function printCompactPlaySearchResult(play) {
|
|
|
30146
30600
|
}
|
|
30147
30601
|
function compactPlaySchema(schema) {
|
|
30148
30602
|
if (!schema) return null;
|
|
30149
|
-
const
|
|
30603
|
+
const fields2 = Array.isArray(schema.fields) ? schema.fields.map(
|
|
30150
30604
|
(field) => field && typeof field === "object" ? {
|
|
30151
30605
|
name: String(field.name ?? ""),
|
|
30152
30606
|
type: field.type ?? void 0,
|
|
30153
30607
|
required: field.required ?? void 0
|
|
30154
30608
|
} : null
|
|
30155
30609
|
).filter((field) => Boolean(field?.name)) : [];
|
|
30156
|
-
return
|
|
30610
|
+
return fields2.length > 0 ? { fields: fields2 } : schema;
|
|
30157
30611
|
}
|
|
30158
30612
|
function summarizePlayGrepResult(play) {
|
|
30159
30613
|
const reference = formatPlayListReference(play);
|
|
@@ -30782,6 +31236,8 @@ Concepts:
|
|
|
30782
31236
|
Installed npm and repo-local CLIs can run saved/prebuilt plays by name or
|
|
30783
31237
|
bundle local .play.ts files for development workflows.
|
|
30784
31238
|
Running a local file does not make it live; use publish or set-live for that.
|
|
31239
|
+
plays settings organizes a Play independently of code revisions.
|
|
31240
|
+
New Plays start at person; publishing moves them to team, preserving folders.
|
|
30785
31241
|
|
|
30786
31242
|
Authoring:
|
|
30787
31243
|
Use normal TypeScript interpolation for human-facing strings:
|
|
@@ -30987,6 +31443,7 @@ Pass-through input flags:
|
|
|
30987
31443
|
process.exitCode = exitCode;
|
|
30988
31444
|
});
|
|
30989
31445
|
registerPlayBootstrapCommand(play);
|
|
31446
|
+
registerPlaySettingsCommands(play);
|
|
30990
31447
|
play.command("get <target>").description(
|
|
30991
31448
|
"Fetch full play details or materialize a saved source bundle."
|
|
30992
31449
|
).addHelpText(
|
|
@@ -31255,6 +31712,8 @@ Notes:
|
|
|
31255
31712
|
plays check to refuse publishing bytes that changed after validation.
|
|
31256
31713
|
--dry-run bundles only and prints the exact artifact that would be published.
|
|
31257
31714
|
Running a local file with plays run does not publish it.
|
|
31715
|
+
Publishing moves personal locations into Team library, preserving folders.
|
|
31716
|
+
Change location with: deepline plays settings set --play <play> --name path --value team/Research
|
|
31258
31717
|
|
|
31259
31718
|
Examples:
|
|
31260
31719
|
deepline plays set-live my-play --latest --json
|
|
@@ -31398,7 +31857,10 @@ Examples:
|
|
|
31398
31857
|
deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
|
|
31399
31858
|
`
|
|
31400
31859
|
);
|
|
31401
|
-
runs
|
|
31860
|
+
registerRunHistoryCommand(runs);
|
|
31861
|
+
runs.command("status <runId>").description(
|
|
31862
|
+
"Legacy scalar-only read. Use runs get for canonical status, progress, logs, and results."
|
|
31863
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
|
|
31402
31864
|
process.exitCode = await handleRunLifecycleStatus([
|
|
31403
31865
|
runId,
|
|
31404
31866
|
...options.json ? ["--json"] : []
|
|
@@ -35004,9 +35466,9 @@ function readEnrichRunStatus(status) {
|
|
|
35004
35466
|
return null;
|
|
35005
35467
|
}
|
|
35006
35468
|
function firstCollectedStringField(value, key) {
|
|
35007
|
-
const
|
|
35008
|
-
collectStringFields(value, key,
|
|
35009
|
-
return
|
|
35469
|
+
const fields2 = /* @__PURE__ */ new Set();
|
|
35470
|
+
collectStringFields(value, key, fields2);
|
|
35471
|
+
return fields2.values().next().value ?? null;
|
|
35010
35472
|
}
|
|
35011
35473
|
function emitPlainRunFailure(status) {
|
|
35012
35474
|
const runId = extractRunId(status) ?? firstCollectedStringField(status, "runId");
|
|
@@ -47803,7 +48265,7 @@ function requireCatalogEvent(settings, eventType) {
|
|
|
47803
48265
|
}
|
|
47804
48266
|
return event;
|
|
47805
48267
|
}
|
|
47806
|
-
async function
|
|
48268
|
+
async function printSettings2(options) {
|
|
47807
48269
|
const settings = await new DeeplineClient().getNotificationSettings();
|
|
47808
48270
|
const slack = slackDestination(settings);
|
|
47809
48271
|
const destinationId = typeof slack?._id === "string" ? slack._id : void 0;
|
|
@@ -47930,7 +48392,7 @@ Slack is the delivery integration. This command group only manages product
|
|
|
47930
48392
|
notifications; there is no general integrations CLI.
|
|
47931
48393
|
`
|
|
47932
48394
|
);
|
|
47933
|
-
notifications.command("get").description("Show destination, subscriptions, and DLQ health.").option("--json", "Emit JSON output").action(
|
|
48395
|
+
notifications.command("get").description("Show destination, subscriptions, and DLQ health.").option("--json", "Emit JSON output").action(printSettings2);
|
|
47934
48396
|
notifications.command("connect").description("Start the OAuth connection required by a destination.").argument("<destination>", "Destination kind (currently slack)").option("--open", "Open the Slack authorization URL in a browser").option("--dry-run", "Describe the mutation without starting OAuth").option("--json", "Emit JSON output").action(
|
|
47935
48397
|
async (destination, options) => {
|
|
47936
48398
|
if (destination !== "slack")
|
|
@@ -49368,6 +49830,8 @@ async function searchTools(queryInput, options = {}) {
|
|
|
49368
49830
|
query,
|
|
49369
49831
|
categories: options.categories,
|
|
49370
49832
|
searchTerms: options.searchTerms,
|
|
49833
|
+
limit: options.limit,
|
|
49834
|
+
offset: options.offset,
|
|
49371
49835
|
searchMode: options.searchMode,
|
|
49372
49836
|
includeSearchDebug: options.includeSearchDebug
|
|
49373
49837
|
});
|
|
@@ -49598,13 +50062,15 @@ Notes:
|
|
|
49598
50062
|
that can be passed to deepline tools describe or deepline tools execute.
|
|
49599
50063
|
Provide a query, or omit it only when --categories and/or --search_terms is
|
|
49600
50064
|
supplied. Providing neither is a usage error. Both filters accept
|
|
49601
|
-
comma-separated values. Use
|
|
49602
|
-
|
|
50065
|
+
comma-separated values. Use --limit and --offset to page through ranked
|
|
50066
|
+
results (limit 1-50, offset is zero-based); JSON includes next_offset.
|
|
50067
|
+
Use a provider name in the query; --prefix is not a supported option.
|
|
49603
50068
|
The grep alias is the same ranked retrieval surface with a more literal name
|
|
49604
50069
|
for agents that are filtering a registry rather than choosing a workflow.
|
|
49605
50070
|
|
|
49606
50071
|
Examples:
|
|
49607
|
-
deepline tools search email
|
|
50072
|
+
deepline tools search email --limit 10 --json
|
|
50073
|
+
deepline tools search email --limit 10 --offset 10 --json
|
|
49608
50074
|
deepline tools search --categories company_search --search_terms "investors,funding"
|
|
49609
50075
|
deepline tools grep "company enrichment" --categories enrichment --json
|
|
49610
50076
|
deepline tools search verifier --search-mode v2 --json
|
|
@@ -49615,10 +50081,12 @@ Examples:
|
|
|
49615
50081
|
).option(
|
|
49616
50082
|
"--search_terms <terms>",
|
|
49617
50083
|
"Comma-separated structured search terms; may be used without a query"
|
|
49618
|
-
).option("--search-terms <terms>", "Alias for --search_terms").option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
|
|
50084
|
+
).option("--search-terms <terms>", "Alias for --search_terms").option("--limit <count>", "Maximum ranked results to return (1-50)").option("--offset <count>", "Zero-based ranked result offset").option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
|
|
49619
50085
|
process.exitCode = await searchTools(query, {
|
|
49620
50086
|
json: options.json,
|
|
49621
50087
|
compact: options.compact,
|
|
50088
|
+
limit: options.limit !== void 0 ? Number.parseInt(options.limit, 10) : void 0,
|
|
50089
|
+
offset: options.offset !== void 0 ? Number.parseInt(options.offset, 10) : void 0,
|
|
49622
50090
|
categories: options.categories,
|
|
49623
50091
|
searchTerms: options.searchTerms ?? options.search_terms,
|
|
49624
50092
|
searchMode: options.searchMode === "v1" || options.searchMode === "v2" ? options.searchMode : void 0,
|
|
@@ -50021,8 +50489,8 @@ function printMonitorTypeFilters(tool) {
|
|
|
50021
50489
|
}
|
|
50022
50490
|
function printMonitorTypeFilterExamples(tool) {
|
|
50023
50491
|
const documentation = recordField2(tool, "documentation");
|
|
50024
|
-
const
|
|
50025
|
-
const examples = Object.entries(
|
|
50492
|
+
const fields2 = recordField2(documentation, "fields");
|
|
50493
|
+
const examples = Object.entries(fields2).flatMap(([name, rawField]) => {
|
|
50026
50494
|
const grammar = recordField2(isRecord12(rawField) ? rawField : {}, "grammar");
|
|
50027
50495
|
const example = stringField2(grammar, "example");
|
|
50028
50496
|
const values = [
|
|
@@ -50377,9 +50845,9 @@ function sampleValueForField(field) {
|
|
|
50377
50845
|
if (type === "object") return {};
|
|
50378
50846
|
return "...";
|
|
50379
50847
|
}
|
|
50380
|
-
function samplePayloadForInputFields(
|
|
50848
|
+
function samplePayloadForInputFields(fields2) {
|
|
50381
50849
|
return Object.fromEntries(
|
|
50382
|
-
|
|
50850
|
+
fields2.slice(0, 4).flatMap((field) => {
|
|
50383
50851
|
if (!isRecord12(field)) return [];
|
|
50384
50852
|
const name = stringField2(field, "name");
|
|
50385
50853
|
if (!name) return [];
|
|
@@ -50510,8 +50978,8 @@ function formatListedToolCost(tool) {
|
|
|
50510
50978
|
}
|
|
50511
50979
|
function toolInputFieldsForDisplay(inputSchema) {
|
|
50512
50980
|
if (Array.isArray(inputSchema.fields)) {
|
|
50513
|
-
const
|
|
50514
|
-
if (!isRecord12(inputSchema.jsonSchema)) return
|
|
50981
|
+
const fields2 = inputSchema.fields.filter(isRecord12);
|
|
50982
|
+
if (!isRecord12(inputSchema.jsonSchema)) return fields2;
|
|
50515
50983
|
const jsonSchemaFields = new Map(
|
|
50516
50984
|
recursiveToolInputFieldsForDisplay({
|
|
50517
50985
|
jsonSchema: inputSchema.jsonSchema
|
|
@@ -50519,7 +50987,7 @@ function toolInputFieldsForDisplay(inputSchema) {
|
|
|
50519
50987
|
(field) => typeof field.name === "string" ? [[field.name, field]] : []
|
|
50520
50988
|
)
|
|
50521
50989
|
);
|
|
50522
|
-
return
|
|
50990
|
+
return fields2.map((field) => {
|
|
50523
50991
|
const jsonSchemaField = typeof field.name === "string" ? jsonSchemaFields.get(field.name) : void 0;
|
|
50524
50992
|
const minItems = typeof field.minItems === "number" ? field.minItems : jsonSchemaField?.minItems;
|
|
50525
50993
|
const maxItems = typeof field.maxItems === "number" ? field.maxItems : jsonSchemaField?.maxItems;
|
|
@@ -50616,7 +51084,7 @@ function publicToolInputSchemaForDescribe(inputSchema) {
|
|
|
50616
51084
|
}
|
|
50617
51085
|
function recursiveToolInputFieldsForDisplay(inputSchema) {
|
|
50618
51086
|
const root = canonicalToolJsonSchema(inputSchema);
|
|
50619
|
-
const
|
|
51087
|
+
const fields2 = /* @__PURE__ */ new Map();
|
|
50620
51088
|
const schemasById = /* @__PURE__ */ new Map();
|
|
50621
51089
|
const collectSchemaIds = (value) => {
|
|
50622
51090
|
if (Array.isArray(value)) {
|
|
@@ -50644,9 +51112,9 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
|
|
|
50644
51112
|
const addField = (field) => {
|
|
50645
51113
|
const name = typeof field.name === "string" ? field.name : "";
|
|
50646
51114
|
if (!name) return;
|
|
50647
|
-
const existing =
|
|
51115
|
+
const existing = fields2.get(name);
|
|
50648
51116
|
if (!existing || existing.type === "unknown") {
|
|
50649
|
-
|
|
51117
|
+
fields2.set(name, field);
|
|
50650
51118
|
}
|
|
50651
51119
|
};
|
|
50652
51120
|
const visit = (unresolvedSchema, path, required, activeRefs = /* @__PURE__ */ new Set()) => {
|
|
@@ -50694,7 +51162,7 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
|
|
|
50694
51162
|
}
|
|
50695
51163
|
};
|
|
50696
51164
|
visit(root, "", false);
|
|
50697
|
-
return
|
|
51165
|
+
return fields2.size ? [...fields2.values()] : toolInputFieldsForDisplay(inputSchema);
|
|
50698
51166
|
}
|
|
50699
51167
|
function inputFieldJsonForDescribe(field) {
|
|
50700
51168
|
const publicItems = isRecord12(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
|