deepline 0.1.126 → 0.1.128

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