soulhubcli 1.0.13 → 1.0.14
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/index.cjs +110 -36
- 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
|
-
|
|
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
|
|
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("
|
|
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);
|
|
@@ -19724,7 +19731,7 @@ async function resolveClawDir(clawDir) {
|
|
|
19724
19731
|
}
|
|
19725
19732
|
return promptSelectClawDir();
|
|
19726
19733
|
}
|
|
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(
|
|
19734
|
+
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 (default is worker/sub-agent)").option(
|
|
19728
19735
|
"--dir <path>",
|
|
19729
19736
|
"Target directory (defaults to OpenClaw/LightClaw workspace)"
|
|
19730
19737
|
).option(
|
|
@@ -19732,14 +19739,16 @@ var installCommand = new Command("install").description("Install an agent or tea
|
|
|
19732
19739
|
"OpenClaw/LightClaw installation directory (overrides OPENCLAW_HOME/LIGHTCLAW_HOME env var, defaults to ~/.openclaw or ~/.lightclaw)"
|
|
19733
19740
|
).action(async (name, options) => {
|
|
19734
19741
|
try {
|
|
19742
|
+
const asMain = !!options.main;
|
|
19735
19743
|
if (options.from) {
|
|
19736
|
-
await installFromSource(options.from, options.dir, options.clawDir);
|
|
19744
|
+
await installFromSource(options.from, options.dir, options.clawDir, asMain);
|
|
19737
19745
|
} else if (name) {
|
|
19738
|
-
await installFromRegistry(name, options.dir, options.clawDir);
|
|
19746
|
+
await installFromRegistry(name, options.dir, options.clawDir, asMain);
|
|
19739
19747
|
} else {
|
|
19740
19748
|
console.error(source_default.red("Please specify an agent or team name, or use --from to install from a local source."));
|
|
19741
19749
|
console.log(source_default.dim(" Examples:"));
|
|
19742
|
-
console.log(source_default.dim(" soulhub install writer-wechat # \
|
|
19750
|
+
console.log(source_default.dim(" soulhub install writer-wechat # \u5B89\u88C5\u4E3A\u5B50 agent (workspace-writer-wechat/)"));
|
|
19751
|
+
console.log(source_default.dim(" soulhub install writer-wechat --main # \u5B89\u88C5\u4E3A\u4E3B agent (workspace/)"));
|
|
19743
19752
|
console.log(source_default.dim(" soulhub install dev-squad # \u4ECE registry \u5B89\u88C5\u56E2\u961F"));
|
|
19744
19753
|
console.log(source_default.dim(" soulhub install --from ./agent-team/ # \u4ECE\u672C\u5730\u76EE\u5F55\u5B89\u88C5"));
|
|
19745
19754
|
process.exit(1);
|
|
@@ -19753,15 +19762,15 @@ var installCommand = new Command("install").description("Install an agent or tea
|
|
|
19753
19762
|
process.exit(1);
|
|
19754
19763
|
}
|
|
19755
19764
|
});
|
|
19756
|
-
async function installFromRegistry(name, targetDir, clawDir) {
|
|
19765
|
+
async function installFromRegistry(name, targetDir, clawDir, asMain = false) {
|
|
19757
19766
|
const spinner = createSpinner(`Checking registry for ${source_default.cyan(name)}...`).start();
|
|
19758
19767
|
const index = await fetchIndex();
|
|
19759
19768
|
const agent = index.agents.find((a) => a.name === name);
|
|
19760
19769
|
const recipe = index.recipes.find((r) => r.name === name);
|
|
19761
19770
|
if (agent && !recipe) {
|
|
19762
19771
|
spinner.stop();
|
|
19763
|
-
logger.info(`Installing single agent from registry: ${name}`);
|
|
19764
|
-
await installSingleAgent(name, targetDir, clawDir);
|
|
19772
|
+
logger.info(`Installing single agent from registry: ${name}, asMain=${asMain}`);
|
|
19773
|
+
await installSingleAgent(name, targetDir, clawDir, asMain);
|
|
19765
19774
|
} else if (recipe) {
|
|
19766
19775
|
spinner.stop();
|
|
19767
19776
|
logger.info(`Installing team recipe from registry: ${name}`);
|
|
@@ -19772,7 +19781,7 @@ async function installFromRegistry(name, targetDir, clawDir) {
|
|
|
19772
19781
|
console.log(source_default.dim(" Use 'soulhub search' to find available agents and teams."));
|
|
19773
19782
|
}
|
|
19774
19783
|
}
|
|
19775
|
-
async function installSingleAgent(name, targetDir, clawDir) {
|
|
19784
|
+
async function installSingleAgent(name, targetDir, clawDir, asMain = false) {
|
|
19776
19785
|
const spinner = createSpinner(`Checking environment...`).start();
|
|
19777
19786
|
let selectedClawDir = null;
|
|
19778
19787
|
if (!targetDir) {
|
|
@@ -19796,13 +19805,16 @@ async function installSingleAgent(name, targetDir, clawDir) {
|
|
|
19796
19805
|
return;
|
|
19797
19806
|
}
|
|
19798
19807
|
let workspaceDir;
|
|
19808
|
+
const agentId = name.toLowerCase().replace(/[\s_]+/g, "-");
|
|
19799
19809
|
if (targetDir) {
|
|
19800
19810
|
workspaceDir = import_node_path12.default.resolve(targetDir);
|
|
19801
|
-
} else {
|
|
19811
|
+
} else if (asMain) {
|
|
19802
19812
|
workspaceDir = getMainWorkspaceDir(selectedClawDir);
|
|
19813
|
+
} else {
|
|
19814
|
+
workspaceDir = getWorkspaceDir(selectedClawDir, agentId);
|
|
19803
19815
|
}
|
|
19804
19816
|
const backupRecord = !targetDir ? createBackupRecord("single-agent", name, selectedClawDir) : null;
|
|
19805
|
-
if (!targetDir) {
|
|
19817
|
+
if (!targetDir && asMain) {
|
|
19806
19818
|
const mainCheck = checkMainAgentExists(selectedClawDir);
|
|
19807
19819
|
if (mainCheck.hasContent) {
|
|
19808
19820
|
spinner.warn(
|
|
@@ -19820,7 +19832,21 @@ async function installSingleAgent(name, targetDir, clawDir) {
|
|
|
19820
19832
|
});
|
|
19821
19833
|
}
|
|
19822
19834
|
}
|
|
19823
|
-
} else {
|
|
19835
|
+
} else if (!targetDir && !asMain) {
|
|
19836
|
+
if (import_node_fs9.default.existsSync(workspaceDir)) {
|
|
19837
|
+
const backupDir = backupAgentWorkspace(workspaceDir);
|
|
19838
|
+
if (backupDir) {
|
|
19839
|
+
console.log(source_default.yellow(` \u26A0 Existing worker ${agentId} backed up to: ${backupDir}`));
|
|
19840
|
+
addBackupItem(backupRecord, {
|
|
19841
|
+
originalPath: workspaceDir,
|
|
19842
|
+
backupPath: backupDir,
|
|
19843
|
+
method: "cp",
|
|
19844
|
+
role: "worker",
|
|
19845
|
+
agentId
|
|
19846
|
+
});
|
|
19847
|
+
}
|
|
19848
|
+
}
|
|
19849
|
+
} else if (targetDir) {
|
|
19824
19850
|
const backupDir = backupAgentWorkspace(workspaceDir);
|
|
19825
19851
|
if (backupDir) {
|
|
19826
19852
|
console.log(source_default.yellow(` \u26A0 Existing agent backed up to: ${backupDir}`));
|
|
@@ -19830,9 +19856,19 @@ async function installSingleAgent(name, targetDir, clawDir) {
|
|
|
19830
19856
|
import_node_fs9.default.mkdirSync(workspaceDir, { recursive: true });
|
|
19831
19857
|
}
|
|
19832
19858
|
if (!targetDir) {
|
|
19833
|
-
|
|
19834
|
-
|
|
19835
|
-
|
|
19859
|
+
if (asMain) {
|
|
19860
|
+
spinner.text = `Registering ${source_default.cyan(agent.displayName)} as main agent...`;
|
|
19861
|
+
addAgentToOpenClawConfig(selectedClawDir, "main", name, true);
|
|
19862
|
+
spinner.text = source_default.dim(`Main agent registered in config`);
|
|
19863
|
+
} else {
|
|
19864
|
+
spinner.text = `Registering ${source_default.cyan(agent.displayName)} as worker agent...`;
|
|
19865
|
+
const regResult = registerAgentToOpenClaw(agentId, workspaceDir, clawDir);
|
|
19866
|
+
if (!regResult.success) {
|
|
19867
|
+
spinner.fail(`Failed to register ${agentId}: ${regResult.message}`);
|
|
19868
|
+
return;
|
|
19869
|
+
}
|
|
19870
|
+
spinner.text = source_default.dim(`Worker agent ${agentId} registered in config`);
|
|
19871
|
+
}
|
|
19836
19872
|
}
|
|
19837
19873
|
spinner.text = `Downloading ${source_default.cyan(agent.displayName)} package...`;
|
|
19838
19874
|
const pkgDir = await downloadAgentPackage(name, agent.version);
|
|
@@ -19840,17 +19876,23 @@ async function installSingleAgent(name, targetDir, clawDir) {
|
|
|
19840
19876
|
import_node_fs9.default.rmSync(pkgDir, { recursive: true, force: true });
|
|
19841
19877
|
recordInstall(name, agent.version, workspaceDir);
|
|
19842
19878
|
if (backupRecord) {
|
|
19843
|
-
|
|
19879
|
+
if (asMain) {
|
|
19880
|
+
backupRecord.installedMainAgent = name;
|
|
19881
|
+
} else {
|
|
19882
|
+
backupRecord.installedWorkerIds = [agentId];
|
|
19883
|
+
}
|
|
19844
19884
|
commitBackupRecord(backupRecord);
|
|
19845
19885
|
}
|
|
19846
|
-
|
|
19886
|
+
const roleLabel = asMain ? "main agent" : "worker agent";
|
|
19887
|
+
const typeLabel = asMain ? source_default.blue("Single Agent (Main)") : source_default.green("Single Agent (Worker)");
|
|
19888
|
+
logger.info(`Single agent installed as ${roleLabel}: ${name}`, { version: agent.version, workspace: workspaceDir });
|
|
19847
19889
|
spinner.succeed(
|
|
19848
|
-
`${source_default.cyan.bold(agent.displayName)} installed as
|
|
19890
|
+
`${source_default.cyan.bold(agent.displayName)} installed as ${roleLabel}!`
|
|
19849
19891
|
);
|
|
19850
19892
|
console.log();
|
|
19851
19893
|
console.log(` ${source_default.dim("Location:")} ${workspaceDir}`);
|
|
19852
19894
|
console.log(` ${source_default.dim("Version:")} ${agent.version}`);
|
|
19853
|
-
console.log(` ${source_default.dim("Type:")} ${
|
|
19895
|
+
console.log(` ${source_default.dim("Type:")} ${typeLabel}`);
|
|
19854
19896
|
if (!targetDir) {
|
|
19855
19897
|
await tryRestartGateway();
|
|
19856
19898
|
}
|
|
@@ -19948,7 +19990,7 @@ async function installRecipeFromRegistry(name, recipe, targetDir, clawDir) {
|
|
|
19948
19990
|
await tryRestartGateway();
|
|
19949
19991
|
}
|
|
19950
19992
|
}
|
|
19951
|
-
async function installFromSource(source, targetDir, clawDir) {
|
|
19993
|
+
async function installFromSource(source, targetDir, clawDir, asMain = false) {
|
|
19952
19994
|
const spinner = createSpinner("Analyzing package...").start();
|
|
19953
19995
|
let packageDir;
|
|
19954
19996
|
let tempDir = null;
|
|
@@ -20002,7 +20044,7 @@ async function installFromSource(source, targetDir, clawDir) {
|
|
|
20002
20044
|
spinner.text = `Detected package type: ${source_default.blue(kind)}`;
|
|
20003
20045
|
if (kind === "agent") {
|
|
20004
20046
|
spinner.stop();
|
|
20005
|
-
await installSingleAgentFromDir(packageDir, targetDir, clawDir);
|
|
20047
|
+
await installSingleAgentFromDir(packageDir, targetDir, clawDir, asMain);
|
|
20006
20048
|
} else if (kind === "team") {
|
|
20007
20049
|
spinner.stop();
|
|
20008
20050
|
await installTeamFromDir(packageDir, targetDir, clawDir);
|
|
@@ -20014,7 +20056,7 @@ async function installFromSource(source, targetDir, clawDir) {
|
|
|
20014
20056
|
import_node_fs9.default.rmSync(tempDir, { recursive: true, force: true });
|
|
20015
20057
|
}
|
|
20016
20058
|
}
|
|
20017
|
-
async function installSingleAgentFromDir(packageDir, targetDir, clawDir) {
|
|
20059
|
+
async function installSingleAgentFromDir(packageDir, targetDir, clawDir, asMain = false) {
|
|
20018
20060
|
const spinner = createSpinner("Installing single agent...").start();
|
|
20019
20061
|
const pkg = readSoulHubPackage(packageDir);
|
|
20020
20062
|
const agentName = pkg?.name || import_node_path12.default.basename(packageDir);
|
|
@@ -20030,13 +20072,16 @@ async function installSingleAgentFromDir(packageDir, targetDir, clawDir) {
|
|
|
20030
20072
|
spinner.start();
|
|
20031
20073
|
}
|
|
20032
20074
|
let workspaceDir;
|
|
20075
|
+
const agentId = agentName.toLowerCase().replace(/[\s_]+/g, "-");
|
|
20033
20076
|
if (targetDir) {
|
|
20034
20077
|
workspaceDir = import_node_path12.default.resolve(targetDir);
|
|
20035
|
-
} else {
|
|
20078
|
+
} else if (asMain) {
|
|
20036
20079
|
workspaceDir = getMainWorkspaceDir(selectedClawDir);
|
|
20080
|
+
} else {
|
|
20081
|
+
workspaceDir = getWorkspaceDir(selectedClawDir, agentId);
|
|
20037
20082
|
}
|
|
20038
20083
|
const localBackupRecord = !targetDir ? createBackupRecord("single-agent-local", agentName, selectedClawDir) : null;
|
|
20039
|
-
if (!targetDir) {
|
|
20084
|
+
if (!targetDir && asMain) {
|
|
20040
20085
|
const mainCheck = checkMainAgentExists(selectedClawDir);
|
|
20041
20086
|
if (mainCheck.hasContent) {
|
|
20042
20087
|
spinner.warn("Existing main agent detected. Backing up...");
|
|
@@ -20052,27 +20097,56 @@ async function installSingleAgentFromDir(packageDir, targetDir, clawDir) {
|
|
|
20052
20097
|
});
|
|
20053
20098
|
}
|
|
20054
20099
|
}
|
|
20100
|
+
} else if (!targetDir && !asMain) {
|
|
20101
|
+
if (import_node_fs9.default.existsSync(workspaceDir)) {
|
|
20102
|
+
const backupDir = backupAgentWorkspace(workspaceDir);
|
|
20103
|
+
if (backupDir) {
|
|
20104
|
+
console.log(source_default.yellow(` \u26A0 Existing worker ${agentId} backed up to: ${backupDir}`));
|
|
20105
|
+
addBackupItem(localBackupRecord, {
|
|
20106
|
+
originalPath: workspaceDir,
|
|
20107
|
+
backupPath: backupDir,
|
|
20108
|
+
method: "cp",
|
|
20109
|
+
role: "worker",
|
|
20110
|
+
agentId
|
|
20111
|
+
});
|
|
20112
|
+
}
|
|
20113
|
+
}
|
|
20055
20114
|
}
|
|
20056
20115
|
if (!import_node_fs9.default.existsSync(workspaceDir)) {
|
|
20057
20116
|
import_node_fs9.default.mkdirSync(workspaceDir, { recursive: true });
|
|
20058
20117
|
}
|
|
20059
20118
|
if (!targetDir) {
|
|
20060
|
-
|
|
20061
|
-
|
|
20119
|
+
if (asMain) {
|
|
20120
|
+
spinner.text = `Registering ${source_default.cyan(agentName)} as main agent...`;
|
|
20121
|
+
addAgentToOpenClawConfig(selectedClawDir, "main", agentName, true);
|
|
20122
|
+
} else {
|
|
20123
|
+
spinner.text = `Registering ${source_default.cyan(agentName)} as worker agent...`;
|
|
20124
|
+
const regResult = registerAgentToOpenClaw(agentId, workspaceDir, clawDir);
|
|
20125
|
+
if (!regResult.success) {
|
|
20126
|
+
spinner.fail(`Failed to register ${agentId}: ${regResult.message}`);
|
|
20127
|
+
return;
|
|
20128
|
+
}
|
|
20129
|
+
}
|
|
20062
20130
|
}
|
|
20063
20131
|
spinner.text = `Copying soul files...`;
|
|
20064
20132
|
copyAgentFilesFromDir(packageDir, workspaceDir);
|
|
20065
20133
|
recordInstall(agentName, pkg?.version || "local", workspaceDir);
|
|
20066
20134
|
if (localBackupRecord) {
|
|
20067
|
-
|
|
20135
|
+
if (asMain) {
|
|
20136
|
+
localBackupRecord.installedMainAgent = agentName;
|
|
20137
|
+
} else {
|
|
20138
|
+
localBackupRecord.installedWorkerIds = [agentId];
|
|
20139
|
+
}
|
|
20068
20140
|
commitBackupRecord(localBackupRecord);
|
|
20069
20141
|
}
|
|
20070
|
-
|
|
20071
|
-
|
|
20142
|
+
const roleLabel = asMain ? "main agent" : "worker agent";
|
|
20143
|
+
const typeLabel = asMain ? source_default.blue("Single Agent (Main)") : source_default.green("Single Agent (Worker)");
|
|
20144
|
+
logger.info(`Single agent installed from dir as ${roleLabel}: ${agentName}`, { source: packageDir, workspace: workspaceDir });
|
|
20145
|
+
spinner.succeed(`${source_default.cyan.bold(agentName)} installed as ${roleLabel}!`);
|
|
20072
20146
|
console.log();
|
|
20073
20147
|
console.log(` ${source_default.dim("Location:")} ${workspaceDir}`);
|
|
20074
20148
|
console.log(` ${source_default.dim("Source:")} ${packageDir}`);
|
|
20075
|
-
console.log(` ${source_default.dim("Type:")} ${
|
|
20149
|
+
console.log(` ${source_default.dim("Type:")} ${typeLabel}`);
|
|
20076
20150
|
if (!targetDir) {
|
|
20077
20151
|
await tryRestartGateway();
|
|
20078
20152
|
}
|
|
@@ -20294,7 +20368,7 @@ async function tryRestartGateway() {
|
|
|
20294
20368
|
}
|
|
20295
20369
|
|
|
20296
20370
|
// src/commands/list.ts
|
|
20297
|
-
var listCommand = new Command("list").description("List installed
|
|
20371
|
+
var listCommand = new Command("list").description("List installed agents").alias("ls").action(async () => {
|
|
20298
20372
|
try {
|
|
20299
20373
|
const config = loadConfig();
|
|
20300
20374
|
if (config.installed.length === 0) {
|
|
@@ -20334,7 +20408,7 @@ var listCommand = new Command("list").description("List installed agent template
|
|
|
20334
20408
|
|
|
20335
20409
|
// src/commands/update.ts
|
|
20336
20410
|
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
20337
|
-
var updateCommand = new Command("update").description("Update installed
|
|
20411
|
+
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
20412
|
try {
|
|
20339
20413
|
const config = loadConfig();
|
|
20340
20414
|
if (config.installed.length === 0) {
|
|
@@ -20575,13 +20649,13 @@ function formatInstallType(type2) {
|
|
|
20575
20649
|
|
|
20576
20650
|
// src/index.ts
|
|
20577
20651
|
var program2 = new Command();
|
|
20578
|
-
program2.name("soulhub").description("SoulHub CLI -
|
|
20652
|
+
program2.name("soulhub").description("SoulHub CLI - Discover, install and manage AI agent souls").version("1.0.14").option("--verbose", "Enable verbose debug logging").hook("preAction", () => {
|
|
20579
20653
|
const opts = program2.opts();
|
|
20580
20654
|
const verbose = opts.verbose || process.env.SOULHUB_DEBUG === "1";
|
|
20581
20655
|
logger.init(verbose);
|
|
20582
20656
|
logger.info("CLI started", {
|
|
20583
20657
|
args: process.argv.slice(2),
|
|
20584
|
-
version: "1.0.
|
|
20658
|
+
version: "1.0.14",
|
|
20585
20659
|
node: process.version
|
|
20586
20660
|
});
|
|
20587
20661
|
});
|