soulhubcli 1.0.13 → 1.0.15

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.
Files changed (2) hide show
  1. package/dist/index.cjs +167 -40
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -19078,7 +19078,14 @@ function findAllClawDirs(customDir) {
19078
19078
  import_node_path11.default.join(process.cwd(), ".openclaw"),
19079
19079
  import_node_path11.default.join(process.cwd(), ".lightclaw")
19080
19080
  ];
19081
- return candidates.filter((c) => import_node_fs8.default.existsSync(c));
19081
+ const existing = candidates.filter((c) => import_node_fs8.default.existsSync(c));
19082
+ const seen = /* @__PURE__ */ new Set();
19083
+ return existing.filter((c) => {
19084
+ const real = import_node_fs8.default.realpathSync(c);
19085
+ if (seen.has(real)) return false;
19086
+ seen.add(real);
19087
+ return true;
19088
+ });
19082
19089
  }
19083
19090
  async function promptSelectClawDir(customDir) {
19084
19091
  const dirs = findAllClawDirs(customDir);
@@ -19491,7 +19498,7 @@ function restartOpenClawGateway() {
19491
19498
  }
19492
19499
 
19493
19500
  // src/commands/search.ts
19494
- var searchCommand = new Command("search").description("Search for agent templates in the SoulHub registry").argument("[query]", "Search query (matches name, description, tags)").option("-c, --category <category>", "Filter by category").option("-l, --limit <number>", "Max results to show", "20").action(async (query, options) => {
19501
+ var searchCommand = new Command("search").description("Search for agents in the SoulHub registry").argument("[query]", "Search query (matches name, description, tags)").option("-c, --category <category>", "Filter by category").option("-l, --limit <number>", "Max results to show", "20").action(async (query, options) => {
19495
19502
  try {
19496
19503
  const index = await fetchIndex();
19497
19504
  let agents = index.agents;
@@ -19557,7 +19564,7 @@ var searchCommand = new Command("search").description("Search for agent template
19557
19564
  });
19558
19565
 
19559
19566
  // src/commands/info.ts
19560
- var infoCommand = new Command("info").description("View detailed information about an agent template").argument("<name>", "Agent name").option("--identity", "Show IDENTITY.md content").option("--soul", "Show SOUL.md content").action(async (name, options) => {
19567
+ var infoCommand = new Command("info").description("Show details of an agent (identity, soul, skills, etc.)").argument("<name>", "Agent name").option("--identity", "Show IDENTITY.md content").option("--soul", "Show SOUL.md content").action(async (name, options) => {
19561
19568
  try {
19562
19569
  const index = await fetchIndex();
19563
19570
  const agent = index.agents.find((a) => a.name === name);
@@ -19718,13 +19725,40 @@ function createSpinner(initialText = "") {
19718
19725
  // src/commands/install.ts
19719
19726
  var import_node_fs9 = __toESM(require("fs"), 1);
19720
19727
  var import_node_path12 = __toESM(require("path"), 1);
19728
+ var import_node_readline2 = __toESM(require("readline"), 1);
19721
19729
  async function resolveClawDir(clawDir) {
19722
19730
  if (clawDir) {
19723
19731
  return findOpenClawDir(clawDir);
19724
19732
  }
19725
19733
  return promptSelectClawDir();
19726
19734
  }
19727
- var installCommand = new Command("install").description("Install an agent or team from the SoulHub registry").argument("[name]", "Agent or team name to install").option("--from <source>", "Install from a local directory, ZIP file, or URL").option(
19735
+ async function promptInstallRole(agentName) {
19736
+ console.log();
19737
+ console.log(` How would you like to install ${source_default.cyan(agentName)}?`);
19738
+ console.log();
19739
+ console.log(` 1) ${source_default.blue("Main Agent")} Install as main agent (workspace/)`);
19740
+ console.log(` 2) ${source_default.green("Worker Agent")} Install as worker agent (workspace-${agentName}/)`);
19741
+ console.log();
19742
+ const rl = import_node_readline2.default.createInterface({
19743
+ input: process.stdin,
19744
+ output: process.stdout
19745
+ });
19746
+ return new Promise((resolve) => {
19747
+ rl.question(" Please select (1-2, default: 2): ", (answer) => {
19748
+ rl.close();
19749
+ const trimmed = answer.trim();
19750
+ if (trimmed === "" || trimmed === "2") {
19751
+ resolve(false);
19752
+ } else if (trimmed === "1") {
19753
+ resolve(true);
19754
+ } else {
19755
+ console.log(" Invalid selection, operation cancelled.");
19756
+ resolve(null);
19757
+ }
19758
+ });
19759
+ });
19760
+ }
19761
+ var installCommand = new Command("install").description("Install an agent or team from the SoulHub registry (default: as worker)").argument("[name]", "Agent or team name to install").option("--from <source>", "Install from a local directory, ZIP file, or URL").option("--main", "Install as main agent (non-interactive)").option("--worker", "Install as worker/sub-agent (non-interactive)").option(
19728
19762
  "--dir <path>",
19729
19763
  "Target directory (defaults to OpenClaw/LightClaw workspace)"
19730
19764
  ).option(
@@ -19732,16 +19766,26 @@ var installCommand = new Command("install").description("Install an agent or tea
19732
19766
  "OpenClaw/LightClaw installation directory (overrides OPENCLAW_HOME/LIGHTCLAW_HOME env var, defaults to ~/.openclaw or ~/.lightclaw)"
19733
19767
  ).action(async (name, options) => {
19734
19768
  try {
19769
+ let asMain;
19770
+ if (options.main && options.worker) {
19771
+ console.error(source_default.red("Error: --main and --worker cannot be used together."));
19772
+ process.exit(1);
19773
+ }
19774
+ if (options.main) asMain = true;
19775
+ if (options.worker) asMain = false;
19735
19776
  if (options.from) {
19736
- await installFromSource(options.from, options.dir, options.clawDir);
19777
+ await installFromSource(options.from, options.dir, options.clawDir, asMain);
19737
19778
  } else if (name) {
19738
- await installFromRegistry(name, options.dir, options.clawDir);
19779
+ await installFromRegistry(name, options.dir, options.clawDir, asMain);
19739
19780
  } else {
19740
19781
  console.error(source_default.red("Please specify an agent or team name, or use --from to install from a local source."));
19741
19782
  console.log(source_default.dim(" Examples:"));
19742
- console.log(source_default.dim(" soulhub install writer-wechat # \u4ECE registry \u5B89\u88C5\u5355 agent"));
19743
- console.log(source_default.dim(" soulhub install dev-squad # \u4ECE registry \u5B89\u88C5\u56E2\u961F"));
19744
- console.log(source_default.dim(" soulhub install --from ./agent-team/ # \u4ECE\u672C\u5730\u76EE\u5F55\u5B89\u88C5"));
19783
+ console.log(source_default.dim(" soulhub install writer-wechat # \u4EA4\u4E92\u5F0F\u9009\u62E9\u5B89\u88C5\u4E3A\u4E3B/\u5B50 agent"));
19784
+ console.log(source_default.dim(" soulhub install writer-wechat --main # \u975E\u4EA4\u4E92\u5F0F\uFF0C\u5B89\u88C5\u4E3A\u4E3B agent (workspace/)"));
19785
+ console.log(source_default.dim(" soulhub install writer-wechat --worker # \u975E\u4EA4\u4E92\u5F0F\uFF0C\u5B89\u88C5\u4E3A\u5B50 agent (workspace-xxx/)"));
19786
+ console.log(source_default.dim(" soulhub install dev-squad # \u4ECE registry \u5B89\u88C5\u56E2\u961F"));
19787
+ console.log(source_default.dim(" soulhub install --from ./agent-team/ # \u4ECE\u672C\u5730\u76EE\u5F55\u5B89\u88C5"));
19788
+ console.log(source_default.dim(" soulhub install writer-wechat --claw-dir ~/.lightclaw # \u975E\u4EA4\u4E92\u5F0F\u6307\u5B9A claw \u76EE\u5F55"));
19745
19789
  process.exit(1);
19746
19790
  }
19747
19791
  } catch (error) {
@@ -19753,15 +19797,15 @@ var installCommand = new Command("install").description("Install an agent or tea
19753
19797
  process.exit(1);
19754
19798
  }
19755
19799
  });
19756
- async function installFromRegistry(name, targetDir, clawDir) {
19800
+ async function installFromRegistry(name, targetDir, clawDir, asMain) {
19757
19801
  const spinner = createSpinner(`Checking registry for ${source_default.cyan(name)}...`).start();
19758
19802
  const index = await fetchIndex();
19759
19803
  const agent = index.agents.find((a) => a.name === name);
19760
19804
  const recipe = index.recipes.find((r) => r.name === name);
19761
19805
  if (agent && !recipe) {
19762
19806
  spinner.stop();
19763
- logger.info(`Installing single agent from registry: ${name}`);
19764
- await installSingleAgent(name, targetDir, clawDir);
19807
+ logger.info(`Installing single agent from registry: ${name}, asMain=${asMain ?? "interactive"}`);
19808
+ await installSingleAgent(name, targetDir, clawDir, asMain);
19765
19809
  } else if (recipe) {
19766
19810
  spinner.stop();
19767
19811
  logger.info(`Installing team recipe from registry: ${name}`);
@@ -19772,7 +19816,7 @@ async function installFromRegistry(name, targetDir, clawDir) {
19772
19816
  console.log(source_default.dim(" Use 'soulhub search' to find available agents and teams."));
19773
19817
  }
19774
19818
  }
19775
- async function installSingleAgent(name, targetDir, clawDir) {
19819
+ async function installSingleAgent(name, targetDir, clawDir, asMain) {
19776
19820
  const spinner = createSpinner(`Checking environment...`).start();
19777
19821
  let selectedClawDir = null;
19778
19822
  if (!targetDir) {
@@ -19783,9 +19827,18 @@ async function installSingleAgent(name, targetDir, clawDir) {
19783
19827
  printOpenClawInstallHelp();
19784
19828
  return;
19785
19829
  }
19786
- spinner.start();
19787
19830
  const brand = detectClawBrand(selectedClawDir);
19788
- spinner.text = source_default.dim(`${brand} detected: ${selectedClawDir}`);
19831
+ console.log(source_default.dim(` ${brand} detected: ${selectedClawDir}`));
19832
+ }
19833
+ const agentId = name.toLowerCase().replace(/[\s_]+/g, "-");
19834
+ if (asMain === void 0) {
19835
+ const choice = await promptInstallRole(agentId);
19836
+ if (choice === null) return;
19837
+ asMain = choice;
19838
+ }
19839
+ logger.info(`Install role resolved: asMain=${asMain}`);
19840
+ if (!targetDir) {
19841
+ spinner.start();
19789
19842
  }
19790
19843
  spinner.text = `Fetching agent ${source_default.cyan(name)}...`;
19791
19844
  const index = await fetchIndex();
@@ -19798,11 +19851,13 @@ async function installSingleAgent(name, targetDir, clawDir) {
19798
19851
  let workspaceDir;
19799
19852
  if (targetDir) {
19800
19853
  workspaceDir = import_node_path12.default.resolve(targetDir);
19801
- } else {
19854
+ } else if (asMain) {
19802
19855
  workspaceDir = getMainWorkspaceDir(selectedClawDir);
19856
+ } else {
19857
+ workspaceDir = getWorkspaceDir(selectedClawDir, agentId);
19803
19858
  }
19804
19859
  const backupRecord = !targetDir ? createBackupRecord("single-agent", name, selectedClawDir) : null;
19805
- if (!targetDir) {
19860
+ if (!targetDir && asMain) {
19806
19861
  const mainCheck = checkMainAgentExists(selectedClawDir);
19807
19862
  if (mainCheck.hasContent) {
19808
19863
  spinner.warn(
@@ -19820,7 +19875,21 @@ async function installSingleAgent(name, targetDir, clawDir) {
19820
19875
  });
19821
19876
  }
19822
19877
  }
19823
- } else {
19878
+ } else if (!targetDir && !asMain) {
19879
+ if (import_node_fs9.default.existsSync(workspaceDir)) {
19880
+ const backupDir = backupAgentWorkspace(workspaceDir);
19881
+ if (backupDir) {
19882
+ console.log(source_default.yellow(` \u26A0 Existing worker ${agentId} backed up to: ${backupDir}`));
19883
+ addBackupItem(backupRecord, {
19884
+ originalPath: workspaceDir,
19885
+ backupPath: backupDir,
19886
+ method: "cp",
19887
+ role: "worker",
19888
+ agentId
19889
+ });
19890
+ }
19891
+ }
19892
+ } else if (targetDir) {
19824
19893
  const backupDir = backupAgentWorkspace(workspaceDir);
19825
19894
  if (backupDir) {
19826
19895
  console.log(source_default.yellow(` \u26A0 Existing agent backed up to: ${backupDir}`));
@@ -19830,9 +19899,19 @@ async function installSingleAgent(name, targetDir, clawDir) {
19830
19899
  import_node_fs9.default.mkdirSync(workspaceDir, { recursive: true });
19831
19900
  }
19832
19901
  if (!targetDir) {
19833
- spinner.text = `Registering ${source_default.cyan(agent.displayName)} as main agent...`;
19834
- addAgentToOpenClawConfig(selectedClawDir, "main", name, true);
19835
- spinner.text = source_default.dim(`Main agent registered in config`);
19902
+ if (asMain) {
19903
+ spinner.text = `Registering ${source_default.cyan(agent.displayName)} as main agent...`;
19904
+ addAgentToOpenClawConfig(selectedClawDir, "main", name, true);
19905
+ spinner.text = source_default.dim(`Main agent registered in config`);
19906
+ } else {
19907
+ spinner.text = `Registering ${source_default.cyan(agent.displayName)} as worker agent...`;
19908
+ const regResult = registerAgentToOpenClaw(agentId, workspaceDir, clawDir);
19909
+ if (!regResult.success) {
19910
+ spinner.fail(`Failed to register ${agentId}: ${regResult.message}`);
19911
+ return;
19912
+ }
19913
+ spinner.text = source_default.dim(`Worker agent ${agentId} registered in config`);
19914
+ }
19836
19915
  }
19837
19916
  spinner.text = `Downloading ${source_default.cyan(agent.displayName)} package...`;
19838
19917
  const pkgDir = await downloadAgentPackage(name, agent.version);
@@ -19840,17 +19919,23 @@ async function installSingleAgent(name, targetDir, clawDir) {
19840
19919
  import_node_fs9.default.rmSync(pkgDir, { recursive: true, force: true });
19841
19920
  recordInstall(name, agent.version, workspaceDir);
19842
19921
  if (backupRecord) {
19843
- backupRecord.installedMainAgent = name;
19922
+ if (asMain) {
19923
+ backupRecord.installedMainAgent = name;
19924
+ } else {
19925
+ backupRecord.installedWorkerIds = [agentId];
19926
+ }
19844
19927
  commitBackupRecord(backupRecord);
19845
19928
  }
19846
- logger.info(`Single agent installed: ${name}`, { version: agent.version, workspace: workspaceDir });
19929
+ const roleLabel = asMain ? "main agent" : "worker agent";
19930
+ const typeLabel = asMain ? source_default.blue("Single Agent (Main)") : source_default.green("Single Agent (Worker)");
19931
+ logger.info(`Single agent installed as ${roleLabel}: ${name}`, { version: agent.version, workspace: workspaceDir });
19847
19932
  spinner.succeed(
19848
- `${source_default.cyan.bold(agent.displayName)} installed as main agent!`
19933
+ `${source_default.cyan.bold(agent.displayName)} installed as ${roleLabel}!`
19849
19934
  );
19850
19935
  console.log();
19851
19936
  console.log(` ${source_default.dim("Location:")} ${workspaceDir}`);
19852
19937
  console.log(` ${source_default.dim("Version:")} ${agent.version}`);
19853
- console.log(` ${source_default.dim("Type:")} ${source_default.blue("Single Agent (Main)")}`);
19938
+ console.log(` ${source_default.dim("Type:")} ${typeLabel}`);
19854
19939
  if (!targetDir) {
19855
19940
  await tryRestartGateway();
19856
19941
  }
@@ -19948,7 +20033,7 @@ async function installRecipeFromRegistry(name, recipe, targetDir, clawDir) {
19948
20033
  await tryRestartGateway();
19949
20034
  }
19950
20035
  }
19951
- async function installFromSource(source, targetDir, clawDir) {
20036
+ async function installFromSource(source, targetDir, clawDir, asMain) {
19952
20037
  const spinner = createSpinner("Analyzing package...").start();
19953
20038
  let packageDir;
19954
20039
  let tempDir = null;
@@ -20002,7 +20087,7 @@ async function installFromSource(source, targetDir, clawDir) {
20002
20087
  spinner.text = `Detected package type: ${source_default.blue(kind)}`;
20003
20088
  if (kind === "agent") {
20004
20089
  spinner.stop();
20005
- await installSingleAgentFromDir(packageDir, targetDir, clawDir);
20090
+ await installSingleAgentFromDir(packageDir, targetDir, clawDir, asMain);
20006
20091
  } else if (kind === "team") {
20007
20092
  spinner.stop();
20008
20093
  await installTeamFromDir(packageDir, targetDir, clawDir);
@@ -20014,7 +20099,7 @@ async function installFromSource(source, targetDir, clawDir) {
20014
20099
  import_node_fs9.default.rmSync(tempDir, { recursive: true, force: true });
20015
20100
  }
20016
20101
  }
20017
- async function installSingleAgentFromDir(packageDir, targetDir, clawDir) {
20102
+ async function installSingleAgentFromDir(packageDir, targetDir, clawDir, asMain) {
20018
20103
  const spinner = createSpinner("Installing single agent...").start();
20019
20104
  const pkg = readSoulHubPackage(packageDir);
20020
20105
  const agentName = pkg?.name || import_node_path12.default.basename(packageDir);
@@ -20027,16 +20112,29 @@ async function installSingleAgentFromDir(packageDir, targetDir, clawDir) {
20027
20112
  printOpenClawInstallHelp();
20028
20113
  return;
20029
20114
  }
20115
+ const brand = detectClawBrand(selectedClawDir);
20116
+ console.log(source_default.dim(` ${brand} detected: ${selectedClawDir}`));
20117
+ }
20118
+ const agentId = agentName.toLowerCase().replace(/[\s_]+/g, "-");
20119
+ if (asMain === void 0) {
20120
+ const choice = await promptInstallRole(agentId);
20121
+ if (choice === null) return;
20122
+ asMain = choice;
20123
+ }
20124
+ logger.info(`Install role resolved: asMain=${asMain}`);
20125
+ if (!targetDir) {
20030
20126
  spinner.start();
20031
20127
  }
20032
20128
  let workspaceDir;
20033
20129
  if (targetDir) {
20034
20130
  workspaceDir = import_node_path12.default.resolve(targetDir);
20035
- } else {
20131
+ } else if (asMain) {
20036
20132
  workspaceDir = getMainWorkspaceDir(selectedClawDir);
20133
+ } else {
20134
+ workspaceDir = getWorkspaceDir(selectedClawDir, agentId);
20037
20135
  }
20038
20136
  const localBackupRecord = !targetDir ? createBackupRecord("single-agent-local", agentName, selectedClawDir) : null;
20039
- if (!targetDir) {
20137
+ if (!targetDir && asMain) {
20040
20138
  const mainCheck = checkMainAgentExists(selectedClawDir);
20041
20139
  if (mainCheck.hasContent) {
20042
20140
  spinner.warn("Existing main agent detected. Backing up...");
@@ -20052,27 +20150,56 @@ async function installSingleAgentFromDir(packageDir, targetDir, clawDir) {
20052
20150
  });
20053
20151
  }
20054
20152
  }
20153
+ } else if (!targetDir && !asMain) {
20154
+ if (import_node_fs9.default.existsSync(workspaceDir)) {
20155
+ const backupDir = backupAgentWorkspace(workspaceDir);
20156
+ if (backupDir) {
20157
+ console.log(source_default.yellow(` \u26A0 Existing worker ${agentId} backed up to: ${backupDir}`));
20158
+ addBackupItem(localBackupRecord, {
20159
+ originalPath: workspaceDir,
20160
+ backupPath: backupDir,
20161
+ method: "cp",
20162
+ role: "worker",
20163
+ agentId
20164
+ });
20165
+ }
20166
+ }
20055
20167
  }
20056
20168
  if (!import_node_fs9.default.existsSync(workspaceDir)) {
20057
20169
  import_node_fs9.default.mkdirSync(workspaceDir, { recursive: true });
20058
20170
  }
20059
20171
  if (!targetDir) {
20060
- spinner.text = `Registering ${source_default.cyan(agentName)} as main agent...`;
20061
- addAgentToOpenClawConfig(selectedClawDir, "main", agentName, true);
20172
+ if (asMain) {
20173
+ spinner.text = `Registering ${source_default.cyan(agentName)} as main agent...`;
20174
+ addAgentToOpenClawConfig(selectedClawDir, "main", agentName, true);
20175
+ } else {
20176
+ spinner.text = `Registering ${source_default.cyan(agentName)} as worker agent...`;
20177
+ const regResult = registerAgentToOpenClaw(agentId, workspaceDir, clawDir);
20178
+ if (!regResult.success) {
20179
+ spinner.fail(`Failed to register ${agentId}: ${regResult.message}`);
20180
+ return;
20181
+ }
20182
+ }
20062
20183
  }
20063
20184
  spinner.text = `Copying soul files...`;
20064
20185
  copyAgentFilesFromDir(packageDir, workspaceDir);
20065
20186
  recordInstall(agentName, pkg?.version || "local", workspaceDir);
20066
20187
  if (localBackupRecord) {
20067
- localBackupRecord.installedMainAgent = agentName;
20188
+ if (asMain) {
20189
+ localBackupRecord.installedMainAgent = agentName;
20190
+ } else {
20191
+ localBackupRecord.installedWorkerIds = [agentId];
20192
+ }
20068
20193
  commitBackupRecord(localBackupRecord);
20069
20194
  }
20070
- logger.info(`Single agent installed from dir: ${agentName}`, { source: packageDir, workspace: workspaceDir });
20071
- spinner.succeed(`${source_default.cyan.bold(agentName)} installed as main agent!`);
20195
+ const roleLabel = asMain ? "main agent" : "worker agent";
20196
+ const typeLabel = asMain ? source_default.blue("Single Agent (Main)") : source_default.green("Single Agent (Worker)");
20197
+ logger.info(`Single agent installed from dir as ${roleLabel}: ${agentName}`, { source: packageDir, workspace: workspaceDir });
20198
+ spinner.succeed(`${source_default.cyan.bold(agentName)} installed as ${roleLabel}!`);
20072
20199
  console.log();
20073
20200
  console.log(` ${source_default.dim("Location:")} ${workspaceDir}`);
20074
20201
  console.log(` ${source_default.dim("Source:")} ${packageDir}`);
20075
- console.log(` ${source_default.dim("Type:")} ${source_default.blue("Single Agent (Main)")}`);
20202
+ console.log(` ${source_default.dim("Type:")} ${typeLabel}`);
20076
20203
  if (!targetDir) {
20077
20204
  await tryRestartGateway();
20078
20205
  }
@@ -20294,7 +20421,7 @@ async function tryRestartGateway() {
20294
20421
  }
20295
20422
 
20296
20423
  // src/commands/list.ts
20297
- var listCommand = new Command("list").description("List installed agent templates").alias("ls").action(async () => {
20424
+ var listCommand = new Command("list").description("List installed agents").alias("ls").action(async () => {
20298
20425
  try {
20299
20426
  const config = loadConfig();
20300
20427
  if (config.installed.length === 0) {
@@ -20334,7 +20461,7 @@ var listCommand = new Command("list").description("List installed agent template
20334
20461
 
20335
20462
  // src/commands/update.ts
20336
20463
  var import_node_fs10 = __toESM(require("fs"), 1);
20337
- var updateCommand = new Command("update").description("Update installed agent templates to latest versions").argument("[name]", "Agent name to update (updates all if omitted)").action(async (name) => {
20464
+ var updateCommand = new Command("update").description("Update installed agents to latest versions").argument("[name]", "Agent name to update (updates all if omitted)").action(async (name) => {
20338
20465
  try {
20339
20466
  const config = loadConfig();
20340
20467
  if (config.installed.length === 0) {
@@ -20575,13 +20702,13 @@ function formatInstallType(type2) {
20575
20702
 
20576
20703
  // src/index.ts
20577
20704
  var program2 = new Command();
20578
- program2.name("soulhub").description("SoulHub CLI - Install and manage AI agent persona templates").version("1.0.13").option("--verbose", "Enable verbose debug logging").hook("preAction", () => {
20705
+ program2.name("soulhub").description("SoulHub CLI - Discover, install and manage AI agent souls").version("1.0.15").option("--verbose", "Enable verbose debug logging").hook("preAction", () => {
20579
20706
  const opts = program2.opts();
20580
20707
  const verbose = opts.verbose || process.env.SOULHUB_DEBUG === "1";
20581
20708
  logger.init(verbose);
20582
20709
  logger.info("CLI started", {
20583
20710
  args: process.argv.slice(2),
20584
- version: "1.0.13",
20711
+ version: "1.0.15",
20585
20712
  node: process.version
20586
20713
  });
20587
20714
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soulhubcli",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "SoulHub CLI - Install and manage AI agent persona templates for OpenClaw",
5
5
  "type": "module",
6
6
  "bin": {