deepline 0.1.105 → 0.1.107
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 +417 -36
- package/dist/cli/index.mjs +413 -32
- package/dist/index.js +14 -3
- package/dist/index.mjs +14 -3
- package/dist/repo/sdk/src/release.ts +48 -7
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -241,12 +241,23 @@ var SDK_RELEASE = {
|
|
|
241
241
|
// 0.1.104 ships postgres_fast suspension/billing parity and runtime worker hardening.
|
|
242
242
|
// 0.1.105 ships the billing catalog surface: billing plans, subscribe,
|
|
243
243
|
// subscription status/cancel, invoices, and the client.billing namespace.
|
|
244
|
-
|
|
244
|
+
// 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
|
|
245
|
+
// 0.1.107 ships the v2 quickstart command, the deepline-plays-quickstart
|
|
246
|
+
// skill on the sdk sync surface, and the people-search-to-email prebuilt.
|
|
247
|
+
version: "0.1.107",
|
|
245
248
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
246
249
|
supportPolicy: {
|
|
247
|
-
latest: "0.1.
|
|
250
|
+
latest: "0.1.107",
|
|
248
251
|
minimumSupported: "0.1.53",
|
|
249
|
-
deprecatedBelow: "0.1.53"
|
|
252
|
+
deprecatedBelow: "0.1.53",
|
|
253
|
+
commandMinimumSupported: [
|
|
254
|
+
{
|
|
255
|
+
command: "enrich",
|
|
256
|
+
minimumSupported: "0.1.106",
|
|
257
|
+
reason: "Older SDK CLI enrich generated stale play source for the current dataset API."
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
autoUpdatePatchLag: 2
|
|
250
261
|
}
|
|
251
262
|
};
|
|
252
263
|
|
|
@@ -3168,7 +3179,7 @@ function shouldSkipCompatibilityCheck() {
|
|
|
3168
3179
|
const value = process.env.DEEPLINE_SKIP_SDK_COMPAT_CHECK?.trim().toLowerCase();
|
|
3169
3180
|
return value === "1" || value === "true" || value === "yes";
|
|
3170
3181
|
}
|
|
3171
|
-
async function checkSdkCompatibility(baseUrl) {
|
|
3182
|
+
async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
3172
3183
|
if (shouldSkipCompatibilityCheck()) {
|
|
3173
3184
|
return { response: null, error: null };
|
|
3174
3185
|
}
|
|
@@ -3177,6 +3188,9 @@ async function checkSdkCompatibility(baseUrl) {
|
|
|
3177
3188
|
try {
|
|
3178
3189
|
const url = new URL("/api/v2/sdk/compat", baseUrl);
|
|
3179
3190
|
url.searchParams.set("version", SDK_VERSION);
|
|
3191
|
+
if (options.command?.trim()) {
|
|
3192
|
+
url.searchParams.set("command", options.command.trim());
|
|
3193
|
+
}
|
|
3180
3194
|
const response = await fetch(url, {
|
|
3181
3195
|
method: "GET",
|
|
3182
3196
|
headers: {
|
|
@@ -3197,9 +3211,8 @@ async function checkSdkCompatibility(baseUrl) {
|
|
|
3197
3211
|
clearTimeout(timeout);
|
|
3198
3212
|
}
|
|
3199
3213
|
}
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
if (error || !response) {
|
|
3214
|
+
function enforceSdkCompatibilityResponse(response) {
|
|
3215
|
+
if (!response) {
|
|
3203
3216
|
return;
|
|
3204
3217
|
}
|
|
3205
3218
|
if (response.update_required) {
|
|
@@ -12271,8 +12284,13 @@ function exportableSheetRow(row) {
|
|
|
12271
12284
|
function mergeExportColumns(preferredColumns, rows) {
|
|
12272
12285
|
const columns = [];
|
|
12273
12286
|
const seen = /* @__PURE__ */ new Set();
|
|
12287
|
+
const hasActualColumn = (column) => rows.some((row) => Object.prototype.hasOwnProperty.call(row, column));
|
|
12288
|
+
const hasCanonicalReplacement = (column) => {
|
|
12289
|
+
const canonical = sqlSafeExportColumnName(column);
|
|
12290
|
+
return canonical !== column && hasActualColumn(canonical);
|
|
12291
|
+
};
|
|
12274
12292
|
for (const column of preferredColumns) {
|
|
12275
|
-
if (!column || seen.has(column)) {
|
|
12293
|
+
if (!column || seen.has(column) || hasCanonicalReplacement(column)) {
|
|
12276
12294
|
continue;
|
|
12277
12295
|
}
|
|
12278
12296
|
seen.add(column);
|
|
@@ -12280,7 +12298,7 @@ function mergeExportColumns(preferredColumns, rows) {
|
|
|
12280
12298
|
}
|
|
12281
12299
|
for (const row of rows) {
|
|
12282
12300
|
for (const column of Object.keys(row)) {
|
|
12283
|
-
if (seen.has(column)) {
|
|
12301
|
+
if (seen.has(column) || hasCanonicalReplacement(column)) {
|
|
12284
12302
|
continue;
|
|
12285
12303
|
}
|
|
12286
12304
|
seen.add(column);
|
|
@@ -12289,6 +12307,11 @@ function mergeExportColumns(preferredColumns, rows) {
|
|
|
12289
12307
|
}
|
|
12290
12308
|
return columns;
|
|
12291
12309
|
}
|
|
12310
|
+
function sqlSafeExportColumnName(id) {
|
|
12311
|
+
const normalized = id.trim().replace(/\.+/g, "__").replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
12312
|
+
const safe = normalized || "column";
|
|
12313
|
+
return /^[A-Za-z_]/.test(safe) ? safe : `c_${safe}`;
|
|
12314
|
+
}
|
|
12292
12315
|
async function fetchBackingDatasetRows(input2) {
|
|
12293
12316
|
const playName = extractRunPlayName(input2.status);
|
|
12294
12317
|
const tableNamespace = input2.rowsInfo.tableNamespace?.trim();
|
|
@@ -17940,6 +17963,244 @@ Examples:
|
|
|
17940
17963
|
).option("--org-id <id>", "Switch using an explicit organization id").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgSwitch);
|
|
17941
17964
|
}
|
|
17942
17965
|
|
|
17966
|
+
// src/cli/commands/quickstart.ts
|
|
17967
|
+
var import_node_child_process = require("child_process");
|
|
17968
|
+
var import_node_crypto4 = require("crypto");
|
|
17969
|
+
var import_node_http = require("http");
|
|
17970
|
+
var EXIT_OK2 = 0;
|
|
17971
|
+
var EXIT_AUTH2 = 1;
|
|
17972
|
+
var EXIT_SERVER3 = 2;
|
|
17973
|
+
var MAX_PROMPT_LENGTH = 8e3;
|
|
17974
|
+
var MAX_BODY_BYTES = 64 * 1024;
|
|
17975
|
+
function shellQuote(arg) {
|
|
17976
|
+
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
17977
|
+
}
|
|
17978
|
+
function hasClaudeBinary() {
|
|
17979
|
+
try {
|
|
17980
|
+
const result = (0, import_node_child_process.spawnSync)("claude", ["--version"], {
|
|
17981
|
+
stdio: "ignore",
|
|
17982
|
+
shell: process.platform === "win32"
|
|
17983
|
+
});
|
|
17984
|
+
return result.status === 0;
|
|
17985
|
+
} catch {
|
|
17986
|
+
return false;
|
|
17987
|
+
}
|
|
17988
|
+
}
|
|
17989
|
+
function launchClaude(prompt) {
|
|
17990
|
+
return new Promise((resolve16) => {
|
|
17991
|
+
const child = (0, import_node_child_process.spawn)("claude", [prompt], {
|
|
17992
|
+
stdio: "inherit",
|
|
17993
|
+
shell: process.platform === "win32"
|
|
17994
|
+
});
|
|
17995
|
+
child.on("error", () => resolve16(EXIT_SERVER3));
|
|
17996
|
+
child.on("close", (status) => resolve16(status ?? EXIT_OK2));
|
|
17997
|
+
});
|
|
17998
|
+
}
|
|
17999
|
+
function readBody(req) {
|
|
18000
|
+
return new Promise((resolve16, reject) => {
|
|
18001
|
+
let raw = "";
|
|
18002
|
+
req.setEncoding("utf8");
|
|
18003
|
+
req.on("data", (chunk) => {
|
|
18004
|
+
raw += chunk;
|
|
18005
|
+
if (raw.length > MAX_BODY_BYTES) {
|
|
18006
|
+
reject(new Error("Request body too large."));
|
|
18007
|
+
req.destroy();
|
|
18008
|
+
}
|
|
18009
|
+
});
|
|
18010
|
+
req.on("end", () => resolve16(raw));
|
|
18011
|
+
req.on("error", reject);
|
|
18012
|
+
});
|
|
18013
|
+
}
|
|
18014
|
+
function writeJson(res, status, payload) {
|
|
18015
|
+
res.writeHead(status, { "content-type": "application/json" });
|
|
18016
|
+
res.end(JSON.stringify(payload));
|
|
18017
|
+
}
|
|
18018
|
+
function startCallbackServer(input2) {
|
|
18019
|
+
const server = (0, import_node_http.createServer)((req, res) => {
|
|
18020
|
+
res.setHeader("Access-Control-Allow-Origin", req.headers.origin ?? "*");
|
|
18021
|
+
res.setHeader("Vary", "Origin");
|
|
18022
|
+
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
18023
|
+
res.setHeader("Access-Control-Allow-Headers", "content-type");
|
|
18024
|
+
res.setHeader("Access-Control-Allow-Private-Network", "true");
|
|
18025
|
+
res.setHeader("Access-Control-Max-Age", "600");
|
|
18026
|
+
if (req.method === "OPTIONS") {
|
|
18027
|
+
res.writeHead(204);
|
|
18028
|
+
res.end();
|
|
18029
|
+
return;
|
|
18030
|
+
}
|
|
18031
|
+
if (req.method !== "POST" || req.url !== "/submit") {
|
|
18032
|
+
writeJson(res, 404, { error: "Not found." });
|
|
18033
|
+
return;
|
|
18034
|
+
}
|
|
18035
|
+
void readBody(req).then((raw) => {
|
|
18036
|
+
let body = null;
|
|
18037
|
+
try {
|
|
18038
|
+
body = JSON.parse(raw);
|
|
18039
|
+
} catch {
|
|
18040
|
+
body = null;
|
|
18041
|
+
}
|
|
18042
|
+
const state = typeof body?.state === "string" ? body.state : "";
|
|
18043
|
+
const prompt = typeof body?.prompt === "string" ? body.prompt.trim() : "";
|
|
18044
|
+
const workflowId = typeof body?.workflow_id === "string" && body.workflow_id.trim() ? body.workflow_id.trim() : null;
|
|
18045
|
+
if (!state || state !== input2.state) {
|
|
18046
|
+
writeJson(res, 403, { error: "Invalid quickstart state token." });
|
|
18047
|
+
return;
|
|
18048
|
+
}
|
|
18049
|
+
if (!prompt) {
|
|
18050
|
+
writeJson(res, 400, { error: "prompt is required." });
|
|
18051
|
+
return;
|
|
18052
|
+
}
|
|
18053
|
+
if (prompt.length > MAX_PROMPT_LENGTH) {
|
|
18054
|
+
writeJson(res, 400, {
|
|
18055
|
+
error: `prompt exceeds ${MAX_PROMPT_LENGTH} characters.`
|
|
18056
|
+
});
|
|
18057
|
+
return;
|
|
18058
|
+
}
|
|
18059
|
+
writeJson(res, 200, { ok: true });
|
|
18060
|
+
setImmediate(() => input2.onSelection({ prompt, workflowId }));
|
|
18061
|
+
}).catch(() => {
|
|
18062
|
+
writeJson(res, 400, { error: "Invalid request body." });
|
|
18063
|
+
});
|
|
18064
|
+
});
|
|
18065
|
+
return new Promise((resolve16, reject) => {
|
|
18066
|
+
server.once("error", reject);
|
|
18067
|
+
server.listen(0, "127.0.0.1", () => {
|
|
18068
|
+
const address = server.address();
|
|
18069
|
+
if (!address || typeof address === "string") {
|
|
18070
|
+
reject(new Error("Failed to bind quickstart callback server."));
|
|
18071
|
+
return;
|
|
18072
|
+
}
|
|
18073
|
+
resolve16({ server, port: address.port });
|
|
18074
|
+
});
|
|
18075
|
+
});
|
|
18076
|
+
}
|
|
18077
|
+
async function handleQuickstart(options) {
|
|
18078
|
+
const jsonOutput = shouldEmitJson(options.json === true);
|
|
18079
|
+
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
18080
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
18081
|
+
let apiKey = resolveApiKeyForBaseUrl(baseUrl);
|
|
18082
|
+
if (!apiKey) {
|
|
18083
|
+
if (interactive) {
|
|
18084
|
+
console.error("Not connected yet \u2014 registering this device first.");
|
|
18085
|
+
const registerExit = await handleRegister([]);
|
|
18086
|
+
if (registerExit !== EXIT_OK2) return registerExit;
|
|
18087
|
+
apiKey = resolveApiKeyForBaseUrl(baseUrl);
|
|
18088
|
+
}
|
|
18089
|
+
if (!apiKey) {
|
|
18090
|
+
console.error("Not connected. Run: deepline auth register");
|
|
18091
|
+
return EXIT_AUTH2;
|
|
18092
|
+
}
|
|
18093
|
+
}
|
|
18094
|
+
const state = (0, import_node_crypto4.randomBytes)(32).toString("hex");
|
|
18095
|
+
let resolveSelection;
|
|
18096
|
+
const selectionPromise = new Promise((resolve16) => {
|
|
18097
|
+
resolveSelection = resolve16;
|
|
18098
|
+
});
|
|
18099
|
+
let callback;
|
|
18100
|
+
try {
|
|
18101
|
+
callback = await startCallbackServer({
|
|
18102
|
+
state,
|
|
18103
|
+
onSelection: (selection) => resolveSelection(selection)
|
|
18104
|
+
});
|
|
18105
|
+
} catch (error) {
|
|
18106
|
+
console.error(
|
|
18107
|
+
`Could not start the local quickstart listener: ${error instanceof Error ? error.message : String(error)}`
|
|
18108
|
+
);
|
|
18109
|
+
return EXIT_SERVER3;
|
|
18110
|
+
}
|
|
18111
|
+
const quickstartUrl = `${baseUrl}/cli/quickstart?cb=${callback.port}&state=${state}`;
|
|
18112
|
+
console.error(" Opening the recipe picker in your browser.");
|
|
18113
|
+
console.error(` If it didn't open, cmd+click: ${quickstartUrl}`);
|
|
18114
|
+
if (options.open !== false) {
|
|
18115
|
+
openInBrowser(quickstartUrl);
|
|
18116
|
+
}
|
|
18117
|
+
const timeoutSeconds = Number.parseInt(options.timeout ?? "300", 10);
|
|
18118
|
+
const timeoutMs = (Number.isFinite(timeoutSeconds) && timeoutSeconds > 0 ? timeoutSeconds : 300) * 1e3;
|
|
18119
|
+
const timeoutHandle = setTimeout(
|
|
18120
|
+
() => resolveSelection("timeout"),
|
|
18121
|
+
timeoutMs
|
|
18122
|
+
);
|
|
18123
|
+
const progress = createCliProgress(!jsonOutput);
|
|
18124
|
+
progress.phase("waiting for your pick in the browser (Ctrl+C to skip)");
|
|
18125
|
+
const onSigint = () => resolveSelection("sigint");
|
|
18126
|
+
process.once("SIGINT", onSigint);
|
|
18127
|
+
const outcome = await selectionPromise;
|
|
18128
|
+
clearTimeout(timeoutHandle);
|
|
18129
|
+
process.removeListener("SIGINT", onSigint);
|
|
18130
|
+
callback.server.close();
|
|
18131
|
+
if (outcome === "sigint") {
|
|
18132
|
+
progress.fail();
|
|
18133
|
+
console.error("\nSkipped \u2014 run `deepline quickstart` anytime.");
|
|
18134
|
+
return EXIT_OK2;
|
|
18135
|
+
}
|
|
18136
|
+
if (outcome === "timeout") {
|
|
18137
|
+
progress.fail();
|
|
18138
|
+
console.error(
|
|
18139
|
+
"Timed out waiting for a selection. Run: deepline quickstart"
|
|
18140
|
+
);
|
|
18141
|
+
return EXIT_AUTH2;
|
|
18142
|
+
}
|
|
18143
|
+
progress.complete();
|
|
18144
|
+
const { prompt, workflowId } = outcome;
|
|
18145
|
+
const claudeCommand = `claude ${shellQuote(prompt)}`;
|
|
18146
|
+
const claudeAvailable = hasClaudeBinary();
|
|
18147
|
+
const willLaunch = options.launch !== false && !jsonOutput && interactive && claudeAvailable;
|
|
18148
|
+
printCommandEnvelope(
|
|
18149
|
+
{
|
|
18150
|
+
status: "submitted",
|
|
18151
|
+
workflowId,
|
|
18152
|
+
prompt,
|
|
18153
|
+
claudeCommand,
|
|
18154
|
+
url: quickstartUrl,
|
|
18155
|
+
launched: willLaunch,
|
|
18156
|
+
render: {
|
|
18157
|
+
sections: [
|
|
18158
|
+
{
|
|
18159
|
+
title: "quickstart",
|
|
18160
|
+
lines: [
|
|
18161
|
+
...workflowId ? [`Recipe: ${workflowId}`] : [],
|
|
18162
|
+
willLaunch ? "Launching Claude Code with your recipe..." : claudeAvailable ? "Run the command below to start your recipe." : "Claude Code not found. Install it (https://code.claude.com/docs/en/overview), then run the command below."
|
|
18163
|
+
]
|
|
18164
|
+
}
|
|
18165
|
+
],
|
|
18166
|
+
actions: [{ label: "Run", command: claudeCommand }]
|
|
18167
|
+
}
|
|
18168
|
+
},
|
|
18169
|
+
{ json: jsonOutput }
|
|
18170
|
+
);
|
|
18171
|
+
if (willLaunch) {
|
|
18172
|
+
return launchClaude(prompt);
|
|
18173
|
+
}
|
|
18174
|
+
return EXIT_OK2;
|
|
18175
|
+
}
|
|
18176
|
+
function registerQuickstartCommands(program) {
|
|
18177
|
+
program.command("quickstart").description(
|
|
18178
|
+
"Pick a starter recipe in the browser and launch it with Claude Code."
|
|
18179
|
+
).addHelpText(
|
|
18180
|
+
"after",
|
|
18181
|
+
`
|
|
18182
|
+
Notes:
|
|
18183
|
+
Opens the hosted recipe picker in your browser. The picker sends your
|
|
18184
|
+
selection back to a temporary listener on 127.0.0.1, so the browser must run
|
|
18185
|
+
on the same machine as the CLI. Once a recipe arrives, the CLI prints the
|
|
18186
|
+
matching claude command and, when Claude Code is installed and the shell is
|
|
18187
|
+
interactive, launches it directly. Press Ctrl+C while waiting to skip.
|
|
18188
|
+
|
|
18189
|
+
Examples:
|
|
18190
|
+
deepline quickstart
|
|
18191
|
+
deepline quickstart --no-open
|
|
18192
|
+
deepline quickstart --no-launch --json
|
|
18193
|
+
deepline quickstart --timeout 120
|
|
18194
|
+
`
|
|
18195
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").option("--no-open", "Do not open the browser; print the URL only").option("--no-launch", "Print the claude command instead of launching it").option(
|
|
18196
|
+
"--timeout <seconds>",
|
|
18197
|
+
"Maximum seconds to wait for a selection",
|
|
18198
|
+
"300"
|
|
18199
|
+
).action(async (options) => {
|
|
18200
|
+
process.exitCode = await handleQuickstart(options);
|
|
18201
|
+
});
|
|
18202
|
+
}
|
|
18203
|
+
|
|
17943
18204
|
// src/cli/commands/secrets.ts
|
|
17944
18205
|
var import_node_process = require("process");
|
|
17945
18206
|
var hiddenInputBuffer = "";
|
|
@@ -18157,7 +18418,7 @@ var import_node_fs11 = require("fs");
|
|
|
18157
18418
|
var import_node_os8 = require("os");
|
|
18158
18419
|
var import_node_path14 = require("path");
|
|
18159
18420
|
var import_node_zlib = require("zlib");
|
|
18160
|
-
var
|
|
18421
|
+
var import_node_crypto5 = require("crypto");
|
|
18161
18422
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
18162
18423
|
var MAX_SESSION_UPLOAD_BYTES = 35e5;
|
|
18163
18424
|
var MAX_DIRECT_SESSION_DECODED_BYTES = 50 * 1024 * 1024;
|
|
@@ -18420,7 +18681,7 @@ async function uploadPayload(path, payload) {
|
|
|
18420
18681
|
return await http.post(path, payload);
|
|
18421
18682
|
}
|
|
18422
18683
|
async function uploadChunkedSessions(sessions, options) {
|
|
18423
|
-
const uploadId = (0,
|
|
18684
|
+
const uploadId = (0, import_node_crypto5.randomUUID)();
|
|
18424
18685
|
for (const session of sessions) {
|
|
18425
18686
|
const bytes = Buffer.from(session.encodedContent, "base64");
|
|
18426
18687
|
const chunks = [];
|
|
@@ -19944,7 +20205,7 @@ function parseExecuteOptions(args) {
|
|
|
19944
20205
|
function safeFileStem(value) {
|
|
19945
20206
|
return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
|
|
19946
20207
|
}
|
|
19947
|
-
function
|
|
20208
|
+
function shellQuote2(value) {
|
|
19948
20209
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
19949
20210
|
}
|
|
19950
20211
|
function powerShellQuote(value) {
|
|
@@ -19996,7 +20257,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
19996
20257
|
path: scriptPath,
|
|
19997
20258
|
sourceCode: script,
|
|
19998
20259
|
projectDir,
|
|
19999
|
-
macCopyCommand: `mkdir -p ${
|
|
20260
|
+
macCopyCommand: `mkdir -p ${shellQuote2(projectDir)} && cp ${shellQuote2(scriptPath)} ${shellQuote2(`${projectDir}/${fileName}`)}`,
|
|
20000
20261
|
windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
|
|
20001
20262
|
};
|
|
20002
20263
|
}
|
|
@@ -20015,7 +20276,7 @@ function buildToolExecuteBaseEnvelope(input2) {
|
|
|
20015
20276
|
summary: input2.summary
|
|
20016
20277
|
};
|
|
20017
20278
|
const envelopeHasCanonicalOutput = isRecord7(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
|
|
20018
|
-
const inspectCommand = `deepline tools execute ${input2.toolId} --input ${
|
|
20279
|
+
const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote2(JSON.stringify(input2.params))} --json`;
|
|
20019
20280
|
const actions = input2.listConversion ? [
|
|
20020
20281
|
{
|
|
20021
20282
|
label: "next",
|
|
@@ -20249,7 +20510,7 @@ var import_promises6 = require("fs/promises");
|
|
|
20249
20510
|
var import_node_path17 = require("path");
|
|
20250
20511
|
|
|
20251
20512
|
// src/cli/workflow-to-play.ts
|
|
20252
|
-
var
|
|
20513
|
+
var import_node_crypto6 = require("crypto");
|
|
20253
20514
|
var HITL_WAIT_FOR_SIGNAL_TOOL = "deepline_workflow_wait_for_signal";
|
|
20254
20515
|
var HITL_SLACK_TOOL = "slack_message_with_hitl";
|
|
20255
20516
|
var SUB_WORKFLOW_TOOL_PREFIX = "deepline_workflow_";
|
|
@@ -20355,7 +20616,7 @@ function sanitizePlayNameSegment(value) {
|
|
|
20355
20616
|
}
|
|
20356
20617
|
function deriveWorkflowPlayName(workflowName) {
|
|
20357
20618
|
const base = sanitizePlayNameSegment(workflowName) || "workflow";
|
|
20358
|
-
const suffix = (0,
|
|
20619
|
+
const suffix = (0, import_node_crypto6.createHash)("sha256").update(workflowName).digest("hex").slice(0, 8);
|
|
20359
20620
|
const reserved = suffix.length + 1;
|
|
20360
20621
|
const allowedBase = Math.max(1, MAX_PLAY_NAME_LENGTH - reserved);
|
|
20361
20622
|
let name = `${base.slice(0, allowedBase)}_${suffix}`;
|
|
@@ -20734,7 +20995,7 @@ Notes:
|
|
|
20734
20995
|
}
|
|
20735
20996
|
|
|
20736
20997
|
// src/cli/commands/update.ts
|
|
20737
|
-
var
|
|
20998
|
+
var import_node_child_process2 = require("child_process");
|
|
20738
20999
|
var import_node_fs14 = require("fs");
|
|
20739
21000
|
var import_node_path18 = require("path");
|
|
20740
21001
|
function posixShellQuote(value) {
|
|
@@ -20743,14 +21004,14 @@ function posixShellQuote(value) {
|
|
|
20743
21004
|
function windowsCmdQuote(value) {
|
|
20744
21005
|
return `"${value.replace(/"/g, '""')}"`;
|
|
20745
21006
|
}
|
|
20746
|
-
function
|
|
21007
|
+
function shellQuote3(value) {
|
|
20747
21008
|
if (process.platform === "win32") {
|
|
20748
21009
|
return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
|
|
20749
21010
|
}
|
|
20750
21011
|
return posixShellQuote(value);
|
|
20751
21012
|
}
|
|
20752
21013
|
function buildSourceUpdateCommand(sourceRoot) {
|
|
20753
|
-
const quotedRoot =
|
|
21014
|
+
const quotedRoot = shellQuote3(sourceRoot);
|
|
20754
21015
|
const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
|
|
20755
21016
|
return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
|
|
20756
21017
|
}
|
|
@@ -20781,12 +21042,12 @@ function resolveUpdatePlan() {
|
|
|
20781
21042
|
kind: "npm-global",
|
|
20782
21043
|
command,
|
|
20783
21044
|
args,
|
|
20784
|
-
manualCommand: `${command} ${args.map(
|
|
21045
|
+
manualCommand: `${command} ${args.map(shellQuote3).join(" ")}`
|
|
20785
21046
|
};
|
|
20786
21047
|
}
|
|
20787
21048
|
function runCommand(command, args) {
|
|
20788
21049
|
return new Promise((resolveExitCode) => {
|
|
20789
|
-
const child = (0,
|
|
21050
|
+
const child = (0, import_node_child_process2.spawn)(command, args, {
|
|
20790
21051
|
stdio: "inherit",
|
|
20791
21052
|
shell: process.platform === "win32",
|
|
20792
21053
|
env: process.env
|
|
@@ -20801,6 +21062,12 @@ function runCommand(command, args) {
|
|
|
20801
21062
|
});
|
|
20802
21063
|
});
|
|
20803
21064
|
}
|
|
21065
|
+
async function runNpmGlobalUpdatePlan(plan) {
|
|
21066
|
+
if (plan.kind !== "npm-global") {
|
|
21067
|
+
return 1;
|
|
21068
|
+
}
|
|
21069
|
+
return runCommand(plan.command, plan.args);
|
|
21070
|
+
}
|
|
20804
21071
|
async function handleUpdate(options) {
|
|
20805
21072
|
const plan = resolveUpdatePlan();
|
|
20806
21073
|
const render = {
|
|
@@ -20947,16 +21214,27 @@ function skillsIndexUrl(baseUrl) {
|
|
|
20947
21214
|
return `${normalizeBaseUrl2(baseUrl)}${INSTALL_COMMANDS.skills.index_path}`;
|
|
20948
21215
|
}
|
|
20949
21216
|
function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
|
|
21217
|
+
const skillNames = Array.isArray(skillName) ? skillName : [skillName];
|
|
21218
|
+
const [firstSkillName, ...extraSkillNames] = skillNames;
|
|
20950
21219
|
const values = {
|
|
20951
21220
|
skills_index_url: skillsIndexUrl(baseUrl),
|
|
20952
21221
|
agents: INSTALL_COMMANDS.skills.default_agents.join(" "),
|
|
20953
|
-
skill_name:
|
|
21222
|
+
skill_name: firstSkillName ?? ""
|
|
20954
21223
|
};
|
|
20955
21224
|
const rendered = INSTALL_COMMANDS.skills.npx_add_args_template.flatMap(
|
|
20956
21225
|
(arg, index) => {
|
|
20957
21226
|
const next = index === 0 && options.firstArg ? options.firstArg : arg;
|
|
20958
21227
|
const value = renderTemplate(next, values);
|
|
20959
|
-
|
|
21228
|
+
if (arg === "{agents}") {
|
|
21229
|
+
return INSTALL_COMMANDS.skills.default_agents;
|
|
21230
|
+
}
|
|
21231
|
+
if (arg === "{skill_name}") {
|
|
21232
|
+
return [
|
|
21233
|
+
value,
|
|
21234
|
+
...extraSkillNames.flatMap((name) => ["--skill", name])
|
|
21235
|
+
];
|
|
21236
|
+
}
|
|
21237
|
+
return value;
|
|
20960
21238
|
}
|
|
20961
21239
|
);
|
|
20962
21240
|
return rendered;
|
|
@@ -21027,13 +21305,78 @@ function unknownCommandNameFromMessage(message) {
|
|
|
21027
21305
|
return command ? command : null;
|
|
21028
21306
|
}
|
|
21029
21307
|
|
|
21308
|
+
// src/cli/self-update.ts
|
|
21309
|
+
var import_node_child_process3 = require("child_process");
|
|
21310
|
+
function envTruthy(name) {
|
|
21311
|
+
const value = process.env[name]?.trim().toLowerCase();
|
|
21312
|
+
return value === "1" || value === "true" || value === "yes";
|
|
21313
|
+
}
|
|
21314
|
+
function isCi() {
|
|
21315
|
+
return envTruthy("CI") || envTruthy("GITHUB_ACTIONS");
|
|
21316
|
+
}
|
|
21317
|
+
function shouldSkipSelfUpdate() {
|
|
21318
|
+
return envTruthy("DEEPLINE_SKIP_SELF_UPDATE") || envTruthy("DEEPLINE_NO_AUTO_UPDATE") || envTruthy("DEEPLINE_SKIP_SDK_AUTO_UPDATE") || envTruthy("DEEPLINE_DISABLE_AUTO_UPDATE") || isCi();
|
|
21319
|
+
}
|
|
21320
|
+
function relaunchCurrentCommand() {
|
|
21321
|
+
return new Promise((resolve16) => {
|
|
21322
|
+
const child = (0, import_node_child_process3.spawn)(process.execPath, process.argv.slice(1), {
|
|
21323
|
+
stdio: "inherit",
|
|
21324
|
+
env: {
|
|
21325
|
+
...process.env,
|
|
21326
|
+
DEEPLINE_NO_AUTO_UPDATE: "1"
|
|
21327
|
+
}
|
|
21328
|
+
});
|
|
21329
|
+
child.on("error", (error) => {
|
|
21330
|
+
process.stderr.write(
|
|
21331
|
+
`Deepline SDK/CLI updated, but relaunch failed: ${error.message}
|
|
21332
|
+
`
|
|
21333
|
+
);
|
|
21334
|
+
resolve16(1);
|
|
21335
|
+
});
|
|
21336
|
+
child.on("close", (code) => resolve16(code ?? 1));
|
|
21337
|
+
});
|
|
21338
|
+
}
|
|
21339
|
+
async function maybeAutoUpdateAndRelaunch(response) {
|
|
21340
|
+
const autoUpdate = response?.auto_update;
|
|
21341
|
+
if (!response || !autoUpdate?.should_auto_update || shouldSkipSelfUpdate()) {
|
|
21342
|
+
return false;
|
|
21343
|
+
}
|
|
21344
|
+
const plan = resolveUpdatePlan();
|
|
21345
|
+
if (plan.kind !== "npm-global") {
|
|
21346
|
+
return false;
|
|
21347
|
+
}
|
|
21348
|
+
const label = autoUpdate.required ? "requires an update" : "is more than the supported auto-update lag behind";
|
|
21349
|
+
process.stderr.write(
|
|
21350
|
+
`Deepline SDK/CLI ${label}; running ${plan.manualCommand}
|
|
21351
|
+
`
|
|
21352
|
+
);
|
|
21353
|
+
const updateExitCode = await runNpmGlobalUpdatePlan(plan);
|
|
21354
|
+
if (updateExitCode !== 0) {
|
|
21355
|
+
if (autoUpdate.required) {
|
|
21356
|
+
throw new Error(
|
|
21357
|
+
`Automatic Deepline SDK/CLI update failed with exit code ${updateExitCode}. ${response.message}`
|
|
21358
|
+
);
|
|
21359
|
+
}
|
|
21360
|
+
process.stderr.write(
|
|
21361
|
+
`Deepline SDK/CLI auto-update failed with exit code ${updateExitCode}; continuing with ${response.current ?? "current version"}.
|
|
21362
|
+
`
|
|
21363
|
+
);
|
|
21364
|
+
return false;
|
|
21365
|
+
}
|
|
21366
|
+
process.stderr.write("Deepline SDK/CLI updated; rerunning command.\n");
|
|
21367
|
+
const exitCode = await relaunchCurrentCommand();
|
|
21368
|
+
process.exit(exitCode);
|
|
21369
|
+
return true;
|
|
21370
|
+
}
|
|
21371
|
+
|
|
21030
21372
|
// src/cli/skills-sync.ts
|
|
21031
|
-
var
|
|
21373
|
+
var import_node_child_process4 = require("child_process");
|
|
21032
21374
|
var import_node_fs15 = require("fs");
|
|
21033
21375
|
var import_node_os11 = require("os");
|
|
21034
21376
|
var import_node_path19 = require("path");
|
|
21035
21377
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
21036
21378
|
var SDK_SKILL_NAME = "deepline-plays";
|
|
21379
|
+
var SDK_SKILL_NAMES = [SDK_SKILL_NAME, "deepline-plays-quickstart"];
|
|
21037
21380
|
var attemptedSync = false;
|
|
21038
21381
|
function shouldSkipSkillsSync() {
|
|
21039
21382
|
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
@@ -21150,19 +21493,19 @@ async function fetchSkillsUpdate(baseUrl, localVersion) {
|
|
|
21150
21493
|
}
|
|
21151
21494
|
}
|
|
21152
21495
|
function buildSkillsInstallArgs(baseUrl) {
|
|
21153
|
-
return buildSkillsAddArgs(baseUrl,
|
|
21496
|
+
return buildSkillsAddArgs(baseUrl, SDK_SKILL_NAMES);
|
|
21154
21497
|
}
|
|
21155
21498
|
function buildBunxSkillsInstallArgs(baseUrl) {
|
|
21156
|
-
return buildSkillsAddArgs(baseUrl,
|
|
21499
|
+
return buildSkillsAddArgs(baseUrl, SDK_SKILL_NAMES, { firstArg: "--bun" });
|
|
21157
21500
|
}
|
|
21158
21501
|
function hasCommand(command) {
|
|
21159
|
-
const result = (0,
|
|
21502
|
+
const result = (0, import_node_child_process4.spawnSync)(command, ["--version"], {
|
|
21160
21503
|
stdio: "ignore",
|
|
21161
21504
|
shell: process.platform === "win32"
|
|
21162
21505
|
});
|
|
21163
21506
|
return result.status === 0;
|
|
21164
21507
|
}
|
|
21165
|
-
function
|
|
21508
|
+
function shellQuote4(arg) {
|
|
21166
21509
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
21167
21510
|
}
|
|
21168
21511
|
function resolveSkillsInstallCommands(baseUrl) {
|
|
@@ -21170,7 +21513,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
21170
21513
|
const npxInstall = {
|
|
21171
21514
|
command: "npx",
|
|
21172
21515
|
args: npxArgs,
|
|
21173
|
-
manualCommand: `npx ${npxArgs.map(
|
|
21516
|
+
manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
|
|
21174
21517
|
};
|
|
21175
21518
|
if (hasCommand("bunx")) {
|
|
21176
21519
|
const bunxArgs = buildBunxSkillsInstallArgs(baseUrl);
|
|
@@ -21178,7 +21521,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
21178
21521
|
{
|
|
21179
21522
|
command: "bunx",
|
|
21180
21523
|
args: bunxArgs,
|
|
21181
|
-
manualCommand: `bunx ${bunxArgs.map(
|
|
21524
|
+
manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
|
|
21182
21525
|
},
|
|
21183
21526
|
npxInstall
|
|
21184
21527
|
];
|
|
@@ -21187,7 +21530,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
21187
21530
|
}
|
|
21188
21531
|
function runOneSkillsInstall(install) {
|
|
21189
21532
|
return new Promise((resolve16) => {
|
|
21190
|
-
const child = (0,
|
|
21533
|
+
const child = (0, import_node_child_process4.spawn)(install.command, install.args, {
|
|
21191
21534
|
stdio: ["ignore", "ignore", "pipe"],
|
|
21192
21535
|
env: process.env
|
|
21193
21536
|
});
|
|
@@ -21255,7 +21598,7 @@ async function syncSdkSkillsIfNeeded(baseUrl) {
|
|
|
21255
21598
|
if (!update?.needsUpdate && !hasStaleInstalledSkill || !update?.remoteVersion) {
|
|
21256
21599
|
return;
|
|
21257
21600
|
}
|
|
21258
|
-
writeSdkSkillsStatusLine("SDK skills changed; syncing
|
|
21601
|
+
writeSdkSkillsStatusLine("SDK skills changed; syncing Deepline SDK skills...");
|
|
21259
21602
|
const installed = await runSkillsInstall(baseUrl);
|
|
21260
21603
|
if (!installed) return;
|
|
21261
21604
|
if (installedSdkSkillHasStalePositionalExecuteExamples()) {
|
|
@@ -21478,7 +21821,9 @@ async function main() {
|
|
|
21478
21821
|
progress?.phase("loading deepline cli");
|
|
21479
21822
|
}
|
|
21480
21823
|
const program = new import_commander3.Command();
|
|
21481
|
-
program.name("deepline").description(
|
|
21824
|
+
program.name("deepline").description(
|
|
21825
|
+
"Deepline CLI \u2014 GTM enrichment tools, plays, and runs from your terminal."
|
|
21826
|
+
).version(SDK_VERSION, "-v, --version", "Show version").exitOverride().showHelpAfterError().showSuggestionAfterError(true).addHelpText(
|
|
21482
21827
|
"after",
|
|
21483
21828
|
`
|
|
21484
21829
|
Common commands:
|
|
@@ -21519,11 +21864,23 @@ Exit codes:
|
|
|
21519
21864
|
progress?.phase("checking sdk compatibility");
|
|
21520
21865
|
}
|
|
21521
21866
|
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
21522
|
-
await traceCliSpan(
|
|
21867
|
+
const compatibility = await traceCliSpan(
|
|
21523
21868
|
"cli.sdk_compatibility",
|
|
21524
|
-
{ baseUrl },
|
|
21525
|
-
() =>
|
|
21869
|
+
{ baseUrl, command: actionCommand.name() },
|
|
21870
|
+
() => checkSdkCompatibility(baseUrl, {
|
|
21871
|
+
command: actionCommand.name()
|
|
21872
|
+
})
|
|
21873
|
+
);
|
|
21874
|
+
if (compatibility.error) {
|
|
21875
|
+
return;
|
|
21876
|
+
}
|
|
21877
|
+
const relaunched = await maybeAutoUpdateAndRelaunch(
|
|
21878
|
+
compatibility.response
|
|
21526
21879
|
);
|
|
21880
|
+
if (relaunched) {
|
|
21881
|
+
return;
|
|
21882
|
+
}
|
|
21883
|
+
enforceSdkCompatibilityResponse(compatibility.response);
|
|
21527
21884
|
if (printStartupPhase) {
|
|
21528
21885
|
progress?.phase("checking sdk skills");
|
|
21529
21886
|
}
|
|
@@ -21548,6 +21905,7 @@ Exit codes:
|
|
|
21548
21905
|
registerDbCommands(program);
|
|
21549
21906
|
registerFeedbackCommands(program);
|
|
21550
21907
|
registerUpdateCommand(program);
|
|
21908
|
+
registerQuickstartCommands(program);
|
|
21551
21909
|
program.command("preflight").description("Run compact health, auth, and Deepline billing checks.").option("--json", "Force JSON output.").addHelpText(
|
|
21552
21910
|
"after",
|
|
21553
21911
|
`
|
|
@@ -21623,6 +21981,29 @@ Examples:
|
|
|
21623
21981
|
process.stdout.write(`deepline ${SDK_VERSION}
|
|
21624
21982
|
`);
|
|
21625
21983
|
});
|
|
21984
|
+
if (process.argv.slice(2).length === 0) {
|
|
21985
|
+
if (!process.stdout.isTTY) {
|
|
21986
|
+
printJson({
|
|
21987
|
+
ok: false,
|
|
21988
|
+
exitCode: 2,
|
|
21989
|
+
code: "MISSING_COMMAND",
|
|
21990
|
+
message: "No command provided.",
|
|
21991
|
+
next: "deepline --help"
|
|
21992
|
+
});
|
|
21993
|
+
console.error("error: missing command (see: deepline --help)");
|
|
21994
|
+
} else {
|
|
21995
|
+
program.outputHelp({ error: true });
|
|
21996
|
+
console.error("\nerror: missing command (see usage above)");
|
|
21997
|
+
}
|
|
21998
|
+
recordCliTrace({
|
|
21999
|
+
phase: "cli.main_total",
|
|
22000
|
+
ms: Date.now() - mainStartedAt,
|
|
22001
|
+
ok: false,
|
|
22002
|
+
error: "missing command"
|
|
22003
|
+
});
|
|
22004
|
+
process.exitCode = 2;
|
|
22005
|
+
return;
|
|
22006
|
+
}
|
|
21626
22007
|
try {
|
|
21627
22008
|
await program.parseAsync(process.argv);
|
|
21628
22009
|
recordCliTrace({
|