@arkhera30/cli 0.1.15 → 0.1.16
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.js +42 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -611,6 +611,16 @@ function mergeAndWriteConfig(configPath, mcpServers) {
|
|
|
611
611
|
mkdirSync2(dir, { recursive: true });
|
|
612
612
|
writeFileSync3(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
613
613
|
}
|
|
614
|
+
function getMcpRemoteWrapperPath() {
|
|
615
|
+
return join3(homedir3(), ".forge", "bin", "mcp-remote-wrapper");
|
|
616
|
+
}
|
|
617
|
+
function buildStdioServers(config, wrapperPath, host) {
|
|
618
|
+
return {
|
|
619
|
+
anvil: { command: wrapperPath, args: [`http://${host}:${config.ports.anvil}/mcp`] },
|
|
620
|
+
vault: { command: wrapperPath, args: [`http://${host}:${config.ports.vault_mcp}/mcp`] },
|
|
621
|
+
forge: { command: wrapperPath, args: [`http://${host}:${config.ports.forge}/mcp`] }
|
|
622
|
+
};
|
|
623
|
+
}
|
|
614
624
|
async function isClaudeCliAvailable() {
|
|
615
625
|
try {
|
|
616
626
|
const result = await execa2("claude", ["--version"], { reject: false });
|
|
@@ -657,21 +667,25 @@ async function syncSkills(runtime) {
|
|
|
657
667
|
async function syncSkillsForCursor(runtime) {
|
|
658
668
|
const home = homedir3();
|
|
659
669
|
const rulesDir = join3(home, ".cursor", "rules");
|
|
670
|
+
const skillsBase = join3(home, ".cursor", "skills-cursor");
|
|
660
671
|
const skills = ["horus-anvil", "horus-vault", "horus-forge"];
|
|
661
672
|
const forgeContainer = "horus-forge-1";
|
|
662
673
|
mkdirSync2(rulesDir, { recursive: true });
|
|
663
674
|
for (const skill of skills) {
|
|
664
675
|
const src = `/home/forge/.claude/skills/${skill}/SKILL.md`;
|
|
665
|
-
const dest = join3(rulesDir, `${skill}.mdc`);
|
|
666
676
|
const result = await runtime.exec(forgeContainer, "cat", src);
|
|
667
677
|
if (result.exitCode === 0 && result.stdout.trim()) {
|
|
678
|
+
const ruleDest = join3(rulesDir, `${skill}.mdc`);
|
|
668
679
|
const frontmatter = `---
|
|
669
680
|
description: Horus ${skill} reference
|
|
670
681
|
alwaysApply: true
|
|
671
682
|
---
|
|
672
683
|
|
|
673
684
|
`;
|
|
674
|
-
writeFileSync3(
|
|
685
|
+
writeFileSync3(ruleDest, frontmatter + result.stdout, "utf-8");
|
|
686
|
+
const skillDir = join3(skillsBase, skill);
|
|
687
|
+
mkdirSync2(skillDir, { recursive: true });
|
|
688
|
+
writeFileSync3(join3(skillDir, "SKILL.md"), result.stdout, "utf-8");
|
|
675
689
|
}
|
|
676
690
|
}
|
|
677
691
|
}
|
|
@@ -694,18 +708,38 @@ function printNextSteps(targets) {
|
|
|
694
708
|
console.log("");
|
|
695
709
|
}
|
|
696
710
|
async function runConnect(config, runtime, targets, host = "localhost") {
|
|
697
|
-
const
|
|
711
|
+
const httpServers = {
|
|
698
712
|
anvil: { url: `http://${host}:${config.ports.anvil}/sse` },
|
|
699
713
|
vault: { url: `http://${host}:${config.ports.vault_mcp}/sse` },
|
|
700
714
|
forge: { url: `http://${host}:${config.ports.forge}/sse` }
|
|
701
715
|
};
|
|
702
716
|
const configured = [];
|
|
703
717
|
for (const target of targets) {
|
|
704
|
-
if (target === "claude-
|
|
718
|
+
if (target === "claude-desktop") {
|
|
719
|
+
const desktopSpinner = ora(`Configuring ${chalk.cyan("claude-desktop")}...`).start();
|
|
720
|
+
const wrapperPath = getMcpRemoteWrapperPath();
|
|
721
|
+
if (!existsSync4(wrapperPath)) {
|
|
722
|
+
desktopSpinner.fail("mcp-remote-wrapper not found");
|
|
723
|
+
console.log(chalk.dim(`Expected at: ${wrapperPath}`));
|
|
724
|
+
console.log(chalk.dim("Install it with: npx --yes mcp-remote --help"));
|
|
725
|
+
console.log(chalk.dim("Then place the wrapper script at the path above."));
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
try {
|
|
729
|
+
const stdioServers = buildStdioServers(config, wrapperPath, host);
|
|
730
|
+
const configPath = getConfigPath(target);
|
|
731
|
+
mergeAndWriteConfig(configPath, stdioServers);
|
|
732
|
+
desktopSpinner.succeed(`Configured ${chalk.cyan("claude-desktop")} \u2014 ${chalk.dim(configPath)}`);
|
|
733
|
+
configured.push(target);
|
|
734
|
+
} catch (error) {
|
|
735
|
+
desktopSpinner.fail("Failed to configure claude-desktop");
|
|
736
|
+
console.log(chalk.dim(error.message));
|
|
737
|
+
}
|
|
738
|
+
} else if (target === "claude-code") {
|
|
705
739
|
const cliSpinner = ora("Registering MCP servers with Claude Code CLI...").start();
|
|
706
740
|
const cliAvailable = await isClaudeCliAvailable();
|
|
707
741
|
if (cliAvailable) {
|
|
708
|
-
const { registered, failed } = await registerWithClaudeCode(
|
|
742
|
+
const { registered, failed } = await registerWithClaudeCode(httpServers);
|
|
709
743
|
if (failed.length === 0) {
|
|
710
744
|
cliSpinner.succeed(
|
|
711
745
|
`Registered with Claude Code: ${registered.map((n) => chalk.cyan(n)).join(", ")}`
|
|
@@ -721,7 +755,7 @@ async function runConnect(config, runtime, targets, host = "localhost") {
|
|
|
721
755
|
}
|
|
722
756
|
} else {
|
|
723
757
|
cliSpinner.warn("claude CLI not found on PATH \u2014 register manually:");
|
|
724
|
-
for (const [name, entry] of Object.entries(
|
|
758
|
+
for (const [name, entry] of Object.entries(httpServers)) {
|
|
725
759
|
const baseUrl = entry.url.replace(/\/sse$/, "");
|
|
726
760
|
console.log(
|
|
727
761
|
chalk.dim(` claude mcp add --transport http --scope user ${name} ${baseUrl}`)
|
|
@@ -732,7 +766,7 @@ async function runConnect(config, runtime, targets, host = "localhost") {
|
|
|
732
766
|
const configPath = getConfigPath(target);
|
|
733
767
|
const writeSpinner = ora(`Configuring ${chalk.cyan(target)}...`).start();
|
|
734
768
|
try {
|
|
735
|
-
mergeAndWriteConfig(configPath,
|
|
769
|
+
mergeAndWriteConfig(configPath, httpServers);
|
|
736
770
|
writeSpinner.succeed(`Configured ${chalk.cyan(target)} \u2014 ${chalk.dim(configPath)}`);
|
|
737
771
|
configured.push(target);
|
|
738
772
|
} catch (error) {
|
|
@@ -755,7 +789,7 @@ async function runConnect(config, runtime, targets, host = "localhost") {
|
|
|
755
789
|
const cursorRulesSpinner = ora("Syncing horus-core rules for Cursor...").start();
|
|
756
790
|
try {
|
|
757
791
|
await syncSkillsForCursor(runtime);
|
|
758
|
-
cursorRulesSpinner.succeed("horus-core rules synced to ~/.cursor/rules/");
|
|
792
|
+
cursorRulesSpinner.succeed("horus-core rules synced to ~/.cursor/rules/ and skills to ~/.cursor/skills-cursor/");
|
|
759
793
|
} catch (error) {
|
|
760
794
|
cursorRulesSpinner.warn("Could not sync Cursor rules (Forge container may not be running)");
|
|
761
795
|
console.log(chalk.dim(error.message));
|