deepline 0.1.126 → 0.1.127

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 CHANGED
@@ -404,10 +404,10 @@ var SDK_RELEASE = {
404
404
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
405
405
  // the SDK enrich generator's one-second stale policy.
406
406
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
407
- version: "0.1.126",
407
+ version: "0.1.127",
408
408
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
409
409
  supportPolicy: {
410
- latest: "0.1.126",
410
+ latest: "0.1.127",
411
411
  minimumSupported: "0.1.53",
412
412
  deprecatedBelow: "0.1.53",
413
413
  commandMinimumSupported: [
@@ -21248,24 +21248,362 @@ Notes:
21248
21248
  }
21249
21249
 
21250
21250
  // src/cli/commands/update.ts
21251
+ var import_node_child_process3 = require("child_process");
21252
+ var import_node_fs15 = require("fs");
21253
+ var import_node_os13 = require("os");
21254
+ var import_node_path18 = require("path");
21255
+
21256
+ // src/cli/skills-sync.ts
21251
21257
  var import_node_child_process2 = require("child_process");
21252
21258
  var import_node_fs14 = require("fs");
21253
21259
  var import_node_os12 = require("os");
21254
21260
  var import_node_path17 = require("path");
21261
+
21262
+ // ../shared_libs/cli/install-commands.json
21263
+ var install_commands_default = {
21264
+ skills: {
21265
+ index_path: "/.well-known/skills/index.json",
21266
+ default_agents: [
21267
+ "codex",
21268
+ "claude-code",
21269
+ "cursor",
21270
+ "gemini-cli",
21271
+ "antigravity"
21272
+ ],
21273
+ npx_binary: "npx",
21274
+ npx_add_args_template: [
21275
+ "--yes",
21276
+ "skills",
21277
+ "add",
21278
+ "{skills_index_url}",
21279
+ "--agent",
21280
+ "{agents}",
21281
+ "--global",
21282
+ "--yes",
21283
+ "--skill",
21284
+ "{skill_name}",
21285
+ "--full-depth"
21286
+ ]
21287
+ },
21288
+ cli: {
21289
+ legacy_python_shell_template: "curl -s {base_url}/api/v2/cli/install | bash",
21290
+ sdk_npm_global: "npm install -g deepline@latest"
21291
+ }
21292
+ };
21293
+
21294
+ // src/cli/install-commands.ts
21295
+ var INSTALL_COMMANDS = install_commands_default;
21296
+ var DEFAULT_V1_SKILL_NAMES = [
21297
+ "build-tam",
21298
+ "clay-to-deepline",
21299
+ "deepline-analytics",
21300
+ "deepline-feedback",
21301
+ "deepline-gtm",
21302
+ "deepline-quickstart",
21303
+ "find-qualified-titles",
21304
+ "linkedin-url-lookup",
21305
+ "niche-signal-discovery",
21306
+ "portfolio-prospecting",
21307
+ "workflow-hello-world"
21308
+ ];
21309
+ var DEFAULT_SDK_SKILL_NAMES = [
21310
+ ...DEFAULT_V1_SKILL_NAMES,
21311
+ "deepline-plays"
21312
+ ];
21313
+ function normalizeBaseUrl2(baseUrl) {
21314
+ return baseUrl.replace(/\/$/, "");
21315
+ }
21316
+ function renderTemplate(template, values) {
21317
+ return template.replace(/\{([a-z_]+)\}/g, (match, key) => {
21318
+ return values[key] ?? match;
21319
+ });
21320
+ }
21321
+ function shellJoin(args) {
21322
+ return args.join(" ");
21323
+ }
21324
+ function skillsIndexUrl(baseUrl) {
21325
+ return `${normalizeBaseUrl2(baseUrl)}${INSTALL_COMMANDS.skills.index_path}`;
21326
+ }
21327
+ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
21328
+ const skillNames = Array.isArray(skillName) ? skillName : [skillName];
21329
+ const [firstSkillName, ...extraSkillNames] = skillNames;
21330
+ const values = {
21331
+ skills_index_url: skillsIndexUrl(baseUrl),
21332
+ agents: INSTALL_COMMANDS.skills.default_agents.join(" "),
21333
+ skill_name: firstSkillName ?? ""
21334
+ };
21335
+ const rendered = INSTALL_COMMANDS.skills.npx_add_args_template.flatMap(
21336
+ (arg, index) => {
21337
+ const next = index === 0 && options.firstArg ? options.firstArg : arg;
21338
+ const value = renderTemplate(next, values);
21339
+ if (arg === "{agents}") {
21340
+ return INSTALL_COMMANDS.skills.default_agents;
21341
+ }
21342
+ if (arg === "{skill_name}") {
21343
+ return [value, ...extraSkillNames.flatMap((name) => ["--skill", name])];
21344
+ }
21345
+ return value;
21346
+ }
21347
+ );
21348
+ return rendered;
21349
+ }
21350
+ function skillsInstallCommand(baseUrl, skillName) {
21351
+ return `${INSTALL_COMMANDS.skills.npx_binary} ${shellJoin(
21352
+ buildSkillsAddArgs(baseUrl, skillName)
21353
+ )}`;
21354
+ }
21355
+ function legacyPythonInstallCommand(baseUrl) {
21356
+ return renderTemplate(INSTALL_COMMANDS.cli.legacy_python_shell_template, {
21357
+ base_url: normalizeBaseUrl2(baseUrl)
21358
+ });
21359
+ }
21360
+ function sdkNpmGlobalInstallCommand() {
21361
+ return INSTALL_COMMANDS.cli.sdk_npm_global;
21362
+ }
21363
+
21364
+ // src/cli/skills-sync.ts
21365
+ var CHECK_TIMEOUT_MS2 = 3e3;
21366
+ var SDK_PLAY_SKILL_NAME = "deepline-plays";
21367
+ var attemptedSync = false;
21368
+ function shouldSkipSkillsSync() {
21369
+ const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
21370
+ return value === "1" || value === "true" || value === "yes" || value === "on";
21371
+ }
21372
+ function activePluginSkillsDir() {
21373
+ const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
21374
+ if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
21375
+ return "";
21376
+ }
21377
+ const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
21378
+ return dir && (0, import_node_fs14.existsSync)(dir) ? dir : "";
21379
+ }
21380
+ function readPluginSkillsVersion() {
21381
+ const dir = activePluginSkillsDir();
21382
+ if (!dir) return "";
21383
+ try {
21384
+ return (0, import_node_fs14.readFileSync)((0, import_node_path17.join)(dir, ".version"), "utf-8").trim();
21385
+ } catch {
21386
+ return "";
21387
+ }
21388
+ }
21389
+ function sdkSkillsVersionPath(baseUrl) {
21390
+ const home = process.env.HOME?.trim() || (0, import_node_os12.homedir)();
21391
+ return (0, import_node_path17.join)(
21392
+ home,
21393
+ ".local",
21394
+ "deepline",
21395
+ baseUrlSlug(baseUrl),
21396
+ "sdk-skills",
21397
+ ".version"
21398
+ );
21399
+ }
21400
+ function readLocalSkillsVersion(baseUrl) {
21401
+ const pluginVersion = readPluginSkillsVersion();
21402
+ if (pluginVersion) return pluginVersion;
21403
+ const path = sdkSkillsVersionPath(baseUrl);
21404
+ if (!(0, import_node_fs14.existsSync)(path)) return "";
21405
+ try {
21406
+ return (0, import_node_fs14.readFileSync)(path, "utf-8").trim();
21407
+ } catch {
21408
+ return "";
21409
+ }
21410
+ }
21411
+ function writeLocalSkillsVersion(baseUrl, version) {
21412
+ const path = sdkSkillsVersionPath(baseUrl);
21413
+ (0, import_node_fs14.mkdirSync)((0, import_node_path17.dirname)(path), { recursive: true });
21414
+ (0, import_node_fs14.writeFileSync)(path, `${version}
21415
+ `, "utf-8");
21416
+ }
21417
+ function sortedUniqueSkillNames(names) {
21418
+ return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
21419
+ (a, b) => a.localeCompare(b)
21420
+ );
21421
+ }
21422
+ async function fetchV1SkillNames(baseUrl) {
21423
+ const controller = new AbortController();
21424
+ const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
21425
+ try {
21426
+ const response = await fetch(
21427
+ new URL("/.well-known/skills/index.json", baseUrl),
21428
+ { signal: controller.signal }
21429
+ );
21430
+ if (!response.ok) return [];
21431
+ const data = await response.json().catch(() => null);
21432
+ const names = (data?.skills ?? []).filter((skill) => skill.install_surface === "v1").map((skill) => skill.name).filter(
21433
+ (name) => typeof name === "string" && name.length > 0
21434
+ );
21435
+ return sortedUniqueSkillNames(names);
21436
+ } catch {
21437
+ return [];
21438
+ } finally {
21439
+ clearTimeout(timeout);
21440
+ }
21441
+ }
21442
+ function buildSdkSkillNames(v1SkillNames) {
21443
+ return sortedUniqueSkillNames([...v1SkillNames, SDK_PLAY_SKILL_NAME]);
21444
+ }
21445
+ async function fetchSkillsUpdate(baseUrl, localVersion) {
21446
+ const controller = new AbortController();
21447
+ const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
21448
+ try {
21449
+ const response = await fetch(new URL("/api/v2/cli/update-check", baseUrl), {
21450
+ method: "POST",
21451
+ headers: { "Content-Type": "application/json" },
21452
+ body: JSON.stringify({
21453
+ skills: {
21454
+ version: localVersion
21455
+ }
21456
+ }),
21457
+ signal: controller.signal
21458
+ });
21459
+ if (!response.ok) return null;
21460
+ const data = await response.json().catch(() => null);
21461
+ const skills = data?.skills;
21462
+ if (!skills) return null;
21463
+ return {
21464
+ needsUpdate: skills.needs_update === true,
21465
+ remoteVersion: typeof skills.remote?.version === "string" ? skills.remote.version.trim() : ""
21466
+ };
21467
+ } catch {
21468
+ return null;
21469
+ } finally {
21470
+ clearTimeout(timeout);
21471
+ }
21472
+ }
21473
+ function buildSkillsInstallArgs(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
21474
+ return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames));
21475
+ }
21476
+ function buildBunxSkillsInstallArgs(baseUrl, skillNames) {
21477
+ return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
21478
+ firstArg: "--bun"
21479
+ });
21480
+ }
21481
+ function hasCommand(command) {
21482
+ const result = (0, import_node_child_process2.spawnSync)(command, ["--version"], {
21483
+ stdio: "ignore",
21484
+ shell: process.platform === "win32"
21485
+ });
21486
+ return result.status === 0;
21487
+ }
21488
+ function shellQuote3(arg) {
21489
+ return `'${arg.replace(/'/g, `'\\''`)}'`;
21490
+ }
21491
+ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
21492
+ const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames);
21493
+ const npxInstall = {
21494
+ command: "npx",
21495
+ args: npxArgs,
21496
+ manualCommand: `npx ${npxArgs.map(shellQuote3).join(" ")}`
21497
+ };
21498
+ if (hasCommand("bunx")) {
21499
+ const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
21500
+ return [
21501
+ {
21502
+ command: "bunx",
21503
+ args: bunxArgs,
21504
+ manualCommand: `bunx ${bunxArgs.map(shellQuote3).join(" ")}`
21505
+ },
21506
+ npxInstall
21507
+ ];
21508
+ }
21509
+ return [npxInstall];
21510
+ }
21511
+ function runOneSkillsInstall(install) {
21512
+ return new Promise((resolve13) => {
21513
+ const child = (0, import_node_child_process2.spawn)(install.command, install.args, {
21514
+ stdio: ["ignore", "ignore", "pipe"],
21515
+ env: process.env
21516
+ });
21517
+ let stderr = "";
21518
+ child.stderr.on("data", (chunk) => {
21519
+ stderr += chunk.toString("utf-8");
21520
+ });
21521
+ child.on("error", (error) => {
21522
+ resolve13({
21523
+ ok: false,
21524
+ detail: `failed to start ${install.command}: ${error.message}`,
21525
+ manualCommand: install.manualCommand
21526
+ });
21527
+ });
21528
+ child.on("close", (code) => {
21529
+ if (code === 0) {
21530
+ resolve13({ ok: true, detail: "", manualCommand: install.manualCommand });
21531
+ return;
21532
+ }
21533
+ const detail = stderr.trim();
21534
+ resolve13({
21535
+ ok: false,
21536
+ detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
21537
+ manualCommand: install.manualCommand
21538
+ });
21539
+ });
21540
+ });
21541
+ }
21542
+ async function runSkillsInstall(baseUrl, skillNames) {
21543
+ const failures = [];
21544
+ for (const install of resolveSkillsInstallCommands(baseUrl, skillNames)) {
21545
+ const result = await runOneSkillsInstall(install);
21546
+ if (result.ok) return true;
21547
+ failures.push(result);
21548
+ }
21549
+ const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
21550
+ const manualCommand = failures.at(-1)?.manualCommand;
21551
+ process.stderr.write(
21552
+ `SDK skills sync failed${details ? `:
21553
+ ${details}` : ""}
21554
+ ` + (manualCommand ? `Run manually: ${manualCommand}
21555
+ ` : "")
21556
+ );
21557
+ return false;
21558
+ }
21559
+ function writeSdkSkillsStatusLine(line) {
21560
+ const progress = getActiveCliProgress();
21561
+ if (progress) {
21562
+ progress.writeLine(line);
21563
+ return;
21564
+ }
21565
+ process.stderr.write(`${line}
21566
+ `);
21567
+ }
21568
+ async function syncSdkSkillsIfNeeded(baseUrl) {
21569
+ if (attemptedSync || shouldSkipSkillsSync()) return;
21570
+ attemptedSync = true;
21571
+ const usingPluginSkills = Boolean(activePluginSkillsDir());
21572
+ const localVersion = readLocalSkillsVersion(baseUrl);
21573
+ const update = await fetchSkillsUpdate(baseUrl, localVersion);
21574
+ if (usingPluginSkills) {
21575
+ return;
21576
+ }
21577
+ if (!update?.needsUpdate || !update.remoteVersion) {
21578
+ return;
21579
+ }
21580
+ const remoteSkillNames = await fetchV1SkillNames(baseUrl);
21581
+ const skillNames = buildSdkSkillNames(
21582
+ remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
21583
+ );
21584
+ if (skillNames.length === 0) return;
21585
+ writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
21586
+ const installed = await runSkillsInstall(baseUrl, skillNames);
21587
+ if (!installed) return;
21588
+ writeLocalSkillsVersion(baseUrl, update.remoteVersion);
21589
+ writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
21590
+ }
21591
+
21592
+ // src/cli/commands/update.ts
21255
21593
  function posixShellQuote(value) {
21256
21594
  return `'${value.replace(/'/g, `'\\''`)}'`;
21257
21595
  }
21258
21596
  function windowsCmdQuote(value) {
21259
21597
  return `"${value.replace(/"/g, '""')}"`;
21260
21598
  }
21261
- function shellQuote3(value) {
21599
+ function shellQuote4(value) {
21262
21600
  if (process.platform === "win32") {
21263
21601
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
21264
21602
  }
21265
21603
  return posixShellQuote(value);
21266
21604
  }
21267
21605
  function buildSourceUpdateCommand(sourceRoot) {
21268
- const quotedRoot = shellQuote3(sourceRoot);
21606
+ const quotedRoot = shellQuote4(sourceRoot);
21269
21607
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
21270
21608
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
21271
21609
  }
@@ -21274,11 +21612,11 @@ function sidecarStateDir(input2) {
21274
21612
  if (!scope || scope.includes("/") || scope.includes("\\")) {
21275
21613
  return null;
21276
21614
  }
21277
- return (0, import_node_path17.join)(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
21615
+ return (0, import_node_path18.join)(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
21278
21616
  }
21279
21617
  function readOptionalText(path) {
21280
21618
  try {
21281
- return (0, import_node_fs14.readFileSync)(path, "utf8").trim();
21619
+ return (0, import_node_fs15.readFileSync)(path, "utf8").trim();
21282
21620
  } catch {
21283
21621
  return "";
21284
21622
  }
@@ -21286,26 +21624,26 @@ function readOptionalText(path) {
21286
21624
  function resolvePythonSidecarUpdatePlan(options) {
21287
21625
  const stateDir = sidecarStateDir(options);
21288
21626
  if (!stateDir) return null;
21289
- const relativeEntrypoint = (0, import_node_path17.relative)(
21290
- (0, import_node_path17.resolve)(stateDir),
21291
- (0, import_node_path17.resolve)(options.entrypoint)
21627
+ const relativeEntrypoint = (0, import_node_path18.relative)(
21628
+ (0, import_node_path18.resolve)(stateDir),
21629
+ (0, import_node_path18.resolve)(options.entrypoint)
21292
21630
  );
21293
- if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || (0, import_node_path17.isAbsolute)(relativeEntrypoint)) {
21631
+ if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || (0, import_node_path18.isAbsolute)(relativeEntrypoint)) {
21294
21632
  return null;
21295
21633
  }
21296
- const installMethod = readOptionalText((0, import_node_path17.join)(stateDir, ".install-method"));
21634
+ const installMethod = readOptionalText((0, import_node_path18.join)(stateDir, ".install-method"));
21297
21635
  if (installMethod !== "python-sidecar") return null;
21298
21636
  const scope = options.env.DEEPLINE_CONFIG_SCOPE?.trim() || "";
21299
21637
  const hostUrl = options.env.DEEPLINE_HOST_URL?.trim() || "";
21300
- const nodeBin = readOptionalText((0, import_node_path17.join)(stateDir, ".node-bin")) || process.execPath;
21301
- const sidecarPath = readOptionalText((0, import_node_path17.join)(stateDir, ".command-path")) || (0, import_node_path17.join)(
21638
+ const nodeBin = readOptionalText((0, import_node_path18.join)(stateDir, ".node-bin")) || process.execPath;
21639
+ const sidecarPath = readOptionalText((0, import_node_path18.join)(stateDir, ".command-path")) || (0, import_node_path18.join)(
21302
21640
  stateDir,
21303
21641
  "bin",
21304
21642
  process.platform === "win32" ? "deepline-sdk.cmd" : "deepline-sdk"
21305
21643
  );
21306
21644
  const packageSpec = options.packageSpec || "deepline@latest";
21307
21645
  const npmCommand = "npm";
21308
- const manualCommand = `${npmCommand} install --prefix ${shellQuote3((0, import_node_path17.join)(stateDir, "versions", "<version>"))} --no-audit --no-fund ${shellQuote3(packageSpec)}`;
21646
+ const manualCommand = `${npmCommand} install --prefix ${shellQuote4((0, import_node_path18.join)(stateDir, "versions", "<version>"))} --no-audit --no-fund ${shellQuote4(packageSpec)}`;
21309
21647
  return {
21310
21648
  kind: "python-sidecar",
21311
21649
  stateDir,
@@ -21319,12 +21657,12 @@ function resolvePythonSidecarUpdatePlan(options) {
21319
21657
  };
21320
21658
  }
21321
21659
  function findRepoBackedSdkRoot(startPath) {
21322
- let current = (0, import_node_path17.resolve)(startPath);
21660
+ let current = (0, import_node_path18.resolve)(startPath);
21323
21661
  while (true) {
21324
- if ((0, import_node_fs14.existsSync)((0, import_node_path17.join)(current, "sdk", "package.json")) && (0, import_node_fs14.existsSync)((0, import_node_path17.join)(current, "sdk", "bin", "deepline-dev.ts"))) {
21662
+ if ((0, import_node_fs15.existsSync)((0, import_node_path18.join)(current, "sdk", "package.json")) && (0, import_node_fs15.existsSync)((0, import_node_path18.join)(current, "sdk", "bin", "deepline-dev.ts"))) {
21325
21663
  return current;
21326
21664
  }
21327
- const parent = (0, import_node_path17.dirname)(current);
21665
+ const parent = (0, import_node_path18.dirname)(current);
21328
21666
  if (parent === current) return null;
21329
21667
  current = parent;
21330
21668
  }
@@ -21332,9 +21670,9 @@ function findRepoBackedSdkRoot(startPath) {
21332
21670
  function inferNpmGlobalPrefixFromEntrypoint(entrypoint) {
21333
21671
  const normalized = (() => {
21334
21672
  try {
21335
- return (0, import_node_fs14.realpathSync)(entrypoint);
21673
+ return (0, import_node_fs15.realpathSync)(entrypoint);
21336
21674
  } catch {
21337
- return (0, import_node_path17.resolve)(entrypoint);
21675
+ return (0, import_node_path18.resolve)(entrypoint);
21338
21676
  }
21339
21677
  })();
21340
21678
  const parts = normalized.split(/[\\/]+/);
@@ -21352,9 +21690,9 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint) {
21352
21690
  }
21353
21691
  function resolveUpdatePlan(options = {}) {
21354
21692
  const env = options.env ?? process.env;
21355
- const homeDir2 = options.homeDir ?? (0, import_node_os12.homedir)();
21356
- const entrypoint = options.entrypoint ?? (process.argv[1] ? (0, import_node_path17.resolve)(process.argv[1]) : "");
21357
- const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0, import_node_path17.dirname)(entrypoint)) : null;
21693
+ const homeDir2 = options.homeDir ?? (0, import_node_os13.homedir)();
21694
+ const entrypoint = options.entrypoint ?? (process.argv[1] ? (0, import_node_path18.resolve)(process.argv[1]) : "");
21695
+ const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0, import_node_path18.dirname)(entrypoint)) : null;
21358
21696
  if (sourceRoot) {
21359
21697
  return {
21360
21698
  kind: "source",
@@ -21378,17 +21716,17 @@ function resolveUpdatePlan(options = {}) {
21378
21716
  command,
21379
21717
  args,
21380
21718
  ...installPrefix ? { installPrefix } : {},
21381
- manualCommand: `${command} ${args.map(shellQuote3).join(" ")}`
21719
+ manualCommand: `${command} ${args.map(shellQuote4).join(" ")}`
21382
21720
  };
21383
21721
  }
21384
21722
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
21385
21723
  function autoUpdateFailurePath(plan) {
21386
21724
  if (plan.kind === "source") return null;
21387
21725
  if (plan.kind === "python-sidecar") {
21388
- return (0, import_node_path17.join)(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
21726
+ return (0, import_node_path18.join)(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
21389
21727
  }
21390
- return (0, import_node_path17.join)(
21391
- (0, import_node_os12.homedir)(),
21728
+ return (0, import_node_path18.join)(
21729
+ (0, import_node_os13.homedir)(),
21392
21730
  ".local",
21393
21731
  "deepline",
21394
21732
  "sdk-cli",
@@ -21405,7 +21743,7 @@ function readAutoUpdateFailure(plan) {
21405
21743
  if (!path) return null;
21406
21744
  try {
21407
21745
  const parsed = JSON.parse(
21408
- (0, import_node_fs14.readFileSync)(path, "utf8")
21746
+ (0, import_node_fs15.readFileSync)(path, "utf8")
21409
21747
  );
21410
21748
  if ((parsed.kind === "npm-global" || parsed.kind === "python-sidecar") && typeof parsed.packageSpec === "string" && typeof parsed.failedAt === "string" && typeof parsed.exitCode === "number" && typeof parsed.manualCommand === "string") {
21411
21749
  return parsed;
@@ -21426,8 +21764,8 @@ function writeAutoUpdateFailure(plan, exitCode) {
21426
21764
  manualCommand: plan.manualCommand
21427
21765
  };
21428
21766
  try {
21429
- (0, import_node_fs14.mkdirSync)((0, import_node_path17.dirname)(path), { recursive: true });
21430
- (0, import_node_fs14.writeFileSync)(path, `${JSON.stringify(marker, null, 2)}
21767
+ (0, import_node_fs15.mkdirSync)((0, import_node_path18.dirname)(path), { recursive: true });
21768
+ (0, import_node_fs15.writeFileSync)(path, `${JSON.stringify(marker, null, 2)}
21431
21769
  `, "utf8");
21432
21770
  } catch {
21433
21771
  }
@@ -21436,7 +21774,7 @@ function clearAutoUpdateFailure(plan) {
21436
21774
  const path = autoUpdateFailurePath(plan);
21437
21775
  if (!path) return;
21438
21776
  try {
21439
- (0, import_node_fs14.unlinkSync)(path);
21777
+ (0, import_node_fs15.unlinkSync)(path);
21440
21778
  } catch {
21441
21779
  }
21442
21780
  }
@@ -21472,7 +21810,7 @@ function safeVersionSegment(value) {
21472
21810
  return /^[0-9A-Za-z._-]+$/.test(normalized) ? normalized : "";
21473
21811
  }
21474
21812
  function entryPathInVersionDir(versionDir) {
21475
- return (0, import_node_path17.join)(
21813
+ return (0, import_node_path18.join)(
21476
21814
  versionDir,
21477
21815
  "node_modules",
21478
21816
  "deepline",
@@ -21482,14 +21820,14 @@ function entryPathInVersionDir(versionDir) {
21482
21820
  );
21483
21821
  }
21484
21822
  function installedPackageVersion(versionDir) {
21485
- const packageJsonPath = (0, import_node_path17.join)(
21823
+ const packageJsonPath = (0, import_node_path18.join)(
21486
21824
  versionDir,
21487
21825
  "node_modules",
21488
21826
  "deepline",
21489
21827
  "package.json"
21490
21828
  );
21491
21829
  try {
21492
- const parsed = JSON.parse((0, import_node_fs14.readFileSync)(packageJsonPath, "utf8"));
21830
+ const parsed = JSON.parse((0, import_node_fs15.readFileSync)(packageJsonPath, "utf8"));
21493
21831
  return typeof parsed.version === "string" ? safeVersionSegment(parsed.version) : "";
21494
21832
  } catch {
21495
21833
  return "";
@@ -21497,7 +21835,7 @@ function installedPackageVersion(versionDir) {
21497
21835
  }
21498
21836
  function runCommand(command, args, env = process.env) {
21499
21837
  return new Promise((resolveExitCode) => {
21500
- const child = (0, import_node_child_process2.spawn)(command, args, {
21838
+ const child = (0, import_node_child_process3.spawn)(command, args, {
21501
21839
  stdio: "inherit",
21502
21840
  shell: process.platform === "win32",
21503
21841
  env
@@ -21513,9 +21851,9 @@ function runCommand(command, args, env = process.env) {
21513
21851
  });
21514
21852
  }
21515
21853
  function writeSidecarLauncher(input2) {
21516
- (0, import_node_fs14.mkdirSync)((0, import_node_path17.dirname)(input2.path), { recursive: true });
21854
+ (0, import_node_fs15.mkdirSync)((0, import_node_path18.dirname)(input2.path), { recursive: true });
21517
21855
  if (process.platform === "win32") {
21518
- (0, import_node_fs14.writeFileSync)(
21856
+ (0, import_node_fs15.writeFileSync)(
21519
21857
  input2.path,
21520
21858
  [
21521
21859
  `@set DEEPLINE_HOST_URL=${input2.hostUrl.replace(/\r?\n/g, "")}`,
@@ -21527,30 +21865,30 @@ function writeSidecarLauncher(input2) {
21527
21865
  );
21528
21866
  return;
21529
21867
  }
21530
- (0, import_node_fs14.writeFileSync)(
21868
+ (0, import_node_fs15.writeFileSync)(
21531
21869
  input2.path,
21532
21870
  [
21533
21871
  "#!/usr/bin/env sh",
21534
- `export DEEPLINE_HOST_URL=${shellQuote3(input2.hostUrl)}`,
21535
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote3(input2.scope)}`,
21536
- `exec ${shellQuote3(input2.nodeBin)} ${shellQuote3(input2.entryPath)} "$@"`,
21872
+ `export DEEPLINE_HOST_URL=${shellQuote4(input2.hostUrl)}`,
21873
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote4(input2.scope)}`,
21874
+ `exec ${shellQuote4(input2.nodeBin)} ${shellQuote4(input2.entryPath)} "$@"`,
21537
21875
  ""
21538
21876
  ].join("\n"),
21539
21877
  { encoding: "utf8", mode: 493 }
21540
21878
  );
21541
21879
  }
21542
21880
  async function runPythonSidecarUpdatePlan(plan) {
21543
- const versionsDir = (0, import_node_path17.join)(plan.stateDir, "versions");
21544
- const tempDir = (0, import_node_path17.join)(
21881
+ const versionsDir = (0, import_node_path18.join)(plan.stateDir, "versions");
21882
+ const tempDir = (0, import_node_path18.join)(
21545
21883
  versionsDir,
21546
21884
  `.tmp-sdk-update-${process.pid}-${Date.now()}`
21547
21885
  );
21548
- (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
21549
- (0, import_node_fs14.mkdirSync)(tempDir, { recursive: true });
21550
- (0, import_node_fs14.writeFileSync)((0, import_node_path17.join)(tempDir, "package.json"), '{"private":true}\n', "utf8");
21886
+ (0, import_node_fs15.rmSync)(tempDir, { recursive: true, force: true });
21887
+ (0, import_node_fs15.mkdirSync)(tempDir, { recursive: true });
21888
+ (0, import_node_fs15.writeFileSync)((0, import_node_path18.join)(tempDir, "package.json"), '{"private":true}\n', "utf8");
21551
21889
  const env = {
21552
21890
  ...process.env,
21553
- PATH: `${(0, import_node_path17.dirname)(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
21891
+ PATH: `${(0, import_node_path18.dirname)(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
21554
21892
  };
21555
21893
  const installExitCode = await runCommand(
21556
21894
  plan.npmCommand,
@@ -21565,7 +21903,7 @@ async function runPythonSidecarUpdatePlan(plan) {
21565
21903
  env
21566
21904
  );
21567
21905
  if (installExitCode !== 0) {
21568
- (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
21906
+ (0, import_node_fs15.rmSync)(tempDir, { recursive: true, force: true });
21569
21907
  return installExitCode;
21570
21908
  }
21571
21909
  const installedVersion = installedPackageVersion(tempDir);
@@ -21573,19 +21911,19 @@ async function runPythonSidecarUpdatePlan(plan) {
21573
21911
  process.stderr.write(
21574
21912
  "Updated Deepline SDK package did not report a version.\n"
21575
21913
  );
21576
- (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
21914
+ (0, import_node_fs15.rmSync)(tempDir, { recursive: true, force: true });
21577
21915
  return 1;
21578
21916
  }
21579
- const finalDir = (0, import_node_path17.join)(versionsDir, installedVersion);
21917
+ const finalDir = (0, import_node_path18.join)(versionsDir, installedVersion);
21580
21918
  const finalEntryPath = entryPathInVersionDir(finalDir);
21581
- if ((0, import_node_fs14.existsSync)(finalEntryPath)) {
21582
- (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
21919
+ if ((0, import_node_fs15.existsSync)(finalEntryPath)) {
21920
+ (0, import_node_fs15.rmSync)(tempDir, { recursive: true, force: true });
21583
21921
  } else {
21584
- (0, import_node_fs14.rmSync)(finalDir, { recursive: true, force: true });
21922
+ (0, import_node_fs15.rmSync)(finalDir, { recursive: true, force: true });
21585
21923
  try {
21586
- (0, import_node_fs14.renameSync)(tempDir, finalDir);
21924
+ (0, import_node_fs15.renameSync)(tempDir, finalDir);
21587
21925
  } catch (error) {
21588
- (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
21926
+ (0, import_node_fs15.rmSync)(tempDir, { recursive: true, force: true });
21589
21927
  process.stderr.write(
21590
21928
  `Failed to publish Deepline SDK sidecar update: ${error.message}
21591
21929
  `
@@ -21593,7 +21931,7 @@ async function runPythonSidecarUpdatePlan(plan) {
21593
21931
  return 1;
21594
21932
  }
21595
21933
  }
21596
- if (!(0, import_node_fs14.existsSync)(finalEntryPath)) {
21934
+ if (!(0, import_node_fs15.existsSync)(finalEntryPath)) {
21597
21935
  process.stderr.write(
21598
21936
  `Updated Deepline SDK CLI entrypoint missing: ${finalEntryPath}
21599
21937
  `
@@ -21607,28 +21945,28 @@ async function runPythonSidecarUpdatePlan(plan) {
21607
21945
  nodeBin: plan.nodeBin,
21608
21946
  entryPath: finalEntryPath
21609
21947
  });
21610
- (0, import_node_fs14.writeFileSync)(
21611
- (0, import_node_path17.join)(plan.stateDir, ".version"),
21948
+ (0, import_node_fs15.writeFileSync)(
21949
+ (0, import_node_path18.join)(plan.stateDir, ".version"),
21612
21950
  `${installedVersion}
21613
21951
  `,
21614
21952
  "utf8"
21615
21953
  );
21616
- (0, import_node_fs14.writeFileSync)(
21617
- (0, import_node_path17.join)(plan.stateDir, ".install-method"),
21954
+ (0, import_node_fs15.writeFileSync)(
21955
+ (0, import_node_path18.join)(plan.stateDir, ".install-method"),
21618
21956
  "python-sidecar\n",
21619
21957
  "utf8"
21620
21958
  );
21621
- (0, import_node_fs14.writeFileSync)(
21622
- (0, import_node_path17.join)(plan.stateDir, ".command-path"),
21959
+ (0, import_node_fs15.writeFileSync)(
21960
+ (0, import_node_path18.join)(plan.stateDir, ".command-path"),
21623
21961
  `${plan.sidecarPath}
21624
21962
  `,
21625
21963
  "utf8"
21626
21964
  );
21627
- (0, import_node_fs14.writeFileSync)((0, import_node_path17.join)(plan.stateDir, ".runner"), "node\n", "utf8");
21628
- (0, import_node_fs14.writeFileSync)((0, import_node_path17.join)(plan.stateDir, ".node-bin"), `${plan.nodeBin}
21965
+ (0, import_node_fs15.writeFileSync)((0, import_node_path18.join)(plan.stateDir, ".runner"), "node\n", "utf8");
21966
+ (0, import_node_fs15.writeFileSync)((0, import_node_path18.join)(plan.stateDir, ".node-bin"), `${plan.nodeBin}
21629
21967
  `, "utf8");
21630
- (0, import_node_fs14.writeFileSync)(
21631
- (0, import_node_path17.join)(plan.stateDir, ".entry-path"),
21968
+ (0, import_node_fs15.writeFileSync)(
21969
+ (0, import_node_path18.join)(plan.stateDir, ".entry-path"),
21632
21970
  `${finalEntryPath}
21633
21971
  `,
21634
21972
  "utf8"
@@ -21649,8 +21987,16 @@ async function runUpdatePlan(plan) {
21649
21987
  }
21650
21988
  return exitCode;
21651
21989
  }
21652
- async function handleUpdate(options) {
21653
- const plan = resolveUpdatePlan();
21990
+ function normalizeBaseUrl3(value) {
21991
+ return value.replace(/\/$/, "");
21992
+ }
21993
+ async function runUpdateCommand(options, dependencies = {}) {
21994
+ const detectBaseUrl = dependencies.detectBaseUrl ?? autoDetectBaseUrl;
21995
+ const resolvePlan = dependencies.resolvePlan ?? resolveUpdatePlan;
21996
+ const runPlan = dependencies.runPlan ?? runUpdatePlan;
21997
+ const syncSkills = dependencies.syncSkillsIfNeeded ?? syncSdkSkillsIfNeeded;
21998
+ const stderr = dependencies.stderr ?? process.stderr;
21999
+ const plan = resolvePlan();
21654
22000
  const render = {
21655
22001
  sections: [
21656
22002
  {
@@ -21686,11 +22032,14 @@ async function handleUpdate(options) {
21686
22032
  printCommandEnvelope({ ...plan, render }, { json: false });
21687
22033
  return 0;
21688
22034
  }
21689
- process.stderr.write(
21690
- `Updating Deepline SDK/CLI with: ${plan.manualCommand}
21691
- `
21692
- );
21693
- return runUpdatePlan(plan);
22035
+ stderr.write(`Updating Deepline SDK/CLI with: ${plan.manualCommand}
22036
+ `);
22037
+ const updateExitCode = await runPlan(plan);
22038
+ if (updateExitCode !== 0) {
22039
+ return updateExitCode;
22040
+ }
22041
+ await syncSkills(normalizeBaseUrl3(detectBaseUrl()));
22042
+ return 0;
21694
22043
  }
21695
22044
  function registerUpdateCommand(program) {
21696
22045
  program.command("update").description("Update the Deepline SDK/CLI.").addHelpText(
@@ -21709,7 +22058,7 @@ Examples:
21709
22058
  deepline update --json
21710
22059
  `
21711
22060
  ).option("--print-command", "Print the update command without running it").option("--json", "Emit the resolved update plan as JSON").action(async (options) => {
21712
- process.exitCode = await handleUpdate(options);
22061
+ process.exitCode = await runUpdateCommand(options);
21713
22062
  });
21714
22063
  }
21715
22064
 
@@ -21719,141 +22068,39 @@ var command_compatibility_default = {
21719
22068
  family: "python",
21720
22069
  label: "a legacy Python CLI enrichment command",
21721
22070
  sdk_alternative: "Use `deepline plays ...` for durable workflows or `deepline tools execute ...` for one tool call."
21722
- },
21723
- session: {
21724
- family: "python",
21725
- label: "a legacy Python CLI session/playground command",
21726
- sdk_alternative: "Use `deepline sessions send ...` or `deepline sessions render ...` for transcript workflows."
21727
- },
21728
- workflows: {
21729
- family: "python",
21730
- label: "a legacy Python CLI workflow command",
21731
- sdk_alternative: "Use `deepline plays ...` in the SDK CLI."
21732
- },
21733
- events: {
21734
- family: "python",
21735
- label: "a legacy Python CLI event command"
21736
- },
21737
- plays: {
21738
- family: "sdk",
21739
- label: "an SDK CLI play command",
21740
- python_alternative: "Use `deepline workflows ...` only for legacy workflows."
21741
- },
21742
- runs: {
21743
- family: "sdk",
21744
- label: "an SDK CLI run inspection command"
21745
- },
21746
- sessions: {
21747
- family: "sdk",
21748
- label: "an SDK CLI session transcript command"
21749
- },
21750
- health: {
21751
- family: "sdk",
21752
- label: "an SDK CLI health command"
21753
- }
21754
- };
21755
-
21756
- // ../shared_libs/cli/install-commands.json
21757
- var install_commands_default = {
21758
- skills: {
21759
- index_path: "/.well-known/skills/index.json",
21760
- default_agents: [
21761
- "codex",
21762
- "claude-code",
21763
- "cursor",
21764
- "gemini-cli",
21765
- "antigravity"
21766
- ],
21767
- npx_binary: "npx",
21768
- npx_add_args_template: [
21769
- "--yes",
21770
- "skills",
21771
- "add",
21772
- "{skills_index_url}",
21773
- "--agent",
21774
- "{agents}",
21775
- "--global",
21776
- "--yes",
21777
- "--skill",
21778
- "{skill_name}",
21779
- "--full-depth"
21780
- ]
21781
- },
21782
- cli: {
21783
- legacy_python_shell_template: "curl -s {base_url}/api/v2/cli/install | bash",
21784
- sdk_npm_global: "npm install -g deepline@latest"
21785
- }
21786
- };
21787
-
21788
- // src/cli/install-commands.ts
21789
- var INSTALL_COMMANDS = install_commands_default;
21790
- var DEFAULT_V1_SKILL_NAMES = [
21791
- "build-tam",
21792
- "clay-to-deepline",
21793
- "deepline-analytics",
21794
- "deepline-feedback",
21795
- "deepline-gtm",
21796
- "deepline-quickstart",
21797
- "find-qualified-titles",
21798
- "linkedin-url-lookup",
21799
- "niche-signal-discovery",
21800
- "portfolio-prospecting",
21801
- "workflow-hello-world"
21802
- ];
21803
- var DEFAULT_SDK_SKILL_NAMES = [
21804
- ...DEFAULT_V1_SKILL_NAMES,
21805
- "deepline-plays"
21806
- ];
21807
- function normalizeBaseUrl2(baseUrl) {
21808
- return baseUrl.replace(/\/$/, "");
21809
- }
21810
- function renderTemplate(template, values) {
21811
- return template.replace(/\{([a-z_]+)\}/g, (match, key) => {
21812
- return values[key] ?? match;
21813
- });
21814
- }
21815
- function shellJoin(args) {
21816
- return args.join(" ");
21817
- }
21818
- function skillsIndexUrl(baseUrl) {
21819
- return `${normalizeBaseUrl2(baseUrl)}${INSTALL_COMMANDS.skills.index_path}`;
21820
- }
21821
- function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
21822
- const skillNames = Array.isArray(skillName) ? skillName : [skillName];
21823
- const [firstSkillName, ...extraSkillNames] = skillNames;
21824
- const values = {
21825
- skills_index_url: skillsIndexUrl(baseUrl),
21826
- agents: INSTALL_COMMANDS.skills.default_agents.join(" "),
21827
- skill_name: firstSkillName ?? ""
21828
- };
21829
- const rendered = INSTALL_COMMANDS.skills.npx_add_args_template.flatMap(
21830
- (arg, index) => {
21831
- const next = index === 0 && options.firstArg ? options.firstArg : arg;
21832
- const value = renderTemplate(next, values);
21833
- if (arg === "{agents}") {
21834
- return INSTALL_COMMANDS.skills.default_agents;
21835
- }
21836
- if (arg === "{skill_name}") {
21837
- return [value, ...extraSkillNames.flatMap((name) => ["--skill", name])];
21838
- }
21839
- return value;
21840
- }
21841
- );
21842
- return rendered;
21843
- }
21844
- function skillsInstallCommand(baseUrl, skillName) {
21845
- return `${INSTALL_COMMANDS.skills.npx_binary} ${shellJoin(
21846
- buildSkillsAddArgs(baseUrl, skillName)
21847
- )}`;
21848
- }
21849
- function legacyPythonInstallCommand(baseUrl) {
21850
- return renderTemplate(INSTALL_COMMANDS.cli.legacy_python_shell_template, {
21851
- base_url: normalizeBaseUrl2(baseUrl)
21852
- });
21853
- }
21854
- function sdkNpmGlobalInstallCommand() {
21855
- return INSTALL_COMMANDS.cli.sdk_npm_global;
21856
- }
22071
+ },
22072
+ session: {
22073
+ family: "python",
22074
+ label: "a legacy Python CLI session/playground command",
22075
+ sdk_alternative: "Use `deepline sessions send ...` or `deepline sessions render ...` for transcript workflows."
22076
+ },
22077
+ workflows: {
22078
+ family: "python",
22079
+ label: "a legacy Python CLI workflow command",
22080
+ sdk_alternative: "Use `deepline plays ...` in the SDK CLI."
22081
+ },
22082
+ events: {
22083
+ family: "python",
22084
+ label: "a legacy Python CLI event command"
22085
+ },
22086
+ plays: {
22087
+ family: "sdk",
22088
+ label: "an SDK CLI play command",
22089
+ python_alternative: "Use `deepline workflows ...` only for legacy workflows."
22090
+ },
22091
+ runs: {
22092
+ family: "sdk",
22093
+ label: "an SDK CLI run inspection command"
22094
+ },
22095
+ sessions: {
22096
+ family: "sdk",
22097
+ label: "an SDK CLI session transcript command"
22098
+ },
22099
+ health: {
22100
+ family: "sdk",
22101
+ label: "an SDK CLI health command"
22102
+ }
22103
+ };
21857
22104
 
21858
22105
  // src/cli/command-compatibility.ts
21859
22106
  var COMMAND_COMPATIBILITY = command_compatibility_default;
@@ -21908,7 +22155,7 @@ function unknownCommandNameFromMessage(message) {
21908
22155
  }
21909
22156
 
21910
22157
  // src/cli/self-update.ts
21911
- var import_node_child_process3 = require("child_process");
22158
+ var import_node_child_process4 = require("child_process");
21912
22159
  function envTruthy(name) {
21913
22160
  const value = process.env[name]?.trim().toLowerCase();
21914
22161
  return value === "1" || value === "true" || value === "yes";
@@ -21923,7 +22170,7 @@ function relaunchCurrentCommand(plan) {
21923
22170
  return new Promise((resolve13) => {
21924
22171
  const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
21925
22172
  const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
21926
- const child = (0, import_node_child_process3.spawn)(command, args, {
22173
+ const child = (0, import_node_child_process4.spawn)(command, args, {
21927
22174
  stdio: "inherit",
21928
22175
  shell: process.platform === "win32",
21929
22176
  env: {
@@ -21978,238 +22225,6 @@ async function maybeAutoUpdateAndRelaunch(response) {
21978
22225
  return true;
21979
22226
  }
21980
22227
 
21981
- // src/cli/skills-sync.ts
21982
- var import_node_child_process4 = require("child_process");
21983
- var import_node_fs15 = require("fs");
21984
- var import_node_os13 = require("os");
21985
- var import_node_path18 = require("path");
21986
- var CHECK_TIMEOUT_MS2 = 3e3;
21987
- var SDK_PLAY_SKILL_NAME = "deepline-plays";
21988
- var attemptedSync = false;
21989
- function shouldSkipSkillsSync() {
21990
- const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
21991
- return value === "1" || value === "true" || value === "yes" || value === "on";
21992
- }
21993
- function activePluginSkillsDir() {
21994
- const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
21995
- if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
21996
- return "";
21997
- }
21998
- const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
21999
- return dir && (0, import_node_fs15.existsSync)(dir) ? dir : "";
22000
- }
22001
- function readPluginSkillsVersion() {
22002
- const dir = activePluginSkillsDir();
22003
- if (!dir) return "";
22004
- try {
22005
- return (0, import_node_fs15.readFileSync)((0, import_node_path18.join)(dir, ".version"), "utf-8").trim();
22006
- } catch {
22007
- return "";
22008
- }
22009
- }
22010
- function sdkSkillsVersionPath(baseUrl) {
22011
- const home = process.env.HOME?.trim() || (0, import_node_os13.homedir)();
22012
- return (0, import_node_path18.join)(
22013
- home,
22014
- ".local",
22015
- "deepline",
22016
- baseUrlSlug(baseUrl),
22017
- "sdk-skills",
22018
- ".version"
22019
- );
22020
- }
22021
- function readLocalSkillsVersion(baseUrl) {
22022
- const pluginVersion = readPluginSkillsVersion();
22023
- if (pluginVersion) return pluginVersion;
22024
- const path = sdkSkillsVersionPath(baseUrl);
22025
- if (!(0, import_node_fs15.existsSync)(path)) return "";
22026
- try {
22027
- return (0, import_node_fs15.readFileSync)(path, "utf-8").trim();
22028
- } catch {
22029
- return "";
22030
- }
22031
- }
22032
- function writeLocalSkillsVersion(baseUrl, version) {
22033
- const path = sdkSkillsVersionPath(baseUrl);
22034
- (0, import_node_fs15.mkdirSync)((0, import_node_path18.dirname)(path), { recursive: true });
22035
- (0, import_node_fs15.writeFileSync)(path, `${version}
22036
- `, "utf-8");
22037
- }
22038
- function sortedUniqueSkillNames(names) {
22039
- return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
22040
- (a, b) => a.localeCompare(b)
22041
- );
22042
- }
22043
- async function fetchV1SkillNames(baseUrl) {
22044
- const controller = new AbortController();
22045
- const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
22046
- try {
22047
- const response = await fetch(
22048
- new URL("/.well-known/skills/index.json", baseUrl),
22049
- { signal: controller.signal }
22050
- );
22051
- if (!response.ok) return [];
22052
- const data = await response.json().catch(() => null);
22053
- const names = (data?.skills ?? []).filter((skill) => skill.install_surface === "v1").map((skill) => skill.name).filter(
22054
- (name) => typeof name === "string" && name.length > 0
22055
- );
22056
- return sortedUniqueSkillNames(names);
22057
- } catch {
22058
- return [];
22059
- } finally {
22060
- clearTimeout(timeout);
22061
- }
22062
- }
22063
- function buildSdkSkillNames(v1SkillNames) {
22064
- return sortedUniqueSkillNames([...v1SkillNames, SDK_PLAY_SKILL_NAME]);
22065
- }
22066
- async function fetchSkillsUpdate(baseUrl, localVersion) {
22067
- const controller = new AbortController();
22068
- const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
22069
- try {
22070
- const response = await fetch(new URL("/api/v2/cli/update-check", baseUrl), {
22071
- method: "POST",
22072
- headers: { "Content-Type": "application/json" },
22073
- body: JSON.stringify({
22074
- skills: {
22075
- version: localVersion
22076
- }
22077
- }),
22078
- signal: controller.signal
22079
- });
22080
- if (!response.ok) return null;
22081
- const data = await response.json().catch(() => null);
22082
- const skills = data?.skills;
22083
- if (!skills) return null;
22084
- return {
22085
- needsUpdate: skills.needs_update === true,
22086
- remoteVersion: typeof skills.remote?.version === "string" ? skills.remote.version.trim() : ""
22087
- };
22088
- } catch {
22089
- return null;
22090
- } finally {
22091
- clearTimeout(timeout);
22092
- }
22093
- }
22094
- function buildSkillsInstallArgs(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
22095
- return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames));
22096
- }
22097
- function buildBunxSkillsInstallArgs(baseUrl, skillNames) {
22098
- return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
22099
- firstArg: "--bun"
22100
- });
22101
- }
22102
- function hasCommand(command) {
22103
- const result = (0, import_node_child_process4.spawnSync)(command, ["--version"], {
22104
- stdio: "ignore",
22105
- shell: process.platform === "win32"
22106
- });
22107
- return result.status === 0;
22108
- }
22109
- function shellQuote4(arg) {
22110
- return `'${arg.replace(/'/g, `'\\''`)}'`;
22111
- }
22112
- function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
22113
- const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames);
22114
- const npxInstall = {
22115
- command: "npx",
22116
- args: npxArgs,
22117
- manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
22118
- };
22119
- if (hasCommand("bunx")) {
22120
- const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
22121
- return [
22122
- {
22123
- command: "bunx",
22124
- args: bunxArgs,
22125
- manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
22126
- },
22127
- npxInstall
22128
- ];
22129
- }
22130
- return [npxInstall];
22131
- }
22132
- function runOneSkillsInstall(install) {
22133
- return new Promise((resolve13) => {
22134
- const child = (0, import_node_child_process4.spawn)(install.command, install.args, {
22135
- stdio: ["ignore", "ignore", "pipe"],
22136
- env: process.env
22137
- });
22138
- let stderr = "";
22139
- child.stderr.on("data", (chunk) => {
22140
- stderr += chunk.toString("utf-8");
22141
- });
22142
- child.on("error", (error) => {
22143
- resolve13({
22144
- ok: false,
22145
- detail: `failed to start ${install.command}: ${error.message}`,
22146
- manualCommand: install.manualCommand
22147
- });
22148
- });
22149
- child.on("close", (code) => {
22150
- if (code === 0) {
22151
- resolve13({ ok: true, detail: "", manualCommand: install.manualCommand });
22152
- return;
22153
- }
22154
- const detail = stderr.trim();
22155
- resolve13({
22156
- ok: false,
22157
- detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
22158
- manualCommand: install.manualCommand
22159
- });
22160
- });
22161
- });
22162
- }
22163
- async function runSkillsInstall(baseUrl, skillNames) {
22164
- const failures = [];
22165
- for (const install of resolveSkillsInstallCommands(baseUrl, skillNames)) {
22166
- const result = await runOneSkillsInstall(install);
22167
- if (result.ok) return true;
22168
- failures.push(result);
22169
- }
22170
- const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
22171
- const manualCommand = failures.at(-1)?.manualCommand;
22172
- process.stderr.write(
22173
- `SDK skills sync failed${details ? `:
22174
- ${details}` : ""}
22175
- ` + (manualCommand ? `Run manually: ${manualCommand}
22176
- ` : "")
22177
- );
22178
- return false;
22179
- }
22180
- function writeSdkSkillsStatusLine(line) {
22181
- const progress = getActiveCliProgress();
22182
- if (progress) {
22183
- progress.writeLine(line);
22184
- return;
22185
- }
22186
- process.stderr.write(`${line}
22187
- `);
22188
- }
22189
- async function syncSdkSkillsIfNeeded(baseUrl) {
22190
- if (attemptedSync || shouldSkipSkillsSync()) return;
22191
- attemptedSync = true;
22192
- const usingPluginSkills = Boolean(activePluginSkillsDir());
22193
- const localVersion = readLocalSkillsVersion(baseUrl);
22194
- const update = await fetchSkillsUpdate(baseUrl, localVersion);
22195
- if (usingPluginSkills) {
22196
- return;
22197
- }
22198
- if (!update?.needsUpdate || !update.remoteVersion) {
22199
- return;
22200
- }
22201
- const remoteSkillNames = await fetchV1SkillNames(baseUrl);
22202
- const skillNames = buildSdkSkillNames(
22203
- remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
22204
- );
22205
- if (skillNames.length === 0) return;
22206
- writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
22207
- const installed = await runSkillsInstall(baseUrl, skillNames);
22208
- if (!installed) return;
22209
- writeLocalSkillsVersion(baseUrl, update.remoteVersion);
22210
- writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
22211
- }
22212
-
22213
22228
  // src/cli/failure-reporting.ts
22214
22229
  var import_node_os14 = require("os");
22215
22230
  var FAILURE_REPORT_DISABLE_ENV = "DEEPLINE_DISABLE_FAILURE_REPORTING";