@tankpkg/cli 0.13.0 → 0.14.1

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/bin/tank.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as VERSION, i as USER_AGENT, l as setConfig, n as flushLogs, o as getConfig, s as getConfigDir, t as authFlowLog } from "../debug-logger-DpL2B_iY.js";
2
+ import { a as VERSION, i as USER_AGENT, l as setConfig, n as flushLogs, o as getConfig, s as getConfigDir, t as authFlowLog } from "../debug-logger-CO7j3esl.js";
3
3
  import { t as logger } from "../logger-BhULz3Uz.js";
4
4
  import { createRequire } from "node:module";
5
5
  import { Command } from "commander";
@@ -11,10 +11,10 @@ import { z } from "zod";
11
11
  import semver from "semver";
12
12
  import ora from "ora";
13
13
  import { confirm, input } from "@inquirer/prompts";
14
+ import { execSync, spawn } from "node:child_process";
14
15
  import crypto$1 from "node:crypto";
15
16
  import { create, extract } from "tar";
16
17
  import { createInterface } from "node:readline";
17
- import { execSync, spawn } from "node:child_process";
18
18
  import { mkdir, mkdtemp, rm, stat } from "node:fs/promises";
19
19
  import { Readable } from "node:stream";
20
20
  import { pipeline } from "node:stream/promises";
@@ -2044,10 +2044,24 @@ function loadManifest(skillDir) {
2044
2044
  if (!result.success) throw new Error(result.error);
2045
2045
  return result.data;
2046
2046
  }
2047
+ function deepMerge(a, b) {
2048
+ const result = { ...a };
2049
+ for (const [key, val] of Object.entries(b)) {
2050
+ const existing = result[key];
2051
+ if (val !== null && typeof val === "object" && !Array.isArray(val) && existing !== null && typeof existing === "object" && !Array.isArray(existing)) result[key] = deepMerge(existing, val);
2052
+ else result[key] = val;
2053
+ }
2054
+ return result;
2055
+ }
2047
2056
  function writeFiles(targetDir, compiled) {
2048
2057
  for (const f of compiled.files) {
2049
2058
  const fullPath = path.join(targetDir, f.path);
2050
2059
  fs.mkdirSync(path.dirname(fullPath), { recursive: true });
2060
+ if (f.path.endsWith(".json") && fs.existsSync(fullPath)) try {
2061
+ const merged = deepMerge(JSON.parse(fs.readFileSync(fullPath, "utf-8")), JSON.parse(f.content));
2062
+ fs.writeFileSync(fullPath, JSON.stringify(merged, null, 2));
2063
+ continue;
2064
+ } catch {}
2051
2065
  fs.writeFileSync(fullPath, f.content);
2052
2066
  }
2053
2067
  return compiled.files.length;
@@ -9368,6 +9382,21 @@ async function runLegacyFallback(options) {
9368
9382
  }
9369
9383
  }
9370
9384
  }
9385
+ function installToolDependencies(extractDir, skillName) {
9386
+ const packageJsonPath = path.join(extractDir, "package.json");
9387
+ if (!fs.existsSync(packageJsonPath)) return;
9388
+ try {
9389
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
9390
+ if (!(pkg.dependencies && Object.keys(pkg.dependencies).length > 0 || pkg.peerDependencies && Object.keys(pkg.peerDependencies).length > 0)) return;
9391
+ execSync("npm install --production --ignore-scripts --no-audit --no-fund", {
9392
+ cwd: extractDir,
9393
+ stdio: "pipe",
9394
+ timeout: 6e4
9395
+ });
9396
+ } catch {
9397
+ logger.warn(`Dependency install skipped for ${skillName} (non-fatal)`);
9398
+ }
9399
+ }
9371
9400
  async function linkInstalledRoots(options) {
9372
9401
  const { rootSkillNames, resolvedNodeByName, extractDirForSkill, directory, global, resolvedHome, homedir } = options;
9373
9402
  const agentSkillsBaseDir = global ? getGlobalAgentSkillsDir(resolvedHome) : path.join(directory, ".tank", "agent-skills");
@@ -9393,7 +9422,16 @@ async function linkInstalledRoots(options) {
9393
9422
  if (rootSkillNames.length === 1) logger.warn("Agent linking skipped (non-fatal)");
9394
9423
  else logger.warn(`Agent linking skipped for ${skillName} (non-fatal)`);
9395
9424
  }
9396
- if (detectInstalledAgents(homedir).length === 0) logger.warn("No agents detected for linking");
9425
+ const detectedAgents = detectInstalledAgents(homedir);
9426
+ if (detectedAgents.length === 0) logger.warn("No agents detected for linking");
9427
+ const agentToPlatform = {
9428
+ claude: "claude-code",
9429
+ opencode: "opencode",
9430
+ cursor: "cursor",
9431
+ codex: "claude-code",
9432
+ openclaw: "opencode"
9433
+ };
9434
+ const platforms = new Set(detectedAgents.map((a) => agentToPlatform[a.id]).filter(Boolean));
9397
9435
  for (const skillName of rootSkillNames) {
9398
9436
  if (!resolvedNodeByName.get(skillName)) continue;
9399
9437
  const skillDir = extractDirForSkill(skillName);
@@ -9403,9 +9441,10 @@ async function linkInstalledRoots(options) {
9403
9441
  const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
9404
9442
  if (!manifest.atoms || !Array.isArray(manifest.atoms) || manifest.atoms.length === 0) continue;
9405
9443
  const { buildCommand: runBuild } = await Promise.resolve().then(() => build_exports);
9406
- await runBuild({
9444
+ for (const platform of platforms) await runBuild({
9407
9445
  skill: skillDir,
9408
- target: directory
9446
+ target: directory,
9447
+ platform
9409
9448
  });
9410
9449
  } catch {
9411
9450
  logger.warn(`Auto-build skipped for ${skillName} (non-fatal)`);
@@ -9428,6 +9467,8 @@ async function executeInstallPipeline(options) {
9428
9467
  fs.mkdirSync(extractDir, { recursive: true });
9429
9468
  await extractSafely(payload.buffer, extractDir);
9430
9469
  verifyExtractedDependencies(extractDir, node);
9470
+ spinner.text = `Installing dependencies for ${node.name}...`;
9471
+ installToolDependencies(extractDir, node.name);
9431
9472
  }
9432
9473
  lock.lockfileVersion = 2;
9433
9474
  const updatedLock = writeLockfileWithResolvedGraph(lock, resolvedNodes, downloaded);