@arkhera30/cli 0.1.16 → 0.1.17
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 +52 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -38,7 +38,8 @@ function findPackageJson() {
|
|
|
38
38
|
}
|
|
39
39
|
var pkg = JSON.parse(readFileSync(findPackageJson(), "utf-8"));
|
|
40
40
|
var CLI_VERSION = pkg.version;
|
|
41
|
-
var HORUS_DIR = join(homedir(), "
|
|
41
|
+
var HORUS_DIR = join(homedir(), "Horus");
|
|
42
|
+
var LEGACY_HORUS_DIR = join(homedir(), ".horus");
|
|
42
43
|
var CONFIG_PATH = join(HORUS_DIR, "config.yaml");
|
|
43
44
|
var ENV_PATH = join(HORUS_DIR, ".env");
|
|
44
45
|
var COMPOSE_PATH = join(HORUS_DIR, "docker-compose.yml");
|
|
@@ -53,7 +54,7 @@ var DEFAULT_REPOS = {
|
|
|
53
54
|
vault_knowledge: "",
|
|
54
55
|
forge_registry: ""
|
|
55
56
|
};
|
|
56
|
-
var DEFAULT_DATA_DIR = join(homedir(), "
|
|
57
|
+
var DEFAULT_DATA_DIR = join(homedir(), "Horus", "data");
|
|
57
58
|
var SERVICES = [
|
|
58
59
|
"qmd-daemon",
|
|
59
60
|
"anvil",
|
|
@@ -85,6 +86,38 @@ function configExists() {
|
|
|
85
86
|
}
|
|
86
87
|
function loadConfig() {
|
|
87
88
|
if (!existsSync2(CONFIG_PATH)) {
|
|
89
|
+
const legacyConfigPath = pathJoin(LEGACY_HORUS_DIR, "config.yaml");
|
|
90
|
+
if (existsSync2(legacyConfigPath)) {
|
|
91
|
+
console.warn(
|
|
92
|
+
`
|
|
93
|
+
Warning: Horus config found at ~/.horus/config.yaml (legacy location).
|
|
94
|
+
The new default is ~/Horus. Run \`horus setup\` to migrate.
|
|
95
|
+
`
|
|
96
|
+
);
|
|
97
|
+
const raw2 = readFileSync2(legacyConfigPath, "utf-8");
|
|
98
|
+
const parsed2 = parseYaml(raw2);
|
|
99
|
+
const defaults2 = defaultConfig();
|
|
100
|
+
return {
|
|
101
|
+
version: parsed2.version ?? defaults2.version,
|
|
102
|
+
data_dir: parsed2.data_dir ?? defaults2.data_dir,
|
|
103
|
+
runtime: parsed2.runtime ?? defaults2.runtime,
|
|
104
|
+
ports: {
|
|
105
|
+
anvil: parsed2.ports?.anvil ?? defaults2.ports.anvil,
|
|
106
|
+
vault_rest: parsed2.ports?.vault_rest ?? defaults2.ports.vault_rest,
|
|
107
|
+
vault_mcp: parsed2.ports?.vault_mcp ?? defaults2.ports.vault_mcp,
|
|
108
|
+
forge: parsed2.ports?.forge ?? defaults2.ports.forge
|
|
109
|
+
},
|
|
110
|
+
git_host: parsed2.git_host ?? defaults2.git_host,
|
|
111
|
+
repos: {
|
|
112
|
+
anvil_notes: parsed2.repos?.anvil_notes ?? defaults2.repos.anvil_notes,
|
|
113
|
+
vault_knowledge: parsed2.repos?.vault_knowledge ?? defaults2.repos.vault_knowledge,
|
|
114
|
+
forge_registry: parsed2.repos?.forge_registry ?? defaults2.repos.forge_registry
|
|
115
|
+
},
|
|
116
|
+
host_repos_path: parsed2.host_repos_path ?? defaults2.host_repos_path,
|
|
117
|
+
host_repos_extra_scan_dirs: parsed2.host_repos_extra_scan_dirs ?? defaults2.host_repos_extra_scan_dirs,
|
|
118
|
+
github_token: parsed2.github_token ?? defaults2.github_token
|
|
119
|
+
};
|
|
120
|
+
}
|
|
88
121
|
return defaultConfig();
|
|
89
122
|
}
|
|
90
123
|
const raw = readFileSync2(CONFIG_PATH, "utf-8");
|
|
@@ -502,7 +535,7 @@ async function pollUntilHealthy(runtime, onUpdate, timeoutMs = 3e5, intervalMs =
|
|
|
502
535
|
const unhealthyServices = states.filter((s) => s.status === "unhealthy").map((s) => s.name).join(", ");
|
|
503
536
|
throw new Error(
|
|
504
537
|
`Services failed health check: ${unhealthyServices}
|
|
505
|
-
Run '${runtime.name} compose logs <service>' from
|
|
538
|
+
Run '${runtime.name} compose logs <service>' from ~/Horus/ to investigate.`
|
|
506
539
|
);
|
|
507
540
|
}
|
|
508
541
|
const elapsed = Date.now() - startTime;
|
|
@@ -510,7 +543,7 @@ Run '${runtime.name} compose logs <service>' from ~/.horus/ to investigate.`
|
|
|
510
543
|
const notReady = states.filter((s) => s.status !== "healthy").map((s) => `${s.name} (${s.status})`).join(", ");
|
|
511
544
|
throw new Error(
|
|
512
545
|
`Timed out after ${Math.round(timeoutMs / 1e3)}s waiting for services: ${notReady}
|
|
513
|
-
Run '${runtime.name} compose logs' from
|
|
546
|
+
Run '${runtime.name} compose logs' from ~/Horus/ to investigate.`
|
|
514
547
|
);
|
|
515
548
|
}
|
|
516
549
|
await new Promise((resolve2) => setTimeout(resolve2, intervalMs));
|
|
@@ -616,9 +649,9 @@ function getMcpRemoteWrapperPath() {
|
|
|
616
649
|
}
|
|
617
650
|
function buildStdioServers(config, wrapperPath, host) {
|
|
618
651
|
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
|
|
652
|
+
anvil: { command: wrapperPath, args: [`http://${host}:${config.ports.anvil}/mcp`, "--transport", "http-only"] },
|
|
653
|
+
vault: { command: wrapperPath, args: [`http://${host}:${config.ports.vault_mcp}/mcp`, "--transport", "http-only"] },
|
|
654
|
+
forge: { command: wrapperPath, args: [`http://${host}:${config.ports.forge}/mcp`, "--transport", "http-only"] }
|
|
622
655
|
};
|
|
623
656
|
}
|
|
624
657
|
async function isClaudeCliAvailable() {
|
|
@@ -1047,7 +1080,7 @@ ${example("forge-registry")}
|
|
|
1047
1080
|
const configSpinner = ora2("Saving configuration...").start();
|
|
1048
1081
|
try {
|
|
1049
1082
|
saveConfig(config);
|
|
1050
|
-
configSpinner.succeed("Configuration saved to
|
|
1083
|
+
configSpinner.succeed("Configuration saved to ~/Horus/config.yaml");
|
|
1051
1084
|
} catch (error) {
|
|
1052
1085
|
configSpinner.fail("Failed to save configuration");
|
|
1053
1086
|
console.error(error.message);
|
|
@@ -1056,7 +1089,7 @@ ${example("forge-registry")}
|
|
|
1056
1089
|
const envSpinner = ora2("Generating .env file...").start();
|
|
1057
1090
|
try {
|
|
1058
1091
|
writeEnvFile(config);
|
|
1059
|
-
envSpinner.succeed("Environment file written to
|
|
1092
|
+
envSpinner.succeed("Environment file written to ~/Horus/.env");
|
|
1060
1093
|
} catch (error) {
|
|
1061
1094
|
envSpinner.fail("Failed to generate .env");
|
|
1062
1095
|
console.error(error.message);
|
|
@@ -1065,7 +1098,7 @@ ${example("forge-registry")}
|
|
|
1065
1098
|
const composeSpinner = ora2("Installing docker-compose.yml...").start();
|
|
1066
1099
|
try {
|
|
1067
1100
|
installComposeFile(runtime.name);
|
|
1068
|
-
composeSpinner.succeed("Compose file installed to
|
|
1101
|
+
composeSpinner.succeed("Compose file installed to ~/Horus/docker-compose.yml");
|
|
1069
1102
|
} catch (error) {
|
|
1070
1103
|
composeSpinner.fail("Failed to install compose file");
|
|
1071
1104
|
console.error(error.message);
|
|
@@ -1151,7 +1184,7 @@ ${example("forge-registry")}
|
|
|
1151
1184
|
healthSpinner.fail("Some services did not become healthy");
|
|
1152
1185
|
console.log(chalk2.dim(error.message));
|
|
1153
1186
|
console.log("");
|
|
1154
|
-
console.log(chalk2.dim("Tip: Check logs with `docker compose logs` from
|
|
1187
|
+
console.log(chalk2.dim("Tip: Check logs with `docker compose logs` from ~/Horus/"));
|
|
1155
1188
|
process.exit(1);
|
|
1156
1189
|
}
|
|
1157
1190
|
console.log("");
|
|
@@ -1172,7 +1205,7 @@ ${example("forge-registry")}
|
|
|
1172
1205
|
console.log(chalk2.dim("\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"));
|
|
1173
1206
|
console.log("");
|
|
1174
1207
|
console.log(` ${chalk2.bold("Runtime:")} ${runtime.name}`);
|
|
1175
|
-
console.log(` ${chalk2.bold("Config:")}
|
|
1208
|
+
console.log(` ${chalk2.bold("Config:")} ~/Horus/config.yaml`);
|
|
1176
1209
|
console.log(` ${chalk2.bold("Data:")} ${config.data_dir}`);
|
|
1177
1210
|
console.log("");
|
|
1178
1211
|
console.log(chalk2.bold(" Service URLs:"));
|
|
@@ -1314,7 +1347,7 @@ var statusCommand = new Command5("status").description("Show status of Horus ser
|
|
|
1314
1347
|
console.log(chalk5.dim("\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"));
|
|
1315
1348
|
console.log(` ${chalk5.bold("Version:")} ${CLI_VERSION}`);
|
|
1316
1349
|
console.log(` ${chalk5.bold("Runtime:")} ${runtime.name}`);
|
|
1317
|
-
console.log(` ${chalk5.bold("Config:")}
|
|
1350
|
+
console.log(` ${chalk5.bold("Config:")} ~/Horus/config.yaml`);
|
|
1318
1351
|
console.log("");
|
|
1319
1352
|
if (containers.length === 0) {
|
|
1320
1353
|
console.log(chalk5.yellow(" No services are running."));
|
|
@@ -1399,7 +1432,7 @@ var configCommand = new Command6("config").description("View or modify Horus con
|
|
|
1399
1432
|
console.log(` ${chalk6.bold("vault-knowledge:")} ${config.repos.vault_knowledge || chalk6.dim("(not set)")}`);
|
|
1400
1433
|
console.log(` ${chalk6.bold("forge-registry:")} ${config.repos.forge_registry || chalk6.dim("(not set)")}`);
|
|
1401
1434
|
console.log("");
|
|
1402
|
-
console.log(chalk6.dim(` Config file:
|
|
1435
|
+
console.log(chalk6.dim(` Config file: ~/Horus/config.yaml`));
|
|
1403
1436
|
console.log(chalk6.dim(` Use 'horus config get <key>' or 'horus config set <key> <value>'`));
|
|
1404
1437
|
console.log("");
|
|
1405
1438
|
});
|
|
@@ -1790,23 +1823,23 @@ async function checkCompose(preferred) {
|
|
|
1790
1823
|
}
|
|
1791
1824
|
function checkConfig() {
|
|
1792
1825
|
if (configExists()) {
|
|
1793
|
-
return { status: "pass", label: "Config", message: "Configuration file exists (
|
|
1826
|
+
return { status: "pass", label: "Config", message: "Configuration file exists (~/Horus/config.yaml)" };
|
|
1794
1827
|
}
|
|
1795
1828
|
return {
|
|
1796
1829
|
status: "fail",
|
|
1797
1830
|
label: "Config",
|
|
1798
|
-
message: "Configuration file missing (
|
|
1831
|
+
message: "Configuration file missing (~/Horus/config.yaml)",
|
|
1799
1832
|
hint: "Run `horus setup` to create the configuration"
|
|
1800
1833
|
};
|
|
1801
1834
|
}
|
|
1802
1835
|
function checkComposeFile() {
|
|
1803
1836
|
if (existsSync7(COMPOSE_PATH)) {
|
|
1804
|
-
return { status: "pass", label: "Compose file", message: "Compose file installed (
|
|
1837
|
+
return { status: "pass", label: "Compose file", message: "Compose file installed (~/Horus/docker-compose.yml)" };
|
|
1805
1838
|
}
|
|
1806
1839
|
return {
|
|
1807
1840
|
status: "fail",
|
|
1808
1841
|
label: "Compose file",
|
|
1809
|
-
message: "Compose file missing (
|
|
1842
|
+
message: "Compose file missing (~/Horus/docker-compose.yml)",
|
|
1810
1843
|
hint: "Run `horus setup` to install the compose file"
|
|
1811
1844
|
};
|
|
1812
1845
|
}
|
|
@@ -1939,7 +1972,7 @@ var doctorCommand = new Command8("doctor").description("Diagnose common Horus is
|
|
|
1939
1972
|
allResults.push(checkConfig());
|
|
1940
1973
|
allResults.push(checkComposeFile());
|
|
1941
1974
|
const ports = config?.ports ?? DEFAULT_PORTS;
|
|
1942
|
-
const dataDir = config?.data_dir ??
|
|
1975
|
+
const dataDir = config?.data_dir ?? DEFAULT_DATA_DIR;
|
|
1943
1976
|
allResults.push(checkPort(ports.anvil, "Anvil"));
|
|
1944
1977
|
allResults.push(checkPort(ports.vault_rest, "Vault"));
|
|
1945
1978
|
allResults.push(checkPort(ports.vault_mcp, "Vault MCP"));
|