@arkhera30/cli 0.3.11 → 0.3.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.js +65 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -243,6 +243,8 @@ function generateEnv(config) {
243
243
  `VAULT_ROUTER_PORT=${config.ports.vault_router}`,
244
244
  `FORGE_PORT=${config.ports.forge}`,
245
245
  `TYPESENSE_PORT=${config.ports.typesense}`,
246
+ `NEO4J_HTTP_PORT=${config.ports.neo4j_http}`,
247
+ `NEO4J_BOLT_PORT=${config.ports.neo4j_bolt}`,
246
248
  "",
247
249
  "# Search",
248
250
  `TYPESENSE_API_KEY=${config.search.api_key}`,
@@ -611,9 +613,14 @@ var ANVIL_SERVICE = ` # \u2500\u2500 Anvil \u2500\u2500\u2500\u2500\u2500\u2500
611
613
  - TYPESENSE_HOST=typesense
612
614
  - TYPESENSE_PORT=8108
613
615
  - TYPESENSE_API_KEY=\${TYPESENSE_API_KEY:-horus-local-key}
616
+ - NEO4J_URI=bolt://neo4j:7687
617
+ - NEO4J_USER=neo4j
618
+ - NEO4J_PASSWORD=horus-neo4j
614
619
  depends_on:
615
620
  typesense:
616
621
  condition: service_healthy
622
+ neo4j:
623
+ condition: service_healthy
617
624
  networks:
618
625
  - horus-net
619
626
  restart: unless-stopped
@@ -691,6 +698,38 @@ var FORGE_SERVICE = ` # \u2500\u2500 Forge \u2500\u2500\u2500\u2500\u2500\u2500
691
698
  timeout: 5s
692
699
  start_period: 60s
693
700
  retries: 3`;
701
+ var NEO4J_SERVICE = ` # \u2500\u2500 Neo4j \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
702
+ # Graph database for relationship-aware knowledge queries.
703
+ neo4j:
704
+ image: neo4j:5-community
705
+ ports:
706
+ - "\${NEO4J_HTTP_PORT:-7474}:7474"
707
+ - "\${NEO4J_BOLT_PORT:-7687}:7687"
708
+ volumes:
709
+ - neo4j-data:/data
710
+ - neo4j-logs:/logs
711
+ environment:
712
+ - NEO4J_AUTH=neo4j/horus-neo4j
713
+ - NEO4J_server_memory_heap_initial__size=256m
714
+ - NEO4J_server_memory_heap_max__size=512m
715
+ - NEO4J_server_memory_pagecache_size=256m
716
+ - NEO4J_PLUGINS=[]
717
+ networks:
718
+ - horus-net
719
+ restart: unless-stopped
720
+ stop_grace_period: 30s
721
+ deploy:
722
+ resources:
723
+ limits:
724
+ memory: 1g
725
+ reservations:
726
+ memory: 512m
727
+ healthcheck:
728
+ test: ["CMD", "wget", "--spider", "-q", "http://localhost:7474"]
729
+ interval: 30s
730
+ timeout: 10s
731
+ start_period: 60s
732
+ retries: 3`;
694
733
  var TYPESENSE_SERVICE = ` # \u2500\u2500 Typesense \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
695
734
  # Full-text and vector search engine for unified Horus Search.
696
735
  typesense:
@@ -811,6 +850,14 @@ services:
811
850
  horus-ui:
812
851
  ports:
813
852
  - "\${TEST_PORT_UI:-9260}:8400"
853
+
854
+ neo4j:
855
+ ports:
856
+ - "\${TEST_PORT_NEO4J_HTTP:-9474}:7474"
857
+ - "\${TEST_PORT_NEO4J_BOLT:-9687}:7687"
858
+ volumes:
859
+ - "\${TEST_DATA_PATH:-/tmp/horus-test}/neo4j-data:/data"
860
+ - "\${TEST_DATA_PATH:-/tmp/horus-test}/neo4j-logs:/logs"
814
861
  `;
815
862
  }
816
863
  function generateComposeFile(config, runtime) {
@@ -844,9 +891,14 @@ function generateComposeFile(config, runtime) {
844
891
  - TYPESENSE_HOST=typesense
845
892
  - TYPESENSE_PORT=8108
846
893
  - TYPESENSE_API_KEY=\${TYPESENSE_API_KEY:-horus-local-key}
894
+ - NEO4J_URI=bolt://neo4j:7687
895
+ - NEO4J_USER=neo4j
896
+ - NEO4J_PASSWORD=horus-neo4j
847
897
  depends_on:
848
898
  typesense:
849
899
  condition: service_healthy
900
+ neo4j:
901
+ condition: service_healthy
850
902
  networks:
851
903
  - horus-net
852
904
  restart: unless-stopped
@@ -924,7 +976,11 @@ ${vaultRouterDependsOn}
924
976
  timeout: 5s
925
977
  start_period: 30s
926
978
  retries: 3`;
927
- const vaultVolumeEntries = vaultEntries.map(([name]) => ` vault-${name}-workspace:`).join("\n");
979
+ const vaultVolumeEntries = [
980
+ ...vaultEntries.map(([name]) => ` vault-${name}-workspace:`),
981
+ " neo4j-data:",
982
+ " neo4j-logs:"
983
+ ].join("\n");
928
984
  const sections = [
929
985
  "# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
930
986
  "# Horus \u2014 Generated Docker Compose",
@@ -943,6 +999,8 @@ ${vaultRouterDependsOn}
943
999
  "",
944
1000
  FORGE_SERVICE,
945
1001
  "",
1002
+ NEO4J_SERVICE,
1003
+ "",
946
1004
  TYPESENSE_SERVICE,
947
1005
  "",
948
1006
  ...config.enable_ui !== false ? [HORUS_UI_SERVICE, ""] : [],
@@ -1025,16 +1083,6 @@ function mergeAndWriteConfig(configPath, mcpServers) {
1025
1083
  mkdirSync2(dir, { recursive: true });
1026
1084
  writeFileSync3(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
1027
1085
  }
1028
- function getMcpRemoteWrapperPath() {
1029
- return join2(homedir3(), ".forge", "bin", "mcp-remote-wrapper");
1030
- }
1031
- function buildStdioServers(config, wrapperPath, host) {
1032
- return {
1033
- anvil: { command: wrapperPath, args: [`http://${host}:${config.ports.anvil}/mcp`, "--transport", "http-only"] },
1034
- vault: { command: wrapperPath, args: [`http://${host}:${config.ports.vault_mcp}/mcp`, "--transport", "http-only"] },
1035
- forge: { command: wrapperPath, args: [`http://${host}:${config.ports.forge}/mcp`, "--transport", "http-only"] }
1036
- };
1037
- }
1038
1086
  async function isClaudeCliAvailable() {
1039
1087
  try {
1040
1088
  const result = await execa2("claude", ["--version"], { reject: false });
@@ -1047,7 +1095,7 @@ async function registerWithClaudeCode(mcpServers) {
1047
1095
  const registered = [];
1048
1096
  const failed = [];
1049
1097
  for (const [name, entry] of Object.entries(mcpServers)) {
1050
- const baseUrl = entry.url.replace(/\/sse$/, "");
1098
+ const baseUrl = entry.url.replace(/\/(mcp|sse)$/, "");
1051
1099
  await execa2("claude", ["mcp", "remove", "--scope", "user", name], { reject: false });
1052
1100
  const result = await execa2(
1053
1101
  "claude",
@@ -1123,26 +1171,17 @@ function printNextSteps(targets) {
1123
1171
  }
1124
1172
  async function runConnect(config, runtime, targets, host = "localhost") {
1125
1173
  const httpServers = {
1126
- anvil: { url: `http://${host}:${config.ports.anvil}/sse` },
1127
- vault: { url: `http://${host}:${config.ports.vault_mcp}/sse` },
1128
- forge: { url: `http://${host}:${config.ports.forge}/sse` }
1174
+ anvil: { url: `http://${host}:${config.ports.anvil}/mcp` },
1175
+ vault: { url: `http://${host}:${config.ports.vault_mcp}/mcp` },
1176
+ forge: { url: `http://${host}:${config.ports.forge}/mcp` }
1129
1177
  };
1130
1178
  const configured = [];
1131
1179
  for (const target of targets) {
1132
1180
  if (target === "claude-desktop") {
1133
1181
  const desktopSpinner = ora(`Configuring ${chalk.cyan("claude-desktop")}...`).start();
1134
- const wrapperPath = getMcpRemoteWrapperPath();
1135
- if (!existsSync4(wrapperPath)) {
1136
- desktopSpinner.fail("mcp-remote-wrapper not found");
1137
- console.log(chalk.dim(`Expected at: ${wrapperPath}`));
1138
- console.log(chalk.dim("Install it with: npx --yes mcp-remote --help"));
1139
- console.log(chalk.dim("Then place the wrapper script at the path above."));
1140
- continue;
1141
- }
1142
1182
  try {
1143
- const stdioServers = buildStdioServers(config, wrapperPath, host);
1144
1183
  const configPath = getConfigPath(target);
1145
- mergeAndWriteConfig(configPath, stdioServers);
1184
+ mergeAndWriteConfig(configPath, httpServers);
1146
1185
  desktopSpinner.succeed(`Configured ${chalk.cyan("claude-desktop")} \u2014 ${chalk.dim(configPath)}`);
1147
1186
  configured.push(target);
1148
1187
  } catch (error) {
@@ -1170,7 +1209,7 @@ async function runConnect(config, runtime, targets, host = "localhost") {
1170
1209
  } else {
1171
1210
  cliSpinner.warn("claude CLI not found on PATH \u2014 register manually:");
1172
1211
  for (const [name, entry] of Object.entries(httpServers)) {
1173
- const baseUrl = entry.url.replace(/\/sse$/, "");
1212
+ const baseUrl = entry.url.replace(/\/(mcp|sse)$/, "");
1174
1213
  console.log(
1175
1214
  chalk.dim(` claude mcp add --transport http --scope user ${name} ${baseUrl}`)
1176
1215
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkhera30/cli",
3
- "version": "0.3.11",
3
+ "version": "0.3.15",
4
4
  "description": "CLI for managing the Horus AI development stack",
5
5
  "type": "module",
6
6
  "bin": {