deepline 0.1.54 → 0.1.56
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 +673 -127
- package/dist/cli/index.mjs +681 -128
- package/dist/index.d.mts +220 -34
- package/dist/index.d.ts +220 -34
- package/dist/index.js +22 -4
- package/dist/index.mjs +22 -4
- package/dist/repo/apps/play-runner-workers/src/entry.ts +36 -12
- package/dist/repo/apps/play-runner-workers/src/runtime/dataset-handles.ts +35 -7
- package/dist/repo/sdk/src/client.ts +33 -2
- package/dist/repo/sdk/src/play.ts +167 -33
- package/dist/repo/sdk/src/plays/bundle-play-file.ts +27 -18
- package/dist/repo/sdk/src/release.ts +3 -3
- package/dist/repo/sdk/src/types.ts +21 -0
- package/dist/repo/shared_libs/play-runtime/csv-rename.ts +55 -3
- package/dist/repo/shared_libs/play-runtime/profiles.ts +26 -54
- package/dist/repo/shared_libs/play-runtime/providers.ts +71 -0
- package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +9 -1
- package/dist/repo/shared_libs/plays/bundling/index.ts +225 -69
- package/dist/repo/shared_libs/plays/dataset.ts +25 -1
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -197,10 +197,10 @@ function resolveConfig(options) {
|
|
|
197
197
|
|
|
198
198
|
// src/release.ts
|
|
199
199
|
var SDK_RELEASE = {
|
|
200
|
-
version: "0.1.
|
|
201
|
-
apiContract: "2026-05-
|
|
200
|
+
version: "0.1.56",
|
|
201
|
+
apiContract: "2026-05-play-tool-describe-starters",
|
|
202
202
|
supportPolicy: {
|
|
203
|
-
latest: "0.1.
|
|
203
|
+
latest: "0.1.56",
|
|
204
204
|
minimumSupported: "0.1.53",
|
|
205
205
|
deprecatedBelow: "0.1.53"
|
|
206
206
|
}
|
|
@@ -704,6 +704,23 @@ var DeeplineClient = class {
|
|
|
704
704
|
}
|
|
705
705
|
return `deepline plays run ${target} --input '{...}' --watch`;
|
|
706
706
|
}
|
|
707
|
+
starterPlayPath(play) {
|
|
708
|
+
const target = play.reference || play.name;
|
|
709
|
+
const unqualifiedName = target.split("/").pop() || play.name;
|
|
710
|
+
const safeName = unqualifiedName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
711
|
+
return `./${safeName || "play"}.play.ts`;
|
|
712
|
+
}
|
|
713
|
+
playCloneEditStarter(play) {
|
|
714
|
+
const readonlyPrebuilt = (play.origin === "prebuilt" || play.ownerType === "deepline") && !play.canEdit;
|
|
715
|
+
if (!play.canClone && !readonlyPrebuilt) return void 0;
|
|
716
|
+
const target = play.reference || play.name;
|
|
717
|
+
const path = this.starterPlayPath(play);
|
|
718
|
+
return {
|
|
719
|
+
path,
|
|
720
|
+
command: `deepline plays get ${target} --source --out ${path}`,
|
|
721
|
+
checkCommand: `deepline plays check ${path}`
|
|
722
|
+
};
|
|
723
|
+
}
|
|
707
724
|
summarizePlayListItem(play, options) {
|
|
708
725
|
const aliases = play.aliases?.length ? play.aliases : [play.name];
|
|
709
726
|
const csvInput = this.schemaMetadata(play.inputSchema, "csvInput");
|
|
@@ -712,6 +729,7 @@ var DeeplineClient = class {
|
|
|
712
729
|
"rowOutputSchema"
|
|
713
730
|
);
|
|
714
731
|
const runCommand2 = this.playRunCommand(play, { csvInput });
|
|
732
|
+
const cloneEditStarter = this.playCloneEditStarter(play);
|
|
715
733
|
return {
|
|
716
734
|
name: play.name,
|
|
717
735
|
...play.reference ? { reference: play.reference } : {},
|
|
@@ -727,6 +745,7 @@ var DeeplineClient = class {
|
|
|
727
745
|
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
728
746
|
runCommand: runCommand2,
|
|
729
747
|
examples: [runCommand2],
|
|
748
|
+
...cloneEditStarter ? { cloneEditStarter } : {},
|
|
730
749
|
currentPublishedVersion: play.currentPublishedVersion ?? null,
|
|
731
750
|
isDraftDirty: play.isDraftDirty
|
|
732
751
|
};
|
|
@@ -1429,7 +1448,6 @@ var DeeplineClient = class {
|
|
|
1429
1448
|
async searchPlays(options) {
|
|
1430
1449
|
const params = new URLSearchParams();
|
|
1431
1450
|
params.set("search", options.query.trim());
|
|
1432
|
-
if (options.origin) params.set("origin", options.origin);
|
|
1433
1451
|
const response = await this.http.get(
|
|
1434
1452
|
`/api/v2/plays?${params.toString()}`
|
|
1435
1453
|
);
|
|
@@ -4009,7 +4027,14 @@ import { createHash } from "crypto";
|
|
|
4009
4027
|
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
4010
4028
|
import { mkdir as mkdir3, readFile, realpath, stat, writeFile as writeFile3 } from "fs/promises";
|
|
4011
4029
|
import { tmpdir } from "os";
|
|
4012
|
-
import {
|
|
4030
|
+
import {
|
|
4031
|
+
basename,
|
|
4032
|
+
dirname as dirname5,
|
|
4033
|
+
extname,
|
|
4034
|
+
isAbsolute,
|
|
4035
|
+
join as join3,
|
|
4036
|
+
resolve as resolve6
|
|
4037
|
+
} from "path";
|
|
4013
4038
|
import { builtinModules } from "module";
|
|
4014
4039
|
import { build } from "esbuild";
|
|
4015
4040
|
|
|
@@ -4073,11 +4098,23 @@ var PLAY_ARTIFACT_CACHE_DIR = join3(
|
|
|
4073
4098
|
`deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`
|
|
4074
4099
|
);
|
|
4075
4100
|
var PLAY_PROXY_NAMESPACE = "deepline-play-runtime-ref";
|
|
4076
|
-
var SOURCE_EXTENSIONS = [
|
|
4101
|
+
var SOURCE_EXTENSIONS = [
|
|
4102
|
+
".ts",
|
|
4103
|
+
".tsx",
|
|
4104
|
+
".mts",
|
|
4105
|
+
".cts",
|
|
4106
|
+
".js",
|
|
4107
|
+
".jsx",
|
|
4108
|
+
".mjs",
|
|
4109
|
+
".cjs",
|
|
4110
|
+
".json"
|
|
4111
|
+
];
|
|
4077
4112
|
var WORKERS_PLAY_ENTRY_VIRTUAL = "deepline-play-entry";
|
|
4078
4113
|
var PLAY_SOURCE_FILE_PATTERN = /\.play\.(?:[cm]?[jt]sx?)$/i;
|
|
4079
4114
|
var NODE_BUILTIN_SET = new Set(
|
|
4080
|
-
builtinModules.flatMap(
|
|
4115
|
+
builtinModules.flatMap(
|
|
4116
|
+
(name) => name.startsWith("node:") ? [name, name.slice(5)] : [name, `node:${name}`]
|
|
4117
|
+
)
|
|
4081
4118
|
);
|
|
4082
4119
|
function assertValidExportName(exportName) {
|
|
4083
4120
|
if (exportName === "default") return;
|
|
@@ -4157,15 +4194,27 @@ function findSourceImportReferences(sourceCode) {
|
|
|
4157
4194
|
};
|
|
4158
4195
|
const staticImportPattern = /\b(?:import|export)\s+(?!type\b)(?:[\s\S]*?\s+from\s*)?(['"])([^'"\n]+)\1/g;
|
|
4159
4196
|
for (const match of source.matchAll(staticImportPattern)) {
|
|
4160
|
-
addReference(
|
|
4197
|
+
addReference(
|
|
4198
|
+
match[2],
|
|
4199
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
4200
|
+
"static"
|
|
4201
|
+
);
|
|
4161
4202
|
}
|
|
4162
4203
|
const dynamicImportPattern = /\bimport\s*\(\s*(['"])([^'"\n]+)\1/g;
|
|
4163
4204
|
for (const match of source.matchAll(dynamicImportPattern)) {
|
|
4164
|
-
addReference(
|
|
4205
|
+
addReference(
|
|
4206
|
+
match[2],
|
|
4207
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
4208
|
+
"dynamic-import"
|
|
4209
|
+
);
|
|
4165
4210
|
}
|
|
4166
4211
|
const requirePattern = /\brequire\s*\(\s*(['"])([^'"\n]+)\1/g;
|
|
4167
4212
|
for (const match of source.matchAll(requirePattern)) {
|
|
4168
|
-
addReference(
|
|
4213
|
+
addReference(
|
|
4214
|
+
match[2],
|
|
4215
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
4216
|
+
"require"
|
|
4217
|
+
);
|
|
4169
4218
|
}
|
|
4170
4219
|
const literalDynamicImportIndexes = new Set(
|
|
4171
4220
|
[...source.matchAll(dynamicImportPattern)].map((match) => match.index)
|
|
@@ -4198,7 +4247,9 @@ function unquoteStringLiteral(literal) {
|
|
|
4198
4247
|
return null;
|
|
4199
4248
|
}
|
|
4200
4249
|
try {
|
|
4201
|
-
return JSON.parse(
|
|
4250
|
+
return JSON.parse(
|
|
4251
|
+
quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`
|
|
4252
|
+
);
|
|
4202
4253
|
} catch {
|
|
4203
4254
|
return trimmed.slice(1, -1);
|
|
4204
4255
|
}
|
|
@@ -4250,7 +4301,9 @@ function extractDefinedPlayName(sourceCode) {
|
|
|
4250
4301
|
const closeBrace = findMatchingBrace(source, argIndex);
|
|
4251
4302
|
if (closeBrace < 0) continue;
|
|
4252
4303
|
const objectSource = source.slice(argIndex + 1, closeBrace);
|
|
4253
|
-
const idMatch = objectSource.match(
|
|
4304
|
+
const idMatch = objectSource.match(
|
|
4305
|
+
/(?:^|[,{\s])(?:id|['"]id['"])\s*:\s*(['"])([\s\S]*?)\1/
|
|
4306
|
+
);
|
|
4254
4307
|
if (idMatch?.[2]?.trim()) {
|
|
4255
4308
|
return idMatch[2].trim();
|
|
4256
4309
|
}
|
|
@@ -4359,7 +4412,12 @@ function workersNamedPlayEntryAliasPlugin(playFilePath, exportName) {
|
|
|
4359
4412
|
};
|
|
4360
4413
|
}
|
|
4361
4414
|
function workersNodeBuiltinStubPlugin() {
|
|
4362
|
-
const UNSUPPORTED = /* @__PURE__ */ new Set([
|
|
4415
|
+
const UNSUPPORTED = /* @__PURE__ */ new Set([
|
|
4416
|
+
"node:fs",
|
|
4417
|
+
"node:fs/promises",
|
|
4418
|
+
"node:os",
|
|
4419
|
+
"node:child_process"
|
|
4420
|
+
]);
|
|
4363
4421
|
return {
|
|
4364
4422
|
name: "deepline-workers-node-builtin-stub",
|
|
4365
4423
|
setup(buildContext) {
|
|
@@ -4408,16 +4466,13 @@ function zodNonEnglishLocaleStubPlugin() {
|
|
|
4408
4466
|
}
|
|
4409
4467
|
return { path: args.path, namespace: NAMESPACE };
|
|
4410
4468
|
});
|
|
4411
|
-
buildContext.onLoad(
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
loader: "js"
|
|
4419
|
-
})
|
|
4420
|
-
);
|
|
4469
|
+
buildContext.onLoad({ filter: /.*/, namespace: NAMESPACE }, () => ({
|
|
4470
|
+
// zod locales export a default object literal. Empty object is
|
|
4471
|
+
// structurally compatible — accessing any locale key returns
|
|
4472
|
+
// undefined and zod falls back to its built-in English.
|
|
4473
|
+
contents: "export default {};",
|
|
4474
|
+
loader: "js"
|
|
4475
|
+
}));
|
|
4421
4476
|
}
|
|
4422
4477
|
};
|
|
4423
4478
|
}
|
|
@@ -4488,7 +4543,10 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
|
|
|
4488
4543
|
return null;
|
|
4489
4544
|
}
|
|
4490
4545
|
const dependenciesByPath = new Map(
|
|
4491
|
-
importedPlayDependencies.map((dependency) => [
|
|
4546
|
+
importedPlayDependencies.map((dependency) => [
|
|
4547
|
+
dependency.filePath,
|
|
4548
|
+
dependency
|
|
4549
|
+
])
|
|
4492
4550
|
);
|
|
4493
4551
|
return {
|
|
4494
4552
|
name: "deepline-imported-play-proxy",
|
|
@@ -4508,17 +4566,20 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
|
|
|
4508
4566
|
pluginData: dependency
|
|
4509
4567
|
};
|
|
4510
4568
|
});
|
|
4511
|
-
buildContext.onLoad(
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4569
|
+
buildContext.onLoad(
|
|
4570
|
+
{ filter: /.*/, namespace: PLAY_PROXY_NAMESPACE },
|
|
4571
|
+
async (args) => {
|
|
4572
|
+
const dependency = args.pluginData ?? dependenciesByPath.get(args.path);
|
|
4573
|
+
if (!dependency) {
|
|
4574
|
+
return null;
|
|
4575
|
+
}
|
|
4576
|
+
return {
|
|
4577
|
+
contents: buildImportedPlayProxyModule(dependency.playName),
|
|
4578
|
+
loader: "ts",
|
|
4579
|
+
resolveDir: dirname5(args.path)
|
|
4580
|
+
};
|
|
4515
4581
|
}
|
|
4516
|
-
|
|
4517
|
-
contents: buildImportedPlayProxyModule(dependency.playName),
|
|
4518
|
-
loader: "ts",
|
|
4519
|
-
resolveDir: dirname5(args.path)
|
|
4520
|
-
};
|
|
4521
|
-
});
|
|
4582
|
+
);
|
|
4522
4583
|
}
|
|
4523
4584
|
};
|
|
4524
4585
|
}
|
|
@@ -4538,18 +4599,26 @@ async function resolveLocalImport(fromFile, specifier) {
|
|
|
4538
4599
|
const candidates = [base];
|
|
4539
4600
|
const explicitExtension = extname(base).toLowerCase();
|
|
4540
4601
|
if (!explicitExtension) {
|
|
4541
|
-
candidates.push(
|
|
4542
|
-
|
|
4602
|
+
candidates.push(
|
|
4603
|
+
...SOURCE_EXTENSIONS.map((extension) => `${base}${extension}`)
|
|
4604
|
+
);
|
|
4605
|
+
candidates.push(
|
|
4606
|
+
...SOURCE_EXTENSIONS.map((extension) => join3(base, `index${extension}`))
|
|
4607
|
+
);
|
|
4543
4608
|
} else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
|
|
4544
4609
|
const stem = base.slice(0, -explicitExtension.length);
|
|
4545
|
-
candidates.push(
|
|
4610
|
+
candidates.push(
|
|
4611
|
+
...SOURCE_EXTENSIONS.map((extension) => `${stem}${extension}`)
|
|
4612
|
+
);
|
|
4546
4613
|
}
|
|
4547
4614
|
for (const candidate of candidates) {
|
|
4548
4615
|
if (await fileExists(candidate)) {
|
|
4549
4616
|
return normalizeLocalPath(candidate);
|
|
4550
4617
|
}
|
|
4551
4618
|
}
|
|
4552
|
-
throw new Error(
|
|
4619
|
+
throw new Error(
|
|
4620
|
+
`Could not resolve local import "${specifier}" from ${fromFile}`
|
|
4621
|
+
);
|
|
4553
4622
|
}
|
|
4554
4623
|
function resolvePackageImport(specifier, fromFile, adapter) {
|
|
4555
4624
|
const packageName = getPackageName(specifier);
|
|
@@ -4597,7 +4666,9 @@ async function analyzeSourceGraph(entryFile, adapter) {
|
|
|
4597
4666
|
);
|
|
4598
4667
|
}
|
|
4599
4668
|
if (NODE_BUILTIN_SET.has(specifier)) {
|
|
4600
|
-
nodeBuiltins.add(
|
|
4669
|
+
nodeBuiltins.add(
|
|
4670
|
+
specifier.startsWith("node:") ? specifier : `node:${specifier}`
|
|
4671
|
+
);
|
|
4601
4672
|
return;
|
|
4602
4673
|
}
|
|
4603
4674
|
if (isLocalSpecifier(specifier)) {
|
|
@@ -4632,7 +4703,11 @@ async function analyzeSourceGraph(entryFile, adapter) {
|
|
|
4632
4703
|
`${absolutePath}:${line}:${column} Unsupported import specifier "${specifier}". Allowed imports are relative files, Node builtins, and installed packages.`
|
|
4633
4704
|
);
|
|
4634
4705
|
}
|
|
4635
|
-
const packageImport = resolvePackageImport(
|
|
4706
|
+
const packageImport = resolvePackageImport(
|
|
4707
|
+
specifier,
|
|
4708
|
+
absolutePath,
|
|
4709
|
+
adapter
|
|
4710
|
+
);
|
|
4636
4711
|
packages.set(packageImport.name, packageImport.version);
|
|
4637
4712
|
};
|
|
4638
4713
|
try {
|
|
@@ -4682,16 +4757,23 @@ async function analyzeSourceGraph(entryFile, adapter) {
|
|
|
4682
4757
|
packages: [...packages.entries()].map(([name, version]) => ({ name, version })).sort((left, right) => left.name.localeCompare(right.name))
|
|
4683
4758
|
},
|
|
4684
4759
|
playName,
|
|
4685
|
-
importedPlayDependencies: [...importedPlayDependencies.values()].sort(
|
|
4760
|
+
importedPlayDependencies: [...importedPlayDependencies.values()].sort(
|
|
4761
|
+
(left, right) => left.filePath.localeCompare(right.filePath)
|
|
4762
|
+
)
|
|
4686
4763
|
};
|
|
4687
4764
|
}
|
|
4688
4765
|
async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
|
|
4689
4766
|
const { readdir } = await import("fs/promises");
|
|
4690
|
-
const entries = await readdir(adapter.workersHarnessFilesDir, {
|
|
4767
|
+
const entries = await readdir(adapter.workersHarnessFilesDir, {
|
|
4768
|
+
withFileTypes: true
|
|
4769
|
+
});
|
|
4691
4770
|
const tsFiles = entries.filter((e) => e.isFile() && /\.[cm]?ts$/.test(e.name)).map((e) => e.name).sort();
|
|
4692
4771
|
const parts = [];
|
|
4693
4772
|
for (const name of tsFiles) {
|
|
4694
|
-
const contents = await readFile(
|
|
4773
|
+
const contents = await readFile(
|
|
4774
|
+
join3(adapter.workersHarnessFilesDir, name),
|
|
4775
|
+
"utf-8"
|
|
4776
|
+
);
|
|
4695
4777
|
parts.push({ name, hash: sha256(contents) });
|
|
4696
4778
|
}
|
|
4697
4779
|
return sha256(JSON.stringify(parts));
|
|
@@ -4867,9 +4949,47 @@ async function runEsbuildForEsmWorkers(playEntryFile, importedPlayDependencies,
|
|
|
4867
4949
|
outputExtension: "mjs"
|
|
4868
4950
|
};
|
|
4869
4951
|
}
|
|
4952
|
+
var PLAY_ARTIFACT_TARGET_ADAPTERS = {
|
|
4953
|
+
[PLAY_ARTIFACT_KINDS.cjsNode20]: {
|
|
4954
|
+
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
4955
|
+
codeFormat: "cjs_module",
|
|
4956
|
+
includeWorkersHarnessInGraphHash: false,
|
|
4957
|
+
runEsbuild: ({
|
|
4958
|
+
entryFile,
|
|
4959
|
+
importedPlayDependencies,
|
|
4960
|
+
adapter,
|
|
4961
|
+
exportName
|
|
4962
|
+
}) => runEsbuildForCjsNode(
|
|
4963
|
+
entryFile,
|
|
4964
|
+
importedPlayDependencies,
|
|
4965
|
+
adapter,
|
|
4966
|
+
exportName
|
|
4967
|
+
)
|
|
4968
|
+
},
|
|
4969
|
+
[PLAY_ARTIFACT_KINDS.esmWorkers]: {
|
|
4970
|
+
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
4971
|
+
codeFormat: "esm_module",
|
|
4972
|
+
includeWorkersHarnessInGraphHash: true,
|
|
4973
|
+
runEsbuild: ({
|
|
4974
|
+
entryFile,
|
|
4975
|
+
importedPlayDependencies,
|
|
4976
|
+
adapter,
|
|
4977
|
+
exportName
|
|
4978
|
+
}) => runEsbuildForEsmWorkers(
|
|
4979
|
+
entryFile,
|
|
4980
|
+
importedPlayDependencies,
|
|
4981
|
+
adapter,
|
|
4982
|
+
exportName
|
|
4983
|
+
)
|
|
4984
|
+
}
|
|
4985
|
+
};
|
|
4986
|
+
function resolvePlayArtifactTargetAdapter(artifactKind) {
|
|
4987
|
+
return PLAY_ARTIFACT_TARGET_ADAPTERS[artifactKind];
|
|
4988
|
+
}
|
|
4870
4989
|
async function bundlePlayFile(filePath, options) {
|
|
4871
4990
|
const adapter = options.adapter;
|
|
4872
4991
|
const target = options.target ?? PLAY_ARTIFACT_KINDS.cjsNode20;
|
|
4992
|
+
const targetAdapter = resolvePlayArtifactTargetAdapter(target);
|
|
4873
4993
|
const exportName = options.exportName?.trim() || "default";
|
|
4874
4994
|
assertValidExportName(exportName);
|
|
4875
4995
|
const absolutePath = await normalizeLocalPath(filePath);
|
|
@@ -4880,7 +5000,7 @@ async function bundlePlayFile(filePath, options) {
|
|
|
4880
5000
|
`${analysis.graphHash}
|
|
4881
5001
|
entry-export:${exportName}`
|
|
4882
5002
|
);
|
|
4883
|
-
if (
|
|
5003
|
+
if (targetAdapter.includeWorkersHarnessInGraphHash) {
|
|
4884
5004
|
const harnessFingerprint = await computeWorkersHarnessFingerprintWithAdapter(adapter);
|
|
4885
5005
|
analysis.graphHash = sha256(
|
|
4886
5006
|
`${analysis.graphHash}
|
|
@@ -4893,7 +5013,9 @@ workers-harness:${harnessFingerprint}`
|
|
|
4893
5013
|
sourcePath: absolutePath,
|
|
4894
5014
|
importedFilePaths: [
|
|
4895
5015
|
...analysis.importPolicy.localFiles,
|
|
4896
|
-
...analysis.importedPlayDependencies.map(
|
|
5016
|
+
...analysis.importedPlayDependencies.map(
|
|
5017
|
+
(dependency) => dependency.filePath
|
|
5018
|
+
)
|
|
4897
5019
|
]
|
|
4898
5020
|
}) ?? []
|
|
4899
5021
|
];
|
|
@@ -4904,7 +5026,11 @@ workers-harness:${harnessFingerprint}`
|
|
|
4904
5026
|
errors: typecheckErrors
|
|
4905
5027
|
};
|
|
4906
5028
|
}
|
|
4907
|
-
const cachedArtifact = await readArtifactCache(
|
|
5029
|
+
const cachedArtifact = await readArtifactCache(
|
|
5030
|
+
analysis.graphHash,
|
|
5031
|
+
target,
|
|
5032
|
+
adapter
|
|
5033
|
+
);
|
|
4908
5034
|
const discoveredFiles = await adapter.discoverPackagedLocalFiles(absolutePath);
|
|
4909
5035
|
if (cachedArtifact) {
|
|
4910
5036
|
const cachedArtifactSizeError = getBundleSizeError(
|
|
@@ -4931,7 +5057,12 @@ workers-harness:${harnessFingerprint}`
|
|
|
4931
5057
|
importedPlayDependencies: analysis.importedPlayDependencies
|
|
4932
5058
|
};
|
|
4933
5059
|
}
|
|
4934
|
-
const buildOutcome =
|
|
5060
|
+
const buildOutcome = await targetAdapter.runEsbuild({
|
|
5061
|
+
entryFile: absolutePath,
|
|
5062
|
+
importedPlayDependencies: analysis.importedPlayDependencies,
|
|
5063
|
+
adapter,
|
|
5064
|
+
exportName
|
|
5065
|
+
});
|
|
4935
5066
|
if (Array.isArray(buildOutcome)) {
|
|
4936
5067
|
return {
|
|
4937
5068
|
success: false,
|
|
@@ -4958,9 +5089,8 @@ workers-harness:${harnessFingerprint}`
|
|
|
4958
5089
|
errors: [bundleSizeError]
|
|
4959
5090
|
};
|
|
4960
5091
|
}
|
|
4961
|
-
const codeFormat = target === PLAY_ARTIFACT_KINDS.esmWorkers ? "esm_module" : "cjs_module";
|
|
4962
5092
|
const artifact = {
|
|
4963
|
-
codeFormat,
|
|
5093
|
+
codeFormat: targetAdapter.codeFormat,
|
|
4964
5094
|
artifactKind: target,
|
|
4965
5095
|
entryFile: absolutePath,
|
|
4966
5096
|
virtualFilename,
|
|
@@ -5004,6 +5134,13 @@ workers-harness:${harnessFingerprint}`
|
|
|
5004
5134
|
}
|
|
5005
5135
|
}
|
|
5006
5136
|
|
|
5137
|
+
// ../shared_libs/play-runtime/dedup-backend.ts
|
|
5138
|
+
var PLAY_DEDUP_BACKENDS = {
|
|
5139
|
+
inMemory: "in_memory",
|
|
5140
|
+
neonTable: "neon_table",
|
|
5141
|
+
durableObject: "durable_object"
|
|
5142
|
+
};
|
|
5143
|
+
|
|
5007
5144
|
// ../shared_libs/play-runtime/scheduler-backend.ts
|
|
5008
5145
|
var PLAY_SCHEDULER_BACKENDS = {
|
|
5009
5146
|
temporal: "temporal",
|
|
@@ -5011,44 +5148,65 @@ var PLAY_SCHEDULER_BACKENDS = {
|
|
|
5011
5148
|
inProcess: "in-process"
|
|
5012
5149
|
};
|
|
5013
5150
|
|
|
5014
|
-
// ../shared_libs/play-runtime/
|
|
5015
|
-
var
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
durableObject: "durable_object"
|
|
5151
|
+
// ../shared_libs/play-runtime/providers.ts
|
|
5152
|
+
var PLAY_RUNTIME_PROVIDER_IDS = {
|
|
5153
|
+
workersEdge: "workers_edge",
|
|
5154
|
+
local: "local"
|
|
5019
5155
|
};
|
|
5020
|
-
|
|
5021
|
-
// ../shared_libs/play-runtime/profiles.ts
|
|
5022
|
-
var PLAY_EXECUTION_PROFILES = {
|
|
5156
|
+
var PLAY_RUNTIME_PROVIDERS = {
|
|
5023
5157
|
workers_edge: {
|
|
5024
|
-
id:
|
|
5158
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.workersEdge,
|
|
5025
5159
|
scheduler: PLAY_SCHEDULER_BACKENDS.cfWorkflows,
|
|
5026
5160
|
runner: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
|
|
5027
5161
|
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
5162
|
+
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
5028
5163
|
label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
|
|
5029
5164
|
},
|
|
5030
5165
|
local: {
|
|
5031
|
-
id:
|
|
5166
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.local,
|
|
5032
5167
|
scheduler: PLAY_SCHEDULER_BACKENDS.temporal,
|
|
5033
5168
|
runner: PLAY_RUNTIME_BACKENDS.localProcess,
|
|
5034
5169
|
dedup: PLAY_DEDUP_BACKENDS.inMemory,
|
|
5170
|
+
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
5035
5171
|
label: "Local Temporal scheduler + local subprocess runner (tests)"
|
|
5036
5172
|
}
|
|
5037
5173
|
};
|
|
5038
|
-
function
|
|
5039
|
-
return
|
|
5174
|
+
function defaultPlayRuntimeProvider() {
|
|
5175
|
+
return PLAY_RUNTIME_PROVIDERS.workers_edge;
|
|
5040
5176
|
}
|
|
5041
|
-
function
|
|
5177
|
+
function resolvePlayRuntimeProvider(override) {
|
|
5042
5178
|
if (override?.trim()) {
|
|
5043
5179
|
const id = override.trim();
|
|
5044
|
-
if (id in
|
|
5045
|
-
return
|
|
5180
|
+
if (id in PLAY_RUNTIME_PROVIDERS) {
|
|
5181
|
+
return PLAY_RUNTIME_PROVIDERS[id];
|
|
5046
5182
|
}
|
|
5047
5183
|
throw new Error(
|
|
5048
|
-
`Unknown
|
|
5184
|
+
`Unknown play runtime provider "${id}". Expected one of: ${Object.keys(
|
|
5185
|
+
PLAY_RUNTIME_PROVIDERS
|
|
5186
|
+
).join(", ")}.`
|
|
5049
5187
|
);
|
|
5050
5188
|
}
|
|
5051
|
-
return
|
|
5189
|
+
return defaultPlayRuntimeProvider();
|
|
5190
|
+
}
|
|
5191
|
+
|
|
5192
|
+
// ../shared_libs/play-runtime/profiles.ts
|
|
5193
|
+
var PLAY_EXECUTION_PROFILE_IDS = {
|
|
5194
|
+
...PLAY_RUNTIME_PROVIDER_IDS
|
|
5195
|
+
};
|
|
5196
|
+
var PLAY_EXECUTION_PROFILES = PLAY_RUNTIME_PROVIDERS;
|
|
5197
|
+
function resolveExecutionProfile(override) {
|
|
5198
|
+
try {
|
|
5199
|
+
return resolvePlayRuntimeProvider(override);
|
|
5200
|
+
} catch (error) {
|
|
5201
|
+
if (override?.trim()) {
|
|
5202
|
+
throw new Error(
|
|
5203
|
+
`Unknown execution profile "${override.trim()}". Expected one of: ${Object.keys(
|
|
5204
|
+
PLAY_EXECUTION_PROFILES
|
|
5205
|
+
).join(", ")}.`
|
|
5206
|
+
);
|
|
5207
|
+
}
|
|
5208
|
+
throw error;
|
|
5209
|
+
}
|
|
5052
5210
|
}
|
|
5053
5211
|
|
|
5054
5212
|
// src/plays/local-file-discovery.ts
|
|
@@ -5366,8 +5524,19 @@ var SDK_PACKAGE_JSON = resolve8(SDK_PACKAGE_ROOT, "package.json");
|
|
|
5366
5524
|
var SDK_ENTRY_FILE = resolve8(SDK_SOURCE_ROOT, "index.ts");
|
|
5367
5525
|
var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : resolve8(SDK_PACKAGE_ROOT, "dist", "index.d.ts");
|
|
5368
5526
|
var SDK_WORKERS_ENTRY_FILE = resolve8(SDK_SOURCE_ROOT, "worker-play-entry.ts");
|
|
5369
|
-
var WORKERS_HARNESS_ENTRY_FILE = resolve8(
|
|
5370
|
-
|
|
5527
|
+
var WORKERS_HARNESS_ENTRY_FILE = resolve8(
|
|
5528
|
+
PROJECT_ROOT,
|
|
5529
|
+
"apps",
|
|
5530
|
+
"play-runner-workers",
|
|
5531
|
+
"src",
|
|
5532
|
+
"entry.ts"
|
|
5533
|
+
);
|
|
5534
|
+
var WORKERS_HARNESS_FILES_DIR = resolve8(
|
|
5535
|
+
PROJECT_ROOT,
|
|
5536
|
+
"apps",
|
|
5537
|
+
"play-runner-workers",
|
|
5538
|
+
"src"
|
|
5539
|
+
);
|
|
5371
5540
|
var hasWarnedAboutNonDevelopmentBundling = false;
|
|
5372
5541
|
function warnAboutNonDevelopmentBundling(filePath) {
|
|
5373
5542
|
if (hasWarnedAboutNonDevelopmentBundling) {
|
|
@@ -5386,13 +5555,16 @@ function warnAboutNonDevelopmentBundling(filePath) {
|
|
|
5386
5555
|
);
|
|
5387
5556
|
}
|
|
5388
5557
|
function defaultPlayBundleTarget() {
|
|
5389
|
-
return
|
|
5558
|
+
return resolveExecutionProfile(null).artifactKind;
|
|
5390
5559
|
}
|
|
5391
5560
|
function createSdkPlayBundlingAdapter() {
|
|
5392
5561
|
return {
|
|
5393
5562
|
projectRoot: PROJECT_ROOT,
|
|
5394
5563
|
nodeModulesDir: resolve8(PROJECT_ROOT, "node_modules"),
|
|
5395
|
-
cacheDir: join5(
|
|
5564
|
+
cacheDir: join5(
|
|
5565
|
+
tmpdir2(),
|
|
5566
|
+
`deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION2}`
|
|
5567
|
+
),
|
|
5396
5568
|
sdkSourceRoot: SDK_SOURCE_ROOT,
|
|
5397
5569
|
sdkPackageJson: SDK_PACKAGE_JSON,
|
|
5398
5570
|
sdkEntryFile: SDK_ENTRY_FILE,
|
|
@@ -5557,6 +5729,204 @@ function createCliProgress(enabled) {
|
|
|
5557
5729
|
return progress;
|
|
5558
5730
|
}
|
|
5559
5731
|
|
|
5732
|
+
// ../shared_libs/plays/row-identity.ts
|
|
5733
|
+
var POSTGRES_IDENTIFIER_MAX_LENGTH = 63;
|
|
5734
|
+
var PLAY_NAME_MAX_LENGTH = POSTGRES_IDENTIFIER_MAX_LENGTH;
|
|
5735
|
+
var MAP_KEY_NAMESPACE_MAX_LENGTH = POSTGRES_IDENTIFIER_MAX_LENGTH;
|
|
5736
|
+
var SHA256_INITIAL_HASH = [
|
|
5737
|
+
1779033703,
|
|
5738
|
+
3144134277,
|
|
5739
|
+
1013904242,
|
|
5740
|
+
2773480762,
|
|
5741
|
+
1359893119,
|
|
5742
|
+
2600822924,
|
|
5743
|
+
528734635,
|
|
5744
|
+
1541459225
|
|
5745
|
+
];
|
|
5746
|
+
var SHA256_ROUND_CONSTANTS = [
|
|
5747
|
+
1116352408,
|
|
5748
|
+
1899447441,
|
|
5749
|
+
3049323471,
|
|
5750
|
+
3921009573,
|
|
5751
|
+
961987163,
|
|
5752
|
+
1508970993,
|
|
5753
|
+
2453635748,
|
|
5754
|
+
2870763221,
|
|
5755
|
+
3624381080,
|
|
5756
|
+
310598401,
|
|
5757
|
+
607225278,
|
|
5758
|
+
1426881987,
|
|
5759
|
+
1925078388,
|
|
5760
|
+
2162078206,
|
|
5761
|
+
2614888103,
|
|
5762
|
+
3248222580,
|
|
5763
|
+
3835390401,
|
|
5764
|
+
4022224774,
|
|
5765
|
+
264347078,
|
|
5766
|
+
604807628,
|
|
5767
|
+
770255983,
|
|
5768
|
+
1249150122,
|
|
5769
|
+
1555081692,
|
|
5770
|
+
1996064986,
|
|
5771
|
+
2554220882,
|
|
5772
|
+
2821834349,
|
|
5773
|
+
2952996808,
|
|
5774
|
+
3210313671,
|
|
5775
|
+
3336571891,
|
|
5776
|
+
3584528711,
|
|
5777
|
+
113926993,
|
|
5778
|
+
338241895,
|
|
5779
|
+
666307205,
|
|
5780
|
+
773529912,
|
|
5781
|
+
1294757372,
|
|
5782
|
+
1396182291,
|
|
5783
|
+
1695183700,
|
|
5784
|
+
1986661051,
|
|
5785
|
+
2177026350,
|
|
5786
|
+
2456956037,
|
|
5787
|
+
2730485921,
|
|
5788
|
+
2820302411,
|
|
5789
|
+
3259730800,
|
|
5790
|
+
3345764771,
|
|
5791
|
+
3516065817,
|
|
5792
|
+
3600352804,
|
|
5793
|
+
4094571909,
|
|
5794
|
+
275423344,
|
|
5795
|
+
430227734,
|
|
5796
|
+
506948616,
|
|
5797
|
+
659060556,
|
|
5798
|
+
883997877,
|
|
5799
|
+
958139571,
|
|
5800
|
+
1322822218,
|
|
5801
|
+
1537002063,
|
|
5802
|
+
1747873779,
|
|
5803
|
+
1955562222,
|
|
5804
|
+
2024104815,
|
|
5805
|
+
2227730452,
|
|
5806
|
+
2361852424,
|
|
5807
|
+
2428436474,
|
|
5808
|
+
2756734187,
|
|
5809
|
+
3204031479,
|
|
5810
|
+
3329325298
|
|
5811
|
+
];
|
|
5812
|
+
function rightRotate32(value, bits) {
|
|
5813
|
+
return value >>> bits | value << 32 - bits;
|
|
5814
|
+
}
|
|
5815
|
+
function sha256Hex(input) {
|
|
5816
|
+
const bytes = Array.from(new TextEncoder().encode(input));
|
|
5817
|
+
const bitLength = bytes.length * 8;
|
|
5818
|
+
bytes.push(128);
|
|
5819
|
+
while (bytes.length % 64 !== 56) {
|
|
5820
|
+
bytes.push(0);
|
|
5821
|
+
}
|
|
5822
|
+
const highBits = Math.floor(bitLength / 4294967296);
|
|
5823
|
+
const lowBits = bitLength >>> 0;
|
|
5824
|
+
bytes.push(
|
|
5825
|
+
highBits >>> 24 & 255,
|
|
5826
|
+
highBits >>> 16 & 255,
|
|
5827
|
+
highBits >>> 8 & 255,
|
|
5828
|
+
highBits & 255,
|
|
5829
|
+
lowBits >>> 24 & 255,
|
|
5830
|
+
lowBits >>> 16 & 255,
|
|
5831
|
+
lowBits >>> 8 & 255,
|
|
5832
|
+
lowBits & 255
|
|
5833
|
+
);
|
|
5834
|
+
const hash = [...SHA256_INITIAL_HASH];
|
|
5835
|
+
const words = new Array(64).fill(0);
|
|
5836
|
+
for (let offset = 0; offset < bytes.length; offset += 64) {
|
|
5837
|
+
for (let index = 0; index < 16; index += 1) {
|
|
5838
|
+
const wordOffset = offset + index * 4;
|
|
5839
|
+
words[index] = (bytes[wordOffset] ?? 0) << 24 | (bytes[wordOffset + 1] ?? 0) << 16 | (bytes[wordOffset + 2] ?? 0) << 8 | (bytes[wordOffset + 3] ?? 0);
|
|
5840
|
+
}
|
|
5841
|
+
for (let index = 16; index < 64; index += 1) {
|
|
5842
|
+
const s0 = rightRotate32(words[index - 15], 7) ^ rightRotate32(words[index - 15], 18) ^ words[index - 15] >>> 3;
|
|
5843
|
+
const s1 = rightRotate32(words[index - 2], 17) ^ rightRotate32(words[index - 2], 19) ^ words[index - 2] >>> 10;
|
|
5844
|
+
words[index] = words[index - 16] + s0 + words[index - 7] + s1 >>> 0;
|
|
5845
|
+
}
|
|
5846
|
+
let [a, b, c, d, e, f, g, h] = hash;
|
|
5847
|
+
for (let index = 0; index < 64; index += 1) {
|
|
5848
|
+
const s1 = rightRotate32(e, 6) ^ rightRotate32(e, 11) ^ rightRotate32(e, 25);
|
|
5849
|
+
const ch = e & f ^ ~e & g;
|
|
5850
|
+
const temp1 = h + s1 + ch + SHA256_ROUND_CONSTANTS[index] + words[index] >>> 0;
|
|
5851
|
+
const s0 = rightRotate32(a, 2) ^ rightRotate32(a, 13) ^ rightRotate32(a, 22);
|
|
5852
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
5853
|
+
const temp2 = s0 + maj >>> 0;
|
|
5854
|
+
h = g;
|
|
5855
|
+
g = f;
|
|
5856
|
+
f = e;
|
|
5857
|
+
e = d + temp1 >>> 0;
|
|
5858
|
+
d = c;
|
|
5859
|
+
c = b;
|
|
5860
|
+
b = a;
|
|
5861
|
+
a = temp1 + temp2 >>> 0;
|
|
5862
|
+
}
|
|
5863
|
+
hash[0] = hash[0] + a >>> 0;
|
|
5864
|
+
hash[1] = hash[1] + b >>> 0;
|
|
5865
|
+
hash[2] = hash[2] + c >>> 0;
|
|
5866
|
+
hash[3] = hash[3] + d >>> 0;
|
|
5867
|
+
hash[4] = hash[4] + e >>> 0;
|
|
5868
|
+
hash[5] = hash[5] + f >>> 0;
|
|
5869
|
+
hash[6] = hash[6] + g >>> 0;
|
|
5870
|
+
hash[7] = hash[7] + h >>> 0;
|
|
5871
|
+
}
|
|
5872
|
+
return hash.map((word) => word.toString(16).padStart(8, "0")).join("");
|
|
5873
|
+
}
|
|
5874
|
+
function sanitizeIdentifierPart(value) {
|
|
5875
|
+
return value.trim().replace(/[^a-z0-9]+/gi, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
5876
|
+
}
|
|
5877
|
+
function validateIdentifierPart(rawValue, label, maxLength) {
|
|
5878
|
+
const sanitized = sanitizeIdentifierPart(rawValue);
|
|
5879
|
+
if (!sanitized) {
|
|
5880
|
+
throw new Error(
|
|
5881
|
+
`${label} must contain at least one letter or number after normalization. Use only letters, numbers, underscores, or hyphens.`
|
|
5882
|
+
);
|
|
5883
|
+
}
|
|
5884
|
+
if (sanitized.length > maxLength) {
|
|
5885
|
+
throw new Error(
|
|
5886
|
+
`${label} is too long after normalization (${sanitized.length}/${maxLength}). Shorten it to ${maxLength} characters or fewer. Normalized value: "${sanitized}".`
|
|
5887
|
+
);
|
|
5888
|
+
}
|
|
5889
|
+
return sanitized;
|
|
5890
|
+
}
|
|
5891
|
+
function normalizePlayName(value) {
|
|
5892
|
+
if (value.includes("/")) {
|
|
5893
|
+
throw new Error(
|
|
5894
|
+
'Play name cannot contain "/". Slash is reserved for qualified play references like "prebuilt/example" or "self/example".'
|
|
5895
|
+
);
|
|
5896
|
+
}
|
|
5897
|
+
return validateIdentifierPart(value, "Play name", PLAY_NAME_MAX_LENGTH);
|
|
5898
|
+
}
|
|
5899
|
+
function normalizePlayNameForSheet(value) {
|
|
5900
|
+
if (!value.includes("/")) {
|
|
5901
|
+
return normalizePlayName(value);
|
|
5902
|
+
}
|
|
5903
|
+
const digest = sha256Hex(value).slice(0, 12);
|
|
5904
|
+
const normalizedReference = sanitizeIdentifierPart(
|
|
5905
|
+
value.replace(/\//g, "__")
|
|
5906
|
+
);
|
|
5907
|
+
const prefixLength = Math.max(1, PLAY_NAME_MAX_LENGTH - digest.length - 1);
|
|
5908
|
+
const prefix = normalizedReference.slice(0, prefixLength).replace(/_+$/g, "") || "qualified_play";
|
|
5909
|
+
return `${prefix}_${digest}`;
|
|
5910
|
+
}
|
|
5911
|
+
function normalizeTableNamespace(value) {
|
|
5912
|
+
return validateIdentifierPart(
|
|
5913
|
+
value,
|
|
5914
|
+
"ctx.map() key",
|
|
5915
|
+
MAP_KEY_NAMESPACE_MAX_LENGTH
|
|
5916
|
+
);
|
|
5917
|
+
}
|
|
5918
|
+
function validatePlaySheetTableName(playName, tableNamespace) {
|
|
5919
|
+
const playSegment = normalizePlayNameForSheet(playName);
|
|
5920
|
+
const keySegment = normalizeTableNamespace(tableNamespace);
|
|
5921
|
+
const resolved = `${playSegment}_${keySegment}`;
|
|
5922
|
+
if (resolved.length > POSTGRES_IDENTIFIER_MAX_LENGTH) {
|
|
5923
|
+
throw new Error(
|
|
5924
|
+
`Play sheet table name is too long after normalization (${resolved.length}/63). Shorten the play name or ctx.map() key. Resolved table name: "${resolved}".`
|
|
5925
|
+
);
|
|
5926
|
+
}
|
|
5927
|
+
return resolved;
|
|
5928
|
+
}
|
|
5929
|
+
|
|
5560
5930
|
// src/cli/trace.ts
|
|
5561
5931
|
var cliTraceStartedAt = Date.now();
|
|
5562
5932
|
function isTruthyEnv(value) {
|
|
@@ -5605,6 +5975,31 @@ async function traceCliSpan(phase, fields, run) {
|
|
|
5605
5975
|
}
|
|
5606
5976
|
}
|
|
5607
5977
|
|
|
5978
|
+
// src/cli/play-check-hints.ts
|
|
5979
|
+
var EXTRACTED_GETTER_ERROR_HINT = "Deepline hint: extractedValues/extractedLists .get() only works for declared Deepline getters listed by `deepline tools describe <tool> --json`. Use `toolExecutionResult.toolResponse.raw` for provider/tool-specific fields.";
|
|
5980
|
+
function sourceLineForError(sourceCode, error) {
|
|
5981
|
+
const match = error.match(/:(\d+):(\d+)\s/);
|
|
5982
|
+
const lineNumber = match?.[1] ? Number(match[1]) : NaN;
|
|
5983
|
+
if (!Number.isInteger(lineNumber) || lineNumber < 1) return "";
|
|
5984
|
+
return sourceCode.split(/\r?\n/)[lineNumber - 1] ?? "";
|
|
5985
|
+
}
|
|
5986
|
+
function looksLikeInvalidExtractedGetter(error, sourceLine) {
|
|
5987
|
+
if (!/Property '[^']+' does not exist on type/.test(error)) return false;
|
|
5988
|
+
return /\bextracted(?:Values|Lists)\s*\./.test(sourceLine);
|
|
5989
|
+
}
|
|
5990
|
+
function addPlayCheckRepairHints(input) {
|
|
5991
|
+
let addedHint = false;
|
|
5992
|
+
return input.errors.map((error) => {
|
|
5993
|
+
const line = sourceLineForError(input.sourceCode, error);
|
|
5994
|
+
if (addedHint || !looksLikeInvalidExtractedGetter(error, line) || error.includes(EXTRACTED_GETTER_ERROR_HINT)) {
|
|
5995
|
+
return error;
|
|
5996
|
+
}
|
|
5997
|
+
addedHint = true;
|
|
5998
|
+
return `${error}
|
|
5999
|
+
${EXTRACTED_GETTER_ERROR_HINT}`;
|
|
6000
|
+
});
|
|
6001
|
+
}
|
|
6002
|
+
|
|
5608
6003
|
// src/cli/commands/play.ts
|
|
5609
6004
|
var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
5610
6005
|
"--json",
|
|
@@ -5684,9 +6079,23 @@ function formatPlayListReference(play) {
|
|
|
5684
6079
|
return play.reference || play.name;
|
|
5685
6080
|
}
|
|
5686
6081
|
function defaultMaterializedPlayPath(reference) {
|
|
6082
|
+
return resolve9(defaultStarterPlayPath(reference));
|
|
6083
|
+
}
|
|
6084
|
+
function defaultStarterPlayPath(reference) {
|
|
5687
6085
|
const playName = parseReferencedPlayTarget(reference).unqualifiedPlayName;
|
|
5688
6086
|
const safeName = playName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
5689
|
-
return
|
|
6087
|
+
return `./${safeName || "play"}.play.ts`;
|
|
6088
|
+
}
|
|
6089
|
+
function buildCloneEditStarter(play) {
|
|
6090
|
+
const readonlyPrebuilt = (play.origin === "prebuilt" || play.ownerType === "deepline") && !play.canEdit;
|
|
6091
|
+
if (!play.canClone && !readonlyPrebuilt) return void 0;
|
|
6092
|
+
const reference = play.reference || play.name;
|
|
6093
|
+
const path = defaultStarterPlayPath(reference);
|
|
6094
|
+
return {
|
|
6095
|
+
path,
|
|
6096
|
+
command: `deepline plays get ${reference} --source --out ${path}`,
|
|
6097
|
+
checkCommand: `deepline plays check ${path}`
|
|
6098
|
+
};
|
|
5690
6099
|
}
|
|
5691
6100
|
function materializeRemotePlaySource(input) {
|
|
5692
6101
|
if (isFileTarget(input.target)) {
|
|
@@ -6132,6 +6541,8 @@ var TERMINAL_PLAY_STATUSES2 = /* @__PURE__ */ new Set([
|
|
|
6132
6541
|
"cancelled"
|
|
6133
6542
|
]);
|
|
6134
6543
|
var PLAY_START_TRANSIENT_RETRY_DELAYS_MS = [500, 1500];
|
|
6544
|
+
var PLAY_CUSTOMER_STORAGE_SCHEMA_NAME = "storage";
|
|
6545
|
+
var PLAY_INTERNAL_STEP_RECEIPT_TABLE = "_deepline_step_receipts";
|
|
6135
6546
|
function getEventPayload(event) {
|
|
6136
6547
|
return event.payload && typeof event.payload === "object" ? event.payload : {};
|
|
6137
6548
|
}
|
|
@@ -6185,6 +6596,86 @@ function getLogLinesFromLiveEvent(event) {
|
|
|
6185
6596
|
const lines = getEventPayload(event).lines;
|
|
6186
6597
|
return Array.isArray(lines) ? lines.filter((line) => typeof line === "string") : [];
|
|
6187
6598
|
}
|
|
6599
|
+
function quoteSqlIdentifier(identifier) {
|
|
6600
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
6601
|
+
}
|
|
6602
|
+
function quoteSqlLiteral(value) {
|
|
6603
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
6604
|
+
}
|
|
6605
|
+
function buildDebugDbQueryCommand(sql) {
|
|
6606
|
+
return `deepline db query --sql ${shellSingleQuote(sql)} --max-rows 20 --json`;
|
|
6607
|
+
}
|
|
6608
|
+
function buildStepReceiptsDebugCommand(runId) {
|
|
6609
|
+
const table = `${quoteSqlIdentifier(
|
|
6610
|
+
PLAY_CUSTOMER_STORAGE_SCHEMA_NAME
|
|
6611
|
+
)}.${quoteSqlIdentifier(PLAY_INTERNAL_STEP_RECEIPT_TABLE)}`;
|
|
6612
|
+
const sql = `select convert_from(k, 'UTF8') as receipt_key, case status when 0 then 'pending' when 1 then 'running' when 2 then 'completed' when 3 then 'failed' when 4 then 'skipped' else status::text end as status, output, error, updated_at from ${table} where run_id = ${quoteSqlLiteral(runId)} order by updated_at asc, receipt_key asc limit 20`;
|
|
6613
|
+
return buildDebugDbQueryCommand(sql);
|
|
6614
|
+
}
|
|
6615
|
+
function buildMapTableDebugCommand(input) {
|
|
6616
|
+
try {
|
|
6617
|
+
const tableName = validatePlaySheetTableName(
|
|
6618
|
+
input.playName,
|
|
6619
|
+
input.tableNamespace
|
|
6620
|
+
);
|
|
6621
|
+
const table = `${quoteSqlIdentifier(
|
|
6622
|
+
PLAY_CUSTOMER_STORAGE_SCHEMA_NAME
|
|
6623
|
+
)}.${quoteSqlIdentifier(tableName)}`;
|
|
6624
|
+
const sql = `select * from ${table} where _run_id = ${quoteSqlLiteral(input.runId)} limit 20`;
|
|
6625
|
+
return buildDebugDbQueryCommand(sql);
|
|
6626
|
+
} catch {
|
|
6627
|
+
return null;
|
|
6628
|
+
}
|
|
6629
|
+
}
|
|
6630
|
+
function extractTableNamespaceFromLiveEvent(event) {
|
|
6631
|
+
const payload = getEventPayload(event);
|
|
6632
|
+
const candidates = [
|
|
6633
|
+
payload.artifactTableNamespace,
|
|
6634
|
+
payload.tableNamespace,
|
|
6635
|
+
payload.mapNodeId
|
|
6636
|
+
];
|
|
6637
|
+
for (const candidate of candidates) {
|
|
6638
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
6639
|
+
return candidate.trim();
|
|
6640
|
+
}
|
|
6641
|
+
}
|
|
6642
|
+
return null;
|
|
6643
|
+
}
|
|
6644
|
+
function emitLiveDebugTableHints(input) {
|
|
6645
|
+
if (input.jsonOutput || !input.runId || input.runId === "pending") {
|
|
6646
|
+
return;
|
|
6647
|
+
}
|
|
6648
|
+
input.state.emittedDebugKeys ??= /* @__PURE__ */ new Set();
|
|
6649
|
+
const receiptsKey = `receipts:${input.runId}`;
|
|
6650
|
+
if (!input.state.emittedDebugKeys.has(receiptsKey)) {
|
|
6651
|
+
input.state.emittedDebugKeys.add(receiptsKey);
|
|
6652
|
+
input.progress.writeLine(
|
|
6653
|
+
`Debug top-level outputs: ${buildStepReceiptsDebugCommand(input.runId)}`,
|
|
6654
|
+
process.stdout
|
|
6655
|
+
);
|
|
6656
|
+
}
|
|
6657
|
+
const tableNamespace = extractTableNamespaceFromLiveEvent(input.event);
|
|
6658
|
+
if (!tableNamespace) {
|
|
6659
|
+
return;
|
|
6660
|
+
}
|
|
6661
|
+
const tableKey = `table:${input.runId}:${tableNamespace}`;
|
|
6662
|
+
if (input.state.emittedDebugKeys.has(tableKey)) {
|
|
6663
|
+
return;
|
|
6664
|
+
}
|
|
6665
|
+
const command = buildMapTableDebugCommand({
|
|
6666
|
+
playName: input.playName,
|
|
6667
|
+
runId: input.runId,
|
|
6668
|
+
tableNamespace
|
|
6669
|
+
});
|
|
6670
|
+
if (!command) {
|
|
6671
|
+
return;
|
|
6672
|
+
}
|
|
6673
|
+
input.state.emittedDebugKeys.add(tableKey);
|
|
6674
|
+
input.progress.writeLine(
|
|
6675
|
+
`Debug rows for ${tableNamespace}: ${command}`,
|
|
6676
|
+
process.stdout
|
|
6677
|
+
);
|
|
6678
|
+
}
|
|
6188
6679
|
function describeLiveEventPhase(event) {
|
|
6189
6680
|
const payload = getEventPayload(event);
|
|
6190
6681
|
if (event.type === "play.run.status") {
|
|
@@ -6337,6 +6828,14 @@ async function waitForPlayCompletionByStream(input) {
|
|
|
6337
6828
|
lastPhase = phase;
|
|
6338
6829
|
input.progress.phase(phase);
|
|
6339
6830
|
}
|
|
6831
|
+
emitLiveDebugTableHints({
|
|
6832
|
+
event,
|
|
6833
|
+
playName: input.playName,
|
|
6834
|
+
runId: input.workflowId,
|
|
6835
|
+
jsonOutput: input.jsonOutput,
|
|
6836
|
+
state: input.state,
|
|
6837
|
+
progress: input.progress
|
|
6838
|
+
});
|
|
6340
6839
|
printPlayLogLines({
|
|
6341
6840
|
lines: getLogLinesFromLiveEvent(event),
|
|
6342
6841
|
status: null,
|
|
@@ -6485,6 +6984,14 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
|
|
|
6485
6984
|
state,
|
|
6486
6985
|
progress: input.progress
|
|
6487
6986
|
});
|
|
6987
|
+
emitLiveDebugTableHints({
|
|
6988
|
+
event,
|
|
6989
|
+
playName: input.playName,
|
|
6990
|
+
runId: workflowId,
|
|
6991
|
+
jsonOutput: input.jsonOutput,
|
|
6992
|
+
state,
|
|
6993
|
+
progress: input.progress
|
|
6994
|
+
});
|
|
6488
6995
|
if (!input.jsonOutput) {
|
|
6489
6996
|
printPlayProgressLines({
|
|
6490
6997
|
lines: getProgressLinesFromLiveEvent(event),
|
|
@@ -6540,6 +7047,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
|
|
|
6540
7047
|
});
|
|
6541
7048
|
return waitForPlayCompletionByStream({
|
|
6542
7049
|
client: input.client,
|
|
7050
|
+
playName: input.playName,
|
|
6543
7051
|
workflowId: lastKnownWorkflowId,
|
|
6544
7052
|
dashboardUrl,
|
|
6545
7053
|
jsonOutput: input.jsonOutput,
|
|
@@ -6575,6 +7083,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
|
|
|
6575
7083
|
});
|
|
6576
7084
|
return waitForPlayCompletionByStream({
|
|
6577
7085
|
client: input.client,
|
|
7086
|
+
playName: input.playName,
|
|
6578
7087
|
workflowId: lastKnownWorkflowId,
|
|
6579
7088
|
dashboardUrl,
|
|
6580
7089
|
jsonOutput: input.jsonOutput,
|
|
@@ -7958,6 +8467,10 @@ async function handlePlayCheck(args) {
|
|
|
7958
8467
|
});
|
|
7959
8468
|
const enrichedResult = {
|
|
7960
8469
|
...result,
|
|
8470
|
+
errors: result.valid ? result.errors : addPlayCheckRepairHints({
|
|
8471
|
+
errors: result.errors,
|
|
8472
|
+
sourceCode: graph.root.sourceCode
|
|
8473
|
+
}),
|
|
7961
8474
|
toolGetterHints: result.toolGetterHints ?? await buildToolGetterHints(client, result.staticPipeline)
|
|
7962
8475
|
};
|
|
7963
8476
|
if (options.jsonOutput) {
|
|
@@ -8743,25 +9256,13 @@ function parsePlaySearchOptions(args) {
|
|
|
8743
9256
|
const query = args[0]?.trim();
|
|
8744
9257
|
if (!query) {
|
|
8745
9258
|
throw new Error(
|
|
8746
|
-
"Usage: deepline plays search <query> [--
|
|
9259
|
+
"Usage: deepline plays search <query> [--compact] [--json]"
|
|
8747
9260
|
);
|
|
8748
9261
|
}
|
|
8749
|
-
let origin;
|
|
8750
|
-
for (let index = 1; index < args.length; index += 1) {
|
|
8751
|
-
const arg = args[index];
|
|
8752
|
-
if (arg === "--origin" && args[index + 1]) {
|
|
8753
|
-
const rawOrigin = args[++index].trim().toLowerCase();
|
|
8754
|
-
if (rawOrigin !== "prebuilt" && rawOrigin !== "owned") {
|
|
8755
|
-
throw new Error(`Invalid value for --origin: ${rawOrigin}`);
|
|
8756
|
-
}
|
|
8757
|
-
origin = rawOrigin;
|
|
8758
|
-
}
|
|
8759
|
-
}
|
|
8760
9262
|
return {
|
|
8761
9263
|
query,
|
|
8762
9264
|
jsonOutput: argsWantJson(args),
|
|
8763
|
-
compact: args.includes("--compact")
|
|
8764
|
-
origin
|
|
9265
|
+
compact: args.includes("--compact")
|
|
8765
9266
|
};
|
|
8766
9267
|
}
|
|
8767
9268
|
function printPlayDescription(play) {
|
|
@@ -8810,10 +9311,10 @@ function printPlayDescription(play) {
|
|
|
8810
9311
|
}
|
|
8811
9312
|
}
|
|
8812
9313
|
console.log(` Run: ${play.runCommand}`);
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
);
|
|
9314
|
+
const cloneEditStarter = play.cloneEditStarter ?? buildCloneEditStarter(play);
|
|
9315
|
+
if (cloneEditStarter) {
|
|
9316
|
+
console.log(` Clone/edit starter: ${cloneEditStarter.command}`);
|
|
9317
|
+
console.log(` Check starter: ${cloneEditStarter.checkCommand}`);
|
|
8817
9318
|
}
|
|
8818
9319
|
}
|
|
8819
9320
|
function compactPlaySchema(schema) {
|
|
@@ -8845,6 +9346,7 @@ function summarizePlayListItemForCli(play, options) {
|
|
|
8845
9346
|
const csvInput = playSchemaMetadata(play.inputSchema, "csvInput");
|
|
8846
9347
|
const rowOutputSchema = playSchemaMetadata(play.outputSchema, "rowOutputSchema");
|
|
8847
9348
|
const runCommand2 = playRunCommand(play, { csvInput });
|
|
9349
|
+
const cloneEditStarter = buildCloneEditStarter(play);
|
|
8848
9350
|
return {
|
|
8849
9351
|
name: play.name,
|
|
8850
9352
|
...play.reference ? { reference: play.reference } : {},
|
|
@@ -8860,6 +9362,7 @@ function summarizePlayListItemForCli(play, options) {
|
|
|
8860
9362
|
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
8861
9363
|
runCommand: runCommand2,
|
|
8862
9364
|
examples: [runCommand2],
|
|
9365
|
+
...cloneEditStarter ? { cloneEditStarter } : {},
|
|
8863
9366
|
currentPublishedVersion: play.currentPublishedVersion ?? null,
|
|
8864
9367
|
isDraftDirty: play.isDraftDirty
|
|
8865
9368
|
};
|
|
@@ -8875,7 +9378,6 @@ async function handlePlaySearch(args) {
|
|
|
8875
9378
|
const client = new DeeplineClient();
|
|
8876
9379
|
const plays = await client.searchPlays({
|
|
8877
9380
|
query: options.query,
|
|
8878
|
-
...options.origin ? { origin: options.origin } : {},
|
|
8879
9381
|
compact: options.compact
|
|
8880
9382
|
});
|
|
8881
9383
|
if (options.jsonOutput) {
|
|
@@ -8921,20 +9423,12 @@ function matchesPlayGrepQuery(value, query, mode) {
|
|
|
8921
9423
|
async function handlePlayGrep(args) {
|
|
8922
9424
|
const query = args[0]?.trim();
|
|
8923
9425
|
if (!query) {
|
|
8924
|
-
console.error("Usage: deepline plays grep <query> [--
|
|
9426
|
+
console.error("Usage: deepline plays grep <query> [--mode all|any|phrase] [--compact] [--json]");
|
|
8925
9427
|
return 1;
|
|
8926
9428
|
}
|
|
8927
|
-
let origin;
|
|
8928
9429
|
let mode = "all";
|
|
8929
9430
|
for (let index = 1; index < args.length; index += 1) {
|
|
8930
9431
|
const arg = args[index];
|
|
8931
|
-
if (arg === "--origin" && args[index + 1]) {
|
|
8932
|
-
const rawOrigin = args[++index].trim().toLowerCase();
|
|
8933
|
-
if (rawOrigin !== "prebuilt" && rawOrigin !== "owned") {
|
|
8934
|
-
throw new Error(`Invalid value for --origin: ${rawOrigin}`);
|
|
8935
|
-
}
|
|
8936
|
-
origin = rawOrigin;
|
|
8937
|
-
}
|
|
8938
9432
|
if (arg === "--mode" && args[index + 1]) {
|
|
8939
9433
|
const rawMode = args[++index].trim().toLowerCase();
|
|
8940
9434
|
mode = rawMode === "any" || rawMode === "phrase" ? rawMode : "all";
|
|
@@ -8944,13 +9438,8 @@ async function handlePlayGrep(args) {
|
|
|
8944
9438
|
const client = new DeeplineClient();
|
|
8945
9439
|
const plays = (await client.listPlays({
|
|
8946
9440
|
grep: query,
|
|
8947
|
-
grepMode: mode
|
|
8948
|
-
|
|
8949
|
-
})).filter((play) => {
|
|
8950
|
-
if (!origin) return true;
|
|
8951
|
-
const isPrebuilt = play.origin === "prebuilt" || play.ownerType === "deepline";
|
|
8952
|
-
return origin === "prebuilt" ? isPrebuilt : !isPrebuilt;
|
|
8953
|
-
}).filter(
|
|
9441
|
+
grepMode: mode
|
|
9442
|
+
})).filter(
|
|
8954
9443
|
(play) => matchesPlayGrepQuery(
|
|
8955
9444
|
{
|
|
8956
9445
|
name: play.name,
|
|
@@ -8971,8 +9460,7 @@ async function handlePlayGrep(args) {
|
|
|
8971
9460
|
plays,
|
|
8972
9461
|
count: plays.length,
|
|
8973
9462
|
query,
|
|
8974
|
-
grep: { mode, terms: parsePlayGrepTerms(query, mode) }
|
|
8975
|
-
filters: { origin: origin ?? null }
|
|
9463
|
+
grep: { mode, terms: parsePlayGrepTerms(query, mode) }
|
|
8976
9464
|
})}
|
|
8977
9465
|
`);
|
|
8978
9466
|
return 0;
|
|
@@ -9308,7 +9796,7 @@ Notes:
|
|
|
9308
9796
|
Examples:
|
|
9309
9797
|
deepline plays list
|
|
9310
9798
|
deepline plays list --origin prebuilt --json
|
|
9311
|
-
deepline plays search email --
|
|
9799
|
+
deepline plays search email --json
|
|
9312
9800
|
`
|
|
9313
9801
|
).option("--origin <origin>", "Filter to prebuilt or owned plays").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
|
|
9314
9802
|
process.exitCode = await handlePlayList([
|
|
@@ -9320,20 +9808,18 @@ Examples:
|
|
|
9320
9808
|
"after",
|
|
9321
9809
|
`
|
|
9322
9810
|
Notes:
|
|
9323
|
-
Ranked discovery for workflows. Use
|
|
9324
|
-
you need to narrow results. Use describe on a result before running it.
|
|
9811
|
+
Ranked discovery for workflows. Use describe on a result before running it.
|
|
9325
9812
|
The grep alias is the same ranked retrieval surface with a more literal name
|
|
9326
9813
|
for agents that are filtering the play registry.
|
|
9327
9814
|
|
|
9328
9815
|
Examples:
|
|
9329
9816
|
deepline plays search email
|
|
9330
|
-
deepline plays grep "linkedin to email" --
|
|
9817
|
+
deepline plays grep "linkedin to email" --compact --json
|
|
9331
9818
|
deepline plays describe person-linkedin-to-email --json
|
|
9332
9819
|
`
|
|
9333
|
-
).option("--
|
|
9820
|
+
).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
|
|
9334
9821
|
process.exitCode = await handlePlaySearch([
|
|
9335
9822
|
query,
|
|
9336
|
-
...options.origin ? ["--origin", options.origin] : [],
|
|
9337
9823
|
...options.compact ? ["--compact"] : [],
|
|
9338
9824
|
...options.json ? ["--json"] : []
|
|
9339
9825
|
]);
|
|
@@ -9349,14 +9835,13 @@ Notes:
|
|
|
9349
9835
|
--mode all for AND.
|
|
9350
9836
|
|
|
9351
9837
|
Examples:
|
|
9352
|
-
deepline plays grep email --
|
|
9353
|
-
deepline plays grep "company contact" --
|
|
9838
|
+
deepline plays grep email --json
|
|
9839
|
+
deepline plays grep "company contact" --mode all --json
|
|
9354
9840
|
deepline plays describe prebuilt/company-to-contact --json
|
|
9355
9841
|
`
|
|
9356
|
-
).option("--
|
|
9842
|
+
).option("--compact", "Emit compact schemas").option("--mode <mode>", "Grep matching mode: all, any, or phrase").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
|
|
9357
9843
|
process.exitCode = await handlePlayGrep([
|
|
9358
9844
|
query,
|
|
9359
|
-
...options.origin ? ["--origin", options.origin] : [],
|
|
9360
9845
|
...options.compact ? ["--compact"] : [],
|
|
9361
9846
|
...options.mode ? ["--mode", options.mode] : [],
|
|
9362
9847
|
...options.json ? ["--json"] : []
|
|
@@ -9372,6 +9857,7 @@ Notes:
|
|
|
9372
9857
|
Examples:
|
|
9373
9858
|
deepline plays describe person-linkedin-to-email
|
|
9374
9859
|
deepline plays describe person-linkedin-to-email --json
|
|
9860
|
+
deepline plays get prebuilt/person-linkedin-to-email --source --out ./person-linkedin-to-email.play.ts
|
|
9375
9861
|
`
|
|
9376
9862
|
).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
|
|
9377
9863
|
process.exitCode = await handlePlayDescribe([
|
|
@@ -10196,6 +10682,11 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
|
|
|
10196
10682
|
const cost = recordField(tool, "cost");
|
|
10197
10683
|
const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
|
|
10198
10684
|
const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
|
|
10685
|
+
const starterScript = seedToolListScript({
|
|
10686
|
+
toolId,
|
|
10687
|
+
payload: samplePayloadForInputFields(inputFields),
|
|
10688
|
+
rows: []
|
|
10689
|
+
});
|
|
10199
10690
|
return {
|
|
10200
10691
|
schemaVersion: 1,
|
|
10201
10692
|
toolId,
|
|
@@ -10220,7 +10711,16 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
|
|
|
10220
10711
|
extractedLists,
|
|
10221
10712
|
extractedValues
|
|
10222
10713
|
},
|
|
10223
|
-
executeCommand: `deepline tools execute ${toolId} --input '{...}' --json
|
|
10714
|
+
executeCommand: `deepline tools execute ${toolId} --input '{...}' --json`,
|
|
10715
|
+
starterScript: {
|
|
10716
|
+
path: starterScript.path,
|
|
10717
|
+
sourceCode: starterScript.sourceCode,
|
|
10718
|
+
projectDir: starterScript.projectDir,
|
|
10719
|
+
copyToProject: {
|
|
10720
|
+
macosLinux: starterScript.macCopyCommand,
|
|
10721
|
+
windowsPowerShell: starterScript.windowsCopyCommand
|
|
10722
|
+
}
|
|
10723
|
+
}
|
|
10224
10724
|
};
|
|
10225
10725
|
}
|
|
10226
10726
|
function extractionContractEntries(entries) {
|
|
@@ -10262,6 +10762,13 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
10262
10762
|
}
|
|
10263
10763
|
console.log("");
|
|
10264
10764
|
printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
|
|
10765
|
+
const starterScript = isRecord4(contract.starterScript) ? contract.starterScript : {};
|
|
10766
|
+
const starterPath = stringField(starterScript, "path");
|
|
10767
|
+
if (starterPath) {
|
|
10768
|
+
console.log("");
|
|
10769
|
+
console.log(`Starter script: ${starterPath}`);
|
|
10770
|
+
console.log("Copy it into your project and replace the sample input with the proven probe payload.");
|
|
10771
|
+
}
|
|
10265
10772
|
if (listGetters.length || valueGetters.length) {
|
|
10266
10773
|
console.log("");
|
|
10267
10774
|
console.log("Getters:");
|
|
@@ -10313,14 +10820,7 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
|
|
|
10313
10820
|
const contract = toolContractJsonForDescribe(tool, requestedToolId);
|
|
10314
10821
|
const toolId = String(contract.toolId);
|
|
10315
10822
|
const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
|
|
10316
|
-
const sampleInput =
|
|
10317
|
-
inputFields.slice(0, 4).flatMap((field) => {
|
|
10318
|
-
if (!isRecord4(field)) return [];
|
|
10319
|
-
const name = stringField(field, "name");
|
|
10320
|
-
if (!name) return [];
|
|
10321
|
-
return [[name, sampleValueForField(field)]];
|
|
10322
|
-
})
|
|
10323
|
-
);
|
|
10823
|
+
const sampleInput = samplePayloadForInputFields(inputFields);
|
|
10324
10824
|
console.log(`Use in a play:`);
|
|
10325
10825
|
console.log("```ts");
|
|
10326
10826
|
console.log("const result = await ctx.tools.execute({");
|
|
@@ -10381,6 +10881,16 @@ function sampleValueForField(field) {
|
|
|
10381
10881
|
if (type === "object") return {};
|
|
10382
10882
|
return "...";
|
|
10383
10883
|
}
|
|
10884
|
+
function samplePayloadForInputFields(fields) {
|
|
10885
|
+
return Object.fromEntries(
|
|
10886
|
+
fields.slice(0, 4).flatMap((field) => {
|
|
10887
|
+
if (!isRecord4(field)) return [];
|
|
10888
|
+
const name = stringField(field, "name");
|
|
10889
|
+
if (!name) return [];
|
|
10890
|
+
return [[name, sampleValueForField(field)]];
|
|
10891
|
+
})
|
|
10892
|
+
);
|
|
10893
|
+
}
|
|
10384
10894
|
function stableStepIdForTool(toolId) {
|
|
10385
10895
|
return toolId.replace(/^[a-z0-9]+_/, "").replace(/[^a-z0-9_]+/gi, "_") || "tool_call";
|
|
10386
10896
|
}
|
|
@@ -10393,6 +10903,12 @@ function playResultExpression(entry) {
|
|
|
10393
10903
|
}
|
|
10394
10904
|
function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
10395
10905
|
const toolId = String(tool.toolId || requestedToolId);
|
|
10906
|
+
const inputFields = toolInputFieldsForDisplay(recordField(tool, "inputSchema", "input_schema"));
|
|
10907
|
+
const starterScript = seedToolListScript({
|
|
10908
|
+
toolId,
|
|
10909
|
+
payload: samplePayloadForInputFields(inputFields),
|
|
10910
|
+
rows: []
|
|
10911
|
+
});
|
|
10396
10912
|
const {
|
|
10397
10913
|
cost: _cost,
|
|
10398
10914
|
deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
|
|
@@ -10412,12 +10928,48 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
10412
10928
|
toolId,
|
|
10413
10929
|
provider: tool.provider,
|
|
10414
10930
|
displayName: tool.displayName,
|
|
10931
|
+
usageGuidance: usageGuidanceWithAccessDefaults(recordField(tool, "usageGuidance", "usage_guidance")),
|
|
10415
10932
|
runtimeOutputHelp: {
|
|
10416
|
-
contract: "tools describe shows
|
|
10933
|
+
contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
|
|
10934
|
+
getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
|
|
10935
|
+
rawToolResponse: "Use toolExecutionResult.toolResponse.raw for provider/tool-specific fields, fields in outputSchema that are not declared getters, and debugging.",
|
|
10936
|
+
invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
|
|
10417
10937
|
observeActualShape: `deepline tools execute ${toolId} --input '{...}' --json`,
|
|
10418
10938
|
observedOutput: `deepline tools execute ${toolId} --input '{...}' --json`,
|
|
10419
10939
|
forPlayGetterBugs: "Run the play, then inspect the emitted table commands from runs get. Use deepline db query against the run tables before editing getters.",
|
|
10420
10940
|
executeOutputFields: "tools execute JSON may include output_preview for this direct probe only; play debugging uses run tables."
|
|
10941
|
+
},
|
|
10942
|
+
starterScript: {
|
|
10943
|
+
path: starterScript.path,
|
|
10944
|
+
sourceCode: starterScript.sourceCode,
|
|
10945
|
+
projectDir: starterScript.projectDir,
|
|
10946
|
+
copyToProject: {
|
|
10947
|
+
macosLinux: starterScript.macCopyCommand,
|
|
10948
|
+
windowsPowerShell: starterScript.windowsCopyCommand
|
|
10949
|
+
}
|
|
10950
|
+
}
|
|
10951
|
+
};
|
|
10952
|
+
}
|
|
10953
|
+
function usageGuidanceWithAccessDefaults(usageGuidance) {
|
|
10954
|
+
if (Object.keys(usageGuidance).length === 0) return usageGuidance;
|
|
10955
|
+
const existingAccess = recordField(usageGuidance, "access");
|
|
10956
|
+
return {
|
|
10957
|
+
...usageGuidance,
|
|
10958
|
+
access: {
|
|
10959
|
+
extractedLists: {
|
|
10960
|
+
expression: "toolExecutionResult.extractedLists.<name>.get()",
|
|
10961
|
+
meaning: "Declared Deepline list extractors only."
|
|
10962
|
+
},
|
|
10963
|
+
extractedValues: {
|
|
10964
|
+
expression: "toolExecutionResult.extractedValues.<name>.get()",
|
|
10965
|
+
meaning: "Declared Deepline scalar extractors only."
|
|
10966
|
+
},
|
|
10967
|
+
rawToolResponse: {
|
|
10968
|
+
expression: "toolExecutionResult.toolResponse.raw",
|
|
10969
|
+
meaning: "Raw tool response for provider/tool-specific fields and debugging."
|
|
10970
|
+
},
|
|
10971
|
+
invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter; use toolResponse.raw for provider/tool-specific fields.",
|
|
10972
|
+
...existingAccess
|
|
10421
10973
|
}
|
|
10422
10974
|
};
|
|
10423
10975
|
}
|
|
@@ -10634,6 +11186,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
10634
11186
|
writeFileSync8(scriptPath, script, { encoding: "utf-8", mode: 384 });
|
|
10635
11187
|
return {
|
|
10636
11188
|
path: scriptPath,
|
|
11189
|
+
sourceCode: script,
|
|
10637
11190
|
projectDir,
|
|
10638
11191
|
macCopyCommand: `mkdir -p ${shellQuote(projectDir)} && cp ${shellQuote(scriptPath)} ${shellQuote(`${projectDir}/${fileName}`)}`,
|
|
10639
11192
|
windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
|