deepline 0.1.106 → 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 +404 -34
- package/dist/cli/index.mjs +400 -30
- package/dist/index.js +13 -3
- package/dist/index.mjs +13 -3
- package/dist/repo/sdk/src/release.ts +47 -7
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -219,12 +219,22 @@ var SDK_RELEASE = {
|
|
|
219
219
|
// 0.1.105 ships the billing catalog surface: billing plans, subscribe,
|
|
220
220
|
// subscription status/cancel, invoices, and the client.billing namespace.
|
|
221
221
|
// 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
|
|
222
|
-
|
|
222
|
+
// 0.1.107 ships the v2 quickstart command, the deepline-plays-quickstart
|
|
223
|
+
// skill on the sdk sync surface, and the people-search-to-email prebuilt.
|
|
224
|
+
version: "0.1.107",
|
|
223
225
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
224
226
|
supportPolicy: {
|
|
225
|
-
latest: "0.1.
|
|
227
|
+
latest: "0.1.107",
|
|
226
228
|
minimumSupported: "0.1.53",
|
|
227
|
-
deprecatedBelow: "0.1.53"
|
|
229
|
+
deprecatedBelow: "0.1.53",
|
|
230
|
+
commandMinimumSupported: [
|
|
231
|
+
{
|
|
232
|
+
command: "enrich",
|
|
233
|
+
minimumSupported: "0.1.106",
|
|
234
|
+
reason: "Older SDK CLI enrich generated stale play source for the current dataset API."
|
|
235
|
+
}
|
|
236
|
+
],
|
|
237
|
+
autoUpdatePatchLag: 2
|
|
228
238
|
}
|
|
229
239
|
};
|
|
230
240
|
|
|
@@ -3146,7 +3156,7 @@ function shouldSkipCompatibilityCheck() {
|
|
|
3146
3156
|
const value = process.env.DEEPLINE_SKIP_SDK_COMPAT_CHECK?.trim().toLowerCase();
|
|
3147
3157
|
return value === "1" || value === "true" || value === "yes";
|
|
3148
3158
|
}
|
|
3149
|
-
async function checkSdkCompatibility(baseUrl) {
|
|
3159
|
+
async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
3150
3160
|
if (shouldSkipCompatibilityCheck()) {
|
|
3151
3161
|
return { response: null, error: null };
|
|
3152
3162
|
}
|
|
@@ -3155,6 +3165,9 @@ async function checkSdkCompatibility(baseUrl) {
|
|
|
3155
3165
|
try {
|
|
3156
3166
|
const url = new URL("/api/v2/sdk/compat", baseUrl);
|
|
3157
3167
|
url.searchParams.set("version", SDK_VERSION);
|
|
3168
|
+
if (options.command?.trim()) {
|
|
3169
|
+
url.searchParams.set("command", options.command.trim());
|
|
3170
|
+
}
|
|
3158
3171
|
const response = await fetch(url, {
|
|
3159
3172
|
method: "GET",
|
|
3160
3173
|
headers: {
|
|
@@ -3175,9 +3188,8 @@ async function checkSdkCompatibility(baseUrl) {
|
|
|
3175
3188
|
clearTimeout(timeout);
|
|
3176
3189
|
}
|
|
3177
3190
|
}
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
if (error || !response) {
|
|
3191
|
+
function enforceSdkCompatibilityResponse(response) {
|
|
3192
|
+
if (!response) {
|
|
3181
3193
|
return;
|
|
3182
3194
|
}
|
|
3183
3195
|
if (response.update_required) {
|
|
@@ -17968,6 +17980,244 @@ Examples:
|
|
|
17968
17980
|
).option("--org-id <id>", "Switch using an explicit organization id").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgSwitch);
|
|
17969
17981
|
}
|
|
17970
17982
|
|
|
17983
|
+
// src/cli/commands/quickstart.ts
|
|
17984
|
+
import { spawn, spawnSync } from "child_process";
|
|
17985
|
+
import { randomBytes } from "crypto";
|
|
17986
|
+
import { createServer } from "http";
|
|
17987
|
+
var EXIT_OK2 = 0;
|
|
17988
|
+
var EXIT_AUTH2 = 1;
|
|
17989
|
+
var EXIT_SERVER3 = 2;
|
|
17990
|
+
var MAX_PROMPT_LENGTH = 8e3;
|
|
17991
|
+
var MAX_BODY_BYTES = 64 * 1024;
|
|
17992
|
+
function shellQuote(arg) {
|
|
17993
|
+
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
17994
|
+
}
|
|
17995
|
+
function hasClaudeBinary() {
|
|
17996
|
+
try {
|
|
17997
|
+
const result = spawnSync("claude", ["--version"], {
|
|
17998
|
+
stdio: "ignore",
|
|
17999
|
+
shell: process.platform === "win32"
|
|
18000
|
+
});
|
|
18001
|
+
return result.status === 0;
|
|
18002
|
+
} catch {
|
|
18003
|
+
return false;
|
|
18004
|
+
}
|
|
18005
|
+
}
|
|
18006
|
+
function launchClaude(prompt) {
|
|
18007
|
+
return new Promise((resolve16) => {
|
|
18008
|
+
const child = spawn("claude", [prompt], {
|
|
18009
|
+
stdio: "inherit",
|
|
18010
|
+
shell: process.platform === "win32"
|
|
18011
|
+
});
|
|
18012
|
+
child.on("error", () => resolve16(EXIT_SERVER3));
|
|
18013
|
+
child.on("close", (status) => resolve16(status ?? EXIT_OK2));
|
|
18014
|
+
});
|
|
18015
|
+
}
|
|
18016
|
+
function readBody(req) {
|
|
18017
|
+
return new Promise((resolve16, reject) => {
|
|
18018
|
+
let raw = "";
|
|
18019
|
+
req.setEncoding("utf8");
|
|
18020
|
+
req.on("data", (chunk) => {
|
|
18021
|
+
raw += chunk;
|
|
18022
|
+
if (raw.length > MAX_BODY_BYTES) {
|
|
18023
|
+
reject(new Error("Request body too large."));
|
|
18024
|
+
req.destroy();
|
|
18025
|
+
}
|
|
18026
|
+
});
|
|
18027
|
+
req.on("end", () => resolve16(raw));
|
|
18028
|
+
req.on("error", reject);
|
|
18029
|
+
});
|
|
18030
|
+
}
|
|
18031
|
+
function writeJson(res, status, payload) {
|
|
18032
|
+
res.writeHead(status, { "content-type": "application/json" });
|
|
18033
|
+
res.end(JSON.stringify(payload));
|
|
18034
|
+
}
|
|
18035
|
+
function startCallbackServer(input2) {
|
|
18036
|
+
const server = createServer((req, res) => {
|
|
18037
|
+
res.setHeader("Access-Control-Allow-Origin", req.headers.origin ?? "*");
|
|
18038
|
+
res.setHeader("Vary", "Origin");
|
|
18039
|
+
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
18040
|
+
res.setHeader("Access-Control-Allow-Headers", "content-type");
|
|
18041
|
+
res.setHeader("Access-Control-Allow-Private-Network", "true");
|
|
18042
|
+
res.setHeader("Access-Control-Max-Age", "600");
|
|
18043
|
+
if (req.method === "OPTIONS") {
|
|
18044
|
+
res.writeHead(204);
|
|
18045
|
+
res.end();
|
|
18046
|
+
return;
|
|
18047
|
+
}
|
|
18048
|
+
if (req.method !== "POST" || req.url !== "/submit") {
|
|
18049
|
+
writeJson(res, 404, { error: "Not found." });
|
|
18050
|
+
return;
|
|
18051
|
+
}
|
|
18052
|
+
void readBody(req).then((raw) => {
|
|
18053
|
+
let body = null;
|
|
18054
|
+
try {
|
|
18055
|
+
body = JSON.parse(raw);
|
|
18056
|
+
} catch {
|
|
18057
|
+
body = null;
|
|
18058
|
+
}
|
|
18059
|
+
const state = typeof body?.state === "string" ? body.state : "";
|
|
18060
|
+
const prompt = typeof body?.prompt === "string" ? body.prompt.trim() : "";
|
|
18061
|
+
const workflowId = typeof body?.workflow_id === "string" && body.workflow_id.trim() ? body.workflow_id.trim() : null;
|
|
18062
|
+
if (!state || state !== input2.state) {
|
|
18063
|
+
writeJson(res, 403, { error: "Invalid quickstart state token." });
|
|
18064
|
+
return;
|
|
18065
|
+
}
|
|
18066
|
+
if (!prompt) {
|
|
18067
|
+
writeJson(res, 400, { error: "prompt is required." });
|
|
18068
|
+
return;
|
|
18069
|
+
}
|
|
18070
|
+
if (prompt.length > MAX_PROMPT_LENGTH) {
|
|
18071
|
+
writeJson(res, 400, {
|
|
18072
|
+
error: `prompt exceeds ${MAX_PROMPT_LENGTH} characters.`
|
|
18073
|
+
});
|
|
18074
|
+
return;
|
|
18075
|
+
}
|
|
18076
|
+
writeJson(res, 200, { ok: true });
|
|
18077
|
+
setImmediate(() => input2.onSelection({ prompt, workflowId }));
|
|
18078
|
+
}).catch(() => {
|
|
18079
|
+
writeJson(res, 400, { error: "Invalid request body." });
|
|
18080
|
+
});
|
|
18081
|
+
});
|
|
18082
|
+
return new Promise((resolve16, reject) => {
|
|
18083
|
+
server.once("error", reject);
|
|
18084
|
+
server.listen(0, "127.0.0.1", () => {
|
|
18085
|
+
const address = server.address();
|
|
18086
|
+
if (!address || typeof address === "string") {
|
|
18087
|
+
reject(new Error("Failed to bind quickstart callback server."));
|
|
18088
|
+
return;
|
|
18089
|
+
}
|
|
18090
|
+
resolve16({ server, port: address.port });
|
|
18091
|
+
});
|
|
18092
|
+
});
|
|
18093
|
+
}
|
|
18094
|
+
async function handleQuickstart(options) {
|
|
18095
|
+
const jsonOutput = shouldEmitJson(options.json === true);
|
|
18096
|
+
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
18097
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
18098
|
+
let apiKey = resolveApiKeyForBaseUrl(baseUrl);
|
|
18099
|
+
if (!apiKey) {
|
|
18100
|
+
if (interactive) {
|
|
18101
|
+
console.error("Not connected yet \u2014 registering this device first.");
|
|
18102
|
+
const registerExit = await handleRegister([]);
|
|
18103
|
+
if (registerExit !== EXIT_OK2) return registerExit;
|
|
18104
|
+
apiKey = resolveApiKeyForBaseUrl(baseUrl);
|
|
18105
|
+
}
|
|
18106
|
+
if (!apiKey) {
|
|
18107
|
+
console.error("Not connected. Run: deepline auth register");
|
|
18108
|
+
return EXIT_AUTH2;
|
|
18109
|
+
}
|
|
18110
|
+
}
|
|
18111
|
+
const state = randomBytes(32).toString("hex");
|
|
18112
|
+
let resolveSelection;
|
|
18113
|
+
const selectionPromise = new Promise((resolve16) => {
|
|
18114
|
+
resolveSelection = resolve16;
|
|
18115
|
+
});
|
|
18116
|
+
let callback;
|
|
18117
|
+
try {
|
|
18118
|
+
callback = await startCallbackServer({
|
|
18119
|
+
state,
|
|
18120
|
+
onSelection: (selection) => resolveSelection(selection)
|
|
18121
|
+
});
|
|
18122
|
+
} catch (error) {
|
|
18123
|
+
console.error(
|
|
18124
|
+
`Could not start the local quickstart listener: ${error instanceof Error ? error.message : String(error)}`
|
|
18125
|
+
);
|
|
18126
|
+
return EXIT_SERVER3;
|
|
18127
|
+
}
|
|
18128
|
+
const quickstartUrl = `${baseUrl}/cli/quickstart?cb=${callback.port}&state=${state}`;
|
|
18129
|
+
console.error(" Opening the recipe picker in your browser.");
|
|
18130
|
+
console.error(` If it didn't open, cmd+click: ${quickstartUrl}`);
|
|
18131
|
+
if (options.open !== false) {
|
|
18132
|
+
openInBrowser(quickstartUrl);
|
|
18133
|
+
}
|
|
18134
|
+
const timeoutSeconds = Number.parseInt(options.timeout ?? "300", 10);
|
|
18135
|
+
const timeoutMs = (Number.isFinite(timeoutSeconds) && timeoutSeconds > 0 ? timeoutSeconds : 300) * 1e3;
|
|
18136
|
+
const timeoutHandle = setTimeout(
|
|
18137
|
+
() => resolveSelection("timeout"),
|
|
18138
|
+
timeoutMs
|
|
18139
|
+
);
|
|
18140
|
+
const progress = createCliProgress(!jsonOutput);
|
|
18141
|
+
progress.phase("waiting for your pick in the browser (Ctrl+C to skip)");
|
|
18142
|
+
const onSigint = () => resolveSelection("sigint");
|
|
18143
|
+
process.once("SIGINT", onSigint);
|
|
18144
|
+
const outcome = await selectionPromise;
|
|
18145
|
+
clearTimeout(timeoutHandle);
|
|
18146
|
+
process.removeListener("SIGINT", onSigint);
|
|
18147
|
+
callback.server.close();
|
|
18148
|
+
if (outcome === "sigint") {
|
|
18149
|
+
progress.fail();
|
|
18150
|
+
console.error("\nSkipped \u2014 run `deepline quickstart` anytime.");
|
|
18151
|
+
return EXIT_OK2;
|
|
18152
|
+
}
|
|
18153
|
+
if (outcome === "timeout") {
|
|
18154
|
+
progress.fail();
|
|
18155
|
+
console.error(
|
|
18156
|
+
"Timed out waiting for a selection. Run: deepline quickstart"
|
|
18157
|
+
);
|
|
18158
|
+
return EXIT_AUTH2;
|
|
18159
|
+
}
|
|
18160
|
+
progress.complete();
|
|
18161
|
+
const { prompt, workflowId } = outcome;
|
|
18162
|
+
const claudeCommand = `claude ${shellQuote(prompt)}`;
|
|
18163
|
+
const claudeAvailable = hasClaudeBinary();
|
|
18164
|
+
const willLaunch = options.launch !== false && !jsonOutput && interactive && claudeAvailable;
|
|
18165
|
+
printCommandEnvelope(
|
|
18166
|
+
{
|
|
18167
|
+
status: "submitted",
|
|
18168
|
+
workflowId,
|
|
18169
|
+
prompt,
|
|
18170
|
+
claudeCommand,
|
|
18171
|
+
url: quickstartUrl,
|
|
18172
|
+
launched: willLaunch,
|
|
18173
|
+
render: {
|
|
18174
|
+
sections: [
|
|
18175
|
+
{
|
|
18176
|
+
title: "quickstart",
|
|
18177
|
+
lines: [
|
|
18178
|
+
...workflowId ? [`Recipe: ${workflowId}`] : [],
|
|
18179
|
+
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."
|
|
18180
|
+
]
|
|
18181
|
+
}
|
|
18182
|
+
],
|
|
18183
|
+
actions: [{ label: "Run", command: claudeCommand }]
|
|
18184
|
+
}
|
|
18185
|
+
},
|
|
18186
|
+
{ json: jsonOutput }
|
|
18187
|
+
);
|
|
18188
|
+
if (willLaunch) {
|
|
18189
|
+
return launchClaude(prompt);
|
|
18190
|
+
}
|
|
18191
|
+
return EXIT_OK2;
|
|
18192
|
+
}
|
|
18193
|
+
function registerQuickstartCommands(program) {
|
|
18194
|
+
program.command("quickstart").description(
|
|
18195
|
+
"Pick a starter recipe in the browser and launch it with Claude Code."
|
|
18196
|
+
).addHelpText(
|
|
18197
|
+
"after",
|
|
18198
|
+
`
|
|
18199
|
+
Notes:
|
|
18200
|
+
Opens the hosted recipe picker in your browser. The picker sends your
|
|
18201
|
+
selection back to a temporary listener on 127.0.0.1, so the browser must run
|
|
18202
|
+
on the same machine as the CLI. Once a recipe arrives, the CLI prints the
|
|
18203
|
+
matching claude command and, when Claude Code is installed and the shell is
|
|
18204
|
+
interactive, launches it directly. Press Ctrl+C while waiting to skip.
|
|
18205
|
+
|
|
18206
|
+
Examples:
|
|
18207
|
+
deepline quickstart
|
|
18208
|
+
deepline quickstart --no-open
|
|
18209
|
+
deepline quickstart --no-launch --json
|
|
18210
|
+
deepline quickstart --timeout 120
|
|
18211
|
+
`
|
|
18212
|
+
).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(
|
|
18213
|
+
"--timeout <seconds>",
|
|
18214
|
+
"Maximum seconds to wait for a selection",
|
|
18215
|
+
"300"
|
|
18216
|
+
).action(async (options) => {
|
|
18217
|
+
process.exitCode = await handleQuickstart(options);
|
|
18218
|
+
});
|
|
18219
|
+
}
|
|
18220
|
+
|
|
17971
18221
|
// src/cli/commands/secrets.ts
|
|
17972
18222
|
import { stdin as input, stdout as output } from "process";
|
|
17973
18223
|
var hiddenInputBuffer = "";
|
|
@@ -19985,7 +20235,7 @@ function parseExecuteOptions(args) {
|
|
|
19985
20235
|
function safeFileStem(value) {
|
|
19986
20236
|
return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
|
|
19987
20237
|
}
|
|
19988
|
-
function
|
|
20238
|
+
function shellQuote2(value) {
|
|
19989
20239
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
19990
20240
|
}
|
|
19991
20241
|
function powerShellQuote(value) {
|
|
@@ -20037,7 +20287,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
20037
20287
|
path: scriptPath,
|
|
20038
20288
|
sourceCode: script,
|
|
20039
20289
|
projectDir,
|
|
20040
|
-
macCopyCommand: `mkdir -p ${
|
|
20290
|
+
macCopyCommand: `mkdir -p ${shellQuote2(projectDir)} && cp ${shellQuote2(scriptPath)} ${shellQuote2(`${projectDir}/${fileName}`)}`,
|
|
20041
20291
|
windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
|
|
20042
20292
|
};
|
|
20043
20293
|
}
|
|
@@ -20056,7 +20306,7 @@ function buildToolExecuteBaseEnvelope(input2) {
|
|
|
20056
20306
|
summary: input2.summary
|
|
20057
20307
|
};
|
|
20058
20308
|
const envelopeHasCanonicalOutput = isRecord7(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
|
|
20059
|
-
const inspectCommand = `deepline tools execute ${input2.toolId} --input ${
|
|
20309
|
+
const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote2(JSON.stringify(input2.params))} --json`;
|
|
20060
20310
|
const actions = input2.listConversion ? [
|
|
20061
20311
|
{
|
|
20062
20312
|
label: "next",
|
|
@@ -20775,7 +21025,7 @@ Notes:
|
|
|
20775
21025
|
}
|
|
20776
21026
|
|
|
20777
21027
|
// src/cli/commands/update.ts
|
|
20778
|
-
import { spawn } from "child_process";
|
|
21028
|
+
import { spawn as spawn2 } from "child_process";
|
|
20779
21029
|
import { existsSync as existsSync10 } from "fs";
|
|
20780
21030
|
import { dirname as dirname11, join as join13, resolve as resolve15 } from "path";
|
|
20781
21031
|
function posixShellQuote(value) {
|
|
@@ -20784,14 +21034,14 @@ function posixShellQuote(value) {
|
|
|
20784
21034
|
function windowsCmdQuote(value) {
|
|
20785
21035
|
return `"${value.replace(/"/g, '""')}"`;
|
|
20786
21036
|
}
|
|
20787
|
-
function
|
|
21037
|
+
function shellQuote3(value) {
|
|
20788
21038
|
if (process.platform === "win32") {
|
|
20789
21039
|
return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
|
|
20790
21040
|
}
|
|
20791
21041
|
return posixShellQuote(value);
|
|
20792
21042
|
}
|
|
20793
21043
|
function buildSourceUpdateCommand(sourceRoot) {
|
|
20794
|
-
const quotedRoot =
|
|
21044
|
+
const quotedRoot = shellQuote3(sourceRoot);
|
|
20795
21045
|
const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
|
|
20796
21046
|
return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
|
|
20797
21047
|
}
|
|
@@ -20822,12 +21072,12 @@ function resolveUpdatePlan() {
|
|
|
20822
21072
|
kind: "npm-global",
|
|
20823
21073
|
command,
|
|
20824
21074
|
args,
|
|
20825
|
-
manualCommand: `${command} ${args.map(
|
|
21075
|
+
manualCommand: `${command} ${args.map(shellQuote3).join(" ")}`
|
|
20826
21076
|
};
|
|
20827
21077
|
}
|
|
20828
21078
|
function runCommand(command, args) {
|
|
20829
21079
|
return new Promise((resolveExitCode) => {
|
|
20830
|
-
const child =
|
|
21080
|
+
const child = spawn2(command, args, {
|
|
20831
21081
|
stdio: "inherit",
|
|
20832
21082
|
shell: process.platform === "win32",
|
|
20833
21083
|
env: process.env
|
|
@@ -20842,6 +21092,12 @@ function runCommand(command, args) {
|
|
|
20842
21092
|
});
|
|
20843
21093
|
});
|
|
20844
21094
|
}
|
|
21095
|
+
async function runNpmGlobalUpdatePlan(plan) {
|
|
21096
|
+
if (plan.kind !== "npm-global") {
|
|
21097
|
+
return 1;
|
|
21098
|
+
}
|
|
21099
|
+
return runCommand(plan.command, plan.args);
|
|
21100
|
+
}
|
|
20845
21101
|
async function handleUpdate(options) {
|
|
20846
21102
|
const plan = resolveUpdatePlan();
|
|
20847
21103
|
const render = {
|
|
@@ -20988,16 +21244,27 @@ function skillsIndexUrl(baseUrl) {
|
|
|
20988
21244
|
return `${normalizeBaseUrl2(baseUrl)}${INSTALL_COMMANDS.skills.index_path}`;
|
|
20989
21245
|
}
|
|
20990
21246
|
function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
|
|
21247
|
+
const skillNames = Array.isArray(skillName) ? skillName : [skillName];
|
|
21248
|
+
const [firstSkillName, ...extraSkillNames] = skillNames;
|
|
20991
21249
|
const values = {
|
|
20992
21250
|
skills_index_url: skillsIndexUrl(baseUrl),
|
|
20993
21251
|
agents: INSTALL_COMMANDS.skills.default_agents.join(" "),
|
|
20994
|
-
skill_name:
|
|
21252
|
+
skill_name: firstSkillName ?? ""
|
|
20995
21253
|
};
|
|
20996
21254
|
const rendered = INSTALL_COMMANDS.skills.npx_add_args_template.flatMap(
|
|
20997
21255
|
(arg, index) => {
|
|
20998
21256
|
const next = index === 0 && options.firstArg ? options.firstArg : arg;
|
|
20999
21257
|
const value = renderTemplate(next, values);
|
|
21000
|
-
|
|
21258
|
+
if (arg === "{agents}") {
|
|
21259
|
+
return INSTALL_COMMANDS.skills.default_agents;
|
|
21260
|
+
}
|
|
21261
|
+
if (arg === "{skill_name}") {
|
|
21262
|
+
return [
|
|
21263
|
+
value,
|
|
21264
|
+
...extraSkillNames.flatMap((name) => ["--skill", name])
|
|
21265
|
+
];
|
|
21266
|
+
}
|
|
21267
|
+
return value;
|
|
21001
21268
|
}
|
|
21002
21269
|
);
|
|
21003
21270
|
return rendered;
|
|
@@ -21068,8 +21335,72 @@ function unknownCommandNameFromMessage(message) {
|
|
|
21068
21335
|
return command ? command : null;
|
|
21069
21336
|
}
|
|
21070
21337
|
|
|
21338
|
+
// src/cli/self-update.ts
|
|
21339
|
+
import { spawn as spawn3 } from "child_process";
|
|
21340
|
+
function envTruthy(name) {
|
|
21341
|
+
const value = process.env[name]?.trim().toLowerCase();
|
|
21342
|
+
return value === "1" || value === "true" || value === "yes";
|
|
21343
|
+
}
|
|
21344
|
+
function isCi() {
|
|
21345
|
+
return envTruthy("CI") || envTruthy("GITHUB_ACTIONS");
|
|
21346
|
+
}
|
|
21347
|
+
function shouldSkipSelfUpdate() {
|
|
21348
|
+
return envTruthy("DEEPLINE_SKIP_SELF_UPDATE") || envTruthy("DEEPLINE_NO_AUTO_UPDATE") || envTruthy("DEEPLINE_SKIP_SDK_AUTO_UPDATE") || envTruthy("DEEPLINE_DISABLE_AUTO_UPDATE") || isCi();
|
|
21349
|
+
}
|
|
21350
|
+
function relaunchCurrentCommand() {
|
|
21351
|
+
return new Promise((resolve16) => {
|
|
21352
|
+
const child = spawn3(process.execPath, process.argv.slice(1), {
|
|
21353
|
+
stdio: "inherit",
|
|
21354
|
+
env: {
|
|
21355
|
+
...process.env,
|
|
21356
|
+
DEEPLINE_NO_AUTO_UPDATE: "1"
|
|
21357
|
+
}
|
|
21358
|
+
});
|
|
21359
|
+
child.on("error", (error) => {
|
|
21360
|
+
process.stderr.write(
|
|
21361
|
+
`Deepline SDK/CLI updated, but relaunch failed: ${error.message}
|
|
21362
|
+
`
|
|
21363
|
+
);
|
|
21364
|
+
resolve16(1);
|
|
21365
|
+
});
|
|
21366
|
+
child.on("close", (code) => resolve16(code ?? 1));
|
|
21367
|
+
});
|
|
21368
|
+
}
|
|
21369
|
+
async function maybeAutoUpdateAndRelaunch(response) {
|
|
21370
|
+
const autoUpdate = response?.auto_update;
|
|
21371
|
+
if (!response || !autoUpdate?.should_auto_update || shouldSkipSelfUpdate()) {
|
|
21372
|
+
return false;
|
|
21373
|
+
}
|
|
21374
|
+
const plan = resolveUpdatePlan();
|
|
21375
|
+
if (plan.kind !== "npm-global") {
|
|
21376
|
+
return false;
|
|
21377
|
+
}
|
|
21378
|
+
const label = autoUpdate.required ? "requires an update" : "is more than the supported auto-update lag behind";
|
|
21379
|
+
process.stderr.write(
|
|
21380
|
+
`Deepline SDK/CLI ${label}; running ${plan.manualCommand}
|
|
21381
|
+
`
|
|
21382
|
+
);
|
|
21383
|
+
const updateExitCode = await runNpmGlobalUpdatePlan(plan);
|
|
21384
|
+
if (updateExitCode !== 0) {
|
|
21385
|
+
if (autoUpdate.required) {
|
|
21386
|
+
throw new Error(
|
|
21387
|
+
`Automatic Deepline SDK/CLI update failed with exit code ${updateExitCode}. ${response.message}`
|
|
21388
|
+
);
|
|
21389
|
+
}
|
|
21390
|
+
process.stderr.write(
|
|
21391
|
+
`Deepline SDK/CLI auto-update failed with exit code ${updateExitCode}; continuing with ${response.current ?? "current version"}.
|
|
21392
|
+
`
|
|
21393
|
+
);
|
|
21394
|
+
return false;
|
|
21395
|
+
}
|
|
21396
|
+
process.stderr.write("Deepline SDK/CLI updated; rerunning command.\n");
|
|
21397
|
+
const exitCode = await relaunchCurrentCommand();
|
|
21398
|
+
process.exit(exitCode);
|
|
21399
|
+
return true;
|
|
21400
|
+
}
|
|
21401
|
+
|
|
21071
21402
|
// src/cli/skills-sync.ts
|
|
21072
|
-
import { spawn as
|
|
21403
|
+
import { spawn as spawn4, spawnSync as spawnSync2 } from "child_process";
|
|
21073
21404
|
import {
|
|
21074
21405
|
existsSync as existsSync11,
|
|
21075
21406
|
mkdirSync as mkdirSync6,
|
|
@@ -21082,6 +21413,7 @@ import { homedir as homedir7 } from "os";
|
|
|
21082
21413
|
import { dirname as dirname12, join as join14 } from "path";
|
|
21083
21414
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
21084
21415
|
var SDK_SKILL_NAME = "deepline-plays";
|
|
21416
|
+
var SDK_SKILL_NAMES = [SDK_SKILL_NAME, "deepline-plays-quickstart"];
|
|
21085
21417
|
var attemptedSync = false;
|
|
21086
21418
|
function shouldSkipSkillsSync() {
|
|
21087
21419
|
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
@@ -21198,19 +21530,19 @@ async function fetchSkillsUpdate(baseUrl, localVersion) {
|
|
|
21198
21530
|
}
|
|
21199
21531
|
}
|
|
21200
21532
|
function buildSkillsInstallArgs(baseUrl) {
|
|
21201
|
-
return buildSkillsAddArgs(baseUrl,
|
|
21533
|
+
return buildSkillsAddArgs(baseUrl, SDK_SKILL_NAMES);
|
|
21202
21534
|
}
|
|
21203
21535
|
function buildBunxSkillsInstallArgs(baseUrl) {
|
|
21204
|
-
return buildSkillsAddArgs(baseUrl,
|
|
21536
|
+
return buildSkillsAddArgs(baseUrl, SDK_SKILL_NAMES, { firstArg: "--bun" });
|
|
21205
21537
|
}
|
|
21206
21538
|
function hasCommand(command) {
|
|
21207
|
-
const result =
|
|
21539
|
+
const result = spawnSync2(command, ["--version"], {
|
|
21208
21540
|
stdio: "ignore",
|
|
21209
21541
|
shell: process.platform === "win32"
|
|
21210
21542
|
});
|
|
21211
21543
|
return result.status === 0;
|
|
21212
21544
|
}
|
|
21213
|
-
function
|
|
21545
|
+
function shellQuote4(arg) {
|
|
21214
21546
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
21215
21547
|
}
|
|
21216
21548
|
function resolveSkillsInstallCommands(baseUrl) {
|
|
@@ -21218,7 +21550,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
21218
21550
|
const npxInstall = {
|
|
21219
21551
|
command: "npx",
|
|
21220
21552
|
args: npxArgs,
|
|
21221
|
-
manualCommand: `npx ${npxArgs.map(
|
|
21553
|
+
manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
|
|
21222
21554
|
};
|
|
21223
21555
|
if (hasCommand("bunx")) {
|
|
21224
21556
|
const bunxArgs = buildBunxSkillsInstallArgs(baseUrl);
|
|
@@ -21226,7 +21558,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
21226
21558
|
{
|
|
21227
21559
|
command: "bunx",
|
|
21228
21560
|
args: bunxArgs,
|
|
21229
|
-
manualCommand: `bunx ${bunxArgs.map(
|
|
21561
|
+
manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
|
|
21230
21562
|
},
|
|
21231
21563
|
npxInstall
|
|
21232
21564
|
];
|
|
@@ -21235,7 +21567,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
21235
21567
|
}
|
|
21236
21568
|
function runOneSkillsInstall(install) {
|
|
21237
21569
|
return new Promise((resolve16) => {
|
|
21238
|
-
const child =
|
|
21570
|
+
const child = spawn4(install.command, install.args, {
|
|
21239
21571
|
stdio: ["ignore", "ignore", "pipe"],
|
|
21240
21572
|
env: process.env
|
|
21241
21573
|
});
|
|
@@ -21303,7 +21635,7 @@ async function syncSdkSkillsIfNeeded(baseUrl) {
|
|
|
21303
21635
|
if (!update?.needsUpdate && !hasStaleInstalledSkill || !update?.remoteVersion) {
|
|
21304
21636
|
return;
|
|
21305
21637
|
}
|
|
21306
|
-
writeSdkSkillsStatusLine("SDK skills changed; syncing
|
|
21638
|
+
writeSdkSkillsStatusLine("SDK skills changed; syncing Deepline SDK skills...");
|
|
21307
21639
|
const installed = await runSkillsInstall(baseUrl);
|
|
21308
21640
|
if (!installed) return;
|
|
21309
21641
|
if (installedSdkSkillHasStalePositionalExecuteExamples()) {
|
|
@@ -21526,7 +21858,9 @@ async function main() {
|
|
|
21526
21858
|
progress?.phase("loading deepline cli");
|
|
21527
21859
|
}
|
|
21528
21860
|
const program = new Command3();
|
|
21529
|
-
program.name("deepline").description(
|
|
21861
|
+
program.name("deepline").description(
|
|
21862
|
+
"Deepline CLI \u2014 GTM enrichment tools, plays, and runs from your terminal."
|
|
21863
|
+
).version(SDK_VERSION, "-v, --version", "Show version").exitOverride().showHelpAfterError().showSuggestionAfterError(true).addHelpText(
|
|
21530
21864
|
"after",
|
|
21531
21865
|
`
|
|
21532
21866
|
Common commands:
|
|
@@ -21567,11 +21901,23 @@ Exit codes:
|
|
|
21567
21901
|
progress?.phase("checking sdk compatibility");
|
|
21568
21902
|
}
|
|
21569
21903
|
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
21570
|
-
await traceCliSpan(
|
|
21904
|
+
const compatibility = await traceCliSpan(
|
|
21571
21905
|
"cli.sdk_compatibility",
|
|
21572
|
-
{ baseUrl },
|
|
21573
|
-
() =>
|
|
21906
|
+
{ baseUrl, command: actionCommand.name() },
|
|
21907
|
+
() => checkSdkCompatibility(baseUrl, {
|
|
21908
|
+
command: actionCommand.name()
|
|
21909
|
+
})
|
|
21910
|
+
);
|
|
21911
|
+
if (compatibility.error) {
|
|
21912
|
+
return;
|
|
21913
|
+
}
|
|
21914
|
+
const relaunched = await maybeAutoUpdateAndRelaunch(
|
|
21915
|
+
compatibility.response
|
|
21574
21916
|
);
|
|
21917
|
+
if (relaunched) {
|
|
21918
|
+
return;
|
|
21919
|
+
}
|
|
21920
|
+
enforceSdkCompatibilityResponse(compatibility.response);
|
|
21575
21921
|
if (printStartupPhase) {
|
|
21576
21922
|
progress?.phase("checking sdk skills");
|
|
21577
21923
|
}
|
|
@@ -21596,6 +21942,7 @@ Exit codes:
|
|
|
21596
21942
|
registerDbCommands(program);
|
|
21597
21943
|
registerFeedbackCommands(program);
|
|
21598
21944
|
registerUpdateCommand(program);
|
|
21945
|
+
registerQuickstartCommands(program);
|
|
21599
21946
|
program.command("preflight").description("Run compact health, auth, and Deepline billing checks.").option("--json", "Force JSON output.").addHelpText(
|
|
21600
21947
|
"after",
|
|
21601
21948
|
`
|
|
@@ -21671,6 +22018,29 @@ Examples:
|
|
|
21671
22018
|
process.stdout.write(`deepline ${SDK_VERSION}
|
|
21672
22019
|
`);
|
|
21673
22020
|
});
|
|
22021
|
+
if (process.argv.slice(2).length === 0) {
|
|
22022
|
+
if (!process.stdout.isTTY) {
|
|
22023
|
+
printJson({
|
|
22024
|
+
ok: false,
|
|
22025
|
+
exitCode: 2,
|
|
22026
|
+
code: "MISSING_COMMAND",
|
|
22027
|
+
message: "No command provided.",
|
|
22028
|
+
next: "deepline --help"
|
|
22029
|
+
});
|
|
22030
|
+
console.error("error: missing command (see: deepline --help)");
|
|
22031
|
+
} else {
|
|
22032
|
+
program.outputHelp({ error: true });
|
|
22033
|
+
console.error("\nerror: missing command (see usage above)");
|
|
22034
|
+
}
|
|
22035
|
+
recordCliTrace({
|
|
22036
|
+
phase: "cli.main_total",
|
|
22037
|
+
ms: Date.now() - mainStartedAt,
|
|
22038
|
+
ok: false,
|
|
22039
|
+
error: "missing command"
|
|
22040
|
+
});
|
|
22041
|
+
process.exitCode = 2;
|
|
22042
|
+
return;
|
|
22043
|
+
}
|
|
21674
22044
|
try {
|
|
21675
22045
|
await program.parseAsync(process.argv);
|
|
21676
22046
|
recordCliTrace({
|
package/dist/index.js
CHANGED
|
@@ -270,12 +270,22 @@ var SDK_RELEASE = {
|
|
|
270
270
|
// 0.1.105 ships the billing catalog surface: billing plans, subscribe,
|
|
271
271
|
// subscription status/cancel, invoices, and the client.billing namespace.
|
|
272
272
|
// 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
|
|
273
|
-
|
|
273
|
+
// 0.1.107 ships the v2 quickstart command, the deepline-plays-quickstart
|
|
274
|
+
// skill on the sdk sync surface, and the people-search-to-email prebuilt.
|
|
275
|
+
version: "0.1.107",
|
|
274
276
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
275
277
|
supportPolicy: {
|
|
276
|
-
latest: "0.1.
|
|
278
|
+
latest: "0.1.107",
|
|
277
279
|
minimumSupported: "0.1.53",
|
|
278
|
-
deprecatedBelow: "0.1.53"
|
|
280
|
+
deprecatedBelow: "0.1.53",
|
|
281
|
+
commandMinimumSupported: [
|
|
282
|
+
{
|
|
283
|
+
command: "enrich",
|
|
284
|
+
minimumSupported: "0.1.106",
|
|
285
|
+
reason: "Older SDK CLI enrich generated stale play source for the current dataset API."
|
|
286
|
+
}
|
|
287
|
+
],
|
|
288
|
+
autoUpdatePatchLag: 2
|
|
279
289
|
}
|
|
280
290
|
};
|
|
281
291
|
|
package/dist/index.mjs
CHANGED
|
@@ -192,12 +192,22 @@ var SDK_RELEASE = {
|
|
|
192
192
|
// 0.1.105 ships the billing catalog surface: billing plans, subscribe,
|
|
193
193
|
// subscription status/cancel, invoices, and the client.billing namespace.
|
|
194
194
|
// 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
|
|
195
|
-
|
|
195
|
+
// 0.1.107 ships the v2 quickstart command, the deepline-plays-quickstart
|
|
196
|
+
// skill on the sdk sync surface, and the people-search-to-email prebuilt.
|
|
197
|
+
version: "0.1.107",
|
|
196
198
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
197
199
|
supportPolicy: {
|
|
198
|
-
latest: "0.1.
|
|
200
|
+
latest: "0.1.107",
|
|
199
201
|
minimumSupported: "0.1.53",
|
|
200
|
-
deprecatedBelow: "0.1.53"
|
|
202
|
+
deprecatedBelow: "0.1.53",
|
|
203
|
+
commandMinimumSupported: [
|
|
204
|
+
{
|
|
205
|
+
command: "enrich",
|
|
206
|
+
minimumSupported: "0.1.106",
|
|
207
|
+
reason: "Older SDK CLI enrich generated stale play source for the current dataset API."
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
autoUpdatePatchLag: 2
|
|
201
211
|
}
|
|
202
212
|
};
|
|
203
213
|
|