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.js
CHANGED
|
@@ -220,10 +220,10 @@ function resolveConfig(options) {
|
|
|
220
220
|
|
|
221
221
|
// src/release.ts
|
|
222
222
|
var SDK_RELEASE = {
|
|
223
|
-
version: "0.1.
|
|
224
|
-
apiContract: "2026-05-
|
|
223
|
+
version: "0.1.56",
|
|
224
|
+
apiContract: "2026-05-play-tool-describe-starters",
|
|
225
225
|
supportPolicy: {
|
|
226
|
-
latest: "0.1.
|
|
226
|
+
latest: "0.1.56",
|
|
227
227
|
minimumSupported: "0.1.53",
|
|
228
228
|
deprecatedBelow: "0.1.53"
|
|
229
229
|
}
|
|
@@ -727,6 +727,23 @@ var DeeplineClient = class {
|
|
|
727
727
|
}
|
|
728
728
|
return `deepline plays run ${target} --input '{...}' --watch`;
|
|
729
729
|
}
|
|
730
|
+
starterPlayPath(play) {
|
|
731
|
+
const target = play.reference || play.name;
|
|
732
|
+
const unqualifiedName = target.split("/").pop() || play.name;
|
|
733
|
+
const safeName = unqualifiedName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
734
|
+
return `./${safeName || "play"}.play.ts`;
|
|
735
|
+
}
|
|
736
|
+
playCloneEditStarter(play) {
|
|
737
|
+
const readonlyPrebuilt = (play.origin === "prebuilt" || play.ownerType === "deepline") && !play.canEdit;
|
|
738
|
+
if (!play.canClone && !readonlyPrebuilt) return void 0;
|
|
739
|
+
const target = play.reference || play.name;
|
|
740
|
+
const path = this.starterPlayPath(play);
|
|
741
|
+
return {
|
|
742
|
+
path,
|
|
743
|
+
command: `deepline plays get ${target} --source --out ${path}`,
|
|
744
|
+
checkCommand: `deepline plays check ${path}`
|
|
745
|
+
};
|
|
746
|
+
}
|
|
730
747
|
summarizePlayListItem(play, options) {
|
|
731
748
|
const aliases = play.aliases?.length ? play.aliases : [play.name];
|
|
732
749
|
const csvInput = this.schemaMetadata(play.inputSchema, "csvInput");
|
|
@@ -735,6 +752,7 @@ var DeeplineClient = class {
|
|
|
735
752
|
"rowOutputSchema"
|
|
736
753
|
);
|
|
737
754
|
const runCommand2 = this.playRunCommand(play, { csvInput });
|
|
755
|
+
const cloneEditStarter = this.playCloneEditStarter(play);
|
|
738
756
|
return {
|
|
739
757
|
name: play.name,
|
|
740
758
|
...play.reference ? { reference: play.reference } : {},
|
|
@@ -750,6 +768,7 @@ var DeeplineClient = class {
|
|
|
750
768
|
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
751
769
|
runCommand: runCommand2,
|
|
752
770
|
examples: [runCommand2],
|
|
771
|
+
...cloneEditStarter ? { cloneEditStarter } : {},
|
|
753
772
|
currentPublishedVersion: play.currentPublishedVersion ?? null,
|
|
754
773
|
isDraftDirty: play.isDraftDirty
|
|
755
774
|
};
|
|
@@ -1452,7 +1471,6 @@ var DeeplineClient = class {
|
|
|
1452
1471
|
async searchPlays(options) {
|
|
1453
1472
|
const params = new URLSearchParams();
|
|
1454
1473
|
params.set("search", options.query.trim());
|
|
1455
|
-
if (options.origin) params.set("origin", options.origin);
|
|
1456
1474
|
const response = await this.http.get(
|
|
1457
1475
|
`/api/v2/plays?${params.toString()}`
|
|
1458
1476
|
);
|
|
@@ -4085,11 +4103,23 @@ var PLAY_ARTIFACT_CACHE_DIR = (0, import_node_path7.join)(
|
|
|
4085
4103
|
`deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`
|
|
4086
4104
|
);
|
|
4087
4105
|
var PLAY_PROXY_NAMESPACE = "deepline-play-runtime-ref";
|
|
4088
|
-
var SOURCE_EXTENSIONS = [
|
|
4106
|
+
var SOURCE_EXTENSIONS = [
|
|
4107
|
+
".ts",
|
|
4108
|
+
".tsx",
|
|
4109
|
+
".mts",
|
|
4110
|
+
".cts",
|
|
4111
|
+
".js",
|
|
4112
|
+
".jsx",
|
|
4113
|
+
".mjs",
|
|
4114
|
+
".cjs",
|
|
4115
|
+
".json"
|
|
4116
|
+
];
|
|
4089
4117
|
var WORKERS_PLAY_ENTRY_VIRTUAL = "deepline-play-entry";
|
|
4090
4118
|
var PLAY_SOURCE_FILE_PATTERN = /\.play\.(?:[cm]?[jt]sx?)$/i;
|
|
4091
4119
|
var NODE_BUILTIN_SET = new Set(
|
|
4092
|
-
import_node_module.builtinModules.flatMap(
|
|
4120
|
+
import_node_module.builtinModules.flatMap(
|
|
4121
|
+
(name) => name.startsWith("node:") ? [name, name.slice(5)] : [name, `node:${name}`]
|
|
4122
|
+
)
|
|
4093
4123
|
);
|
|
4094
4124
|
function assertValidExportName(exportName) {
|
|
4095
4125
|
if (exportName === "default") return;
|
|
@@ -4169,15 +4199,27 @@ function findSourceImportReferences(sourceCode) {
|
|
|
4169
4199
|
};
|
|
4170
4200
|
const staticImportPattern = /\b(?:import|export)\s+(?!type\b)(?:[\s\S]*?\s+from\s*)?(['"])([^'"\n]+)\1/g;
|
|
4171
4201
|
for (const match of source.matchAll(staticImportPattern)) {
|
|
4172
|
-
addReference(
|
|
4202
|
+
addReference(
|
|
4203
|
+
match[2],
|
|
4204
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
4205
|
+
"static"
|
|
4206
|
+
);
|
|
4173
4207
|
}
|
|
4174
4208
|
const dynamicImportPattern = /\bimport\s*\(\s*(['"])([^'"\n]+)\1/g;
|
|
4175
4209
|
for (const match of source.matchAll(dynamicImportPattern)) {
|
|
4176
|
-
addReference(
|
|
4210
|
+
addReference(
|
|
4211
|
+
match[2],
|
|
4212
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
4213
|
+
"dynamic-import"
|
|
4214
|
+
);
|
|
4177
4215
|
}
|
|
4178
4216
|
const requirePattern = /\brequire\s*\(\s*(['"])([^'"\n]+)\1/g;
|
|
4179
4217
|
for (const match of source.matchAll(requirePattern)) {
|
|
4180
|
-
addReference(
|
|
4218
|
+
addReference(
|
|
4219
|
+
match[2],
|
|
4220
|
+
match.index + match[0].lastIndexOf(match[1]),
|
|
4221
|
+
"require"
|
|
4222
|
+
);
|
|
4181
4223
|
}
|
|
4182
4224
|
const literalDynamicImportIndexes = new Set(
|
|
4183
4225
|
[...source.matchAll(dynamicImportPattern)].map((match) => match.index)
|
|
@@ -4210,7 +4252,9 @@ function unquoteStringLiteral(literal) {
|
|
|
4210
4252
|
return null;
|
|
4211
4253
|
}
|
|
4212
4254
|
try {
|
|
4213
|
-
return JSON.parse(
|
|
4255
|
+
return JSON.parse(
|
|
4256
|
+
quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`
|
|
4257
|
+
);
|
|
4214
4258
|
} catch {
|
|
4215
4259
|
return trimmed.slice(1, -1);
|
|
4216
4260
|
}
|
|
@@ -4262,7 +4306,9 @@ function extractDefinedPlayName(sourceCode) {
|
|
|
4262
4306
|
const closeBrace = findMatchingBrace(source, argIndex);
|
|
4263
4307
|
if (closeBrace < 0) continue;
|
|
4264
4308
|
const objectSource = source.slice(argIndex + 1, closeBrace);
|
|
4265
|
-
const idMatch = objectSource.match(
|
|
4309
|
+
const idMatch = objectSource.match(
|
|
4310
|
+
/(?:^|[,{\s])(?:id|['"]id['"])\s*:\s*(['"])([\s\S]*?)\1/
|
|
4311
|
+
);
|
|
4266
4312
|
if (idMatch?.[2]?.trim()) {
|
|
4267
4313
|
return idMatch[2].trim();
|
|
4268
4314
|
}
|
|
@@ -4371,7 +4417,12 @@ function workersNamedPlayEntryAliasPlugin(playFilePath, exportName) {
|
|
|
4371
4417
|
};
|
|
4372
4418
|
}
|
|
4373
4419
|
function workersNodeBuiltinStubPlugin() {
|
|
4374
|
-
const UNSUPPORTED = /* @__PURE__ */ new Set([
|
|
4420
|
+
const UNSUPPORTED = /* @__PURE__ */ new Set([
|
|
4421
|
+
"node:fs",
|
|
4422
|
+
"node:fs/promises",
|
|
4423
|
+
"node:os",
|
|
4424
|
+
"node:child_process"
|
|
4425
|
+
]);
|
|
4375
4426
|
return {
|
|
4376
4427
|
name: "deepline-workers-node-builtin-stub",
|
|
4377
4428
|
setup(buildContext) {
|
|
@@ -4420,16 +4471,13 @@ function zodNonEnglishLocaleStubPlugin() {
|
|
|
4420
4471
|
}
|
|
4421
4472
|
return { path: args.path, namespace: NAMESPACE };
|
|
4422
4473
|
});
|
|
4423
|
-
buildContext.onLoad(
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
loader: "js"
|
|
4431
|
-
})
|
|
4432
|
-
);
|
|
4474
|
+
buildContext.onLoad({ filter: /.*/, namespace: NAMESPACE }, () => ({
|
|
4475
|
+
// zod locales export a default object literal. Empty object is
|
|
4476
|
+
// structurally compatible — accessing any locale key returns
|
|
4477
|
+
// undefined and zod falls back to its built-in English.
|
|
4478
|
+
contents: "export default {};",
|
|
4479
|
+
loader: "js"
|
|
4480
|
+
}));
|
|
4433
4481
|
}
|
|
4434
4482
|
};
|
|
4435
4483
|
}
|
|
@@ -4500,7 +4548,10 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
|
|
|
4500
4548
|
return null;
|
|
4501
4549
|
}
|
|
4502
4550
|
const dependenciesByPath = new Map(
|
|
4503
|
-
importedPlayDependencies.map((dependency) => [
|
|
4551
|
+
importedPlayDependencies.map((dependency) => [
|
|
4552
|
+
dependency.filePath,
|
|
4553
|
+
dependency
|
|
4554
|
+
])
|
|
4504
4555
|
);
|
|
4505
4556
|
return {
|
|
4506
4557
|
name: "deepline-imported-play-proxy",
|
|
@@ -4520,17 +4571,20 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
|
|
|
4520
4571
|
pluginData: dependency
|
|
4521
4572
|
};
|
|
4522
4573
|
});
|
|
4523
|
-
buildContext.onLoad(
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4574
|
+
buildContext.onLoad(
|
|
4575
|
+
{ filter: /.*/, namespace: PLAY_PROXY_NAMESPACE },
|
|
4576
|
+
async (args) => {
|
|
4577
|
+
const dependency = args.pluginData ?? dependenciesByPath.get(args.path);
|
|
4578
|
+
if (!dependency) {
|
|
4579
|
+
return null;
|
|
4580
|
+
}
|
|
4581
|
+
return {
|
|
4582
|
+
contents: buildImportedPlayProxyModule(dependency.playName),
|
|
4583
|
+
loader: "ts",
|
|
4584
|
+
resolveDir: (0, import_node_path7.dirname)(args.path)
|
|
4585
|
+
};
|
|
4527
4586
|
}
|
|
4528
|
-
|
|
4529
|
-
contents: buildImportedPlayProxyModule(dependency.playName),
|
|
4530
|
-
loader: "ts",
|
|
4531
|
-
resolveDir: (0, import_node_path7.dirname)(args.path)
|
|
4532
|
-
};
|
|
4533
|
-
});
|
|
4587
|
+
);
|
|
4534
4588
|
}
|
|
4535
4589
|
};
|
|
4536
4590
|
}
|
|
@@ -4550,18 +4604,26 @@ async function resolveLocalImport(fromFile, specifier) {
|
|
|
4550
4604
|
const candidates = [base];
|
|
4551
4605
|
const explicitExtension = (0, import_node_path7.extname)(base).toLowerCase();
|
|
4552
4606
|
if (!explicitExtension) {
|
|
4553
|
-
candidates.push(
|
|
4554
|
-
|
|
4607
|
+
candidates.push(
|
|
4608
|
+
...SOURCE_EXTENSIONS.map((extension) => `${base}${extension}`)
|
|
4609
|
+
);
|
|
4610
|
+
candidates.push(
|
|
4611
|
+
...SOURCE_EXTENSIONS.map((extension) => (0, import_node_path7.join)(base, `index${extension}`))
|
|
4612
|
+
);
|
|
4555
4613
|
} else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
|
|
4556
4614
|
const stem = base.slice(0, -explicitExtension.length);
|
|
4557
|
-
candidates.push(
|
|
4615
|
+
candidates.push(
|
|
4616
|
+
...SOURCE_EXTENSIONS.map((extension) => `${stem}${extension}`)
|
|
4617
|
+
);
|
|
4558
4618
|
}
|
|
4559
4619
|
for (const candidate of candidates) {
|
|
4560
4620
|
if (await fileExists(candidate)) {
|
|
4561
4621
|
return normalizeLocalPath(candidate);
|
|
4562
4622
|
}
|
|
4563
4623
|
}
|
|
4564
|
-
throw new Error(
|
|
4624
|
+
throw new Error(
|
|
4625
|
+
`Could not resolve local import "${specifier}" from ${fromFile}`
|
|
4626
|
+
);
|
|
4565
4627
|
}
|
|
4566
4628
|
function resolvePackageImport(specifier, fromFile, adapter) {
|
|
4567
4629
|
const packageName = getPackageName(specifier);
|
|
@@ -4609,7 +4671,9 @@ async function analyzeSourceGraph(entryFile, adapter) {
|
|
|
4609
4671
|
);
|
|
4610
4672
|
}
|
|
4611
4673
|
if (NODE_BUILTIN_SET.has(specifier)) {
|
|
4612
|
-
nodeBuiltins.add(
|
|
4674
|
+
nodeBuiltins.add(
|
|
4675
|
+
specifier.startsWith("node:") ? specifier : `node:${specifier}`
|
|
4676
|
+
);
|
|
4613
4677
|
return;
|
|
4614
4678
|
}
|
|
4615
4679
|
if (isLocalSpecifier(specifier)) {
|
|
@@ -4644,7 +4708,11 @@ async function analyzeSourceGraph(entryFile, adapter) {
|
|
|
4644
4708
|
`${absolutePath}:${line}:${column} Unsupported import specifier "${specifier}". Allowed imports are relative files, Node builtins, and installed packages.`
|
|
4645
4709
|
);
|
|
4646
4710
|
}
|
|
4647
|
-
const packageImport = resolvePackageImport(
|
|
4711
|
+
const packageImport = resolvePackageImport(
|
|
4712
|
+
specifier,
|
|
4713
|
+
absolutePath,
|
|
4714
|
+
adapter
|
|
4715
|
+
);
|
|
4648
4716
|
packages.set(packageImport.name, packageImport.version);
|
|
4649
4717
|
};
|
|
4650
4718
|
try {
|
|
@@ -4694,16 +4762,23 @@ async function analyzeSourceGraph(entryFile, adapter) {
|
|
|
4694
4762
|
packages: [...packages.entries()].map(([name, version]) => ({ name, version })).sort((left, right) => left.name.localeCompare(right.name))
|
|
4695
4763
|
},
|
|
4696
4764
|
playName,
|
|
4697
|
-
importedPlayDependencies: [...importedPlayDependencies.values()].sort(
|
|
4765
|
+
importedPlayDependencies: [...importedPlayDependencies.values()].sort(
|
|
4766
|
+
(left, right) => left.filePath.localeCompare(right.filePath)
|
|
4767
|
+
)
|
|
4698
4768
|
};
|
|
4699
4769
|
}
|
|
4700
4770
|
async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
|
|
4701
4771
|
const { readdir } = await import("fs/promises");
|
|
4702
|
-
const entries = await readdir(adapter.workersHarnessFilesDir, {
|
|
4772
|
+
const entries = await readdir(adapter.workersHarnessFilesDir, {
|
|
4773
|
+
withFileTypes: true
|
|
4774
|
+
});
|
|
4703
4775
|
const tsFiles = entries.filter((e) => e.isFile() && /\.[cm]?ts$/.test(e.name)).map((e) => e.name).sort();
|
|
4704
4776
|
const parts = [];
|
|
4705
4777
|
for (const name of tsFiles) {
|
|
4706
|
-
const contents = await (0, import_promises3.readFile)(
|
|
4778
|
+
const contents = await (0, import_promises3.readFile)(
|
|
4779
|
+
(0, import_node_path7.join)(adapter.workersHarnessFilesDir, name),
|
|
4780
|
+
"utf-8"
|
|
4781
|
+
);
|
|
4707
4782
|
parts.push({ name, hash: sha256(contents) });
|
|
4708
4783
|
}
|
|
4709
4784
|
return sha256(JSON.stringify(parts));
|
|
@@ -4879,9 +4954,47 @@ async function runEsbuildForEsmWorkers(playEntryFile, importedPlayDependencies,
|
|
|
4879
4954
|
outputExtension: "mjs"
|
|
4880
4955
|
};
|
|
4881
4956
|
}
|
|
4957
|
+
var PLAY_ARTIFACT_TARGET_ADAPTERS = {
|
|
4958
|
+
[PLAY_ARTIFACT_KINDS.cjsNode20]: {
|
|
4959
|
+
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
4960
|
+
codeFormat: "cjs_module",
|
|
4961
|
+
includeWorkersHarnessInGraphHash: false,
|
|
4962
|
+
runEsbuild: ({
|
|
4963
|
+
entryFile,
|
|
4964
|
+
importedPlayDependencies,
|
|
4965
|
+
adapter,
|
|
4966
|
+
exportName
|
|
4967
|
+
}) => runEsbuildForCjsNode(
|
|
4968
|
+
entryFile,
|
|
4969
|
+
importedPlayDependencies,
|
|
4970
|
+
adapter,
|
|
4971
|
+
exportName
|
|
4972
|
+
)
|
|
4973
|
+
},
|
|
4974
|
+
[PLAY_ARTIFACT_KINDS.esmWorkers]: {
|
|
4975
|
+
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
4976
|
+
codeFormat: "esm_module",
|
|
4977
|
+
includeWorkersHarnessInGraphHash: true,
|
|
4978
|
+
runEsbuild: ({
|
|
4979
|
+
entryFile,
|
|
4980
|
+
importedPlayDependencies,
|
|
4981
|
+
adapter,
|
|
4982
|
+
exportName
|
|
4983
|
+
}) => runEsbuildForEsmWorkers(
|
|
4984
|
+
entryFile,
|
|
4985
|
+
importedPlayDependencies,
|
|
4986
|
+
adapter,
|
|
4987
|
+
exportName
|
|
4988
|
+
)
|
|
4989
|
+
}
|
|
4990
|
+
};
|
|
4991
|
+
function resolvePlayArtifactTargetAdapter(artifactKind) {
|
|
4992
|
+
return PLAY_ARTIFACT_TARGET_ADAPTERS[artifactKind];
|
|
4993
|
+
}
|
|
4882
4994
|
async function bundlePlayFile(filePath, options) {
|
|
4883
4995
|
const adapter = options.adapter;
|
|
4884
4996
|
const target = options.target ?? PLAY_ARTIFACT_KINDS.cjsNode20;
|
|
4997
|
+
const targetAdapter = resolvePlayArtifactTargetAdapter(target);
|
|
4885
4998
|
const exportName = options.exportName?.trim() || "default";
|
|
4886
4999
|
assertValidExportName(exportName);
|
|
4887
5000
|
const absolutePath = await normalizeLocalPath(filePath);
|
|
@@ -4892,7 +5005,7 @@ async function bundlePlayFile(filePath, options) {
|
|
|
4892
5005
|
`${analysis.graphHash}
|
|
4893
5006
|
entry-export:${exportName}`
|
|
4894
5007
|
);
|
|
4895
|
-
if (
|
|
5008
|
+
if (targetAdapter.includeWorkersHarnessInGraphHash) {
|
|
4896
5009
|
const harnessFingerprint = await computeWorkersHarnessFingerprintWithAdapter(adapter);
|
|
4897
5010
|
analysis.graphHash = sha256(
|
|
4898
5011
|
`${analysis.graphHash}
|
|
@@ -4905,7 +5018,9 @@ workers-harness:${harnessFingerprint}`
|
|
|
4905
5018
|
sourcePath: absolutePath,
|
|
4906
5019
|
importedFilePaths: [
|
|
4907
5020
|
...analysis.importPolicy.localFiles,
|
|
4908
|
-
...analysis.importedPlayDependencies.map(
|
|
5021
|
+
...analysis.importedPlayDependencies.map(
|
|
5022
|
+
(dependency) => dependency.filePath
|
|
5023
|
+
)
|
|
4909
5024
|
]
|
|
4910
5025
|
}) ?? []
|
|
4911
5026
|
];
|
|
@@ -4916,7 +5031,11 @@ workers-harness:${harnessFingerprint}`
|
|
|
4916
5031
|
errors: typecheckErrors
|
|
4917
5032
|
};
|
|
4918
5033
|
}
|
|
4919
|
-
const cachedArtifact = await readArtifactCache(
|
|
5034
|
+
const cachedArtifact = await readArtifactCache(
|
|
5035
|
+
analysis.graphHash,
|
|
5036
|
+
target,
|
|
5037
|
+
adapter
|
|
5038
|
+
);
|
|
4920
5039
|
const discoveredFiles = await adapter.discoverPackagedLocalFiles(absolutePath);
|
|
4921
5040
|
if (cachedArtifact) {
|
|
4922
5041
|
const cachedArtifactSizeError = getBundleSizeError(
|
|
@@ -4943,7 +5062,12 @@ workers-harness:${harnessFingerprint}`
|
|
|
4943
5062
|
importedPlayDependencies: analysis.importedPlayDependencies
|
|
4944
5063
|
};
|
|
4945
5064
|
}
|
|
4946
|
-
const buildOutcome =
|
|
5065
|
+
const buildOutcome = await targetAdapter.runEsbuild({
|
|
5066
|
+
entryFile: absolutePath,
|
|
5067
|
+
importedPlayDependencies: analysis.importedPlayDependencies,
|
|
5068
|
+
adapter,
|
|
5069
|
+
exportName
|
|
5070
|
+
});
|
|
4947
5071
|
if (Array.isArray(buildOutcome)) {
|
|
4948
5072
|
return {
|
|
4949
5073
|
success: false,
|
|
@@ -4970,9 +5094,8 @@ workers-harness:${harnessFingerprint}`
|
|
|
4970
5094
|
errors: [bundleSizeError]
|
|
4971
5095
|
};
|
|
4972
5096
|
}
|
|
4973
|
-
const codeFormat = target === PLAY_ARTIFACT_KINDS.esmWorkers ? "esm_module" : "cjs_module";
|
|
4974
5097
|
const artifact = {
|
|
4975
|
-
codeFormat,
|
|
5098
|
+
codeFormat: targetAdapter.codeFormat,
|
|
4976
5099
|
artifactKind: target,
|
|
4977
5100
|
entryFile: absolutePath,
|
|
4978
5101
|
virtualFilename,
|
|
@@ -5016,6 +5139,13 @@ workers-harness:${harnessFingerprint}`
|
|
|
5016
5139
|
}
|
|
5017
5140
|
}
|
|
5018
5141
|
|
|
5142
|
+
// ../shared_libs/play-runtime/dedup-backend.ts
|
|
5143
|
+
var PLAY_DEDUP_BACKENDS = {
|
|
5144
|
+
inMemory: "in_memory",
|
|
5145
|
+
neonTable: "neon_table",
|
|
5146
|
+
durableObject: "durable_object"
|
|
5147
|
+
};
|
|
5148
|
+
|
|
5019
5149
|
// ../shared_libs/play-runtime/scheduler-backend.ts
|
|
5020
5150
|
var PLAY_SCHEDULER_BACKENDS = {
|
|
5021
5151
|
temporal: "temporal",
|
|
@@ -5023,44 +5153,65 @@ var PLAY_SCHEDULER_BACKENDS = {
|
|
|
5023
5153
|
inProcess: "in-process"
|
|
5024
5154
|
};
|
|
5025
5155
|
|
|
5026
|
-
// ../shared_libs/play-runtime/
|
|
5027
|
-
var
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
durableObject: "durable_object"
|
|
5156
|
+
// ../shared_libs/play-runtime/providers.ts
|
|
5157
|
+
var PLAY_RUNTIME_PROVIDER_IDS = {
|
|
5158
|
+
workersEdge: "workers_edge",
|
|
5159
|
+
local: "local"
|
|
5031
5160
|
};
|
|
5032
|
-
|
|
5033
|
-
// ../shared_libs/play-runtime/profiles.ts
|
|
5034
|
-
var PLAY_EXECUTION_PROFILES = {
|
|
5161
|
+
var PLAY_RUNTIME_PROVIDERS = {
|
|
5035
5162
|
workers_edge: {
|
|
5036
|
-
id:
|
|
5163
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.workersEdge,
|
|
5037
5164
|
scheduler: PLAY_SCHEDULER_BACKENDS.cfWorkflows,
|
|
5038
5165
|
runner: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
|
|
5039
5166
|
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
5167
|
+
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
5040
5168
|
label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
|
|
5041
5169
|
},
|
|
5042
5170
|
local: {
|
|
5043
|
-
id:
|
|
5171
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.local,
|
|
5044
5172
|
scheduler: PLAY_SCHEDULER_BACKENDS.temporal,
|
|
5045
5173
|
runner: PLAY_RUNTIME_BACKENDS.localProcess,
|
|
5046
5174
|
dedup: PLAY_DEDUP_BACKENDS.inMemory,
|
|
5175
|
+
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
5047
5176
|
label: "Local Temporal scheduler + local subprocess runner (tests)"
|
|
5048
5177
|
}
|
|
5049
5178
|
};
|
|
5050
|
-
function
|
|
5051
|
-
return
|
|
5179
|
+
function defaultPlayRuntimeProvider() {
|
|
5180
|
+
return PLAY_RUNTIME_PROVIDERS.workers_edge;
|
|
5052
5181
|
}
|
|
5053
|
-
function
|
|
5182
|
+
function resolvePlayRuntimeProvider(override) {
|
|
5054
5183
|
if (override?.trim()) {
|
|
5055
5184
|
const id = override.trim();
|
|
5056
|
-
if (id in
|
|
5057
|
-
return
|
|
5185
|
+
if (id in PLAY_RUNTIME_PROVIDERS) {
|
|
5186
|
+
return PLAY_RUNTIME_PROVIDERS[id];
|
|
5058
5187
|
}
|
|
5059
5188
|
throw new Error(
|
|
5060
|
-
`Unknown
|
|
5189
|
+
`Unknown play runtime provider "${id}". Expected one of: ${Object.keys(
|
|
5190
|
+
PLAY_RUNTIME_PROVIDERS
|
|
5191
|
+
).join(", ")}.`
|
|
5061
5192
|
);
|
|
5062
5193
|
}
|
|
5063
|
-
return
|
|
5194
|
+
return defaultPlayRuntimeProvider();
|
|
5195
|
+
}
|
|
5196
|
+
|
|
5197
|
+
// ../shared_libs/play-runtime/profiles.ts
|
|
5198
|
+
var PLAY_EXECUTION_PROFILE_IDS = {
|
|
5199
|
+
...PLAY_RUNTIME_PROVIDER_IDS
|
|
5200
|
+
};
|
|
5201
|
+
var PLAY_EXECUTION_PROFILES = PLAY_RUNTIME_PROVIDERS;
|
|
5202
|
+
function resolveExecutionProfile(override) {
|
|
5203
|
+
try {
|
|
5204
|
+
return resolvePlayRuntimeProvider(override);
|
|
5205
|
+
} catch (error) {
|
|
5206
|
+
if (override?.trim()) {
|
|
5207
|
+
throw new Error(
|
|
5208
|
+
`Unknown execution profile "${override.trim()}". Expected one of: ${Object.keys(
|
|
5209
|
+
PLAY_EXECUTION_PROFILES
|
|
5210
|
+
).join(", ")}.`
|
|
5211
|
+
);
|
|
5212
|
+
}
|
|
5213
|
+
throw error;
|
|
5214
|
+
}
|
|
5064
5215
|
}
|
|
5065
5216
|
|
|
5066
5217
|
// src/plays/local-file-discovery.ts
|
|
@@ -5379,8 +5530,19 @@ var SDK_PACKAGE_JSON = (0, import_node_path9.resolve)(SDK_PACKAGE_ROOT, "package
|
|
|
5379
5530
|
var SDK_ENTRY_FILE = (0, import_node_path9.resolve)(SDK_SOURCE_ROOT, "index.ts");
|
|
5380
5531
|
var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : (0, import_node_path9.resolve)(SDK_PACKAGE_ROOT, "dist", "index.d.ts");
|
|
5381
5532
|
var SDK_WORKERS_ENTRY_FILE = (0, import_node_path9.resolve)(SDK_SOURCE_ROOT, "worker-play-entry.ts");
|
|
5382
|
-
var WORKERS_HARNESS_ENTRY_FILE = (0, import_node_path9.resolve)(
|
|
5383
|
-
|
|
5533
|
+
var WORKERS_HARNESS_ENTRY_FILE = (0, import_node_path9.resolve)(
|
|
5534
|
+
PROJECT_ROOT,
|
|
5535
|
+
"apps",
|
|
5536
|
+
"play-runner-workers",
|
|
5537
|
+
"src",
|
|
5538
|
+
"entry.ts"
|
|
5539
|
+
);
|
|
5540
|
+
var WORKERS_HARNESS_FILES_DIR = (0, import_node_path9.resolve)(
|
|
5541
|
+
PROJECT_ROOT,
|
|
5542
|
+
"apps",
|
|
5543
|
+
"play-runner-workers",
|
|
5544
|
+
"src"
|
|
5545
|
+
);
|
|
5384
5546
|
var hasWarnedAboutNonDevelopmentBundling = false;
|
|
5385
5547
|
function warnAboutNonDevelopmentBundling(filePath) {
|
|
5386
5548
|
if (hasWarnedAboutNonDevelopmentBundling) {
|
|
@@ -5399,13 +5561,16 @@ function warnAboutNonDevelopmentBundling(filePath) {
|
|
|
5399
5561
|
);
|
|
5400
5562
|
}
|
|
5401
5563
|
function defaultPlayBundleTarget() {
|
|
5402
|
-
return
|
|
5564
|
+
return resolveExecutionProfile(null).artifactKind;
|
|
5403
5565
|
}
|
|
5404
5566
|
function createSdkPlayBundlingAdapter() {
|
|
5405
5567
|
return {
|
|
5406
5568
|
projectRoot: PROJECT_ROOT,
|
|
5407
5569
|
nodeModulesDir: (0, import_node_path9.resolve)(PROJECT_ROOT, "node_modules"),
|
|
5408
|
-
cacheDir: (0, import_node_path9.join)(
|
|
5570
|
+
cacheDir: (0, import_node_path9.join)(
|
|
5571
|
+
(0, import_node_os5.tmpdir)(),
|
|
5572
|
+
`deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION2}`
|
|
5573
|
+
),
|
|
5409
5574
|
sdkSourceRoot: SDK_SOURCE_ROOT,
|
|
5410
5575
|
sdkPackageJson: SDK_PACKAGE_JSON,
|
|
5411
5576
|
sdkEntryFile: SDK_ENTRY_FILE,
|
|
@@ -5570,6 +5735,204 @@ function createCliProgress(enabled) {
|
|
|
5570
5735
|
return progress;
|
|
5571
5736
|
}
|
|
5572
5737
|
|
|
5738
|
+
// ../shared_libs/plays/row-identity.ts
|
|
5739
|
+
var POSTGRES_IDENTIFIER_MAX_LENGTH = 63;
|
|
5740
|
+
var PLAY_NAME_MAX_LENGTH = POSTGRES_IDENTIFIER_MAX_LENGTH;
|
|
5741
|
+
var MAP_KEY_NAMESPACE_MAX_LENGTH = POSTGRES_IDENTIFIER_MAX_LENGTH;
|
|
5742
|
+
var SHA256_INITIAL_HASH = [
|
|
5743
|
+
1779033703,
|
|
5744
|
+
3144134277,
|
|
5745
|
+
1013904242,
|
|
5746
|
+
2773480762,
|
|
5747
|
+
1359893119,
|
|
5748
|
+
2600822924,
|
|
5749
|
+
528734635,
|
|
5750
|
+
1541459225
|
|
5751
|
+
];
|
|
5752
|
+
var SHA256_ROUND_CONSTANTS = [
|
|
5753
|
+
1116352408,
|
|
5754
|
+
1899447441,
|
|
5755
|
+
3049323471,
|
|
5756
|
+
3921009573,
|
|
5757
|
+
961987163,
|
|
5758
|
+
1508970993,
|
|
5759
|
+
2453635748,
|
|
5760
|
+
2870763221,
|
|
5761
|
+
3624381080,
|
|
5762
|
+
310598401,
|
|
5763
|
+
607225278,
|
|
5764
|
+
1426881987,
|
|
5765
|
+
1925078388,
|
|
5766
|
+
2162078206,
|
|
5767
|
+
2614888103,
|
|
5768
|
+
3248222580,
|
|
5769
|
+
3835390401,
|
|
5770
|
+
4022224774,
|
|
5771
|
+
264347078,
|
|
5772
|
+
604807628,
|
|
5773
|
+
770255983,
|
|
5774
|
+
1249150122,
|
|
5775
|
+
1555081692,
|
|
5776
|
+
1996064986,
|
|
5777
|
+
2554220882,
|
|
5778
|
+
2821834349,
|
|
5779
|
+
2952996808,
|
|
5780
|
+
3210313671,
|
|
5781
|
+
3336571891,
|
|
5782
|
+
3584528711,
|
|
5783
|
+
113926993,
|
|
5784
|
+
338241895,
|
|
5785
|
+
666307205,
|
|
5786
|
+
773529912,
|
|
5787
|
+
1294757372,
|
|
5788
|
+
1396182291,
|
|
5789
|
+
1695183700,
|
|
5790
|
+
1986661051,
|
|
5791
|
+
2177026350,
|
|
5792
|
+
2456956037,
|
|
5793
|
+
2730485921,
|
|
5794
|
+
2820302411,
|
|
5795
|
+
3259730800,
|
|
5796
|
+
3345764771,
|
|
5797
|
+
3516065817,
|
|
5798
|
+
3600352804,
|
|
5799
|
+
4094571909,
|
|
5800
|
+
275423344,
|
|
5801
|
+
430227734,
|
|
5802
|
+
506948616,
|
|
5803
|
+
659060556,
|
|
5804
|
+
883997877,
|
|
5805
|
+
958139571,
|
|
5806
|
+
1322822218,
|
|
5807
|
+
1537002063,
|
|
5808
|
+
1747873779,
|
|
5809
|
+
1955562222,
|
|
5810
|
+
2024104815,
|
|
5811
|
+
2227730452,
|
|
5812
|
+
2361852424,
|
|
5813
|
+
2428436474,
|
|
5814
|
+
2756734187,
|
|
5815
|
+
3204031479,
|
|
5816
|
+
3329325298
|
|
5817
|
+
];
|
|
5818
|
+
function rightRotate32(value, bits) {
|
|
5819
|
+
return value >>> bits | value << 32 - bits;
|
|
5820
|
+
}
|
|
5821
|
+
function sha256Hex(input) {
|
|
5822
|
+
const bytes = Array.from(new TextEncoder().encode(input));
|
|
5823
|
+
const bitLength = bytes.length * 8;
|
|
5824
|
+
bytes.push(128);
|
|
5825
|
+
while (bytes.length % 64 !== 56) {
|
|
5826
|
+
bytes.push(0);
|
|
5827
|
+
}
|
|
5828
|
+
const highBits = Math.floor(bitLength / 4294967296);
|
|
5829
|
+
const lowBits = bitLength >>> 0;
|
|
5830
|
+
bytes.push(
|
|
5831
|
+
highBits >>> 24 & 255,
|
|
5832
|
+
highBits >>> 16 & 255,
|
|
5833
|
+
highBits >>> 8 & 255,
|
|
5834
|
+
highBits & 255,
|
|
5835
|
+
lowBits >>> 24 & 255,
|
|
5836
|
+
lowBits >>> 16 & 255,
|
|
5837
|
+
lowBits >>> 8 & 255,
|
|
5838
|
+
lowBits & 255
|
|
5839
|
+
);
|
|
5840
|
+
const hash = [...SHA256_INITIAL_HASH];
|
|
5841
|
+
const words = new Array(64).fill(0);
|
|
5842
|
+
for (let offset = 0; offset < bytes.length; offset += 64) {
|
|
5843
|
+
for (let index = 0; index < 16; index += 1) {
|
|
5844
|
+
const wordOffset = offset + index * 4;
|
|
5845
|
+
words[index] = (bytes[wordOffset] ?? 0) << 24 | (bytes[wordOffset + 1] ?? 0) << 16 | (bytes[wordOffset + 2] ?? 0) << 8 | (bytes[wordOffset + 3] ?? 0);
|
|
5846
|
+
}
|
|
5847
|
+
for (let index = 16; index < 64; index += 1) {
|
|
5848
|
+
const s0 = rightRotate32(words[index - 15], 7) ^ rightRotate32(words[index - 15], 18) ^ words[index - 15] >>> 3;
|
|
5849
|
+
const s1 = rightRotate32(words[index - 2], 17) ^ rightRotate32(words[index - 2], 19) ^ words[index - 2] >>> 10;
|
|
5850
|
+
words[index] = words[index - 16] + s0 + words[index - 7] + s1 >>> 0;
|
|
5851
|
+
}
|
|
5852
|
+
let [a, b, c, d, e, f, g, h] = hash;
|
|
5853
|
+
for (let index = 0; index < 64; index += 1) {
|
|
5854
|
+
const s1 = rightRotate32(e, 6) ^ rightRotate32(e, 11) ^ rightRotate32(e, 25);
|
|
5855
|
+
const ch = e & f ^ ~e & g;
|
|
5856
|
+
const temp1 = h + s1 + ch + SHA256_ROUND_CONSTANTS[index] + words[index] >>> 0;
|
|
5857
|
+
const s0 = rightRotate32(a, 2) ^ rightRotate32(a, 13) ^ rightRotate32(a, 22);
|
|
5858
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
5859
|
+
const temp2 = s0 + maj >>> 0;
|
|
5860
|
+
h = g;
|
|
5861
|
+
g = f;
|
|
5862
|
+
f = e;
|
|
5863
|
+
e = d + temp1 >>> 0;
|
|
5864
|
+
d = c;
|
|
5865
|
+
c = b;
|
|
5866
|
+
b = a;
|
|
5867
|
+
a = temp1 + temp2 >>> 0;
|
|
5868
|
+
}
|
|
5869
|
+
hash[0] = hash[0] + a >>> 0;
|
|
5870
|
+
hash[1] = hash[1] + b >>> 0;
|
|
5871
|
+
hash[2] = hash[2] + c >>> 0;
|
|
5872
|
+
hash[3] = hash[3] + d >>> 0;
|
|
5873
|
+
hash[4] = hash[4] + e >>> 0;
|
|
5874
|
+
hash[5] = hash[5] + f >>> 0;
|
|
5875
|
+
hash[6] = hash[6] + g >>> 0;
|
|
5876
|
+
hash[7] = hash[7] + h >>> 0;
|
|
5877
|
+
}
|
|
5878
|
+
return hash.map((word) => word.toString(16).padStart(8, "0")).join("");
|
|
5879
|
+
}
|
|
5880
|
+
function sanitizeIdentifierPart(value) {
|
|
5881
|
+
return value.trim().replace(/[^a-z0-9]+/gi, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
5882
|
+
}
|
|
5883
|
+
function validateIdentifierPart(rawValue, label, maxLength) {
|
|
5884
|
+
const sanitized = sanitizeIdentifierPart(rawValue);
|
|
5885
|
+
if (!sanitized) {
|
|
5886
|
+
throw new Error(
|
|
5887
|
+
`${label} must contain at least one letter or number after normalization. Use only letters, numbers, underscores, or hyphens.`
|
|
5888
|
+
);
|
|
5889
|
+
}
|
|
5890
|
+
if (sanitized.length > maxLength) {
|
|
5891
|
+
throw new Error(
|
|
5892
|
+
`${label} is too long after normalization (${sanitized.length}/${maxLength}). Shorten it to ${maxLength} characters or fewer. Normalized value: "${sanitized}".`
|
|
5893
|
+
);
|
|
5894
|
+
}
|
|
5895
|
+
return sanitized;
|
|
5896
|
+
}
|
|
5897
|
+
function normalizePlayName(value) {
|
|
5898
|
+
if (value.includes("/")) {
|
|
5899
|
+
throw new Error(
|
|
5900
|
+
'Play name cannot contain "/". Slash is reserved for qualified play references like "prebuilt/example" or "self/example".'
|
|
5901
|
+
);
|
|
5902
|
+
}
|
|
5903
|
+
return validateIdentifierPart(value, "Play name", PLAY_NAME_MAX_LENGTH);
|
|
5904
|
+
}
|
|
5905
|
+
function normalizePlayNameForSheet(value) {
|
|
5906
|
+
if (!value.includes("/")) {
|
|
5907
|
+
return normalizePlayName(value);
|
|
5908
|
+
}
|
|
5909
|
+
const digest = sha256Hex(value).slice(0, 12);
|
|
5910
|
+
const normalizedReference = sanitizeIdentifierPart(
|
|
5911
|
+
value.replace(/\//g, "__")
|
|
5912
|
+
);
|
|
5913
|
+
const prefixLength = Math.max(1, PLAY_NAME_MAX_LENGTH - digest.length - 1);
|
|
5914
|
+
const prefix = normalizedReference.slice(0, prefixLength).replace(/_+$/g, "") || "qualified_play";
|
|
5915
|
+
return `${prefix}_${digest}`;
|
|
5916
|
+
}
|
|
5917
|
+
function normalizeTableNamespace(value) {
|
|
5918
|
+
return validateIdentifierPart(
|
|
5919
|
+
value,
|
|
5920
|
+
"ctx.map() key",
|
|
5921
|
+
MAP_KEY_NAMESPACE_MAX_LENGTH
|
|
5922
|
+
);
|
|
5923
|
+
}
|
|
5924
|
+
function validatePlaySheetTableName(playName, tableNamespace) {
|
|
5925
|
+
const playSegment = normalizePlayNameForSheet(playName);
|
|
5926
|
+
const keySegment = normalizeTableNamespace(tableNamespace);
|
|
5927
|
+
const resolved = `${playSegment}_${keySegment}`;
|
|
5928
|
+
if (resolved.length > POSTGRES_IDENTIFIER_MAX_LENGTH) {
|
|
5929
|
+
throw new Error(
|
|
5930
|
+
`Play sheet table name is too long after normalization (${resolved.length}/63). Shorten the play name or ctx.map() key. Resolved table name: "${resolved}".`
|
|
5931
|
+
);
|
|
5932
|
+
}
|
|
5933
|
+
return resolved;
|
|
5934
|
+
}
|
|
5935
|
+
|
|
5573
5936
|
// src/cli/trace.ts
|
|
5574
5937
|
var cliTraceStartedAt = Date.now();
|
|
5575
5938
|
function isTruthyEnv(value) {
|
|
@@ -5618,6 +5981,31 @@ async function traceCliSpan(phase, fields, run) {
|
|
|
5618
5981
|
}
|
|
5619
5982
|
}
|
|
5620
5983
|
|
|
5984
|
+
// src/cli/play-check-hints.ts
|
|
5985
|
+
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.";
|
|
5986
|
+
function sourceLineForError(sourceCode, error) {
|
|
5987
|
+
const match = error.match(/:(\d+):(\d+)\s/);
|
|
5988
|
+
const lineNumber = match?.[1] ? Number(match[1]) : NaN;
|
|
5989
|
+
if (!Number.isInteger(lineNumber) || lineNumber < 1) return "";
|
|
5990
|
+
return sourceCode.split(/\r?\n/)[lineNumber - 1] ?? "";
|
|
5991
|
+
}
|
|
5992
|
+
function looksLikeInvalidExtractedGetter(error, sourceLine) {
|
|
5993
|
+
if (!/Property '[^']+' does not exist on type/.test(error)) return false;
|
|
5994
|
+
return /\bextracted(?:Values|Lists)\s*\./.test(sourceLine);
|
|
5995
|
+
}
|
|
5996
|
+
function addPlayCheckRepairHints(input) {
|
|
5997
|
+
let addedHint = false;
|
|
5998
|
+
return input.errors.map((error) => {
|
|
5999
|
+
const line = sourceLineForError(input.sourceCode, error);
|
|
6000
|
+
if (addedHint || !looksLikeInvalidExtractedGetter(error, line) || error.includes(EXTRACTED_GETTER_ERROR_HINT)) {
|
|
6001
|
+
return error;
|
|
6002
|
+
}
|
|
6003
|
+
addedHint = true;
|
|
6004
|
+
return `${error}
|
|
6005
|
+
${EXTRACTED_GETTER_ERROR_HINT}`;
|
|
6006
|
+
});
|
|
6007
|
+
}
|
|
6008
|
+
|
|
5621
6009
|
// src/cli/commands/play.ts
|
|
5622
6010
|
var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
5623
6011
|
"--json",
|
|
@@ -5697,9 +6085,23 @@ function formatPlayListReference(play) {
|
|
|
5697
6085
|
return play.reference || play.name;
|
|
5698
6086
|
}
|
|
5699
6087
|
function defaultMaterializedPlayPath(reference) {
|
|
6088
|
+
return (0, import_node_path10.resolve)(defaultStarterPlayPath(reference));
|
|
6089
|
+
}
|
|
6090
|
+
function defaultStarterPlayPath(reference) {
|
|
5700
6091
|
const playName = parseReferencedPlayTarget(reference).unqualifiedPlayName;
|
|
5701
6092
|
const safeName = playName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
5702
|
-
return
|
|
6093
|
+
return `./${safeName || "play"}.play.ts`;
|
|
6094
|
+
}
|
|
6095
|
+
function buildCloneEditStarter(play) {
|
|
6096
|
+
const readonlyPrebuilt = (play.origin === "prebuilt" || play.ownerType === "deepline") && !play.canEdit;
|
|
6097
|
+
if (!play.canClone && !readonlyPrebuilt) return void 0;
|
|
6098
|
+
const reference = play.reference || play.name;
|
|
6099
|
+
const path = defaultStarterPlayPath(reference);
|
|
6100
|
+
return {
|
|
6101
|
+
path,
|
|
6102
|
+
command: `deepline plays get ${reference} --source --out ${path}`,
|
|
6103
|
+
checkCommand: `deepline plays check ${path}`
|
|
6104
|
+
};
|
|
5703
6105
|
}
|
|
5704
6106
|
function materializeRemotePlaySource(input) {
|
|
5705
6107
|
if (isFileTarget(input.target)) {
|
|
@@ -6145,6 +6547,8 @@ var TERMINAL_PLAY_STATUSES2 = /* @__PURE__ */ new Set([
|
|
|
6145
6547
|
"cancelled"
|
|
6146
6548
|
]);
|
|
6147
6549
|
var PLAY_START_TRANSIENT_RETRY_DELAYS_MS = [500, 1500];
|
|
6550
|
+
var PLAY_CUSTOMER_STORAGE_SCHEMA_NAME = "storage";
|
|
6551
|
+
var PLAY_INTERNAL_STEP_RECEIPT_TABLE = "_deepline_step_receipts";
|
|
6148
6552
|
function getEventPayload(event) {
|
|
6149
6553
|
return event.payload && typeof event.payload === "object" ? event.payload : {};
|
|
6150
6554
|
}
|
|
@@ -6198,6 +6602,86 @@ function getLogLinesFromLiveEvent(event) {
|
|
|
6198
6602
|
const lines = getEventPayload(event).lines;
|
|
6199
6603
|
return Array.isArray(lines) ? lines.filter((line) => typeof line === "string") : [];
|
|
6200
6604
|
}
|
|
6605
|
+
function quoteSqlIdentifier(identifier) {
|
|
6606
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
6607
|
+
}
|
|
6608
|
+
function quoteSqlLiteral(value) {
|
|
6609
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
6610
|
+
}
|
|
6611
|
+
function buildDebugDbQueryCommand(sql) {
|
|
6612
|
+
return `deepline db query --sql ${shellSingleQuote(sql)} --max-rows 20 --json`;
|
|
6613
|
+
}
|
|
6614
|
+
function buildStepReceiptsDebugCommand(runId) {
|
|
6615
|
+
const table = `${quoteSqlIdentifier(
|
|
6616
|
+
PLAY_CUSTOMER_STORAGE_SCHEMA_NAME
|
|
6617
|
+
)}.${quoteSqlIdentifier(PLAY_INTERNAL_STEP_RECEIPT_TABLE)}`;
|
|
6618
|
+
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`;
|
|
6619
|
+
return buildDebugDbQueryCommand(sql);
|
|
6620
|
+
}
|
|
6621
|
+
function buildMapTableDebugCommand(input) {
|
|
6622
|
+
try {
|
|
6623
|
+
const tableName = validatePlaySheetTableName(
|
|
6624
|
+
input.playName,
|
|
6625
|
+
input.tableNamespace
|
|
6626
|
+
);
|
|
6627
|
+
const table = `${quoteSqlIdentifier(
|
|
6628
|
+
PLAY_CUSTOMER_STORAGE_SCHEMA_NAME
|
|
6629
|
+
)}.${quoteSqlIdentifier(tableName)}`;
|
|
6630
|
+
const sql = `select * from ${table} where _run_id = ${quoteSqlLiteral(input.runId)} limit 20`;
|
|
6631
|
+
return buildDebugDbQueryCommand(sql);
|
|
6632
|
+
} catch {
|
|
6633
|
+
return null;
|
|
6634
|
+
}
|
|
6635
|
+
}
|
|
6636
|
+
function extractTableNamespaceFromLiveEvent(event) {
|
|
6637
|
+
const payload = getEventPayload(event);
|
|
6638
|
+
const candidates = [
|
|
6639
|
+
payload.artifactTableNamespace,
|
|
6640
|
+
payload.tableNamespace,
|
|
6641
|
+
payload.mapNodeId
|
|
6642
|
+
];
|
|
6643
|
+
for (const candidate of candidates) {
|
|
6644
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
6645
|
+
return candidate.trim();
|
|
6646
|
+
}
|
|
6647
|
+
}
|
|
6648
|
+
return null;
|
|
6649
|
+
}
|
|
6650
|
+
function emitLiveDebugTableHints(input) {
|
|
6651
|
+
if (input.jsonOutput || !input.runId || input.runId === "pending") {
|
|
6652
|
+
return;
|
|
6653
|
+
}
|
|
6654
|
+
input.state.emittedDebugKeys ??= /* @__PURE__ */ new Set();
|
|
6655
|
+
const receiptsKey = `receipts:${input.runId}`;
|
|
6656
|
+
if (!input.state.emittedDebugKeys.has(receiptsKey)) {
|
|
6657
|
+
input.state.emittedDebugKeys.add(receiptsKey);
|
|
6658
|
+
input.progress.writeLine(
|
|
6659
|
+
`Debug top-level outputs: ${buildStepReceiptsDebugCommand(input.runId)}`,
|
|
6660
|
+
process.stdout
|
|
6661
|
+
);
|
|
6662
|
+
}
|
|
6663
|
+
const tableNamespace = extractTableNamespaceFromLiveEvent(input.event);
|
|
6664
|
+
if (!tableNamespace) {
|
|
6665
|
+
return;
|
|
6666
|
+
}
|
|
6667
|
+
const tableKey = `table:${input.runId}:${tableNamespace}`;
|
|
6668
|
+
if (input.state.emittedDebugKeys.has(tableKey)) {
|
|
6669
|
+
return;
|
|
6670
|
+
}
|
|
6671
|
+
const command = buildMapTableDebugCommand({
|
|
6672
|
+
playName: input.playName,
|
|
6673
|
+
runId: input.runId,
|
|
6674
|
+
tableNamespace
|
|
6675
|
+
});
|
|
6676
|
+
if (!command) {
|
|
6677
|
+
return;
|
|
6678
|
+
}
|
|
6679
|
+
input.state.emittedDebugKeys.add(tableKey);
|
|
6680
|
+
input.progress.writeLine(
|
|
6681
|
+
`Debug rows for ${tableNamespace}: ${command}`,
|
|
6682
|
+
process.stdout
|
|
6683
|
+
);
|
|
6684
|
+
}
|
|
6201
6685
|
function describeLiveEventPhase(event) {
|
|
6202
6686
|
const payload = getEventPayload(event);
|
|
6203
6687
|
if (event.type === "play.run.status") {
|
|
@@ -6350,6 +6834,14 @@ async function waitForPlayCompletionByStream(input) {
|
|
|
6350
6834
|
lastPhase = phase;
|
|
6351
6835
|
input.progress.phase(phase);
|
|
6352
6836
|
}
|
|
6837
|
+
emitLiveDebugTableHints({
|
|
6838
|
+
event,
|
|
6839
|
+
playName: input.playName,
|
|
6840
|
+
runId: input.workflowId,
|
|
6841
|
+
jsonOutput: input.jsonOutput,
|
|
6842
|
+
state: input.state,
|
|
6843
|
+
progress: input.progress
|
|
6844
|
+
});
|
|
6353
6845
|
printPlayLogLines({
|
|
6354
6846
|
lines: getLogLinesFromLiveEvent(event),
|
|
6355
6847
|
status: null,
|
|
@@ -6498,6 +6990,14 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
|
|
|
6498
6990
|
state,
|
|
6499
6991
|
progress: input.progress
|
|
6500
6992
|
});
|
|
6993
|
+
emitLiveDebugTableHints({
|
|
6994
|
+
event,
|
|
6995
|
+
playName: input.playName,
|
|
6996
|
+
runId: workflowId,
|
|
6997
|
+
jsonOutput: input.jsonOutput,
|
|
6998
|
+
state,
|
|
6999
|
+
progress: input.progress
|
|
7000
|
+
});
|
|
6501
7001
|
if (!input.jsonOutput) {
|
|
6502
7002
|
printPlayProgressLines({
|
|
6503
7003
|
lines: getProgressLinesFromLiveEvent(event),
|
|
@@ -6553,6 +7053,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
|
|
|
6553
7053
|
});
|
|
6554
7054
|
return waitForPlayCompletionByStream({
|
|
6555
7055
|
client: input.client,
|
|
7056
|
+
playName: input.playName,
|
|
6556
7057
|
workflowId: lastKnownWorkflowId,
|
|
6557
7058
|
dashboardUrl,
|
|
6558
7059
|
jsonOutput: input.jsonOutput,
|
|
@@ -6588,6 +7089,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
|
|
|
6588
7089
|
});
|
|
6589
7090
|
return waitForPlayCompletionByStream({
|
|
6590
7091
|
client: input.client,
|
|
7092
|
+
playName: input.playName,
|
|
6591
7093
|
workflowId: lastKnownWorkflowId,
|
|
6592
7094
|
dashboardUrl,
|
|
6593
7095
|
jsonOutput: input.jsonOutput,
|
|
@@ -7971,6 +8473,10 @@ async function handlePlayCheck(args) {
|
|
|
7971
8473
|
});
|
|
7972
8474
|
const enrichedResult = {
|
|
7973
8475
|
...result,
|
|
8476
|
+
errors: result.valid ? result.errors : addPlayCheckRepairHints({
|
|
8477
|
+
errors: result.errors,
|
|
8478
|
+
sourceCode: graph.root.sourceCode
|
|
8479
|
+
}),
|
|
7974
8480
|
toolGetterHints: result.toolGetterHints ?? await buildToolGetterHints(client, result.staticPipeline)
|
|
7975
8481
|
};
|
|
7976
8482
|
if (options.jsonOutput) {
|
|
@@ -8756,25 +9262,13 @@ function parsePlaySearchOptions(args) {
|
|
|
8756
9262
|
const query = args[0]?.trim();
|
|
8757
9263
|
if (!query) {
|
|
8758
9264
|
throw new Error(
|
|
8759
|
-
"Usage: deepline plays search <query> [--
|
|
9265
|
+
"Usage: deepline plays search <query> [--compact] [--json]"
|
|
8760
9266
|
);
|
|
8761
9267
|
}
|
|
8762
|
-
let origin;
|
|
8763
|
-
for (let index = 1; index < args.length; index += 1) {
|
|
8764
|
-
const arg = args[index];
|
|
8765
|
-
if (arg === "--origin" && args[index + 1]) {
|
|
8766
|
-
const rawOrigin = args[++index].trim().toLowerCase();
|
|
8767
|
-
if (rawOrigin !== "prebuilt" && rawOrigin !== "owned") {
|
|
8768
|
-
throw new Error(`Invalid value for --origin: ${rawOrigin}`);
|
|
8769
|
-
}
|
|
8770
|
-
origin = rawOrigin;
|
|
8771
|
-
}
|
|
8772
|
-
}
|
|
8773
9268
|
return {
|
|
8774
9269
|
query,
|
|
8775
9270
|
jsonOutput: argsWantJson(args),
|
|
8776
|
-
compact: args.includes("--compact")
|
|
8777
|
-
origin
|
|
9271
|
+
compact: args.includes("--compact")
|
|
8778
9272
|
};
|
|
8779
9273
|
}
|
|
8780
9274
|
function printPlayDescription(play) {
|
|
@@ -8823,10 +9317,10 @@ function printPlayDescription(play) {
|
|
|
8823
9317
|
}
|
|
8824
9318
|
}
|
|
8825
9319
|
console.log(` Run: ${play.runCommand}`);
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
);
|
|
9320
|
+
const cloneEditStarter = play.cloneEditStarter ?? buildCloneEditStarter(play);
|
|
9321
|
+
if (cloneEditStarter) {
|
|
9322
|
+
console.log(` Clone/edit starter: ${cloneEditStarter.command}`);
|
|
9323
|
+
console.log(` Check starter: ${cloneEditStarter.checkCommand}`);
|
|
8830
9324
|
}
|
|
8831
9325
|
}
|
|
8832
9326
|
function compactPlaySchema(schema) {
|
|
@@ -8858,6 +9352,7 @@ function summarizePlayListItemForCli(play, options) {
|
|
|
8858
9352
|
const csvInput = playSchemaMetadata(play.inputSchema, "csvInput");
|
|
8859
9353
|
const rowOutputSchema = playSchemaMetadata(play.outputSchema, "rowOutputSchema");
|
|
8860
9354
|
const runCommand2 = playRunCommand(play, { csvInput });
|
|
9355
|
+
const cloneEditStarter = buildCloneEditStarter(play);
|
|
8861
9356
|
return {
|
|
8862
9357
|
name: play.name,
|
|
8863
9358
|
...play.reference ? { reference: play.reference } : {},
|
|
@@ -8873,6 +9368,7 @@ function summarizePlayListItemForCli(play, options) {
|
|
|
8873
9368
|
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
8874
9369
|
runCommand: runCommand2,
|
|
8875
9370
|
examples: [runCommand2],
|
|
9371
|
+
...cloneEditStarter ? { cloneEditStarter } : {},
|
|
8876
9372
|
currentPublishedVersion: play.currentPublishedVersion ?? null,
|
|
8877
9373
|
isDraftDirty: play.isDraftDirty
|
|
8878
9374
|
};
|
|
@@ -8888,7 +9384,6 @@ async function handlePlaySearch(args) {
|
|
|
8888
9384
|
const client = new DeeplineClient();
|
|
8889
9385
|
const plays = await client.searchPlays({
|
|
8890
9386
|
query: options.query,
|
|
8891
|
-
...options.origin ? { origin: options.origin } : {},
|
|
8892
9387
|
compact: options.compact
|
|
8893
9388
|
});
|
|
8894
9389
|
if (options.jsonOutput) {
|
|
@@ -8934,20 +9429,12 @@ function matchesPlayGrepQuery(value, query, mode) {
|
|
|
8934
9429
|
async function handlePlayGrep(args) {
|
|
8935
9430
|
const query = args[0]?.trim();
|
|
8936
9431
|
if (!query) {
|
|
8937
|
-
console.error("Usage: deepline plays grep <query> [--
|
|
9432
|
+
console.error("Usage: deepline plays grep <query> [--mode all|any|phrase] [--compact] [--json]");
|
|
8938
9433
|
return 1;
|
|
8939
9434
|
}
|
|
8940
|
-
let origin;
|
|
8941
9435
|
let mode = "all";
|
|
8942
9436
|
for (let index = 1; index < args.length; index += 1) {
|
|
8943
9437
|
const arg = args[index];
|
|
8944
|
-
if (arg === "--origin" && args[index + 1]) {
|
|
8945
|
-
const rawOrigin = args[++index].trim().toLowerCase();
|
|
8946
|
-
if (rawOrigin !== "prebuilt" && rawOrigin !== "owned") {
|
|
8947
|
-
throw new Error(`Invalid value for --origin: ${rawOrigin}`);
|
|
8948
|
-
}
|
|
8949
|
-
origin = rawOrigin;
|
|
8950
|
-
}
|
|
8951
9438
|
if (arg === "--mode" && args[index + 1]) {
|
|
8952
9439
|
const rawMode = args[++index].trim().toLowerCase();
|
|
8953
9440
|
mode = rawMode === "any" || rawMode === "phrase" ? rawMode : "all";
|
|
@@ -8957,13 +9444,8 @@ async function handlePlayGrep(args) {
|
|
|
8957
9444
|
const client = new DeeplineClient();
|
|
8958
9445
|
const plays = (await client.listPlays({
|
|
8959
9446
|
grep: query,
|
|
8960
|
-
grepMode: mode
|
|
8961
|
-
|
|
8962
|
-
})).filter((play) => {
|
|
8963
|
-
if (!origin) return true;
|
|
8964
|
-
const isPrebuilt = play.origin === "prebuilt" || play.ownerType === "deepline";
|
|
8965
|
-
return origin === "prebuilt" ? isPrebuilt : !isPrebuilt;
|
|
8966
|
-
}).filter(
|
|
9447
|
+
grepMode: mode
|
|
9448
|
+
})).filter(
|
|
8967
9449
|
(play) => matchesPlayGrepQuery(
|
|
8968
9450
|
{
|
|
8969
9451
|
name: play.name,
|
|
@@ -8984,8 +9466,7 @@ async function handlePlayGrep(args) {
|
|
|
8984
9466
|
plays,
|
|
8985
9467
|
count: plays.length,
|
|
8986
9468
|
query,
|
|
8987
|
-
grep: { mode, terms: parsePlayGrepTerms(query, mode) }
|
|
8988
|
-
filters: { origin: origin ?? null }
|
|
9469
|
+
grep: { mode, terms: parsePlayGrepTerms(query, mode) }
|
|
8989
9470
|
})}
|
|
8990
9471
|
`);
|
|
8991
9472
|
return 0;
|
|
@@ -9321,7 +9802,7 @@ Notes:
|
|
|
9321
9802
|
Examples:
|
|
9322
9803
|
deepline plays list
|
|
9323
9804
|
deepline plays list --origin prebuilt --json
|
|
9324
|
-
deepline plays search email --
|
|
9805
|
+
deepline plays search email --json
|
|
9325
9806
|
`
|
|
9326
9807
|
).option("--origin <origin>", "Filter to prebuilt or owned plays").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
|
|
9327
9808
|
process.exitCode = await handlePlayList([
|
|
@@ -9333,20 +9814,18 @@ Examples:
|
|
|
9333
9814
|
"after",
|
|
9334
9815
|
`
|
|
9335
9816
|
Notes:
|
|
9336
|
-
Ranked discovery for workflows. Use
|
|
9337
|
-
you need to narrow results. Use describe on a result before running it.
|
|
9817
|
+
Ranked discovery for workflows. Use describe on a result before running it.
|
|
9338
9818
|
The grep alias is the same ranked retrieval surface with a more literal name
|
|
9339
9819
|
for agents that are filtering the play registry.
|
|
9340
9820
|
|
|
9341
9821
|
Examples:
|
|
9342
9822
|
deepline plays search email
|
|
9343
|
-
deepline plays grep "linkedin to email" --
|
|
9823
|
+
deepline plays grep "linkedin to email" --compact --json
|
|
9344
9824
|
deepline plays describe person-linkedin-to-email --json
|
|
9345
9825
|
`
|
|
9346
|
-
).option("--
|
|
9826
|
+
).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
|
|
9347
9827
|
process.exitCode = await handlePlaySearch([
|
|
9348
9828
|
query,
|
|
9349
|
-
...options.origin ? ["--origin", options.origin] : [],
|
|
9350
9829
|
...options.compact ? ["--compact"] : [],
|
|
9351
9830
|
...options.json ? ["--json"] : []
|
|
9352
9831
|
]);
|
|
@@ -9362,14 +9841,13 @@ Notes:
|
|
|
9362
9841
|
--mode all for AND.
|
|
9363
9842
|
|
|
9364
9843
|
Examples:
|
|
9365
|
-
deepline plays grep email --
|
|
9366
|
-
deepline plays grep "company contact" --
|
|
9844
|
+
deepline plays grep email --json
|
|
9845
|
+
deepline plays grep "company contact" --mode all --json
|
|
9367
9846
|
deepline plays describe prebuilt/company-to-contact --json
|
|
9368
9847
|
`
|
|
9369
|
-
).option("--
|
|
9848
|
+
).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) => {
|
|
9370
9849
|
process.exitCode = await handlePlayGrep([
|
|
9371
9850
|
query,
|
|
9372
|
-
...options.origin ? ["--origin", options.origin] : [],
|
|
9373
9851
|
...options.compact ? ["--compact"] : [],
|
|
9374
9852
|
...options.mode ? ["--mode", options.mode] : [],
|
|
9375
9853
|
...options.json ? ["--json"] : []
|
|
@@ -9385,6 +9863,7 @@ Notes:
|
|
|
9385
9863
|
Examples:
|
|
9386
9864
|
deepline plays describe person-linkedin-to-email
|
|
9387
9865
|
deepline plays describe person-linkedin-to-email --json
|
|
9866
|
+
deepline plays get prebuilt/person-linkedin-to-email --source --out ./person-linkedin-to-email.play.ts
|
|
9388
9867
|
`
|
|
9389
9868
|
).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
|
|
9390
9869
|
process.exitCode = await handlePlayDescribe([
|
|
@@ -10209,6 +10688,11 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
|
|
|
10209
10688
|
const cost = recordField(tool, "cost");
|
|
10210
10689
|
const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
|
|
10211
10690
|
const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
|
|
10691
|
+
const starterScript = seedToolListScript({
|
|
10692
|
+
toolId,
|
|
10693
|
+
payload: samplePayloadForInputFields(inputFields),
|
|
10694
|
+
rows: []
|
|
10695
|
+
});
|
|
10212
10696
|
return {
|
|
10213
10697
|
schemaVersion: 1,
|
|
10214
10698
|
toolId,
|
|
@@ -10233,7 +10717,16 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
|
|
|
10233
10717
|
extractedLists,
|
|
10234
10718
|
extractedValues
|
|
10235
10719
|
},
|
|
10236
|
-
executeCommand: `deepline tools execute ${toolId} --input '{...}' --json
|
|
10720
|
+
executeCommand: `deepline tools execute ${toolId} --input '{...}' --json`,
|
|
10721
|
+
starterScript: {
|
|
10722
|
+
path: starterScript.path,
|
|
10723
|
+
sourceCode: starterScript.sourceCode,
|
|
10724
|
+
projectDir: starterScript.projectDir,
|
|
10725
|
+
copyToProject: {
|
|
10726
|
+
macosLinux: starterScript.macCopyCommand,
|
|
10727
|
+
windowsPowerShell: starterScript.windowsCopyCommand
|
|
10728
|
+
}
|
|
10729
|
+
}
|
|
10237
10730
|
};
|
|
10238
10731
|
}
|
|
10239
10732
|
function extractionContractEntries(entries) {
|
|
@@ -10275,6 +10768,13 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
10275
10768
|
}
|
|
10276
10769
|
console.log("");
|
|
10277
10770
|
printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
|
|
10771
|
+
const starterScript = isRecord4(contract.starterScript) ? contract.starterScript : {};
|
|
10772
|
+
const starterPath = stringField(starterScript, "path");
|
|
10773
|
+
if (starterPath) {
|
|
10774
|
+
console.log("");
|
|
10775
|
+
console.log(`Starter script: ${starterPath}`);
|
|
10776
|
+
console.log("Copy it into your project and replace the sample input with the proven probe payload.");
|
|
10777
|
+
}
|
|
10278
10778
|
if (listGetters.length || valueGetters.length) {
|
|
10279
10779
|
console.log("");
|
|
10280
10780
|
console.log("Getters:");
|
|
@@ -10326,14 +10826,7 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
|
|
|
10326
10826
|
const contract = toolContractJsonForDescribe(tool, requestedToolId);
|
|
10327
10827
|
const toolId = String(contract.toolId);
|
|
10328
10828
|
const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
|
|
10329
|
-
const sampleInput =
|
|
10330
|
-
inputFields.slice(0, 4).flatMap((field) => {
|
|
10331
|
-
if (!isRecord4(field)) return [];
|
|
10332
|
-
const name = stringField(field, "name");
|
|
10333
|
-
if (!name) return [];
|
|
10334
|
-
return [[name, sampleValueForField(field)]];
|
|
10335
|
-
})
|
|
10336
|
-
);
|
|
10829
|
+
const sampleInput = samplePayloadForInputFields(inputFields);
|
|
10337
10830
|
console.log(`Use in a play:`);
|
|
10338
10831
|
console.log("```ts");
|
|
10339
10832
|
console.log("const result = await ctx.tools.execute({");
|
|
@@ -10394,6 +10887,16 @@ function sampleValueForField(field) {
|
|
|
10394
10887
|
if (type === "object") return {};
|
|
10395
10888
|
return "...";
|
|
10396
10889
|
}
|
|
10890
|
+
function samplePayloadForInputFields(fields) {
|
|
10891
|
+
return Object.fromEntries(
|
|
10892
|
+
fields.slice(0, 4).flatMap((field) => {
|
|
10893
|
+
if (!isRecord4(field)) return [];
|
|
10894
|
+
const name = stringField(field, "name");
|
|
10895
|
+
if (!name) return [];
|
|
10896
|
+
return [[name, sampleValueForField(field)]];
|
|
10897
|
+
})
|
|
10898
|
+
);
|
|
10899
|
+
}
|
|
10397
10900
|
function stableStepIdForTool(toolId) {
|
|
10398
10901
|
return toolId.replace(/^[a-z0-9]+_/, "").replace(/[^a-z0-9_]+/gi, "_") || "tool_call";
|
|
10399
10902
|
}
|
|
@@ -10406,6 +10909,12 @@ function playResultExpression(entry) {
|
|
|
10406
10909
|
}
|
|
10407
10910
|
function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
10408
10911
|
const toolId = String(tool.toolId || requestedToolId);
|
|
10912
|
+
const inputFields = toolInputFieldsForDisplay(recordField(tool, "inputSchema", "input_schema"));
|
|
10913
|
+
const starterScript = seedToolListScript({
|
|
10914
|
+
toolId,
|
|
10915
|
+
payload: samplePayloadForInputFields(inputFields),
|
|
10916
|
+
rows: []
|
|
10917
|
+
});
|
|
10409
10918
|
const {
|
|
10410
10919
|
cost: _cost,
|
|
10411
10920
|
deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
|
|
@@ -10425,12 +10934,48 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
10425
10934
|
toolId,
|
|
10426
10935
|
provider: tool.provider,
|
|
10427
10936
|
displayName: tool.displayName,
|
|
10937
|
+
usageGuidance: usageGuidanceWithAccessDefaults(recordField(tool, "usageGuidance", "usage_guidance")),
|
|
10428
10938
|
runtimeOutputHelp: {
|
|
10429
|
-
contract: "tools describe shows
|
|
10939
|
+
contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
|
|
10940
|
+
getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
|
|
10941
|
+
rawToolResponse: "Use toolExecutionResult.toolResponse.raw for provider/tool-specific fields, fields in outputSchema that are not declared getters, and debugging.",
|
|
10942
|
+
invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
|
|
10430
10943
|
observeActualShape: `deepline tools execute ${toolId} --input '{...}' --json`,
|
|
10431
10944
|
observedOutput: `deepline tools execute ${toolId} --input '{...}' --json`,
|
|
10432
10945
|
forPlayGetterBugs: "Run the play, then inspect the emitted table commands from runs get. Use deepline db query against the run tables before editing getters.",
|
|
10433
10946
|
executeOutputFields: "tools execute JSON may include output_preview for this direct probe only; play debugging uses run tables."
|
|
10947
|
+
},
|
|
10948
|
+
starterScript: {
|
|
10949
|
+
path: starterScript.path,
|
|
10950
|
+
sourceCode: starterScript.sourceCode,
|
|
10951
|
+
projectDir: starterScript.projectDir,
|
|
10952
|
+
copyToProject: {
|
|
10953
|
+
macosLinux: starterScript.macCopyCommand,
|
|
10954
|
+
windowsPowerShell: starterScript.windowsCopyCommand
|
|
10955
|
+
}
|
|
10956
|
+
}
|
|
10957
|
+
};
|
|
10958
|
+
}
|
|
10959
|
+
function usageGuidanceWithAccessDefaults(usageGuidance) {
|
|
10960
|
+
if (Object.keys(usageGuidance).length === 0) return usageGuidance;
|
|
10961
|
+
const existingAccess = recordField(usageGuidance, "access");
|
|
10962
|
+
return {
|
|
10963
|
+
...usageGuidance,
|
|
10964
|
+
access: {
|
|
10965
|
+
extractedLists: {
|
|
10966
|
+
expression: "toolExecutionResult.extractedLists.<name>.get()",
|
|
10967
|
+
meaning: "Declared Deepline list extractors only."
|
|
10968
|
+
},
|
|
10969
|
+
extractedValues: {
|
|
10970
|
+
expression: "toolExecutionResult.extractedValues.<name>.get()",
|
|
10971
|
+
meaning: "Declared Deepline scalar extractors only."
|
|
10972
|
+
},
|
|
10973
|
+
rawToolResponse: {
|
|
10974
|
+
expression: "toolExecutionResult.toolResponse.raw",
|
|
10975
|
+
meaning: "Raw tool response for provider/tool-specific fields and debugging."
|
|
10976
|
+
},
|
|
10977
|
+
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.",
|
|
10978
|
+
...existingAccess
|
|
10434
10979
|
}
|
|
10435
10980
|
};
|
|
10436
10981
|
}
|
|
@@ -10647,6 +11192,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
10647
11192
|
(0, import_node_fs10.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
|
|
10648
11193
|
return {
|
|
10649
11194
|
path: scriptPath,
|
|
11195
|
+
sourceCode: script,
|
|
10650
11196
|
projectDir,
|
|
10651
11197
|
macCopyCommand: `mkdir -p ${shellQuote(projectDir)} && cp ${shellQuote(scriptPath)} ${shellQuote(`${projectDir}/${fileName}`)}`,
|
|
10652
11198
|
windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
|