deepline 0.2.71 → 0.2.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/client.ts +8 -2
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +67 -14
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +55 -14
- package/dist/cli/index.js +311 -29
- package/dist/cli/index.mjs +348 -58
- package/dist/index.d.mts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +43 -16
- package/dist/index.mjs +43 -16
- package/dist/plays/bundle-play-file.mjs +35 -14
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1044,7 +1044,7 @@ var SDK_RELEASE = {
|
|
|
1044
1044
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
1045
1045
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
1046
1046
|
// release keeps lazy paging semantics independent of row residency.
|
|
1047
|
-
version: "0.2.
|
|
1047
|
+
version: "0.2.73",
|
|
1048
1048
|
contracts: {
|
|
1049
1049
|
api: {
|
|
1050
1050
|
name: "sdk-http-api",
|
|
@@ -5992,9 +5992,10 @@ var DeeplineClient = class {
|
|
|
5992
5992
|
* console.log(`Total runs: ${detail.play.runCount}`);
|
|
5993
5993
|
* ```
|
|
5994
5994
|
*/
|
|
5995
|
-
async getPlay(name) {
|
|
5995
|
+
async getPlay(name, options) {
|
|
5996
5996
|
const encodedName = encodeURIComponent(name);
|
|
5997
|
-
|
|
5997
|
+
const query = options?.source ? `?include=source&revision=${encodeURIComponent(options.source)}` : "";
|
|
5998
|
+
return this.http.get(`/api/v2/plays/${encodedName}${query}`);
|
|
5998
5999
|
}
|
|
5999
6000
|
/**
|
|
6000
6001
|
* Get a normalized play description suitable for agents and CLIs.
|
|
@@ -18591,7 +18592,10 @@ async function assertCanonicalNamedPlayReference(client2, target, options = {})
|
|
|
18591
18592
|
const parsed = parseReferencedPlayTarget2(target);
|
|
18592
18593
|
let detail;
|
|
18593
18594
|
try {
|
|
18594
|
-
detail = await client2.getPlay(
|
|
18595
|
+
detail = await client2.getPlay(
|
|
18596
|
+
parsed.playName,
|
|
18597
|
+
options.source ? { source: options.source } : void 0
|
|
18598
|
+
);
|
|
18595
18599
|
} catch (error) {
|
|
18596
18600
|
if (isPlayNotFoundError(error)) {
|
|
18597
18601
|
throw await buildPlayReferenceNotFoundError({
|
|
@@ -18644,19 +18648,54 @@ function materializeRemotePlaySource(input2) {
|
|
|
18644
18648
|
if (isFileTarget(input2.target)) {
|
|
18645
18649
|
return null;
|
|
18646
18650
|
}
|
|
18647
|
-
|
|
18651
|
+
const entrySource = input2.source.files[input2.source.entryFile];
|
|
18652
|
+
if (!entrySource?.trim()) {
|
|
18648
18653
|
return null;
|
|
18649
18654
|
}
|
|
18655
|
+
const files = Object.entries(input2.source.files);
|
|
18656
|
+
if (files.length > 1) {
|
|
18657
|
+
if (!input2.outPath) {
|
|
18658
|
+
throw new Error(
|
|
18659
|
+
`Play ${input2.playName} has ${files.length} source files. Use --out <directory> to write the complete bundle.`
|
|
18660
|
+
);
|
|
18661
|
+
}
|
|
18662
|
+
const outputDirectory = (0, import_node_path14.resolve)(input2.outPath);
|
|
18663
|
+
let created = 0;
|
|
18664
|
+
let updated = 0;
|
|
18665
|
+
for (const [logicalPath, sourceCode] of files) {
|
|
18666
|
+
const outputPath2 = (0, import_node_path14.resolve)(outputDirectory, logicalPath);
|
|
18667
|
+
const outputRelativePath = (0, import_node_path14.relative)(outputDirectory, outputPath2);
|
|
18668
|
+
if (!outputRelativePath || outputRelativePath.startsWith("..") || (0, import_node_path14.isAbsolute)(outputRelativePath)) {
|
|
18669
|
+
throw new Error(
|
|
18670
|
+
`Refusing to materialize unsafe Play source path ${JSON.stringify(logicalPath)}.`
|
|
18671
|
+
);
|
|
18672
|
+
}
|
|
18673
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path14.dirname)(outputPath2), { recursive: true });
|
|
18674
|
+
if (!(0, import_node_fs12.existsSync)(outputPath2)) {
|
|
18675
|
+
(0, import_node_fs12.writeFileSync)(outputPath2, sourceCode, "utf-8");
|
|
18676
|
+
created += 1;
|
|
18677
|
+
} else if ((0, import_node_fs12.readFileSync)(outputPath2, "utf-8") !== sourceCode) {
|
|
18678
|
+
(0, import_node_fs12.writeFileSync)(outputPath2, sourceCode, "utf-8");
|
|
18679
|
+
updated += 1;
|
|
18680
|
+
}
|
|
18681
|
+
}
|
|
18682
|
+
return {
|
|
18683
|
+
path: outputDirectory,
|
|
18684
|
+
status: created > 0 ? "created" : updated > 0 ? "updated" : "unchanged",
|
|
18685
|
+
created: created > 0,
|
|
18686
|
+
fileCount: files.length
|
|
18687
|
+
};
|
|
18688
|
+
}
|
|
18650
18689
|
const outputPath = input2.outPath ?? defaultMaterializedPlayPath(input2.playName);
|
|
18651
18690
|
if ((0, import_node_fs12.existsSync)(outputPath)) {
|
|
18652
18691
|
const existingSource = (0, import_node_fs12.readFileSync)(outputPath, "utf-8");
|
|
18653
|
-
if (existingSource ===
|
|
18692
|
+
if (existingSource === entrySource) {
|
|
18654
18693
|
return { path: outputPath, status: "unchanged", created: false };
|
|
18655
18694
|
}
|
|
18656
|
-
(0, import_node_fs12.writeFileSync)(outputPath,
|
|
18695
|
+
(0, import_node_fs12.writeFileSync)(outputPath, entrySource, "utf-8");
|
|
18657
18696
|
return { path: outputPath, status: "updated", created: false };
|
|
18658
18697
|
}
|
|
18659
|
-
(0, import_node_fs12.writeFileSync)(outputPath,
|
|
18698
|
+
(0, import_node_fs12.writeFileSync)(outputPath, entrySource, "utf-8");
|
|
18660
18699
|
return { path: outputPath, status: "created", created: true };
|
|
18661
18700
|
}
|
|
18662
18701
|
function formatLoadedPlayMessage(materializedFile) {
|
|
@@ -22529,6 +22568,47 @@ ${PLAY_PUBLISH_USAGE}`
|
|
|
22529
22568
|
jsonOutput: argsWantJson(args)
|
|
22530
22569
|
};
|
|
22531
22570
|
}
|
|
22571
|
+
var PLAY_SAVE_USAGE = "Usage: deepline plays save <play-file.ts> [--expected-artifact <hash>] [--dry-run] [--json]";
|
|
22572
|
+
function parsePlaySaveOptions(args) {
|
|
22573
|
+
const target = args[0];
|
|
22574
|
+
if (!target) throw new Error(PLAY_SAVE_USAGE);
|
|
22575
|
+
if (target.startsWith("-")) {
|
|
22576
|
+
throw new Error(`${PLAY_SAVE_USAGE}
|
|
22577
|
+
The Play file is positional.`);
|
|
22578
|
+
}
|
|
22579
|
+
let expectedArtifactHash;
|
|
22580
|
+
let dryRun = false;
|
|
22581
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
22582
|
+
const arg = args[index];
|
|
22583
|
+
if (arg === "--expected-artifact") {
|
|
22584
|
+
expectedArtifactHash = args[++index];
|
|
22585
|
+
if (!expectedArtifactHash) {
|
|
22586
|
+
throw new Error("--expected-artifact requires an artifact hash.");
|
|
22587
|
+
}
|
|
22588
|
+
continue;
|
|
22589
|
+
}
|
|
22590
|
+
if (arg.startsWith("--expected-artifact=")) {
|
|
22591
|
+
expectedArtifactHash = arg.slice("--expected-artifact=".length);
|
|
22592
|
+
if (!expectedArtifactHash) {
|
|
22593
|
+
throw new Error("--expected-artifact requires an artifact hash.");
|
|
22594
|
+
}
|
|
22595
|
+
continue;
|
|
22596
|
+
}
|
|
22597
|
+
if (arg === "--dry-run") {
|
|
22598
|
+
dryRun = true;
|
|
22599
|
+
continue;
|
|
22600
|
+
}
|
|
22601
|
+
if (arg === "--json") continue;
|
|
22602
|
+
throw new Error(`Unknown option: ${arg}
|
|
22603
|
+
${PLAY_SAVE_USAGE}`);
|
|
22604
|
+
}
|
|
22605
|
+
return {
|
|
22606
|
+
target,
|
|
22607
|
+
expectedArtifactHash,
|
|
22608
|
+
dryRun,
|
|
22609
|
+
jsonOutput: argsWantJson(args)
|
|
22610
|
+
};
|
|
22611
|
+
}
|
|
22532
22612
|
function formatByteBudget(usedBytes, limitBytes) {
|
|
22533
22613
|
return `${usedBytes.toLocaleString()} B / ${limitBytes.toLocaleString()} B`;
|
|
22534
22614
|
}
|
|
@@ -23992,24 +24072,63 @@ async function handlePlayGet(args) {
|
|
|
23992
24072
|
const explicitJson = args.includes("--json");
|
|
23993
24073
|
const sourceOutput = args.includes("--source");
|
|
23994
24074
|
const jsonOutput = sourceOutput ? explicitJson : argsWantJson(args);
|
|
24075
|
+
const requestedRevisionFlags = [
|
|
24076
|
+
args.includes("--working"),
|
|
24077
|
+
args.includes("--live"),
|
|
24078
|
+
args.includes("--revision")
|
|
24079
|
+
].filter(Boolean).length;
|
|
24080
|
+
if (requestedRevisionFlags > 1) {
|
|
24081
|
+
console.error("Use only one of --working, --live, or --revision <number>.");
|
|
24082
|
+
return 2;
|
|
24083
|
+
}
|
|
24084
|
+
let sourceSelector = "working";
|
|
24085
|
+
if (args.includes("--live")) {
|
|
24086
|
+
sourceSelector = "live";
|
|
24087
|
+
}
|
|
23995
24088
|
let outPath = null;
|
|
24089
|
+
let requestedVersion = null;
|
|
23996
24090
|
for (let index = 1; index < args.length; index += 1) {
|
|
23997
24091
|
const arg = args[index];
|
|
23998
24092
|
if (arg === "--out" && args[index + 1]) {
|
|
23999
24093
|
outPath = (0, import_node_path14.resolve)(args[++index]);
|
|
24000
24094
|
}
|
|
24095
|
+
if (arg === "--revision") {
|
|
24096
|
+
const rawVersion = args[++index];
|
|
24097
|
+
const version = Number(rawVersion);
|
|
24098
|
+
if (!rawVersion || !Number.isInteger(version) || version < 1) {
|
|
24099
|
+
console.error("--revision must be a positive integer.");
|
|
24100
|
+
return 2;
|
|
24101
|
+
}
|
|
24102
|
+
requestedVersion = version;
|
|
24103
|
+
}
|
|
24104
|
+
}
|
|
24105
|
+
if (requestedVersion !== null) {
|
|
24106
|
+
sourceSelector = `version:${requestedVersion}`;
|
|
24107
|
+
}
|
|
24108
|
+
if (requestedRevisionFlags > 0 && !sourceOutput && !outPath) {
|
|
24109
|
+
console.error(
|
|
24110
|
+
"--working, --live, and --revision only apply when reading source with --source or --out."
|
|
24111
|
+
);
|
|
24112
|
+
return 2;
|
|
24001
24113
|
}
|
|
24002
24114
|
const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs12.readFileSync)((0, import_node_path14.resolve)(target), "utf-8"), (0, import_node_path14.resolve)(target)) : parseReferencedPlayTarget2(target).playName;
|
|
24003
|
-
const
|
|
24004
|
-
|
|
24005
|
-
});
|
|
24006
|
-
const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
|
|
24007
|
-
const materializedFile = outPath ? materializeRemotePlaySource({
|
|
24008
|
-
target,
|
|
24115
|
+
const includeSource = sourceOutput || outPath !== null;
|
|
24116
|
+
const detail = isFileTarget(target) ? await client2.getPlay(
|
|
24009
24117
|
playName,
|
|
24010
|
-
|
|
24011
|
-
|
|
24012
|
-
|
|
24118
|
+
includeSource ? { source: sourceSelector } : void 0
|
|
24119
|
+
) : await assertCanonicalNamedPlayReference(client2, target, {
|
|
24120
|
+
command: "get",
|
|
24121
|
+
...includeSource ? { source: sourceSelector } : {}
|
|
24122
|
+
});
|
|
24123
|
+
const source = detail.source;
|
|
24124
|
+
const resolvedSource = source?.files[source.entryFile] ?? "";
|
|
24125
|
+
let materializedFile = null;
|
|
24126
|
+
try {
|
|
24127
|
+
materializedFile = outPath && source ? materializeRemotePlaySource({ target, playName, source, outPath }) : null;
|
|
24128
|
+
} catch (error) {
|
|
24129
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
24130
|
+
return 2;
|
|
24131
|
+
}
|
|
24013
24132
|
const loadedMessage = materializedFile ? formatLoadedPlayMessage(materializedFile) : null;
|
|
24014
24133
|
if (jsonOutput) {
|
|
24015
24134
|
process.stdout.write(
|
|
@@ -24030,14 +24149,20 @@ async function handlePlayGet(args) {
|
|
|
24030
24149
|
return 0;
|
|
24031
24150
|
}
|
|
24032
24151
|
if (sourceOutput) {
|
|
24033
|
-
if (!resolvedSource.trim()) {
|
|
24152
|
+
if (!source || !resolvedSource.trim()) {
|
|
24034
24153
|
console.error(`No source code available for ${playName}.`);
|
|
24035
|
-
return
|
|
24154
|
+
return 4;
|
|
24036
24155
|
}
|
|
24037
24156
|
if (materializedFile) {
|
|
24038
24157
|
console.log(loadedMessage);
|
|
24039
24158
|
return 0;
|
|
24040
24159
|
}
|
|
24160
|
+
if (Object.keys(source.files).length > 1) {
|
|
24161
|
+
console.error(
|
|
24162
|
+
`Play ${playName} has ${Object.keys(source.files).length} source files. Use --out <directory> to write the complete bundle.`
|
|
24163
|
+
);
|
|
24164
|
+
return 2;
|
|
24165
|
+
}
|
|
24041
24166
|
process.stdout.write(resolvedSource);
|
|
24042
24167
|
if (!resolvedSource.endsWith("\n")) {
|
|
24043
24168
|
process.stdout.write("\n");
|
|
@@ -24559,6 +24684,128 @@ async function handlePlayDescribe(args) {
|
|
|
24559
24684
|
printPlayDescription(play);
|
|
24560
24685
|
return 0;
|
|
24561
24686
|
}
|
|
24687
|
+
async function handlePlaySave(args) {
|
|
24688
|
+
let options;
|
|
24689
|
+
try {
|
|
24690
|
+
options = parsePlaySaveOptions(args);
|
|
24691
|
+
} catch (error) {
|
|
24692
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
24693
|
+
return 2;
|
|
24694
|
+
}
|
|
24695
|
+
if (!isFileTarget(options.target)) {
|
|
24696
|
+
console.error(
|
|
24697
|
+
"plays save requires a local .play.ts file. Use plays publish <play-name> to promote an existing saved revision."
|
|
24698
|
+
);
|
|
24699
|
+
return 2;
|
|
24700
|
+
}
|
|
24701
|
+
let graph;
|
|
24702
|
+
try {
|
|
24703
|
+
graph = await traceCliSpan(
|
|
24704
|
+
"cli.play_save_bundle_graph",
|
|
24705
|
+
{ targetKind: "file" },
|
|
24706
|
+
() => collectBundledPlayGraph((0, import_node_path14.resolve)(options.target))
|
|
24707
|
+
);
|
|
24708
|
+
assertBundledPlayGraphDescriptions(graph);
|
|
24709
|
+
} catch (error) {
|
|
24710
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
24711
|
+
return 7;
|
|
24712
|
+
}
|
|
24713
|
+
const playName = graph.root.playName ?? extractPlayName(graph.root.sourceCode, graph.root.filePath);
|
|
24714
|
+
const artifactHash = graph.root.artifact.artifactHash;
|
|
24715
|
+
if (options.expectedArtifactHash && options.expectedArtifactHash !== artifactHash) {
|
|
24716
|
+
const result = {
|
|
24717
|
+
ok: false,
|
|
24718
|
+
code: "PLAY_ARTIFACT_HASH_MISMATCH",
|
|
24719
|
+
message: "Refusing to save: the local file no longer produces the artifact checked earlier.",
|
|
24720
|
+
expectedArtifactHash: options.expectedArtifactHash,
|
|
24721
|
+
currentArtifactHash: artifactHash,
|
|
24722
|
+
next: `deepline plays check ${shellQuote2(options.target)}`
|
|
24723
|
+
};
|
|
24724
|
+
if (options.jsonOutput) {
|
|
24725
|
+
process.stdout.write(`${JSON.stringify(result)}
|
|
24726
|
+
`);
|
|
24727
|
+
} else {
|
|
24728
|
+
console.error(result.message);
|
|
24729
|
+
console.error(` checked artifact: ${result.expectedArtifactHash}`);
|
|
24730
|
+
console.error(` current artifact: ${result.currentArtifactHash}`);
|
|
24731
|
+
console.error(` run: ${result.next}`);
|
|
24732
|
+
}
|
|
24733
|
+
return 7;
|
|
24734
|
+
}
|
|
24735
|
+
const dryRun = {
|
|
24736
|
+
ok: true,
|
|
24737
|
+
dryRun: true,
|
|
24738
|
+
name: playName,
|
|
24739
|
+
sourcePath: graph.root.filePath,
|
|
24740
|
+
sourceHash: graph.root.artifact.sourceHash,
|
|
24741
|
+
artifactHash,
|
|
24742
|
+
graphHash: graph.root.artifact.graphHash,
|
|
24743
|
+
sourceFileCount: Object.keys(graph.root.sourceFiles).length,
|
|
24744
|
+
plannedMutation: "save or update the mutable working draft; does not change the live revision"
|
|
24745
|
+
};
|
|
24746
|
+
if (options.dryRun) {
|
|
24747
|
+
if (options.jsonOutput) {
|
|
24748
|
+
process.stdout.write(`${JSON.stringify(dryRun)}
|
|
24749
|
+
`);
|
|
24750
|
+
} else {
|
|
24751
|
+
console.log(`Dry run: ${playName}`);
|
|
24752
|
+
console.log(` source: ${dryRun.sourceHash}`);
|
|
24753
|
+
console.log(` artifact: ${dryRun.artifactHash}`);
|
|
24754
|
+
console.log(` would: ${dryRun.plannedMutation}`);
|
|
24755
|
+
}
|
|
24756
|
+
return 0;
|
|
24757
|
+
}
|
|
24758
|
+
const client2 = new DeeplineClient();
|
|
24759
|
+
try {
|
|
24760
|
+
await traceCliSpan(
|
|
24761
|
+
"cli.play_save_compile_manifests",
|
|
24762
|
+
{ targetKind: "file", nodeCount: graph.nodes.size },
|
|
24763
|
+
() => compileBundledPlayGraphManifests(client2, graph)
|
|
24764
|
+
);
|
|
24765
|
+
const saved = await traceCliSpan(
|
|
24766
|
+
"cli.play_save_register_draft",
|
|
24767
|
+
{ targetKind: "file", playName, artifactHash },
|
|
24768
|
+
() => client2.registerPlayArtifact({
|
|
24769
|
+
name: playName,
|
|
24770
|
+
sourceCode: graph.root.sourceCode,
|
|
24771
|
+
sourceFiles: graph.root.sourceFiles,
|
|
24772
|
+
description: graph.root.playDescription ?? void 0,
|
|
24773
|
+
artifact: graph.root.artifact,
|
|
24774
|
+
compilerManifest: requireCompilerManifest(graph.root),
|
|
24775
|
+
publish: false
|
|
24776
|
+
})
|
|
24777
|
+
);
|
|
24778
|
+
const result = {
|
|
24779
|
+
success: true,
|
|
24780
|
+
name: playName,
|
|
24781
|
+
draft: true,
|
|
24782
|
+
revisionId: saved.revisionId ?? null,
|
|
24783
|
+
version: saved.version ?? null,
|
|
24784
|
+
sourceHash: graph.root.artifact.sourceHash,
|
|
24785
|
+
artifactHash,
|
|
24786
|
+
graphHash: graph.root.artifact.graphHash,
|
|
24787
|
+
artifactStorageKey: saved.artifactStorageKey,
|
|
24788
|
+
next: {
|
|
24789
|
+
publish: `deepline plays publish ${shellQuote2(options.target)} --expected-artifact ${artifactHash}`,
|
|
24790
|
+
get: `deepline plays get ${playName} --source --out ./${playName}/ --working`
|
|
24791
|
+
}
|
|
24792
|
+
};
|
|
24793
|
+
if (options.jsonOutput) {
|
|
24794
|
+
process.stdout.write(`${JSON.stringify(result)}
|
|
24795
|
+
`);
|
|
24796
|
+
} else {
|
|
24797
|
+
console.log(
|
|
24798
|
+
`\u2713 Saved ${playName} working draft as v${result.version ?? "?"}`
|
|
24799
|
+
);
|
|
24800
|
+
console.log(" Live revision unchanged.");
|
|
24801
|
+
console.log(` publish: ${result.next.publish}`);
|
|
24802
|
+
}
|
|
24803
|
+
return 0;
|
|
24804
|
+
} catch (error) {
|
|
24805
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
24806
|
+
return 5;
|
|
24807
|
+
}
|
|
24808
|
+
}
|
|
24562
24809
|
async function handlePlayPublish(args) {
|
|
24563
24810
|
let options;
|
|
24564
24811
|
try {
|
|
@@ -25089,7 +25336,9 @@ Pass-through input flags:
|
|
|
25089
25336
|
]);
|
|
25090
25337
|
});
|
|
25091
25338
|
registerPlayBootstrapCommand(play);
|
|
25092
|
-
play.command("get <target>").description(
|
|
25339
|
+
play.command("get <target>").description(
|
|
25340
|
+
"Fetch full play details or materialize a saved source bundle."
|
|
25341
|
+
).addHelpText(
|
|
25093
25342
|
"after",
|
|
25094
25343
|
`
|
|
25095
25344
|
Notes:
|
|
@@ -25101,17 +25350,24 @@ Examples:
|
|
|
25101
25350
|
deepline plays get prebuilt/person-linkedin-to-email
|
|
25102
25351
|
deepline plays get prebuilt/person-linkedin-to-email --json | jq '.play.liveRevision'
|
|
25103
25352
|
deepline plays get prebuilt/name-and-domain-to-email-waterfall-batch --source > email-waterfall.play.ts
|
|
25104
|
-
deepline plays get
|
|
25353
|
+
deepline plays get my-play --source --out ./my-play/ --working
|
|
25354
|
+
deepline plays get my-play --source --out ./my-play-v3/ --revision 3
|
|
25105
25355
|
`
|
|
25106
25356
|
).option("--json", "Emit JSON output. Also automatic when stdout is piped").option(
|
|
25107
25357
|
"--source",
|
|
25108
|
-
"
|
|
25109
|
-
).option(
|
|
25358
|
+
"Read source; prints single-file Plays or combines with --out to write the full bundle"
|
|
25359
|
+
).option(
|
|
25360
|
+
"--out <path>",
|
|
25361
|
+
"Write source to a file or, for multi-file Plays, a directory"
|
|
25362
|
+
).option("--working", "Read the current working draft source (default)").option("--live", "Read the live revision source").option("--revision <number>", "Read a specific revision source").action(async (target, options) => {
|
|
25110
25363
|
process.exitCode = await handlePlayGet([
|
|
25111
25364
|
target,
|
|
25112
25365
|
...options.json ? ["--json"] : [],
|
|
25113
25366
|
...options.source ? ["--source"] : [],
|
|
25114
|
-
...options.out ? ["--out", options.out] : []
|
|
25367
|
+
...options.out ? ["--out", options.out] : [],
|
|
25368
|
+
...options.working ? ["--working"] : [],
|
|
25369
|
+
...options.live ? ["--live"] : [],
|
|
25370
|
+
...options.revision ? ["--revision", options.revision] : []
|
|
25115
25371
|
]);
|
|
25116
25372
|
});
|
|
25117
25373
|
play.command("list").description("List saved and prebuilt plays.").addHelpText(
|
|
@@ -25246,6 +25502,32 @@ Examples:
|
|
|
25246
25502
|
...options.json ? ["--json"] : []
|
|
25247
25503
|
]);
|
|
25248
25504
|
});
|
|
25505
|
+
play.command("save <file>").description(
|
|
25506
|
+
"Save or update a local Play working draft without publishing it."
|
|
25507
|
+
).addHelpText(
|
|
25508
|
+
"after",
|
|
25509
|
+
`
|
|
25510
|
+
Notes:
|
|
25511
|
+
Mutates cloud state, but does not change the live revision or active triggers.
|
|
25512
|
+
Repeated saves update one working draft. Publishing it, or running a named
|
|
25513
|
+
draft revision, freezes it; the next save starts a new revision.
|
|
25514
|
+
|
|
25515
|
+
Examples:
|
|
25516
|
+
deepline plays save ./company-research.play.ts
|
|
25517
|
+
deepline plays save ./company-research.play.ts --dry-run --json
|
|
25518
|
+
deepline plays publish ./company-research.play.ts
|
|
25519
|
+
`
|
|
25520
|
+
).option("--expected-artifact <hash>", "Require the checked artifact hash").option(
|
|
25521
|
+
"--dry-run",
|
|
25522
|
+
"Bundle and show the planned draft save without mutation"
|
|
25523
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (file, options) => {
|
|
25524
|
+
process.exitCode = await handlePlaySave([
|
|
25525
|
+
file,
|
|
25526
|
+
...options.expectedArtifact ? ["--expected-artifact", options.expectedArtifact] : [],
|
|
25527
|
+
...options.dryRun ? ["--dry-run"] : [],
|
|
25528
|
+
...options.json ? ["--json"] : []
|
|
25529
|
+
]);
|
|
25530
|
+
});
|
|
25249
25531
|
const addPublishHelp = (command) => command.addHelpText(
|
|
25250
25532
|
"after",
|
|
25251
25533
|
`
|
|
@@ -33757,16 +34039,16 @@ Examples:
|
|
|
33757
34039
|
// src/cli/getting-started.ts
|
|
33758
34040
|
var DEEPLINE_GTM_SKILL = "/deepline-gtm";
|
|
33759
34041
|
var DEEPLINE_GTM_STARTER_PROMPTS = [
|
|
34042
|
+
{
|
|
34043
|
+
id: "competitor-tracking",
|
|
34044
|
+
title: "Competitor tracking",
|
|
34045
|
+
prompt: "/deepline-gtm Track competitors of my company. Use my business email domain when available; otherwise ask for my company name."
|
|
34046
|
+
},
|
|
33760
34047
|
{
|
|
33761
34048
|
id: "contact-email-enrichment",
|
|
33762
34049
|
title: "Contact email enrichment",
|
|
33763
34050
|
prompt: "/deepline-gtm Find 10 CTOs at B2B SaaS companies and enrich them with email addresses."
|
|
33764
34051
|
},
|
|
33765
|
-
{
|
|
33766
|
-
id: "company-signal-enrichment",
|
|
33767
|
-
title: "Company signal enrichment",
|
|
33768
|
-
prompt: "/deepline-gtm Enrich these company domains with employee count, funding, and recent hiring signals."
|
|
33769
|
-
},
|
|
33770
34052
|
{
|
|
33771
34053
|
id: "decision-maker-discovery",
|
|
33772
34054
|
title: "Decision-maker discovery",
|