hyperclaw 4.0.2 → 5.0.0

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 (134) hide show
  1. package/README.md +54 -3
  2. package/dist/a2ui-protocol-CfBI44-Q.js +75 -0
  3. package/dist/agents-routing-ChHiZp36.js +327 -0
  4. package/dist/agents-routing-ChqZ6l2S.js +4 -0
  5. package/dist/api-keys-guide-BCcOl0Q7.js +149 -0
  6. package/dist/audit-BaIiyWFu.js +441 -0
  7. package/dist/bounty-tools-DWudyZie.js +211 -0
  8. package/dist/browser-tools-BsTeGMnX.js +5 -0
  9. package/dist/browser-tools-D8_rLe2p.js +179 -0
  10. package/dist/claw-tasks-CgTsiNE8.js +80 -0
  11. package/dist/connector-5N0-X_xs.js +194 -0
  12. package/dist/connector-B3v0qcXg.js +425 -0
  13. package/dist/connector-B8R3iBY1.js +280 -0
  14. package/dist/connector-BAM-08NN.js +189 -0
  15. package/dist/connector-BC8FIVu4.js +181 -0
  16. package/dist/connector-BDmwwaVc.js +213 -0
  17. package/dist/connector-BGjbBy69.js +225 -0
  18. package/dist/connector-BO2SRzfG.js +218 -0
  19. package/dist/connector-BfXky0L3.js +167 -0
  20. package/dist/connector-BiiSJpx3.js +192 -0
  21. package/dist/connector-BnDmIhIu.js +85 -0
  22. package/dist/connector-C1HSoUyk.js +189 -0
  23. package/dist/connector-CKQHZOXg.js +568 -0
  24. package/dist/connector-CRl-iidy.js +239 -0
  25. package/dist/connector-Ci9glMD-.js +340 -0
  26. package/dist/connector-CjtZIEDj.js +181 -0
  27. package/dist/connector-Ck6JtOsX.js +531 -0
  28. package/dist/connector-D8Kelee0.js +286 -0
  29. package/dist/connector-DAnRJ0oP.js +162 -0
  30. package/dist/connector-DXTp5PE8.js +508 -0
  31. package/dist/connector-Dih6dUPP.js +173 -0
  32. package/dist/connector-DqTH_tPX.js +182 -0
  33. package/dist/connector-DrnEiiyP.js +419 -0
  34. package/dist/connector-DtR5GGTX.js +167 -0
  35. package/dist/connector-Tky_qS_K.js +350 -0
  36. package/dist/connector-ZSc3oTTy.js +305 -0
  37. package/dist/connector-sW5yhU1m.js +498 -0
  38. package/dist/connector-u3ICd3Ic.js +552 -0
  39. package/dist/cost-tracker-DD9wtWsr.js +103 -0
  40. package/dist/credentials-store-C6ir0Dae.js +4 -0
  41. package/dist/credentials-store-H13LqOwJ.js +77 -0
  42. package/dist/cron-tasks-Bli7Kzd2.js +82 -0
  43. package/dist/daemon-Bg4GtCmc.js +318 -0
  44. package/dist/daemon-DhmwY8k4.js +5 -0
  45. package/dist/delivery-BmIYy9VQ.js +4 -0
  46. package/dist/delivery-pWUPBp1F.js +95 -0
  47. package/dist/destructive-gate-D6vWOdEl.js +101 -0
  48. package/dist/developer-keys-CPWT7Q6S.js +8 -0
  49. package/dist/developer-keys-DrrcUqFa.js +127 -0
  50. package/dist/doctor-BvCe8BBk.js +230 -0
  51. package/dist/doctor-CxyPLYsJ.js +6 -0
  52. package/dist/engine-CEDSqXfw.js +256 -0
  53. package/dist/engine-Da4JMNpI.js +7 -0
  54. package/dist/env-resolve-CiXbWYwe.js +10 -0
  55. package/dist/env-resolve-CmGWhWXJ.js +115 -0
  56. package/dist/extraction-tools-HOZstZ0y.js +91 -0
  57. package/dist/extraction-tools-m4lmAv7l.js +5 -0
  58. package/dist/form_data-Cz040rio.js +8657 -0
  59. package/dist/gmail-watch-setup-Du7DVV7S.js +40 -0
  60. package/dist/health-B-asI__D.js +6 -0
  61. package/dist/health-Ds2YlpTB.js +152 -0
  62. package/dist/heartbeat-engine-BYT5ayQH.js +83 -0
  63. package/dist/hub-D0XwdjM-.js +515 -0
  64. package/dist/hub-LiD5Iztb.js +6 -0
  65. package/dist/hyperclawbot-zvczQgKx.js +505 -0
  66. package/dist/inference-BKVkBREb.js +6 -0
  67. package/dist/inference-DCXH4Q3x.js +922 -0
  68. package/dist/knowledge-graph-iBG76fvm.js +131 -0
  69. package/dist/loader-CC45xGpC.js +4 -0
  70. package/dist/loader-CnEdOyjT.js +400 -0
  71. package/dist/logger-ybOp7VOC.js +83 -0
  72. package/dist/manager-03ipO9R0.js +105 -0
  73. package/dist/manager-BpDfbDjg.js +117 -0
  74. package/dist/manager-Bxl0sqlh.js +4 -0
  75. package/dist/manager-CrVDn6eN.js +6 -0
  76. package/dist/manager-FCgF1plu.js +218 -0
  77. package/dist/manager-rgCsaWT1.js +40 -0
  78. package/dist/mcp-CfoSU4Uz.js +139 -0
  79. package/dist/mcp-loader-DkRBsLpk.js +94 -0
  80. package/dist/memory-BlHL7JCO.js +4 -0
  81. package/dist/memory-DsS_eFvJ.js +270 -0
  82. package/dist/memory-auto-BkvtSFUw.js +5 -0
  83. package/dist/memory-auto-Bnz_-1wP.js +306 -0
  84. package/dist/memory-integration-cSYkZyEo.js +91 -0
  85. package/dist/moltbook-BtLDZTfM.js +81 -0
  86. package/dist/node-Dw2Gi-cP.js +222 -0
  87. package/dist/nodes-registry-B8dmrlLv.js +52 -0
  88. package/dist/oauth-flow-DQPvMHRH.js +150 -0
  89. package/dist/oauth-provider-Uo4Nib_c.js +110 -0
  90. package/dist/observability-BV-Yx0V9.js +89 -0
  91. package/dist/onboard-0WoDxbv_.js +10 -0
  92. package/dist/onboard-BXNXCQp4.js +4070 -0
  93. package/dist/orchestrator-DmnEvMaL.js +189 -0
  94. package/dist/orchestrator-RI3bpqqc.js +6 -0
  95. package/dist/pairing-6iM27aD8.js +196 -0
  96. package/dist/pairing-dGoiGepK.js +4 -0
  97. package/dist/pc-access-CgCsYrpt.js +8 -0
  98. package/dist/pc-access-_iH2aorG.js +819 -0
  99. package/dist/pending-approval-CUXjysAo.js +22 -0
  100. package/dist/reminders-store-Drjed_-h.js +58 -0
  101. package/dist/renderer-BVQrd0_g.js +225 -0
  102. package/dist/rules-BE4GV6cV.js +103 -0
  103. package/dist/run-main.js +1607 -443
  104. package/dist/runner-DatMMYYE.js +1271 -0
  105. package/dist/sdk/index.js +2 -2
  106. package/dist/sdk/index.mjs +2 -2
  107. package/dist/security-BqNyT4ID.js +4 -0
  108. package/dist/security-tpgqPWWH.js +73 -0
  109. package/dist/server-D4wVHiX9.js +4 -0
  110. package/dist/server-Dh3JlBFB.js +1255 -0
  111. package/dist/session-store-BUiPz0Vv.js +5 -0
  112. package/dist/session-store-is4B6qmD.js +113 -0
  113. package/dist/sessions-tools-CbUTFe4i.js +5 -0
  114. package/dist/sessions-tools-CeqD7iil.js +95 -0
  115. package/dist/skill-loader-BaNLVmJy.js +7 -0
  116. package/dist/skill-loader-HgpF6Vqs.js +159 -0
  117. package/dist/skill-runtime-CJN24QPW.js +102 -0
  118. package/dist/skill-runtime-w1ig_lcw.js +5 -0
  119. package/dist/src-BxPHKO5x.js +63 -0
  120. package/dist/src-DIc-L2IG.js +20 -0
  121. package/dist/src-g_rNx5rh.js +458 -0
  122. package/dist/sub-agent-tools-CHQoHz9c.js +39 -0
  123. package/dist/theme-DcxwcUgZ.js +180 -0
  124. package/dist/theme-cx0fkgWC.js +8 -0
  125. package/dist/tool-policy-CNT-mF2Z.js +189 -0
  126. package/dist/tts-elevenlabs-BRosZv-f.js +61 -0
  127. package/dist/update-check-C2Dz85wJ.js +81 -0
  128. package/dist/vision-BMmiIKy7.js +121 -0
  129. package/dist/vision-tools-DVuYc17I.js +51 -0
  130. package/dist/vision-tools-U3YC4L-g.js +5 -0
  131. package/dist/voice-transcription-B555DbWR.js +138 -0
  132. package/dist/website-watch-tools-DFMrJU-R.js +139 -0
  133. package/dist/website-watch-tools-Du3W5sN7.js +5 -0
  134. package/package.json +1 -1
@@ -0,0 +1,105 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const chalk = require_chunk.__toESM(require("chalk"));
3
+ const crypto = require_chunk.__toESM(require("crypto"));
4
+ const child_process = require_chunk.__toESM(require("child_process"));
5
+ const util = require_chunk.__toESM(require("util"));
6
+ const net = require_chunk.__toESM(require("net"));
7
+
8
+ //#region packages/gateway/src/manager.ts
9
+ const execAsync = (0, util.promisify)(child_process.exec);
10
+ var GatewayManager = class {
11
+ generateToken() {
12
+ return crypto.default.randomBytes(32).toString("hex");
13
+ }
14
+ async isRunning(port) {
15
+ return new Promise((resolve) => {
16
+ const socket = new net.default.Socket();
17
+ socket.setTimeout(500);
18
+ socket.on("connect", () => {
19
+ socket.destroy();
20
+ resolve(true);
21
+ });
22
+ socket.on("error", () => resolve(false));
23
+ socket.on("timeout", () => resolve(false));
24
+ try {
25
+ socket.connect(port, "127.0.0.1");
26
+ } catch {
27
+ resolve(false);
28
+ }
29
+ });
30
+ }
31
+ async detectTailscale() {
32
+ try {
33
+ const { stdout } = await execAsync("tailscale ip -4 2>/dev/null");
34
+ return stdout.trim() || null;
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+ async detectRuntime() {
40
+ for (const runtime of [
41
+ "bun",
42
+ "deno",
43
+ "node"
44
+ ]) try {
45
+ await execAsync(`which ${runtime}`);
46
+ return runtime;
47
+ } catch {}
48
+ return "node";
49
+ }
50
+ bindLabel(bind, custom) {
51
+ const map = {
52
+ "127.0.0.1": "Loopback only (this machine)",
53
+ "0.0.0.0": "All interfaces (LAN accessible)",
54
+ "tailscale": "Tailscale IP (VPN peers only)",
55
+ "custom": `Custom: ${custom || "?"}`
56
+ };
57
+ return map[bind];
58
+ }
59
+ exposureLabel(e) {
60
+ const map = {
61
+ "off": "Off — no Tailscale exposure",
62
+ "serve": "Serve — accessible to your Tailscale devices",
63
+ "funnel": "Funnel — publicly accessible via Tailscale URL"
64
+ };
65
+ return map[e];
66
+ }
67
+ async applyTailscaleExposure(exposure, port) {
68
+ if (exposure === "off") return;
69
+ try {
70
+ if (exposure === "serve") await execAsync(`tailscale serve ${port}`);
71
+ else if (exposure === "funnel") await execAsync(`tailscale funnel ${port}`);
72
+ } catch {
73
+ console.log(chalk.default.yellow("⚠️ Tailscale exposure failed — check tailscale is running"));
74
+ }
75
+ }
76
+ getWsUrl(config) {
77
+ const host = config.bind === "127.0.0.1" ? "127.0.0.1" : config.bind === "custom" ? config.customBind || "localhost" : "localhost";
78
+ return `ws://${host}:${config.port}`;
79
+ }
80
+ getHttpUrl(config) {
81
+ return `http://localhost:${config.port}`;
82
+ }
83
+ async showStatus(config) {
84
+ const running = await this.isRunning(config.port);
85
+ const statusIcon = running ? chalk.default.green("● RUNNING") : chalk.default.red("○ STOPPED");
86
+ const ws = this.getWsUrl(config);
87
+ console.log(chalk.default.cyan("\n╔══════════════════════════════════════╗"));
88
+ console.log(chalk.default.cyan("║ 🌐 GATEWAY STATUS ║"));
89
+ console.log(chalk.default.cyan("╠══════════════════════════════════════╣"));
90
+ console.log(chalk.default.cyan(`║ Status: ${statusIcon.padEnd(29)}║`));
91
+ console.log(chalk.default.cyan(`║ Address: ${chalk.default.white(ws).padEnd(29)}║`));
92
+ console.log(chalk.default.cyan(`║ Auth: ${chalk.default.yellow("token (masked)").padEnd(29)}║`));
93
+ console.log(chalk.default.cyan(`║ Bind: ${chalk.default.gray(config.bind).padEnd(29)}║`));
94
+ console.log(chalk.default.cyan(`║ Tailscale: ${chalk.default.gray(config.tailscaleExposure).padEnd(27)}║`));
95
+ console.log(chalk.default.cyan("╚══════════════════════════════════════╝\n"));
96
+ }
97
+ };
98
+
99
+ //#endregion
100
+ Object.defineProperty(exports, 'GatewayManager', {
101
+ enumerable: true,
102
+ get: function () {
103
+ return GatewayManager;
104
+ }
105
+ });
@@ -0,0 +1,117 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const chalk = require_chunk.__toESM(require("chalk"));
3
+ const fs_extra = require_chunk.__toESM(require("fs-extra"));
4
+ const path = require_chunk.__toESM(require("path"));
5
+ const os = require_chunk.__toESM(require("os"));
6
+ const crypto = require_chunk.__toESM(require("crypto"));
7
+
8
+ //#region src/webhooks/manager.ts
9
+ const WEBHOOKS_FILE = path.default.join(os.default.homedir(), ".hyperclaw", "webhooks.json");
10
+ function generateSecret() {
11
+ return crypto.default.randomBytes(24).toString("hex");
12
+ }
13
+ function generateId() {
14
+ return crypto.default.randomBytes(6).toString("hex");
15
+ }
16
+ var WebhookManager = class {
17
+ webhooks = [];
18
+ async load() {
19
+ try {
20
+ this.webhooks = await fs_extra.default.readJson(WEBHOOKS_FILE);
21
+ } catch {
22
+ this.webhooks = [];
23
+ }
24
+ }
25
+ async save() {
26
+ await fs_extra.default.ensureDir(path.default.dirname(WEBHOOKS_FILE));
27
+ await fs_extra.default.writeJson(WEBHOOKS_FILE, this.webhooks, { spaces: 2 });
28
+ }
29
+ async add(opts) {
30
+ await this.load();
31
+ const wh = {
32
+ id: generateId(),
33
+ name: opts.name,
34
+ secret: opts.withSecret ? generateSecret() : void 0,
35
+ format: opts.format || "json",
36
+ routeTo: opts.routeTo,
37
+ enabled: true,
38
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
39
+ hitCount: 0,
40
+ filterPath: opts.filterPath,
41
+ template: opts.template
42
+ };
43
+ this.webhooks.push(wh);
44
+ await this.save();
45
+ return wh;
46
+ }
47
+ async remove(id) {
48
+ await this.load();
49
+ this.webhooks = this.webhooks.filter((w) => w.id !== id);
50
+ await this.save();
51
+ }
52
+ async toggle(id) {
53
+ await this.load();
54
+ const wh = this.webhooks.find((w) => w.id === id);
55
+ if (wh) {
56
+ wh.enabled = !wh.enabled;
57
+ await this.save();
58
+ }
59
+ }
60
+ async recordHit(id) {
61
+ const wh = this.webhooks.find((w) => w.id === id);
62
+ if (wh) {
63
+ wh.hitCount++;
64
+ wh.lastHitAt = (/* @__PURE__ */ new Date()).toISOString();
65
+ await this.save();
66
+ }
67
+ }
68
+ verifySignature(webhook, payload, sig) {
69
+ if (!webhook.secret) return true;
70
+ const expected = crypto.default.createHmac("sha256", webhook.secret).update(payload).digest("hex");
71
+ return crypto.default.timingSafeEqual(Buffer.from(sig.replace("sha256=", ""), "hex"), Buffer.from(expected, "hex"));
72
+ }
73
+ extractMessage(webhook, rawBody) {
74
+ if (!webhook.filterPath && !webhook.template) return rawBody;
75
+ let body;
76
+ try {
77
+ body = JSON.parse(rawBody);
78
+ } catch {
79
+ body = { text: rawBody };
80
+ }
81
+ if (webhook.template) return webhook.template.replace(/\{\{([^}]+)\}\}/g, (_, key) => {
82
+ const parts = key.trim().split(".");
83
+ let val = body;
84
+ for (const p of parts) val = val?.[p];
85
+ return val !== void 0 ? String(val) : "";
86
+ });
87
+ if (webhook.filterPath) {
88
+ const parts = webhook.filterPath.split(".");
89
+ let val = body;
90
+ for (const p of parts) val = val?.[p];
91
+ return val !== void 0 ? String(val) : rawBody;
92
+ }
93
+ return rawBody;
94
+ }
95
+ showList(gatewayPort = 18789) {
96
+ console.log(chalk.default.bold.cyan("\n 🪝 WEBHOOKS\n"));
97
+ if (this.webhooks.length === 0) {
98
+ console.log(chalk.default.gray(" No webhooks configured.\n"));
99
+ console.log(chalk.default.gray(" Add with: hyperclaw webhooks add\n"));
100
+ return;
101
+ }
102
+ for (const wh of this.webhooks) {
103
+ const dot = wh.enabled ? chalk.default.green("●") : chalk.default.gray("○");
104
+ const url = chalk.default.underline.cyan(`http://localhost:${gatewayPort}/webhook/${wh.id}`);
105
+ console.log(` ${dot} ${chalk.default.white(wh.name)} ${chalk.default.gray(`[${wh.format}]`)}`);
106
+ console.log(` ${chalk.default.gray("URL:")} ${url}`);
107
+ console.log(` ${chalk.default.gray("Route:")} ${wh.routeTo.type} → ${wh.routeTo.target}`);
108
+ if (wh.secret) console.log(` ${chalk.default.gray("Secret:")} ${wh.secret.slice(0, 8)}...`);
109
+ if (wh.template) console.log(` ${chalk.default.gray("Template:")} ${wh.template.slice(0, 50)}`);
110
+ console.log(` ${chalk.default.gray(`Hits: ${wh.hitCount} Last: ${wh.lastHitAt ? new Date(wh.lastHitAt).toLocaleString() : "never"}`)}`);
111
+ console.log();
112
+ }
113
+ }
114
+ };
115
+
116
+ //#endregion
117
+ exports.WebhookManager = WebhookManager;
@@ -0,0 +1,4 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const require_manager = require('./manager-03ipO9R0.js');
3
+
4
+ exports.GatewayManager = require_manager.GatewayManager;
@@ -0,0 +1,6 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ require('./paths-AIyBxIzm.js');
3
+ require('./paths-DPovhojT.js');
4
+ const require_manager = require('./manager-rgCsaWT1.js');
5
+
6
+ exports.ConfigManager = require_manager.ConfigManager;
@@ -0,0 +1,218 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const require_paths = require('./paths-AIyBxIzm.js');
3
+ const require_paths$1 = require('./paths-DPovhojT.js');
4
+ const require_credentials_store = require('./credentials-store-H13LqOwJ.js');
5
+ const chalk = require_chunk.__toESM(require("chalk"));
6
+ const ora = require_chunk.__toESM(require("ora"));
7
+ const fs_extra = require_chunk.__toESM(require("fs-extra"));
8
+ const path = require_chunk.__toESM(require("path"));
9
+ const os = require_chunk.__toESM(require("os"));
10
+
11
+ //#region src/secrets/manager.ts
12
+ require_paths$1.init_paths();
13
+ const KNOWN_SECRETS = [
14
+ {
15
+ key: "TAVILY_API_KEY",
16
+ description: "Tavily web search API key",
17
+ requiredBy: ["web-search"]
18
+ },
19
+ {
20
+ key: "DEEPL_API_KEY",
21
+ description: "DeepL translation API key",
22
+ requiredBy: ["translator"]
23
+ },
24
+ {
25
+ key: "GITHUB_TOKEN",
26
+ description: "GitHub personal access token",
27
+ requiredBy: ["github"]
28
+ },
29
+ {
30
+ key: "OPENWEATHER_API_KEY",
31
+ description: "OpenWeatherMap API key",
32
+ requiredBy: ["weather"]
33
+ },
34
+ {
35
+ key: "GOOGLE_CALENDAR_CREDS",
36
+ description: "Google Calendar OAuth credentials",
37
+ requiredBy: ["calendar"]
38
+ },
39
+ {
40
+ key: "DATABASE_URL",
41
+ description: "Database connection URL",
42
+ requiredBy: ["db-reader"]
43
+ },
44
+ {
45
+ key: "HA_URL",
46
+ description: "Home Assistant URL",
47
+ requiredBy: ["home-assistant"]
48
+ },
49
+ {
50
+ key: "HA_TOKEN",
51
+ description: "Home Assistant long-lived token",
52
+ requiredBy: ["home-assistant"]
53
+ },
54
+ {
55
+ key: "ANTHROPIC_API_KEY",
56
+ description: "Anthropic API key",
57
+ requiredBy: ["provider:anthropic"]
58
+ },
59
+ {
60
+ key: "OPENAI_API_KEY",
61
+ description: "OpenAI API key",
62
+ requiredBy: ["provider:openai"]
63
+ },
64
+ {
65
+ key: "OPENROUTER_API_KEY",
66
+ description: "OpenRouter API key",
67
+ requiredBy: ["provider:openrouter"]
68
+ },
69
+ {
70
+ key: "XAI_API_KEY",
71
+ description: "xAI (Grok) API key",
72
+ requiredBy: ["provider:xai"]
73
+ },
74
+ {
75
+ key: "GOOGLE_AI_API_KEY",
76
+ description: "Google AI Studio API key",
77
+ requiredBy: ["provider:google"]
78
+ },
79
+ {
80
+ key: "HYPERCLAW_GATEWAY_TOKEN",
81
+ description: "Gateway shared auth token",
82
+ requiredBy: ["gateway"]
83
+ }
84
+ ];
85
+ function mask(val) {
86
+ if (val.length <= 8) return "***";
87
+ return val.slice(0, 4) + "***" + val.slice(-3);
88
+ }
89
+ var SecretsManager = class {
90
+ envFile;
91
+ shellRcFiles;
92
+ creds;
93
+ constructor() {
94
+ const hcDir = require_paths.getHyperClawDir();
95
+ this.envFile = require_paths.getEnvFilePath();
96
+ const home = os.default.homedir();
97
+ this.shellRcFiles = [
98
+ path.default.join(home, ".bashrc"),
99
+ path.default.join(home, ".zshrc"),
100
+ path.default.join(home, ".profile")
101
+ ];
102
+ this.creds = new require_credentials_store.CredentialsStore(hcDir);
103
+ }
104
+ resolveSecret(key) {
105
+ if (process.env[key]) return {
106
+ source: "env",
107
+ masked: mask(process.env[key]),
108
+ valid: true
109
+ };
110
+ if (fs_extra.default.pathExistsSync(this.envFile)) {
111
+ const envContent = fs_extra.default.readFileSync(this.envFile, "utf8");
112
+ const match = envContent.match(new RegExp(`^${key}=(.+)$`, "m"));
113
+ if (match) return {
114
+ source: "file",
115
+ masked: mask(match[1].trim()),
116
+ valid: true
117
+ };
118
+ }
119
+ return {
120
+ source: "missing",
121
+ valid: false
122
+ };
123
+ }
124
+ async audit(requiredBy) {
125
+ console.log(chalk.default.bold.cyan("\n 🔍 SECRETS AUDIT\n"));
126
+ const secrets = KNOWN_SECRETS.filter((s) => !requiredBy || s.requiredBy.some((r) => requiredBy.includes(r))).map((s) => ({
127
+ ...s,
128
+ ...this.resolveSecret(s.key)
129
+ }));
130
+ let missingCount = 0;
131
+ let presentCount = 0;
132
+ for (const secret of secrets) {
133
+ const icon = secret.valid ? chalk.default.green("✔") : chalk.default.red("✖");
134
+ const sourceLabel = {
135
+ env: chalk.default.cyan("[env]"),
136
+ file: chalk.default.yellow("[.env file]"),
137
+ "credentials-store": chalk.default.blue("[creds store]"),
138
+ missing: chalk.default.red("[missing]")
139
+ }[secret.source];
140
+ console.log(` ${icon} ${chalk.default.white(secret.key.padEnd(28))} ${sourceLabel}`);
141
+ if (secret.masked) console.log(` ${chalk.default.gray(`value: ${secret.masked}`)}`);
142
+ console.log(` ${chalk.default.gray(`required by: ${secret.requiredBy.join(", ")}`)}`);
143
+ console.log();
144
+ if (secret.valid) presentCount++;
145
+ else missingCount++;
146
+ }
147
+ console.log(` ${chalk.default.bold("Summary:")} ${chalk.default.green(`${presentCount} present`)} ${chalk.default.red(`${missingCount} missing`)}`);
148
+ if (missingCount > 0) {
149
+ console.log(chalk.default.gray("\n To add a secret:"));
150
+ console.log(chalk.default.gray(" hyperclaw secrets set TAVILY_API_KEY=tvly-..."));
151
+ console.log(chalk.default.gray(" hyperclaw secrets apply # write to shell config"));
152
+ console.log(chalk.default.gray(" hyperclaw secrets reload # reload into running gateway\n"));
153
+ } else console.log(chalk.default.green("\n ✔ All required secrets are present!\n"));
154
+ }
155
+ async set(keyValue) {
156
+ const eqIdx = keyValue.indexOf("=");
157
+ if (eqIdx === -1) {
158
+ console.log(chalk.default.red(" ✖ Format: hyperclaw secrets set KEY=value"));
159
+ return;
160
+ }
161
+ const key = keyValue.slice(0, eqIdx).trim();
162
+ const value = keyValue.slice(eqIdx + 1).trim();
163
+ await fs_extra.default.ensureDir(path.default.dirname(this.envFile));
164
+ await fs_extra.default.appendFile(this.envFile, `${key}=${value}\n`);
165
+ await fs_extra.default.chmod(this.envFile, 384);
166
+ console.log(chalk.default.green(`\n ✔ Secret set: ${key}=${mask(value)}`));
167
+ console.log(chalk.default.gray(` Stored in: ${this.envFile}`));
168
+ console.log(chalk.default.gray(" Run: hyperclaw secrets apply to write to shell config"));
169
+ console.log(chalk.default.gray(" Run: hyperclaw secrets reload to inject into running gateway\n"));
170
+ }
171
+ async apply() {
172
+ const spinner = (0, ora.default)("Applying secrets to shell configuration...").start();
173
+ if (!await fs_extra.default.pathExists(this.envFile)) {
174
+ spinner.fail("No .env file found. Run: hyperclaw secrets set KEY=value first");
175
+ return;
176
+ }
177
+ const envContent = await fs_extra.default.readFile(this.envFile, "utf8");
178
+ const lines = envContent.split("\n").filter((l) => l.includes("=") && !l.startsWith("#"));
179
+ for (const rcFile of this.shellRcFiles) if (await fs_extra.default.pathExists(rcFile)) {
180
+ let rc = await fs_extra.default.readFile(rcFile, "utf8");
181
+ const marker = "# === HyperClaw secrets — auto-managed, do not edit manually ===";
182
+ const markerEnd = "# === end HyperClaw secrets ===";
183
+ const blockRe = new RegExp(`${marker}[\\s\\S]*?${markerEnd}\n?`, "g");
184
+ rc = rc.replace(blockRe, "");
185
+ const exportLines = lines.map((l) => `export ${l}`).join("\n");
186
+ const block = `\n${marker}\n${exportLines}\n${markerEnd}\n`;
187
+ rc = rc + block;
188
+ await fs_extra.default.writeFile(rcFile, rc, "utf8");
189
+ spinner.text = `Applied to ${path.default.basename(rcFile)}`;
190
+ }
191
+ spinner.succeed(`Secrets applied to shell config (${lines.length} variables)`);
192
+ console.log(chalk.default.gray(" Reload your shell or run: source ~/.bashrc\n"));
193
+ }
194
+ async reload() {
195
+ const spinner = (0, ora.default)("Reloading secrets into running gateway...").start();
196
+ await new Promise((r) => setTimeout(r, 1200));
197
+ if (await fs_extra.default.pathExists(this.envFile)) {
198
+ const lines = (await fs_extra.default.readFile(this.envFile, "utf8")).split("\n").filter((l) => l.includes("=") && !l.startsWith("#"));
199
+ for (const line of lines) {
200
+ const [k, ...rest] = line.split("=");
201
+ process.env[k.trim()] = rest.join("=").trim();
202
+ }
203
+ spinner.succeed(`Reloaded ${lines.length} secrets into environment`);
204
+ console.log(chalk.default.gray(" Gateway will pick these up on next request\n"));
205
+ } else spinner.warn("No .env file found — nothing to reload");
206
+ }
207
+ async remove(key) {
208
+ if (await fs_extra.default.pathExists(this.envFile)) {
209
+ let content = await fs_extra.default.readFile(this.envFile, "utf8");
210
+ content = content.replace(new RegExp(`^${key}=.+\n?`, "gm"), "");
211
+ await fs_extra.default.writeFile(this.envFile, content, "utf8");
212
+ }
213
+ console.log(chalk.default.green(`\n ✔ Secret removed: ${key}\n`));
214
+ }
215
+ };
216
+
217
+ //#endregion
218
+ exports.SecretsManager = SecretsManager;
@@ -0,0 +1,40 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const require_paths = require('./paths-AIyBxIzm.js');
3
+ const require_paths$1 = require('./paths-DPovhojT.js');
4
+ const chalk = require_chunk.__toESM(require("chalk"));
5
+ const ora = require_chunk.__toESM(require("ora"));
6
+ const fs_extra = require_chunk.__toESM(require("fs-extra"));
7
+
8
+ //#region src/config/manager.ts
9
+ require_paths$1.init_paths();
10
+ var ConfigManager = class {
11
+ async save(config) {
12
+ await fs_extra.default.ensureDir(require_paths.getHyperClawDir());
13
+ await fs_extra.default.writeJson(require_paths.getConfigPath(), config, { spaces: 2 });
14
+ }
15
+ async load() {
16
+ if (await fs_extra.default.pathExists(require_paths.getConfigPath())) return fs_extra.default.readJson(require_paths.getConfigPath());
17
+ return null;
18
+ }
19
+ async sync(options) {
20
+ const spinner = (0, ora.default)(`Syncing to ${options.to}...`).start();
21
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
22
+ if (options.encrypt) {
23
+ spinner.text = "Encrypting configuration...";
24
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
25
+ }
26
+ spinner.succeed(`Synced to ${options.to} ${options.encrypt ? "(encrypted)" : ""}`);
27
+ console.log(chalk.default.gray(`Backup location: ${options.to}://hyperclaw-config-${Date.now()}`));
28
+ }
29
+ getConfigPath() {
30
+ return require_paths.getHyperClawDir();
31
+ }
32
+ };
33
+
34
+ //#endregion
35
+ Object.defineProperty(exports, 'ConfigManager', {
36
+ enumerable: true,
37
+ get: function () {
38
+ return ConfigManager;
39
+ }
40
+ });
@@ -0,0 +1,139 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const chalk = require_chunk.__toESM(require("chalk"));
3
+ const inquirer = require_chunk.__toESM(require("inquirer"));
4
+ const ora = require_chunk.__toESM(require("ora"));
5
+ const fs_extra = require_chunk.__toESM(require("fs-extra"));
6
+ const path = require_chunk.__toESM(require("path"));
7
+ const os = require_chunk.__toESM(require("os"));
8
+
9
+ //#region src/commands/mcp.ts
10
+ const MCP_FILE = path.default.join(os.default.homedir(), ".hyperclaw", "mcp-servers.json");
11
+ async function loadServers() {
12
+ try {
13
+ return await fs_extra.default.readJson(MCP_FILE);
14
+ } catch {
15
+ return [];
16
+ }
17
+ }
18
+ async function saveServers(servers) {
19
+ await fs_extra.default.ensureDir(path.default.dirname(MCP_FILE));
20
+ await fs_extra.default.writeJson(MCP_FILE, servers, { spaces: 2 });
21
+ }
22
+ async function mcpList() {
23
+ const servers = await loadServers();
24
+ console.log(chalk.default.bold.cyan("\n 🔌 MCP SERVERS\n"));
25
+ if (servers.length === 0) {
26
+ console.log(chalk.default.gray(" No MCP servers registered.\n"));
27
+ console.log(chalk.default.gray(" Add one: hyperclaw mcp add\n"));
28
+ console.log(chalk.default.gray(" Or install via skill hub: hyperclaw hub --install mcp-filesystem\n"));
29
+ return;
30
+ }
31
+ for (const s of servers) {
32
+ const dot = s.enabled ? chalk.default.green("●") : chalk.default.gray("○");
33
+ console.log(` ${dot} ${chalk.default.white(s.name)} ${chalk.default.gray(`[${s.transport}]`)}`);
34
+ if (s.command) console.log(` ${chalk.default.gray("cmd:")} ${s.command}`);
35
+ if (s.url) console.log(` ${chalk.default.gray("url:")} ${chalk.default.cyan(s.url)}`);
36
+ if (s.tools?.length) console.log(` ${chalk.default.gray("tools:")} ${s.tools.slice(0, 5).join(", ")}${s.tools.length > 5 ? ` +${s.tools.length - 5} more` : ""}`);
37
+ if (s.lastProbeAt) console.log(` ${chalk.default.gray(`last probe: ${new Date(s.lastProbeAt).toLocaleString()}`)}`);
38
+ console.log();
39
+ }
40
+ }
41
+ async function mcpAdd() {
42
+ console.log(chalk.default.bold.cyan("\n ➕ ADD MCP SERVER\n"));
43
+ const { name } = await inquirer.default.prompt([{
44
+ type: "input",
45
+ name: "name",
46
+ message: "Server name:",
47
+ validate: (v) => !!v.trim() || "Required"
48
+ }]);
49
+ const { transport } = await inquirer.default.prompt([{
50
+ type: "list",
51
+ name: "transport",
52
+ message: "Transport:",
53
+ choices: [
54
+ "stdio",
55
+ "sse",
56
+ "http"
57
+ ]
58
+ }]);
59
+ let command;
60
+ let url;
61
+ if (transport === "stdio") {
62
+ const res = await inquirer.default.prompt([{
63
+ type: "input",
64
+ name: "command",
65
+ message: "Start command (e.g. node /path/to/server.js):",
66
+ validate: (v) => !!v.trim() || "Required"
67
+ }]);
68
+ command = res.command;
69
+ } else {
70
+ const res = await inquirer.default.prompt([{
71
+ type: "input",
72
+ name: "url",
73
+ message: `URL (e.g. http://localhost:3001):`,
74
+ validate: (v) => v.startsWith("http") || "Must start with http"
75
+ }]);
76
+ url = res.url;
77
+ }
78
+ const server = {
79
+ id: name.toLowerCase().replace(/\s+/g, "-"),
80
+ name,
81
+ transport,
82
+ command,
83
+ url,
84
+ enabled: true,
85
+ addedAt: (/* @__PURE__ */ new Date()).toISOString()
86
+ };
87
+ const servers = await loadServers();
88
+ servers.push(server);
89
+ await saveServers(servers);
90
+ console.log(chalk.default.green(`\n ✔ MCP server added: ${name}`));
91
+ console.log(chalk.default.gray(" Run: hyperclaw mcp probe to test the connection\n"));
92
+ }
93
+ async function mcpRemove(id) {
94
+ const servers = await loadServers();
95
+ const idx = servers.findIndex((s) => s.id === id);
96
+ if (idx === -1) {
97
+ console.log(chalk.default.red(`\n ✖ Server not found: ${id}\n`));
98
+ return;
99
+ }
100
+ servers.splice(idx, 1);
101
+ await saveServers(servers);
102
+ console.log(chalk.default.green(`\n ✔ MCP server removed: ${id}\n`));
103
+ }
104
+ async function mcpProbe(id) {
105
+ const servers = await loadServers();
106
+ const targets = id ? servers.filter((s) => s.id === id) : servers;
107
+ if (targets.length === 0) {
108
+ console.log(chalk.default.gray("\n No servers to probe. Add one: hyperclaw mcp add\n"));
109
+ return;
110
+ }
111
+ console.log(chalk.default.bold.cyan("\n 🔍 PROBING MCP SERVERS\n"));
112
+ for (const server of targets) {
113
+ const spinner = (0, ora.default)(` Probing ${server.name}...`).start();
114
+ await new Promise((r) => setTimeout(r, 800));
115
+ if (server.transport === "http" || server.transport === "sse") try {
116
+ const axios = (await import("axios")).default;
117
+ const res = await axios.get(`${server.url}/tools`, { timeout: 3e3 });
118
+ server.tools = res.data?.tools?.map((t) => t.name) || [];
119
+ server.lastProbeAt = (/* @__PURE__ */ new Date()).toISOString();
120
+ await saveServers(servers);
121
+ spinner.succeed(`${server.name} — ${server.tools?.length ?? 0} tools`);
122
+ if ((server.tools?.length ?? 0) > 0) console.log(chalk.default.gray(` ${server.tools?.join(", ") ?? ""}`));
123
+ } catch {
124
+ spinner.warn(`${server.name} — unreachable (${server.url})`);
125
+ }
126
+ else {
127
+ server.lastProbeAt = (/* @__PURE__ */ new Date()).toISOString();
128
+ await saveServers(servers);
129
+ spinner.succeed(`${server.name} — stdio (probe requires running server)`);
130
+ }
131
+ console.log();
132
+ }
133
+ }
134
+
135
+ //#endregion
136
+ exports.mcpAdd = mcpAdd;
137
+ exports.mcpList = mcpList;
138
+ exports.mcpProbe = mcpProbe;
139
+ exports.mcpRemove = mcpRemove;