hyperclaw 4.0.0 → 4.0.2
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/README.md +53 -18
- package/dist/a2ui-protocol-CT_jDEU9.js +75 -0
- package/dist/agents-routing-683Q2JGp.js +129 -0
- package/dist/agents-routing-BpZBswBH.js +4 -0
- package/dist/api-keys-guide-Bzig1R5W.js +149 -0
- package/dist/api-keys-guide-Dq5Obbp4.js +149 -0
- package/dist/audit-BYxPlnTQ.js +248 -0
- package/dist/bounty-tools-C6LyzxM-.js +211 -0
- package/dist/browser-tools-CQBSbIuO.js +5 -0
- package/dist/browser-tools-YQmwRLLM.js +179 -0
- package/dist/claw-tasks-BRLUvFRD.js +80 -0
- package/dist/connector-3HnyH8fn.js +167 -0
- package/dist/connector-6PMZo5Ky.js +189 -0
- package/dist/connector-B6eoF3DD.js +181 -0
- package/dist/connector-B9tLG8UZ.js +196 -0
- package/dist/connector-BOlqjXWP.js +182 -0
- package/dist/connector-BP8zsbP8.js +189 -0
- package/dist/connector-BPoSevxp.js +286 -0
- package/dist/connector-BRHj773i.js +163 -0
- package/dist/connector-BToxU-jV.js +267 -0
- package/dist/connector-BliDVsJQ.js +239 -0
- package/dist/connector-Bv6s9oP7.js +88 -0
- package/dist/connector-By5wWGTR.js +343 -0
- package/dist/connector-C1BaFFgN.js +213 -0
- package/dist/connector-CRRWY5Wv.js +167 -0
- package/dist/connector-CXPQVGyI.js +85 -0
- package/dist/connector-Cdk1CXKi.js +194 -0
- package/dist/connector-CwlgFgjx.js +181 -0
- package/dist/connector-DFchk6l7.js +178 -0
- package/dist/connector-DKw7tRAy.js +192 -0
- package/dist/connector-DRv1ahC_.js +343 -0
- package/dist/connector-DU63KW94.js +165 -0
- package/dist/connector-Dbvb1Cj9.js +280 -0
- package/dist/connector-DcZdQcgR.js +173 -0
- package/dist/connector-DxKL8VvZ.js +182 -0
- package/dist/connector-T_YdZtzv.js +162 -0
- package/dist/connector-i4gOS9xL.js +154 -0
- package/dist/connector-rHXE1ZD2.js +167 -0
- package/dist/connector-wdUXChwa.js +172 -0
- package/dist/cost-tracker-pVE15Yq4.js +103 -0
- package/dist/credentials-store-BvnMPJwi.js +4 -0
- package/dist/credentials-store-sb-TRLwR.js +77 -0
- package/dist/cron-tasks-BvDFNyiE.js +82 -0
- package/dist/delivery-B-SJqXLn.js +95 -0
- package/dist/delivery-D5Z98EVq.js +95 -0
- package/dist/delivery-DCOXhXEO.js +5 -0
- package/dist/delivery-VgFeuu2J.js +5 -0
- package/dist/destructive-gate-m-dWqUFg.js +101 -0
- package/dist/developer-keys-JaJK3T27.js +127 -0
- package/dist/developer-keys-kyqmtWK3.js +8 -0
- package/dist/doctor-3oi89QIc.js +175 -0
- package/dist/doctor-Cf1XSfp9.js +4 -0
- package/dist/engine-B4eMiTgl.js +7 -0
- package/dist/engine-B8M7dYul.js +7 -0
- package/dist/engine-BhT-1M9W.js +256 -0
- package/dist/engine-D49jnSd_.js +256 -0
- package/dist/env-resolve-DWOQ45jG.js +9 -0
- package/dist/env-resolve-szSWl0UF.js +94 -0
- package/dist/extraction-tools-D3qDFBJ1.js +91 -0
- package/dist/extraction-tools-DLr_AEwq.js +5 -0
- package/dist/form_data-B_hIUrxU.js +8657 -0
- package/dist/gmail-watch-setup-Czt8rXaX.js +40 -0
- package/dist/heartbeat-engine-CRqfPcFM.js +83 -0
- package/dist/hub-DTsqe5Bt.js +6 -0
- package/dist/hub-FrPTA33j.js +515 -0
- package/dist/hyperclawbot-D9KCtc4P.js +480 -0
- package/dist/hyperclawbot-DfMGowZC.js +480 -0
- package/dist/hyperclawbot-Dw27pJo4.js +480 -0
- package/dist/inference-CTWJeX9Q.js +922 -0
- package/dist/inference-ix607p7k.js +6 -0
- package/dist/knowledge-graph-DqA-Fztl.js +131 -0
- package/dist/loader-CISCqBto.js +400 -0
- package/dist/loader-CYMQ8VOS.js +4 -0
- package/dist/logger-8tEtAd3y.js +83 -0
- package/dist/manager-CPjeRe-6.js +4 -0
- package/dist/manager-Cwzj7w5R.js +105 -0
- package/dist/manager-DLmZI-9R.js +6 -0
- package/dist/manager-DSGhn5i3.js +117 -0
- package/dist/manager-DgyF52mg.js +218 -0
- package/dist/manager-Dm8nrMFx.js +40 -0
- package/dist/mcp-B_9Ber63.js +139 -0
- package/dist/mcp-loader-DSM5UiFG.js +94 -0
- package/dist/mcp-loader-j5ZLLw5O.js +94 -0
- package/dist/memory-BI1kPkAN.js +4 -0
- package/dist/memory-BVFGkxxK.js +270 -0
- package/dist/memory-auto-Bc7euou4.js +306 -0
- package/dist/memory-auto-DPfbkMVt.js +5 -0
- package/dist/memory-integration-DZExqWr4.js +91 -0
- package/dist/moltbook-B6ZeGN5_.js +81 -0
- package/dist/node-pwL6O_KX.js +222 -0
- package/dist/nodes-registry-CsPm_-CJ.js +52 -0
- package/dist/oauth-flow-CpWlgvNB.js +150 -0
- package/dist/oauth-provider-BZb6qOw5.js +110 -0
- package/dist/observability-B43YvNQV.js +89 -0
- package/dist/onboard-3q20ZyHj.js +9 -0
- package/dist/onboard-Bd_wsYdi.js +4086 -0
- package/dist/onboard-CAN7x3me.js +3026 -0
- package/dist/onboard-DnegOHMh.js +3026 -0
- package/dist/onboard-RYtDlYBw.js +9 -0
- package/dist/onboard-aTwlQs-4.js +9 -0
- package/dist/orchestrator-BSp2M5EU.js +189 -0
- package/dist/orchestrator-C7ko5tWa.js +6 -0
- package/dist/orchestrator-DfPkIx2Z.js +6 -0
- package/dist/orchestrator-NJQsmiBE.js +189 -0
- package/dist/pairing-DU0_J28n.js +87 -0
- package/dist/pairing-DWllbSbO.js +4 -0
- package/dist/pc-access-Ly-uA8mn.js +8 -0
- package/dist/pc-access-NxBvTrRj.js +819 -0
- package/dist/pending-approval-DIHvwwWS.js +22 -0
- package/dist/puppeteer-2o3QOwAy.js +2 -2
- package/dist/puppeteer-BYTMp3BI.js +2 -2
- package/dist/puppeteer-DQ45qwWk.js +2 -2
- package/dist/reminders-store-D79qdfN0.js +58 -0
- package/dist/renderer-pqlDRKbH.js +225 -0
- package/dist/rules-BooT_qFP.js +103 -0
- package/dist/run-main.js +366 -1109
- package/dist/runner-Bu--_RXw.js +810 -0
- package/dist/runner-D1rjuMTJ.js +810 -0
- package/dist/sdk/index.js +2 -2
- package/dist/sdk/index.mjs +2 -2
- package/dist/security-C-5URby1.js +73 -0
- package/dist/security-_xve79aq.js +4 -0
- package/dist/server-0kgyELx4.js +1047 -0
- package/dist/server-BIuTobTC.js +4 -0
- package/dist/server-BRlCEjyT.js +1047 -0
- package/dist/server-CCI1hv45.js +1047 -0
- package/dist/server-DU9POoWc.js +4 -0
- package/dist/server-RBqwE_GN.js +4 -0
- package/dist/session-store-CujxByI6.js +113 -0
- package/dist/session-store-qpJUg2M1.js +5 -0
- package/dist/sessions-tools-CB2qbwIk.js +5 -0
- package/dist/sessions-tools-DHMaTZIs.js +95 -0
- package/dist/skill-loader-BkceKkIg.js +7 -0
- package/dist/skill-loader-DhgIwK4J.js +159 -0
- package/dist/skill-runtime--LqxWrp5.js +102 -0
- package/dist/skill-runtime-C5l0Tgt-.js +5 -0
- package/dist/skill-runtime-DsXK_HYG.js +102 -0
- package/dist/skill-runtime-IVTiqrMR.js +5 -0
- package/dist/src-BEVLgaF1.js +63 -0
- package/dist/src-Bgu_OxTQ.js +458 -0
- package/dist/src-Bq-oKt7Z.js +458 -0
- package/dist/src-DWCUhnD4.js +20 -0
- package/dist/src-cfRTjFef.js +63 -0
- package/dist/sub-agent-tools-BD9DF8_g.js +39 -0
- package/dist/sub-agent-tools-V7b3T9_s.js +39 -0
- package/dist/tool-policy-DNvNRnve.js +189 -0
- package/dist/tts-elevenlabs-BUOGKL-k.js +61 -0
- package/dist/update-check-BD4qH7Am.js +81 -0
- package/dist/vision-DRq-f-Dj.js +121 -0
- package/dist/vision-tools-CFZEpQKm.js +5 -0
- package/dist/vision-tools-CQnBI9aa.js +51 -0
- package/dist/voice-transcription-CbQBToY0.js +138 -0
- package/dist/voice-transcription-CgWq54hn.js +138 -0
- package/dist/website-watch-tools-Bk_TnwuE.js +5 -0
- package/dist/website-watch-tools-DraMPxdl.js +139 -0
- package/package.json +1 -1
package/dist/run-main.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
require('./env-resolve-
|
|
6
|
-
const require_onboard = require('./onboard-
|
|
7
|
-
require('./server-
|
|
2
|
+
require('./paths-AIyBxIzm.js');
|
|
3
|
+
require('./paths-DPovhojT.js');
|
|
4
|
+
require('./env-resolve-szSWl0UF.js');
|
|
5
|
+
const require_onboard = require('./onboard-Bd_wsYdi.js');
|
|
6
|
+
require('./server-BRlCEjyT.js');
|
|
8
7
|
require('./theme-LUTKWUWd.js');
|
|
9
|
-
const
|
|
10
|
-
const require_manager
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
8
|
+
const require_hub = require('./hub-FrPTA33j.js');
|
|
9
|
+
const require_manager = require('./manager-Dm8nrMFx.js');
|
|
10
|
+
const require_manager$1 = require('./manager-Cwzj7w5R.js');
|
|
11
|
+
const require_memory = require('./memory-BVFGkxxK.js');
|
|
12
|
+
const require_loader = require('./loader-CISCqBto.js');
|
|
13
|
+
const require_agents_routing = require('./agents-routing-683Q2JGp.js');
|
|
14
|
+
const require_pairing = require('./pairing-DU0_J28n.js');
|
|
15
|
+
const require_doctor = require('./doctor-3oi89QIc.js');
|
|
16
|
+
const require_security = require('./security-C-5URby1.js');
|
|
17
|
+
const require_developer_keys = require('./developer-keys-JaJK3T27.js');
|
|
16
18
|
const commander = require_chunk.__toESM(require("commander"));
|
|
17
19
|
const chalk = require_chunk.__toESM(require("chalk"));
|
|
18
20
|
const inquirer = require_chunk.__toESM(require("inquirer"));
|
|
@@ -22,505 +24,9 @@ const path = require_chunk.__toESM(require("path"));
|
|
|
22
24
|
const os = require_chunk.__toESM(require("os"));
|
|
23
25
|
const child_process = require_chunk.__toESM(require("child_process"));
|
|
24
26
|
const util = require_chunk.__toESM(require("util"));
|
|
25
|
-
const http = require_chunk.__toESM(require("http"));
|
|
26
|
-
const https = require_chunk.__toESM(require("https"));
|
|
27
|
-
const readline = require_chunk.__toESM(require("readline"));
|
|
28
|
-
const tar = require_chunk.__toESM(require("tar"));
|
|
29
27
|
const fs = require_chunk.__toESM(require("fs"));
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
//#region src/skills/clawhub.ts
|
|
33
|
-
require_paths$1.init_paths();
|
|
34
|
-
const CLAWHUB_API = process.env.CLAWHUB_API_URL || "https://clawhub.com";
|
|
35
|
-
const WORKSPACE_SKILLS$1 = path.default.join(require_paths.getHyperClawDir(), "workspace", "skills");
|
|
36
|
-
async function searchSkills(query, category) {
|
|
37
|
-
const q = new URLSearchParams({ q: query });
|
|
38
|
-
if (category) q.set("category", category);
|
|
39
|
-
const url = `${CLAWHUB_API}/api/skills/search?${q}`;
|
|
40
|
-
try {
|
|
41
|
-
const body = await fetchJson(url);
|
|
42
|
-
return Array.isArray(body.skills) ? body.skills : Array.isArray(body) ? body : [];
|
|
43
|
-
} catch (e) {
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
async function installSkill(skillId, version) {
|
|
48
|
-
const ver = version ? `@${version}` : "";
|
|
49
|
-
const url = `${CLAWHUB_API}/api/skills/${encodeURIComponent(skillId)}/download${ver}`;
|
|
50
|
-
try {
|
|
51
|
-
const body = await fetchJson(url);
|
|
52
|
-
const tarballUrl = body.url || body.tarball;
|
|
53
|
-
if (!tarballUrl) throw new Error("No download URL in registry response");
|
|
54
|
-
await fs_extra.default.ensureDir(WORKSPACE_SKILLS$1);
|
|
55
|
-
const destDir = path.default.join(WORKSPACE_SKILLS$1, skillId);
|
|
56
|
-
await fs_extra.default.ensureDir(destDir);
|
|
57
|
-
if (body.content || body.skillMarkdown) {
|
|
58
|
-
const content = body.content || body.skillMarkdown;
|
|
59
|
-
await fs_extra.default.writeFile(path.default.join(destDir, "SKILL.md"), content, "utf8");
|
|
60
|
-
return destDir;
|
|
61
|
-
}
|
|
62
|
-
const tarballBuffer = await fetchBuffer(tarballUrl);
|
|
63
|
-
const extractDir = path.default.join(path.default.dirname(destDir), `.skill-extract-${skillId}-${Date.now()}`);
|
|
64
|
-
await fs_extra.default.ensureDir(extractDir);
|
|
65
|
-
try {
|
|
66
|
-
const tarPath = path.default.join(extractDir, "skill.tar.gz");
|
|
67
|
-
await fs_extra.default.writeFile(tarPath, tarballBuffer);
|
|
68
|
-
await tar.default.x({
|
|
69
|
-
file: tarPath,
|
|
70
|
-
cwd: extractDir
|
|
71
|
-
});
|
|
72
|
-
await fs_extra.default.remove(tarPath);
|
|
73
|
-
const entries = await fs_extra.default.readdir(extractDir);
|
|
74
|
-
let skillDir = extractDir;
|
|
75
|
-
const topSkill = path.default.join(extractDir, "SKILL.md");
|
|
76
|
-
if (!await fs_extra.default.pathExists(topSkill)) {
|
|
77
|
-
const sub = entries.find((e) => e !== "package.json" && !e.startsWith("."));
|
|
78
|
-
if (sub) {
|
|
79
|
-
const subPath = path.default.join(extractDir, sub);
|
|
80
|
-
if ((await fs_extra.default.stat(subPath)).isDirectory() && await fs_extra.default.pathExists(path.default.join(subPath, "SKILL.md"))) skillDir = subPath;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
await fs_extra.default.copy(skillDir, destDir, { filter: (src) => !src.includes("node_modules") });
|
|
84
|
-
if (!await fs_extra.default.pathExists(path.default.join(destDir, "SKILL.md"))) throw new Error("Tarball did not contain SKILL.md");
|
|
85
|
-
return destDir;
|
|
86
|
-
} finally {
|
|
87
|
-
await fs_extra.default.remove(extractDir).catch(() => {});
|
|
88
|
-
}
|
|
89
|
-
} catch (e) {
|
|
90
|
-
if (e.message?.includes("ENOTFOUND") || e.code === "ENOTFOUND") throw new Error(`ClawHub registry unavailable. Install manually: mkdir -p ~/.hyperclaw/workspace/skills/${skillId} && add SKILL.md`);
|
|
91
|
-
throw e;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
async function listInstalledFromClawHub() {
|
|
95
|
-
if (!await fs_extra.default.pathExists(WORKSPACE_SKILLS$1)) return [];
|
|
96
|
-
const dirs = await fs_extra.default.readdir(WORKSPACE_SKILLS$1);
|
|
97
|
-
const out = [];
|
|
98
|
-
for (const id of dirs) {
|
|
99
|
-
const p = path.default.join(WORKSPACE_SKILLS$1, id, "SKILL.md");
|
|
100
|
-
if (await fs_extra.default.pathExists(p)) out.push(id);
|
|
101
|
-
}
|
|
102
|
-
return out;
|
|
103
|
-
}
|
|
104
|
-
function fetchBuffer(url) {
|
|
105
|
-
return new Promise((resolve, reject) => {
|
|
106
|
-
const parsed = new URL(url);
|
|
107
|
-
const mod = parsed.protocol === "https:" ? https.default : http.default;
|
|
108
|
-
const req = mod.request({
|
|
109
|
-
hostname: parsed.hostname,
|
|
110
|
-
port: parsed.port || (parsed.protocol === "https:" ? 443 : 80),
|
|
111
|
-
path: parsed.pathname + parsed.search,
|
|
112
|
-
method: "GET",
|
|
113
|
-
headers: { "User-Agent": "HyperClaw/4.0.0" }
|
|
114
|
-
}, (res) => {
|
|
115
|
-
const chunks = [];
|
|
116
|
-
res.on("data", (c) => chunks.push(c));
|
|
117
|
-
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
118
|
-
});
|
|
119
|
-
req.on("error", reject);
|
|
120
|
-
req.setTimeout(3e4, () => {
|
|
121
|
-
req.destroy();
|
|
122
|
-
reject(new Error("Tarball download timeout"));
|
|
123
|
-
});
|
|
124
|
-
req.end();
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
function fetchJson(url) {
|
|
128
|
-
return new Promise((resolve, reject) => {
|
|
129
|
-
const parsed = new URL(url);
|
|
130
|
-
const req = https.default.request({
|
|
131
|
-
hostname: parsed.hostname,
|
|
132
|
-
port: 443,
|
|
133
|
-
path: parsed.pathname + parsed.search,
|
|
134
|
-
method: "GET",
|
|
135
|
-
headers: { "User-Agent": "HyperClaw/4.0.0" }
|
|
136
|
-
}, (res) => {
|
|
137
|
-
let data = "";
|
|
138
|
-
res.on("data", (c) => data += c);
|
|
139
|
-
res.on("end", () => {
|
|
140
|
-
try {
|
|
141
|
-
resolve(JSON.parse(data));
|
|
142
|
-
} catch {
|
|
143
|
-
reject(new Error("Invalid JSON from registry"));
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
req.on("error", reject);
|
|
148
|
-
req.setTimeout(15e3, () => {
|
|
149
|
-
req.destroy();
|
|
150
|
-
reject(new Error("Timeout"));
|
|
151
|
-
});
|
|
152
|
-
req.end();
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
//#endregion
|
|
157
|
-
//#region src/plugins/hub.ts
|
|
158
|
-
require_paths$1.init_paths();
|
|
159
|
-
const SKILL_REGISTRY = [
|
|
160
|
-
{
|
|
161
|
-
id: "web-search",
|
|
162
|
-
name: "Web Search (Tavily)",
|
|
163
|
-
version: "2.1.0",
|
|
164
|
-
description: "Real-time web search via Tavily API. Powers research and news queries.",
|
|
165
|
-
author: "hyperclaw-team",
|
|
166
|
-
category: "utility",
|
|
167
|
-
downloads: 48200,
|
|
168
|
-
rating: 4.8,
|
|
169
|
-
risk: "clean",
|
|
170
|
-
requiresKeys: ["TAVILY_API_KEY"],
|
|
171
|
-
tags: [
|
|
172
|
-
"search",
|
|
173
|
-
"internet",
|
|
174
|
-
"tavily"
|
|
175
|
-
]
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
id: "calendar",
|
|
179
|
-
name: "Google Calendar",
|
|
180
|
-
version: "1.4.0",
|
|
181
|
-
description: "Read and create Google Calendar events via OAuth.",
|
|
182
|
-
author: "hyperclaw-team",
|
|
183
|
-
category: "productivity",
|
|
184
|
-
downloads: 32100,
|
|
185
|
-
rating: 4.6,
|
|
186
|
-
risk: "clean",
|
|
187
|
-
requiresKeys: ["GOOGLE_CALENDAR_CREDS"],
|
|
188
|
-
tags: [
|
|
189
|
-
"calendar",
|
|
190
|
-
"schedule",
|
|
191
|
-
"google"
|
|
192
|
-
],
|
|
193
|
-
npmPackage: "googleapis"
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
id: "github",
|
|
197
|
-
name: "GitHub Integration",
|
|
198
|
-
version: "1.2.0",
|
|
199
|
-
description: "Create issues, PRs, read repos. Requires GitHub PAT.",
|
|
200
|
-
author: "hyperclaw-team",
|
|
201
|
-
category: "integration",
|
|
202
|
-
downloads: 27800,
|
|
203
|
-
rating: 4.7,
|
|
204
|
-
risk: "clean",
|
|
205
|
-
requiresKeys: ["GITHUB_TOKEN"],
|
|
206
|
-
tags: [
|
|
207
|
-
"github",
|
|
208
|
-
"git",
|
|
209
|
-
"code"
|
|
210
|
-
],
|
|
211
|
-
npmPackage: "@octokit/rest"
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
id: "home-assistant",
|
|
215
|
-
name: "Home Assistant",
|
|
216
|
-
version: "1.5.0",
|
|
217
|
-
description: "Control smart home devices via Home Assistant REST API.",
|
|
218
|
-
author: "hyperclaw-team",
|
|
219
|
-
category: "automation",
|
|
220
|
-
downloads: 19400,
|
|
221
|
-
rating: 4.5,
|
|
222
|
-
risk: "clean",
|
|
223
|
-
requiresKeys: ["HA_URL", "HA_TOKEN"],
|
|
224
|
-
tags: [
|
|
225
|
-
"smart-home",
|
|
226
|
-
"iot",
|
|
227
|
-
"automation"
|
|
228
|
-
]
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
id: "code-executor",
|
|
232
|
-
name: "Code Executor (Sandbox)",
|
|
233
|
-
version: "3.0.1",
|
|
234
|
-
description: "Execute Python/JS/Bash code in a sandboxed Docker container.",
|
|
235
|
-
author: "hyperclaw-team",
|
|
236
|
-
category: "utility",
|
|
237
|
-
downloads: 41e3,
|
|
238
|
-
rating: 4.9,
|
|
239
|
-
risk: "clean",
|
|
240
|
-
tags: [
|
|
241
|
-
"code",
|
|
242
|
-
"sandbox",
|
|
243
|
-
"python",
|
|
244
|
-
"bash"
|
|
245
|
-
],
|
|
246
|
-
npmPackage: "dockerode"
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
id: "translator",
|
|
250
|
-
name: "Real-time Translator",
|
|
251
|
-
version: "2.0.0",
|
|
252
|
-
description: "DeepL + Google Translate integration for 90+ languages.",
|
|
253
|
-
author: "hyperclaw-team",
|
|
254
|
-
category: "utility",
|
|
255
|
-
downloads: 38500,
|
|
256
|
-
rating: 4.7,
|
|
257
|
-
risk: "clean",
|
|
258
|
-
requiresKeys: ["DEEPL_API_KEY"],
|
|
259
|
-
tags: [
|
|
260
|
-
"translate",
|
|
261
|
-
"language",
|
|
262
|
-
"deepl"
|
|
263
|
-
],
|
|
264
|
-
installed: true
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
id: "reminders",
|
|
268
|
-
name: "Smart Reminders",
|
|
269
|
-
version: "2.1.0",
|
|
270
|
-
description: "Natural language reminders with cron scheduling.",
|
|
271
|
-
author: "hyperclaw-team",
|
|
272
|
-
category: "productivity",
|
|
273
|
-
downloads: 29e3,
|
|
274
|
-
rating: 4.6,
|
|
275
|
-
risk: "clean",
|
|
276
|
-
tags: [
|
|
277
|
-
"reminders",
|
|
278
|
-
"cron",
|
|
279
|
-
"schedule"
|
|
280
|
-
],
|
|
281
|
-
installed: true
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
id: "weather",
|
|
285
|
-
name: "Weather Forecast",
|
|
286
|
-
version: "1.3.0",
|
|
287
|
-
description: "OpenWeatherMap integration. Current + 7-day forecast.",
|
|
288
|
-
author: "hyperclaw-team",
|
|
289
|
-
category: "utility",
|
|
290
|
-
downloads: 22100,
|
|
291
|
-
rating: 4.4,
|
|
292
|
-
risk: "clean",
|
|
293
|
-
requiresKeys: ["OPENWEATHER_API_KEY"],
|
|
294
|
-
tags: ["weather", "forecast"]
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
id: "stealth-browser",
|
|
298
|
-
name: "Stealth Browser",
|
|
299
|
-
version: "1.0.3",
|
|
300
|
-
description: "Headless browser with fingerprint evasion. Can bypass bot detection.",
|
|
301
|
-
author: "unknown-dev",
|
|
302
|
-
category: "utility",
|
|
303
|
-
downloads: 3200,
|
|
304
|
-
rating: 3.1,
|
|
305
|
-
risk: "suspicious",
|
|
306
|
-
riskReason: "Fingerprint evasion may violate ToS on some sites. VirusTotal: 2/72 engines flagged.",
|
|
307
|
-
tags: [
|
|
308
|
-
"browser",
|
|
309
|
-
"puppeteer",
|
|
310
|
-
"stealth"
|
|
311
|
-
],
|
|
312
|
-
npmPackage: "puppeteer-extra-plugin-stealth"
|
|
313
|
-
},
|
|
314
|
-
{
|
|
315
|
-
id: "db-reader",
|
|
316
|
-
name: "Database Reader",
|
|
317
|
-
version: "1.1.0",
|
|
318
|
-
description: "Read from PostgreSQL/MySQL/SQLite databases.",
|
|
319
|
-
author: "hyperclaw-team",
|
|
320
|
-
category: "integration",
|
|
321
|
-
downloads: 15600,
|
|
322
|
-
rating: 4.5,
|
|
323
|
-
risk: "clean",
|
|
324
|
-
requiresKeys: ["DATABASE_URL"],
|
|
325
|
-
tags: [
|
|
326
|
-
"database",
|
|
327
|
-
"sql",
|
|
328
|
-
"postgres"
|
|
329
|
-
],
|
|
330
|
-
npmPackage: "pg"
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
id: "keylogger-util",
|
|
334
|
-
name: "Input Monitor Pro",
|
|
335
|
-
version: "0.9.1",
|
|
336
|
-
description: "Monitors keyboard events for automation triggers.",
|
|
337
|
-
author: "shadowy-scripts",
|
|
338
|
-
category: "automation",
|
|
339
|
-
downloads: 890,
|
|
340
|
-
rating: 1.8,
|
|
341
|
-
risk: "dangerous",
|
|
342
|
-
riskReason: "Detected keylogging behavior. VirusTotal: 31/72 engines flagged as malware.",
|
|
343
|
-
tags: ["keyboard", "monitor"]
|
|
344
|
-
}
|
|
345
|
-
];
|
|
346
|
-
const WORKSPACE_SKILLS = () => path.default.join(require_paths.getHyperClawDir(), "workspace", "skills");
|
|
347
|
-
var SkillHub = class {
|
|
348
|
-
installed = /* @__PURE__ */ new Set();
|
|
349
|
-
/** Sync installed set from workspace disk (persisted installs). */
|
|
350
|
-
async refreshInstalledFromDisk() {
|
|
351
|
-
const ids = await listInstalledFromClawHub();
|
|
352
|
-
this.installed = new Set(ids);
|
|
353
|
-
}
|
|
354
|
-
/** Persist bundled skill to workspace so it survives restarts and is loaded by skill-loader. */
|
|
355
|
-
async persistBundledSkill(skill) {
|
|
356
|
-
const destDir = path.default.join(WORKSPACE_SKILLS(), skill.id);
|
|
357
|
-
await fs_extra.default.ensureDir(destDir);
|
|
358
|
-
const skillPath = path.default.join(destDir, "SKILL.md");
|
|
359
|
-
const repoSkillPath = path.default.join(process.cwd(), "skills", skill.id, "SKILL.md");
|
|
360
|
-
const altRepoPath = path.default.join(__dirname, "..", "..", "skills", skill.id, "SKILL.md");
|
|
361
|
-
if (await fs_extra.default.pathExists(repoSkillPath)) await fs_extra.default.copy(repoSkillPath, skillPath);
|
|
362
|
-
else if (await fs_extra.default.pathExists(altRepoPath)) await fs_extra.default.copy(altRepoPath, skillPath);
|
|
363
|
-
else {
|
|
364
|
-
const content = `# ${skill.name}\n\n${skill.description}\n\n## Usage\n\nWhen the user needs ${skill.description.toLowerCase()}, use this skill.${skill.requiresKeys?.length ? `\n\nRequires: ${skill.requiresKeys.join(", ")}` : ""}\n`;
|
|
365
|
-
await fs_extra.default.writeFile(skillPath, content, "utf8");
|
|
366
|
-
}
|
|
367
|
-
this.installed.add(skill.id);
|
|
368
|
-
}
|
|
369
|
-
async showHub(hideSuspicious = false) {
|
|
370
|
-
await this.refreshInstalledFromDisk();
|
|
371
|
-
console.log(chalk.default.bold.cyan("\n╔═══════════════════════════════════════════╗"));
|
|
372
|
-
console.log(chalk.default.bold.cyan("║ 🧩 HYPERCLAW SKILL HUB ║"));
|
|
373
|
-
console.log(chalk.default.bold.cyan("╚═══════════════════════════════════════════╝\n"));
|
|
374
|
-
const skills = hideSuspicious ? SKILL_REGISTRY.filter((s) => s.risk === "clean") : SKILL_REGISTRY;
|
|
375
|
-
for (const skill of skills) this.printSkillCard(skill);
|
|
376
|
-
}
|
|
377
|
-
printSkillCard(skill) {
|
|
378
|
-
const riskBadge = {
|
|
379
|
-
"clean": chalk.default.green("✔ CLEAN"),
|
|
380
|
-
"suspicious": chalk.default.yellow("⚠ SUSPICIOUS"),
|
|
381
|
-
"dangerous": chalk.default.red("✖ DANGEROUS")
|
|
382
|
-
}[skill.risk];
|
|
383
|
-
const instBadge = this.installed.has(skill.id) ? chalk.default.green("[installed]") : chalk.default.gray("[available]");
|
|
384
|
-
const stars = "★".repeat(Math.round(skill.rating)) + "☆".repeat(5 - Math.round(skill.rating));
|
|
385
|
-
console.log(` ${chalk.default.bold(skill.name)} ${chalk.default.gray(`v${skill.version}`)} ${instBadge}`);
|
|
386
|
-
console.log(` ${chalk.default.gray(skill.description)}`);
|
|
387
|
-
console.log(` ${riskBadge} ${chalk.default.yellow(stars)} ${chalk.default.gray(`${(skill.downloads / 1e3).toFixed(1)}k downloads`)}`);
|
|
388
|
-
if (skill.riskReason) console.log(` ${chalk.default.yellow("⚠")} ${chalk.default.yellow(skill.riskReason)}`);
|
|
389
|
-
if (skill.requiresKeys?.length) console.log(` 🔑 Requires: ${chalk.default.cyan(skill.requiresKeys.join(", "))}`);
|
|
390
|
-
console.log();
|
|
391
|
-
}
|
|
392
|
-
async install(skillId, force = false) {
|
|
393
|
-
const skill = SKILL_REGISTRY.find((s) => s.id === skillId);
|
|
394
|
-
if (!skill) {
|
|
395
|
-
console.log(chalk.default.red(`❌ Skill not found: ${skillId}`));
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
if (skill.risk === "dangerous" && !force) {
|
|
399
|
-
console.log(chalk.default.red(`\n🚨 DANGEROUS SKILL BLOCKED: ${skill.name}`));
|
|
400
|
-
console.log(chalk.default.red(` ${skill.riskReason}`));
|
|
401
|
-
console.log(chalk.default.gray(" Use --force to override (NOT RECOMMENDED)\n"));
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
if (skill.risk === "suspicious" && !force) {
|
|
405
|
-
console.log(chalk.default.yellow(`\n⚠️ SUSPICIOUS SKILL: ${skill.name}`));
|
|
406
|
-
console.log(chalk.default.yellow(` ${skill.riskReason}`));
|
|
407
|
-
console.log(chalk.default.gray(" Use --force to install anyway\n"));
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
const spinner = (0, ora.default)(`Installing ${skill.name}...`).start();
|
|
411
|
-
if (skill.npmPackage) {
|
|
412
|
-
spinner.text = `Installing npm package: ${skill.npmPackage}`;
|
|
413
|
-
await new Promise((r) => setTimeout(r, 800));
|
|
414
|
-
}
|
|
415
|
-
await this.persistBundledSkill(skill);
|
|
416
|
-
spinner.succeed(`${skill.name} installed ✓`);
|
|
417
|
-
if (skill.requiresKeys?.length) {
|
|
418
|
-
console.log(chalk.default.yellow(`\n📋 Required API keys to activate:`));
|
|
419
|
-
skill.requiresKeys.forEach((k) => {
|
|
420
|
-
console.log(chalk.default.cyan(` hyperclaw config set-key ${k}`));
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
console.log();
|
|
424
|
-
}
|
|
425
|
-
async scan(skillId) {
|
|
426
|
-
const skill = SKILL_REGISTRY.find((s) => s.id === skillId);
|
|
427
|
-
if (!skill) return;
|
|
428
|
-
const spinner = (0, ora.default)(`Scanning ${skill.name}...`).start();
|
|
429
|
-
const stages = [
|
|
430
|
-
"Checking manifest...",
|
|
431
|
-
"Scanning for malicious patterns...",
|
|
432
|
-
"Checking VirusTotal...",
|
|
433
|
-
"Verifying author..."
|
|
434
|
-
];
|
|
435
|
-
for (const stage of stages) {
|
|
436
|
-
spinner.text = stage;
|
|
437
|
-
await new Promise((r) => setTimeout(r, 600));
|
|
438
|
-
}
|
|
439
|
-
const result = {
|
|
440
|
-
"clean": chalk.default.green("✅ All green — safe to install"),
|
|
441
|
-
"suspicious": chalk.default.yellow("⚠️ Suspicious patterns detected — proceed with caution"),
|
|
442
|
-
"dangerous": chalk.default.red("🚨 Malicious patterns detected — do NOT install")
|
|
443
|
-
}[skill.risk];
|
|
444
|
-
spinner.stop();
|
|
445
|
-
console.log(`\n🔬 Scan results for ${chalk.default.bold(skill.name)}:`);
|
|
446
|
-
console.log(` ${result}`);
|
|
447
|
-
if (skill.riskReason) console.log(chalk.default.gray(` Detail: ${skill.riskReason}`));
|
|
448
|
-
console.log();
|
|
449
|
-
}
|
|
450
|
-
async checkEligibility() {
|
|
451
|
-
const spinner = (0, ora.default)("Checking system eligibility...").start();
|
|
452
|
-
await new Promise((r) => setTimeout(r, 1e3));
|
|
453
|
-
spinner.succeed("Eligibility check complete");
|
|
454
|
-
console.log(chalk.default.green("\n✅ All installed skills are eligible on this system\n"));
|
|
455
|
-
}
|
|
456
|
-
async getInstalled() {
|
|
457
|
-
await this.refreshInstalledFromDisk();
|
|
458
|
-
const ids = this.installed;
|
|
459
|
-
const fromRegistry = SKILL_REGISTRY.filter((s) => ids.has(s.id));
|
|
460
|
-
const fromWorkspace = (await listInstalledFromClawHub()).filter((id) => !SKILL_REGISTRY.some((s) => s.id === id));
|
|
461
|
-
return [...fromRegistry, ...fromWorkspace.map((id) => ({
|
|
462
|
-
id,
|
|
463
|
-
name: id,
|
|
464
|
-
version: "0",
|
|
465
|
-
description: "",
|
|
466
|
-
author: "",
|
|
467
|
-
category: "utility",
|
|
468
|
-
downloads: 0,
|
|
469
|
-
rating: 0,
|
|
470
|
-
risk: "clean",
|
|
471
|
-
tags: []
|
|
472
|
-
}))];
|
|
473
|
-
}
|
|
474
|
-
/** ClawHub integration: search remote registry, fallback to bundled when remote unavailable */
|
|
475
|
-
async searchClawHub(query, category) {
|
|
476
|
-
let remote = await searchSkills(query, category);
|
|
477
|
-
if (remote.length === 0) {
|
|
478
|
-
const q = (query || "").toLowerCase();
|
|
479
|
-
const filtered = SKILL_REGISTRY.filter((s) => !q || s.id.includes(q) || s.name.toLowerCase().includes(q) || s.tags.some((t) => t.includes(q))).filter((s) => !category || s.category === category);
|
|
480
|
-
remote = filtered.map((s) => ({
|
|
481
|
-
id: s.id,
|
|
482
|
-
name: s.name,
|
|
483
|
-
author: s.author,
|
|
484
|
-
description: s.description,
|
|
485
|
-
rating: s.rating,
|
|
486
|
-
downloads: s.downloads,
|
|
487
|
-
version: s.version,
|
|
488
|
-
categories: [s.category]
|
|
489
|
-
}));
|
|
490
|
-
}
|
|
491
|
-
return remote;
|
|
492
|
-
}
|
|
493
|
-
/** ClawHub integration: install from remote registry */
|
|
494
|
-
async installFromClawHub(skillId, version) {
|
|
495
|
-
return installSkill(skillId, version);
|
|
496
|
-
}
|
|
497
|
-
/** ClawHub marketplace UX: unified browse (bundled + remote) */
|
|
498
|
-
async showMarketplace(opts) {
|
|
499
|
-
await this.refreshInstalledFromDisk();
|
|
500
|
-
const installedClawHub = await listInstalledFromClawHub();
|
|
501
|
-
const bundled = (opts?.hideSuspicious ? SKILL_REGISTRY.filter((s) => s.risk === "clean") : SKILL_REGISTRY).filter((s) => !opts?.category || s.category === opts.category);
|
|
502
|
-
console.log(chalk.default.bold.cyan("\n╔══════════════════════════════════════════════════════════╗"));
|
|
503
|
-
console.log(chalk.default.bold.cyan("║ 🧩 CLAWHUB MARKETPLACE ║"));
|
|
504
|
-
console.log(chalk.default.bold.cyan("╚══════════════════════════════════════════════════════════╝\n"));
|
|
505
|
-
if (installedClawHub.length > 0) {
|
|
506
|
-
console.log(chalk.default.bold.green(" Installed (ClawHub):"));
|
|
507
|
-
installedClawHub.forEach((id) => console.log(chalk.default.gray(` • ${id}`)));
|
|
508
|
-
console.log();
|
|
509
|
-
}
|
|
510
|
-
console.log(chalk.default.bold(" Bundled skills:"));
|
|
511
|
-
for (const skill of bundled) {
|
|
512
|
-
const inst = this.installed.has(skill.id) || installedClawHub.includes(skill.id);
|
|
513
|
-
const badge = inst ? chalk.default.green("✓ installed") : chalk.default.cyan("hyperclaw skill install " + skill.id);
|
|
514
|
-
const risk = skill.risk === "clean" ? "" : chalk.default.yellow(` [${skill.risk}]`);
|
|
515
|
-
console.log(` ${chalk.default.bold(skill.name)} ${chalk.default.gray(`v${skill.version}`)} ${badge}${risk}`);
|
|
516
|
-
console.log(chalk.default.gray(` ${skill.description}`));
|
|
517
|
-
}
|
|
518
|
-
console.log(chalk.default.gray("\n Search remote: hyperclaw skill search <query>"));
|
|
519
|
-
console.log(chalk.default.gray(" Install: hyperclaw skill install <id>\n"));
|
|
520
|
-
}
|
|
521
|
-
};
|
|
28
|
+
const readline = require_chunk.__toESM(require("readline"));
|
|
522
29
|
|
|
523
|
-
//#endregion
|
|
524
30
|
//#region src/cli/dashboard.ts
|
|
525
31
|
var Dashboard = class {
|
|
526
32
|
async launch(live) {
|
|
@@ -534,7 +40,7 @@ var Dashboard = class {
|
|
|
534
40
|
async drawDashboard() {
|
|
535
41
|
const cfg = await new require_onboard.ConfigStore().load();
|
|
536
42
|
const gm = new require_onboard.GatewayManager();
|
|
537
|
-
const hub = new SkillHub();
|
|
43
|
+
const hub = new require_hub.SkillHub();
|
|
538
44
|
const installed = await hub.getInstalled();
|
|
539
45
|
const port = cfg?.gateway?.port || 1515;
|
|
540
46
|
const agent = cfg?.identity?.agentName || "Hyper";
|
|
@@ -553,7 +59,7 @@ var Dashboard = class {
|
|
|
553
59
|
return c(`║ `) + content + " ".repeat(pad) + c(`║`);
|
|
554
60
|
};
|
|
555
61
|
console.log(c(`╔${line}╗`));
|
|
556
|
-
console.log(c(`║`) + chalk.default.bold.hex("#06b6d4")(`${"🦅 HYPERCLAW v4.0.
|
|
62
|
+
console.log(c(`║`) + chalk.default.bold.hex("#06b6d4")(`${"🦅 HYPERCLAW v4.0.2 — GATEWAY DASHBOARD".padStart(45).padEnd(w)}`) + c(`║`));
|
|
557
63
|
console.log(c(`╠${line}╣`));
|
|
558
64
|
console.log(row(`${statusDot} Gateway ${statusText} ${chalk.default.gray("│")} ws://localhost:${port} ${chalk.default.gray("│")} Agent: ${c(agent)}`));
|
|
559
65
|
console.log(row(`${c("◆")} Model ${chalk.default.gray(model.slice(0, 30))} ${chalk.default.gray("│")} User: ${c(user)}`));
|
|
@@ -634,7 +140,7 @@ async function recordAudio(outFile, seconds) {
|
|
|
634
140
|
async function transcribeWhisper(filePath, lang) {
|
|
635
141
|
const apiKey = process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY;
|
|
636
142
|
if (!apiKey) throw new Error("No OPENAI_API_KEY set");
|
|
637
|
-
const FormData = (await Promise.resolve().then(() => require_chunk.__toDynamicImportESM()(require("./form_data-
|
|
143
|
+
const FormData = (await Promise.resolve().then(() => require_chunk.__toDynamicImportESM()(require("./form_data-B_hIUrxU.js"))).catch(() => null))?.default;
|
|
638
144
|
if (!FormData) throw new Error("form-data not installed");
|
|
639
145
|
const form = new FormData();
|
|
640
146
|
form.append("file", fs.createReadStream(filePath), {
|
|
@@ -700,8 +206,8 @@ var VoiceEngine = class {
|
|
|
700
206
|
console.log(chalk.default.gray(` Gateway: ${GATEWAY_URL}`));
|
|
701
207
|
console.log(chalk.default.gray(` Status: ${chalk.default.green("Ready")}`));
|
|
702
208
|
if (this.lang === "el") {
|
|
703
|
-
console.log(chalk.default.cyan("\n🇬🇷
|
|
704
|
-
console.log(chalk.default.gray(`
|
|
209
|
+
console.log(chalk.default.cyan("\n🇬🇷 Greek language support enabled!"));
|
|
210
|
+
console.log(chalk.default.gray(` Say "${this.wakeWord}" to wake up the assistant.`));
|
|
705
211
|
}
|
|
706
212
|
console.log();
|
|
707
213
|
if (hasRec && hasApiKey) {
|
|
@@ -778,283 +284,6 @@ var VoiceEngine = class {
|
|
|
778
284
|
}
|
|
779
285
|
};
|
|
780
286
|
|
|
781
|
-
//#endregion
|
|
782
|
-
//#region src/routing/agents-routing.ts
|
|
783
|
-
var AgentRouter = class {
|
|
784
|
-
stateFile;
|
|
785
|
-
agents = [];
|
|
786
|
-
constructor() {
|
|
787
|
-
this.stateFile = path.default.join(os.default.homedir(), ".hyperclaw", "agents.json");
|
|
788
|
-
this.load();
|
|
789
|
-
}
|
|
790
|
-
load() {
|
|
791
|
-
try {
|
|
792
|
-
this.agents = fs_extra.default.readJsonSync(this.stateFile);
|
|
793
|
-
} catch {
|
|
794
|
-
this.agents = [{
|
|
795
|
-
workspace: path.default.join(os.default.homedir(), ".hyperclaw", "workspace"),
|
|
796
|
-
name: "default",
|
|
797
|
-
model: void 0,
|
|
798
|
-
bindings: []
|
|
799
|
-
}];
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
save() {
|
|
803
|
-
fs_extra.default.ensureDirSync(path.default.dirname(this.stateFile));
|
|
804
|
-
fs_extra.default.writeJsonSync(this.stateFile, this.agents, { spaces: 2 });
|
|
805
|
-
}
|
|
806
|
-
listBindings() {
|
|
807
|
-
console.log(chalk.default.bold.cyan("\n 🦅 AGENT BINDINGS\n"));
|
|
808
|
-
if (this.agents.length === 0) {
|
|
809
|
-
console.log(chalk.default.gray(" No agents configured."));
|
|
810
|
-
return;
|
|
811
|
-
}
|
|
812
|
-
for (const agent of this.agents) {
|
|
813
|
-
console.log(` ${chalk.default.bold(agent.name)} ${chalk.default.gray(agent.workspace)}`);
|
|
814
|
-
if (agent.bindings.length === 0) console.log(` ${chalk.default.gray("No channel bindings — receives from all channels")}`);
|
|
815
|
-
else for (const b of agent.bindings) {
|
|
816
|
-
const acct = b.accountId ? chalk.default.gray(`@${b.accountId}`) : chalk.default.gray("(all accounts)");
|
|
817
|
-
const role = b.role === "primary" ? chalk.default.green("[primary]") : chalk.default.gray("[secondary]");
|
|
818
|
-
console.log(` ${chalk.default.cyan(b.channelId)} ${acct} ${role}`);
|
|
819
|
-
}
|
|
820
|
-
console.log();
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
async bind() {
|
|
824
|
-
console.log(chalk.default.cyan("\n Bind a channel to an agent workspace\n"));
|
|
825
|
-
const { channel, workspace, role } = await inquirer.default.prompt([
|
|
826
|
-
{
|
|
827
|
-
type: "input",
|
|
828
|
-
name: "channel",
|
|
829
|
-
message: "Channel ID (e.g. telegram, discord, slack):",
|
|
830
|
-
validate: (v) => v.trim().length > 0 || "Required"
|
|
831
|
-
},
|
|
832
|
-
{
|
|
833
|
-
type: "input",
|
|
834
|
-
name: "workspace",
|
|
835
|
-
message: "Agent workspace (directory or name):",
|
|
836
|
-
default: "default"
|
|
837
|
-
},
|
|
838
|
-
{
|
|
839
|
-
type: "list",
|
|
840
|
-
name: "role",
|
|
841
|
-
message: "Binding role:",
|
|
842
|
-
choices: [{
|
|
843
|
-
name: "primary — routes all traffic from this channel",
|
|
844
|
-
value: "primary"
|
|
845
|
-
}, {
|
|
846
|
-
name: "secondary — fallback if primary is busy",
|
|
847
|
-
value: "secondary"
|
|
848
|
-
}]
|
|
849
|
-
}
|
|
850
|
-
]);
|
|
851
|
-
let agent = this.agents.find((a) => a.name === workspace || a.workspace === workspace);
|
|
852
|
-
if (!agent) {
|
|
853
|
-
agent = {
|
|
854
|
-
workspace,
|
|
855
|
-
name: workspace,
|
|
856
|
-
bindings: []
|
|
857
|
-
};
|
|
858
|
-
this.agents.push(agent);
|
|
859
|
-
}
|
|
860
|
-
agent.bindings.push({
|
|
861
|
-
channelId: channel,
|
|
862
|
-
agentWorkspace: agent.workspace,
|
|
863
|
-
role,
|
|
864
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
865
|
-
});
|
|
866
|
-
this.save();
|
|
867
|
-
console.log(chalk.default.green(`\n ✔ Bound ${channel} → ${workspace} (${role})\n`));
|
|
868
|
-
}
|
|
869
|
-
async unbind() {
|
|
870
|
-
const allBindings = [];
|
|
871
|
-
for (const agent of this.agents) for (const b of agent.bindings) allBindings.push({
|
|
872
|
-
agent: agent.name,
|
|
873
|
-
channel: b.channelId
|
|
874
|
-
});
|
|
875
|
-
if (allBindings.length === 0) {
|
|
876
|
-
console.log(chalk.default.gray("\n No bindings to remove.\n"));
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
const { toRemove } = await inquirer.default.prompt([{
|
|
880
|
-
type: "checkbox",
|
|
881
|
-
name: "toRemove",
|
|
882
|
-
message: "Select bindings to remove:",
|
|
883
|
-
choices: allBindings.map((b) => ({
|
|
884
|
-
name: `${b.channel} → ${b.agent}`,
|
|
885
|
-
value: b
|
|
886
|
-
}))
|
|
887
|
-
}]);
|
|
888
|
-
for (const { agent: agentName, channel } of toRemove) {
|
|
889
|
-
const agent = this.agents.find((a) => a.name === agentName);
|
|
890
|
-
if (agent) agent.bindings = agent.bindings.filter((b) => b.channelId !== channel);
|
|
891
|
-
}
|
|
892
|
-
this.save();
|
|
893
|
-
console.log(chalk.default.green(`\n ✔ Removed ${toRemove.length} binding(s)\n`));
|
|
894
|
-
}
|
|
895
|
-
};
|
|
896
|
-
|
|
897
|
-
//#endregion
|
|
898
|
-
//#region src/commands/doctor.ts
|
|
899
|
-
async function isPortOpen(port) {
|
|
900
|
-
return new Promise((resolve) => {
|
|
901
|
-
const s = new net.default.Socket();
|
|
902
|
-
s.setTimeout(500);
|
|
903
|
-
s.on("connect", () => {
|
|
904
|
-
s.destroy();
|
|
905
|
-
resolve(true);
|
|
906
|
-
});
|
|
907
|
-
s.on("error", () => resolve(false));
|
|
908
|
-
s.on("timeout", () => resolve(false));
|
|
909
|
-
try {
|
|
910
|
-
s.connect(port, "127.0.0.1");
|
|
911
|
-
} catch {
|
|
912
|
-
resolve(false);
|
|
913
|
-
}
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
async function runDoctor(fix = false) {
|
|
917
|
-
const spinner = (0, ora.default)("Running health checks...").start();
|
|
918
|
-
await new Promise((r) => setTimeout(r, 800));
|
|
919
|
-
spinner.stop();
|
|
920
|
-
const configDir = path.default.join(os.default.homedir(), ".hyperclaw");
|
|
921
|
-
const configFile = path.default.join(configDir, "config.json");
|
|
922
|
-
const agentsFile = path.default.join(configDir, "AGENTS.md");
|
|
923
|
-
const authFile = path.default.join(configDir, "auth.json");
|
|
924
|
-
const pairingFile = path.default.join(configDir, "pairing-store.json");
|
|
925
|
-
let cfg = null;
|
|
926
|
-
try {
|
|
927
|
-
cfg = fs_extra.default.readJsonSync(configFile);
|
|
928
|
-
} catch {}
|
|
929
|
-
const issues = [];
|
|
930
|
-
if (!cfg) issues.push({
|
|
931
|
-
id: "no-config",
|
|
932
|
-
severity: "error",
|
|
933
|
-
title: "No configuration found",
|
|
934
|
-
detail: "Run: hyperclaw init",
|
|
935
|
-
fixable: false
|
|
936
|
-
});
|
|
937
|
-
else {
|
|
938
|
-
const hasToken = !!cfg.gateway?.authToken;
|
|
939
|
-
issues.push({
|
|
940
|
-
id: "gateway-token",
|
|
941
|
-
severity: hasToken ? "ok" : "warn",
|
|
942
|
-
title: hasToken ? "Gateway auth token set" : "Gateway auth token missing",
|
|
943
|
-
detail: hasToken ? "Token is configured" : "Set a strong token in gateway config",
|
|
944
|
-
fixable: !hasToken,
|
|
945
|
-
fix: async () => {
|
|
946
|
-
const crypto = await import("crypto");
|
|
947
|
-
cfg.gateway = cfg.gateway || {};
|
|
948
|
-
cfg.gateway.authToken = crypto.randomBytes(32).toString("hex");
|
|
949
|
-
fs_extra.default.writeJsonSync(configFile, cfg, { spaces: 2 });
|
|
950
|
-
console.log(chalk.default.green(" ✔ Generated and saved gateway auth token"));
|
|
951
|
-
}
|
|
952
|
-
});
|
|
953
|
-
const channels = cfg.channels || [];
|
|
954
|
-
const channelConfigs = cfg.channelConfigs || {};
|
|
955
|
-
for (const ch of channels) {
|
|
956
|
-
const dmPolicy = channelConfigs[ch]?.dmPolicy?.policy;
|
|
957
|
-
if (dmPolicy === "open") issues.push({
|
|
958
|
-
id: `dm-open-${ch}`,
|
|
959
|
-
severity: "warn",
|
|
960
|
-
title: `DM policy is "open" on ${ch}`,
|
|
961
|
-
detail: `Anyone can DM your agent on ${ch}. Consider using "pairing" or "allowlist".`,
|
|
962
|
-
fixable: false
|
|
963
|
-
});
|
|
964
|
-
if (dmPolicy === "allowlist") {
|
|
965
|
-
const allowFrom = channelConfigs[ch]?.dmPolicy?.allowFrom || [];
|
|
966
|
-
if (allowFrom.length === 0) issues.push({
|
|
967
|
-
id: `dm-empty-allowlist-${ch}`,
|
|
968
|
-
severity: "error",
|
|
969
|
-
title: `Empty allowlist on ${ch} — DMs will be silently dropped`,
|
|
970
|
-
detail: `channel.${ch}.dmPolicy.allowFrom is empty. Add users or change policy.`,
|
|
971
|
-
fixable: true,
|
|
972
|
-
fix: async () => {
|
|
973
|
-
try {
|
|
974
|
-
const pairingEntries = fs_extra.default.readJsonSync(pairingFile);
|
|
975
|
-
const approved = pairingEntries.filter((e) => e.channelId === ch && e.status === "approved" && e.userId);
|
|
976
|
-
if (approved.length > 0) {
|
|
977
|
-
channelConfigs[ch].dmPolicy.allowFrom = approved.map((e) => e.userId);
|
|
978
|
-
cfg.channelConfigs = channelConfigs;
|
|
979
|
-
fs_extra.default.writeJsonSync(configFile, cfg, { spaces: 2 });
|
|
980
|
-
console.log(chalk.default.green(` ✔ Restored ${approved.length} user(s) from pairing store to ${ch} allowlist`));
|
|
981
|
-
}
|
|
982
|
-
} catch {}
|
|
983
|
-
}
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
const hasApiKey = !!cfg.provider?.apiKey;
|
|
988
|
-
const isLocal = cfg.provider?.providerId === "local";
|
|
989
|
-
if (!hasApiKey && !isLocal) issues.push({
|
|
990
|
-
id: "no-api-key",
|
|
991
|
-
severity: "error",
|
|
992
|
-
title: "No AI provider API key configured",
|
|
993
|
-
detail: "Run: hyperclaw config set-key",
|
|
994
|
-
fixable: false
|
|
995
|
-
});
|
|
996
|
-
else issues.push({
|
|
997
|
-
id: "api-key",
|
|
998
|
-
severity: "ok",
|
|
999
|
-
title: "AI provider key configured",
|
|
1000
|
-
detail: `Provider: ${cfg.provider?.providerId}`,
|
|
1001
|
-
fixable: false
|
|
1002
|
-
});
|
|
1003
|
-
issues.push({
|
|
1004
|
-
id: "agents-md",
|
|
1005
|
-
severity: await fs_extra.default.pathExists(agentsFile) ? "ok" : "warn",
|
|
1006
|
-
title: await fs_extra.default.pathExists(agentsFile) ? "AGENTS.md exists" : "AGENTS.md missing",
|
|
1007
|
-
detail: await fs_extra.default.pathExists(agentsFile) ? agentsFile : "Run: hyperclaw memory init to generate",
|
|
1008
|
-
fixable: false
|
|
1009
|
-
});
|
|
1010
|
-
const port = cfg.gateway?.port || 1515;
|
|
1011
|
-
const running = await isPortOpen(port);
|
|
1012
|
-
issues.push({
|
|
1013
|
-
id: "gateway-running",
|
|
1014
|
-
severity: running ? "ok" : "warn",
|
|
1015
|
-
title: running ? `Gateway running on port ${port}` : `Gateway not running on port ${port}`,
|
|
1016
|
-
detail: running ? `ws://127.0.0.1:${port}` : "Run: hyperclaw daemon start",
|
|
1017
|
-
fixable: false
|
|
1018
|
-
});
|
|
1019
|
-
if (await fs_extra.default.pathExists(authFile)) {
|
|
1020
|
-
const stat = await fs_extra.default.stat(authFile);
|
|
1021
|
-
const unsafe = (stat.mode & 63) !== 0;
|
|
1022
|
-
issues.push({
|
|
1023
|
-
id: "auth-permissions",
|
|
1024
|
-
severity: unsafe ? "warn" : "ok",
|
|
1025
|
-
title: unsafe ? "Auth store has unsafe permissions" : "Auth store permissions OK",
|
|
1026
|
-
detail: unsafe ? `chmod 600 ${authFile}` : `Mode: 600`,
|
|
1027
|
-
fixable: unsafe,
|
|
1028
|
-
fix: async () => {
|
|
1029
|
-
await fs_extra.default.chmod(authFile, 384);
|
|
1030
|
-
console.log(chalk.default.green(` ✔ Fixed permissions on ${authFile}`));
|
|
1031
|
-
}
|
|
1032
|
-
});
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
console.log(chalk.default.bold.cyan("\n 🩺 HYPERCLAW DOCTOR\n"));
|
|
1036
|
-
let errorCount = 0, warnCount = 0;
|
|
1037
|
-
for (const issue of issues) {
|
|
1038
|
-
const icon = {
|
|
1039
|
-
error: chalk.default.red("✖"),
|
|
1040
|
-
warn: chalk.default.yellow("⚠"),
|
|
1041
|
-
ok: chalk.default.green("✔")
|
|
1042
|
-
}[issue.severity];
|
|
1043
|
-
console.log(` ${icon} ${chalk.default.white(issue.title)}`);
|
|
1044
|
-
console.log(` ${chalk.default.gray(issue.detail)}`);
|
|
1045
|
-
if (issue.fixable && fix && issue.fix) await issue.fix();
|
|
1046
|
-
else if (issue.fixable && !fix) console.log(chalk.default.gray(" Run with --fix to auto-repair"));
|
|
1047
|
-
if (issue.severity === "error") errorCount++;
|
|
1048
|
-
if (issue.severity === "warn") warnCount++;
|
|
1049
|
-
console.log();
|
|
1050
|
-
}
|
|
1051
|
-
const total = issues.length;
|
|
1052
|
-
const okCount = total - errorCount - warnCount;
|
|
1053
|
-
console.log(` ${chalk.default.bold("Summary:")} ${chalk.default.green(`${okCount} ok`)} ${chalk.default.yellow(`${warnCount} warnings`)} ${chalk.default.red(`${errorCount} errors`)}`);
|
|
1054
|
-
if (errorCount > 0 || warnCount > 0) console.log(chalk.default.gray("\n Run: hyperclaw doctor --fix to auto-repair fixable issues\n"));
|
|
1055
|
-
else console.log(chalk.default.green("\n ✔ All checks passed!\n"));
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
287
|
//#endregion
|
|
1059
288
|
//#region src/commands/message-send.ts
|
|
1060
289
|
async function sendMessage(opts) {
|
|
@@ -1117,11 +346,11 @@ const CHANNELS = [
|
|
|
1117
346
|
tokenLabel: "Telegram Bot Token",
|
|
1118
347
|
tokenHint: "Get from @BotFather → /newbot",
|
|
1119
348
|
setupSteps: [
|
|
1120
|
-
"1.
|
|
1121
|
-
"2.
|
|
1122
|
-
"3.
|
|
1123
|
-
"4.
|
|
1124
|
-
"5.
|
|
349
|
+
"1. Open Telegram and search for @BotFather (the official bot for creating bots).",
|
|
350
|
+
"2. Start a conversation with /start and type /newbot to create a new bot.",
|
|
351
|
+
"3. Give the bot a name (e.g. \"My HyperClaw Bot\") and a username ending in \"bot\" (e.g. my_hyperclaw_bot).",
|
|
352
|
+
"4. @BotFather will send you the Bot Token — a string starting with 7xxxxxx:AAH... Keep it secret!",
|
|
353
|
+
"5. Copy the token and paste it below.",
|
|
1125
354
|
"",
|
|
1126
355
|
" 🔗 t.me/BotFather"
|
|
1127
356
|
],
|
|
@@ -1138,19 +367,19 @@ const CHANNELS = [
|
|
|
1138
367
|
tokenLabel: "Discord Bot Token",
|
|
1139
368
|
tokenHint: "discord.com/developers/applications",
|
|
1140
369
|
setupSteps: [
|
|
1141
|
-
"1.
|
|
1142
|
-
"2.
|
|
1143
|
-
"3.
|
|
1144
|
-
"4.
|
|
1145
|
-
"5.
|
|
1146
|
-
"6.
|
|
370
|
+
"1. Go to Discord Developer Portal: https://discord.com/developers/applications",
|
|
371
|
+
"2. Click \"New Application\", give it a name and create it.",
|
|
372
|
+
"3. Left menu: Bot → Add Bot.",
|
|
373
|
+
"4. Click \"Reset Token\" and copy the token (keep it secret!).",
|
|
374
|
+
"5. Settings → OAuth2 → General, copy the Application ID (Client ID).",
|
|
375
|
+
"6. Optional: To add the bot to a server, Bot → OAuth2 → URL Generator, scope: bot.",
|
|
1147
376
|
"",
|
|
1148
377
|
" 🔗 discord.com/developers/applications"
|
|
1149
378
|
],
|
|
1150
379
|
extraFields: [{
|
|
1151
380
|
name: "clientId",
|
|
1152
381
|
label: "Client ID (Application ID)",
|
|
1153
|
-
hint: "
|
|
382
|
+
hint: "From OAuth2 → General",
|
|
1154
383
|
required: true
|
|
1155
384
|
}],
|
|
1156
385
|
status: "recommended",
|
|
@@ -1166,11 +395,11 @@ const CHANNELS = [
|
|
|
1166
395
|
tokenLabel: "WhatsApp Business API key",
|
|
1167
396
|
tokenHint: "business.whatsapp.com",
|
|
1168
397
|
setupSteps: [
|
|
1169
|
-
"1.
|
|
398
|
+
"1. Go to Meta for Developers: https://developers.facebook.com/",
|
|
1170
399
|
"2. My Apps → Create App → Business type.",
|
|
1171
|
-
"3.
|
|
1172
|
-
"4.
|
|
1173
|
-
"5.
|
|
400
|
+
"3. Add product: WhatsApp → Get started.",
|
|
401
|
+
"4. WhatsApp → API Setup: copy the Temporary access token or create a permanent one.",
|
|
402
|
+
"5. You also need a Phone Number ID and WhatsApp Business Account ID.",
|
|
1174
403
|
"",
|
|
1175
404
|
" 🔗 developers.facebook.com — business.whatsapp.com"
|
|
1176
405
|
],
|
|
@@ -1185,11 +414,11 @@ const CHANNELS = [
|
|
|
1185
414
|
supportsDM: true,
|
|
1186
415
|
platforms: ["all"],
|
|
1187
416
|
setupSteps: [
|
|
1188
|
-
"1.
|
|
1189
|
-
"2.
|
|
1190
|
-
"3.
|
|
1191
|
-
"4.
|
|
1192
|
-
"5.
|
|
417
|
+
"1. No Meta Business API needed — uses WhatsApp Web.",
|
|
418
|
+
"2. Make sure you have installed: npm install @whiskeysockets/baileys",
|
|
419
|
+
"3. Start the gateway. On first connection a QR code will appear.",
|
|
420
|
+
"4. Scan the QR with your phone (WhatsApp → Linked Devices → Link a device).",
|
|
421
|
+
"5. After connecting, the session is saved — no QR needed again.",
|
|
1193
422
|
"",
|
|
1194
423
|
" 📖 docs: github.com/WhiskeySockets/Baileys"
|
|
1195
424
|
],
|
|
@@ -1211,11 +440,11 @@ const CHANNELS = [
|
|
|
1211
440
|
required: true
|
|
1212
441
|
}],
|
|
1213
442
|
setupSteps: [
|
|
1214
|
-
"1.
|
|
1215
|
-
"2.
|
|
1216
|
-
"3. OAuth & Permissions:
|
|
1217
|
-
"4. Install App
|
|
1218
|
-
"5. Basic Information → App Credentials → Signing Secret —
|
|
443
|
+
"1. Go to api.slack.com/apps → Create New App → From scratch.",
|
|
444
|
+
"2. Give it a name and choose a workspace.",
|
|
445
|
+
"3. OAuth & Permissions: Add Bot Token Scopes (chat:write, users:read, im:read, im:history, etc.).",
|
|
446
|
+
"4. Install App to workspace — copy the \"Bot User OAuth Token\" (starts with xoxb-).",
|
|
447
|
+
"5. Basic Information → App Credentials → Signing Secret — copy it.",
|
|
1219
448
|
"",
|
|
1220
449
|
" 🔗 api.slack.com/apps"
|
|
1221
450
|
],
|
|
@@ -1232,10 +461,10 @@ const CHANNELS = [
|
|
|
1232
461
|
tokenLabel: "Signal phone number",
|
|
1233
462
|
tokenHint: "Requires signal-cli installed",
|
|
1234
463
|
setupSteps: [
|
|
1235
|
-
"1.
|
|
1236
|
-
"2.
|
|
1237
|
-
"3.
|
|
1238
|
-
"4.
|
|
464
|
+
"1. Install signal-cli: https://github.com/AsamK/signal-cli",
|
|
465
|
+
"2. Register number: signal-cli -a +1XXXXXXXXX register",
|
|
466
|
+
"3. Verify electronically (if available) or via SMS code.",
|
|
467
|
+
"4. Enter your phone number here (e.g. +1XXXXXXXXX).",
|
|
1239
468
|
"",
|
|
1240
469
|
" 🔗 github.com/AsamK/signal-cli"
|
|
1241
470
|
],
|
|
@@ -1250,10 +479,10 @@ const CHANNELS = [
|
|
|
1250
479
|
supportsDM: true,
|
|
1251
480
|
platforms: ["darwin"],
|
|
1252
481
|
setupSteps: [
|
|
1253
|
-
"1. macOS
|
|
1254
|
-
"2. BlueBubbles:
|
|
1255
|
-
"3.
|
|
1256
|
-
"4.
|
|
482
|
+
"1. macOS only. You need BlueBubbles (bluebubbles.app) or Beeper bridge.",
|
|
483
|
+
"2. BlueBubbles: install on Mac, check server URL and API key.",
|
|
484
|
+
"3. Or Beeper: connect to iMessage via Beeper desktop app.",
|
|
485
|
+
"4. Set server URL and token in the channel configuration.",
|
|
1257
486
|
"",
|
|
1258
487
|
" 🔗 bluebubbles.app — beeper.com"
|
|
1259
488
|
],
|
|
@@ -1280,10 +509,10 @@ const CHANNELS = [
|
|
|
1280
509
|
required: true
|
|
1281
510
|
}],
|
|
1282
511
|
setupSteps: [
|
|
1283
|
-
"1.
|
|
512
|
+
"1. Create a bot account on matrix.org or another homeserver.",
|
|
1284
513
|
"2. Access token: Element/SchildiChat → Settings → Help & About → Access Token.",
|
|
1285
|
-
"3.
|
|
1286
|
-
"4. Homeserver URL: https://matrix.org
|
|
514
|
+
"3. Or via API: POST /_matrix/client/r0/login with type=m.login.password.",
|
|
515
|
+
"4. Homeserver URL: https://matrix.org or your server URL.",
|
|
1287
516
|
"",
|
|
1288
517
|
" 🔗 matrix.org — element.io"
|
|
1289
518
|
],
|
|
@@ -1317,9 +546,9 @@ const CHANNELS = [
|
|
|
1317
546
|
}
|
|
1318
547
|
],
|
|
1319
548
|
setupSteps: [
|
|
1320
|
-
"1.
|
|
1321
|
-
"2.
|
|
1322
|
-
"3.
|
|
549
|
+
"1. Choose an IRC server (e.g. irc.libera.chat, irc.oftc.net).",
|
|
550
|
+
"2. You need a nickname for the bot and optionally a channel to join.",
|
|
551
|
+
"3. Some servers require authentication before /join.",
|
|
1323
552
|
"",
|
|
1324
553
|
" 🔗 libera.chat — oftc.net"
|
|
1325
554
|
],
|
|
@@ -1336,11 +565,11 @@ const CHANNELS = [
|
|
|
1336
565
|
tokenLabel: "Personal Access Token (or Bot token)",
|
|
1337
566
|
tokenHint: "Account Settings > Security > Personal Access Tokens",
|
|
1338
567
|
setupSteps: [
|
|
1339
|
-
"1.
|
|
1340
|
-
"2. Create token —
|
|
568
|
+
"1. In Mattermost: Profile → Account Settings → Security → Personal Access Tokens.",
|
|
569
|
+
"2. Create token — copy it (not shown again).",
|
|
1341
570
|
"3. Integrations → Outgoing Webhooks → Add outgoing webhook.",
|
|
1342
|
-
"4.
|
|
1343
|
-
"5. Webhook URL
|
|
571
|
+
"4. Note the webhook URL and Trigger Word. The webhook token is needed for verification.",
|
|
572
|
+
"5. Webhook URL for gateway: https://<gateway>/webhook/mattermost",
|
|
1344
573
|
"",
|
|
1345
574
|
" 🔗 docs.mattermost.com"
|
|
1346
575
|
],
|
|
@@ -1368,9 +597,9 @@ const CHANNELS = [
|
|
|
1368
597
|
platforms: ["all"],
|
|
1369
598
|
tokenLabel: "Google Chat webhook URL",
|
|
1370
599
|
setupSteps: [
|
|
1371
|
-
"1.
|
|
1372
|
-
"2.
|
|
1373
|
-
"3.
|
|
600
|
+
"1. In Google Chat: Room → Manage webhooks → Add webhook.",
|
|
601
|
+
"2. Give it a name and copy the Webhook URL.",
|
|
602
|
+
"3. Paste the URL below.",
|
|
1374
603
|
"",
|
|
1375
604
|
" 🔗 chat.google.com"
|
|
1376
605
|
],
|
|
@@ -1385,9 +614,9 @@ const CHANNELS = [
|
|
|
1385
614
|
platforms: ["all"],
|
|
1386
615
|
tokenLabel: "Teams incoming webhook URL",
|
|
1387
616
|
setupSteps: [
|
|
1388
|
-
"1.
|
|
1389
|
-
"2.
|
|
1390
|
-
"3.
|
|
617
|
+
"1. In Teams: Channel → Connectors → Incoming Webhook → Configure.",
|
|
618
|
+
"2. Give it a name and copy the Webhook URL.",
|
|
619
|
+
"3. Paste the URL below.",
|
|
1391
620
|
"",
|
|
1392
621
|
" 🔗 docs.microsoft.com/microsoftteams/platform/webhooks-and-connectors"
|
|
1393
622
|
],
|
|
@@ -1408,9 +637,9 @@ const CHANNELS = [
|
|
|
1408
637
|
required: true
|
|
1409
638
|
}],
|
|
1410
639
|
setupSteps: [
|
|
1411
|
-
"1.
|
|
1412
|
-
"2.
|
|
1413
|
-
"3.
|
|
640
|
+
"1. You need a Nostr private key (nsec1...). Create one with Damus, Amethyst or iris.to.",
|
|
641
|
+
"2. Choose a Relay: e.g. wss://relay.damus.io, wss://relay.nostr.band.",
|
|
642
|
+
"3. NEVER share your nsec — it is your private key.",
|
|
1414
643
|
"",
|
|
1415
644
|
" 🔗 nostr.com — damus.io"
|
|
1416
645
|
],
|
|
@@ -1431,10 +660,10 @@ const CHANNELS = [
|
|
|
1431
660
|
required: true
|
|
1432
661
|
}],
|
|
1433
662
|
setupSteps: [
|
|
1434
|
-
"1.
|
|
1435
|
-
"2. Messaging API channel →
|
|
1436
|
-
"3. Channel access token: Issue
|
|
1437
|
-
"4. Channel secret:
|
|
663
|
+
"1. Go to developers.line.biz → Console → Create provider & channel.",
|
|
664
|
+
"2. Messaging API channel → Configure Basic settings.",
|
|
665
|
+
"3. Channel access token: Issue or Regenerate — copy it.",
|
|
666
|
+
"4. Channel secret: from Basic settings — copy it.",
|
|
1438
667
|
"",
|
|
1439
668
|
" 🔗 developers.line.biz"
|
|
1440
669
|
],
|
|
@@ -1455,9 +684,9 @@ const CHANNELS = [
|
|
|
1455
684
|
required: true
|
|
1456
685
|
}],
|
|
1457
686
|
setupSteps: [
|
|
1458
|
-
"1.
|
|
1459
|
-
"2. Credentials:
|
|
1460
|
-
"3.
|
|
687
|
+
"1. Go to open.feishu.cn → Create enterprise app.",
|
|
688
|
+
"2. Credentials: copy App ID and App Secret.",
|
|
689
|
+
"3. Enable permissions: im:message, im:message.group_at_msg etc.",
|
|
1461
690
|
"",
|
|
1462
691
|
" 🔗 open.feishu.cn"
|
|
1463
692
|
],
|
|
@@ -1702,8 +931,8 @@ const CHANNELS = [
|
|
|
1702
931
|
required: true
|
|
1703
932
|
}],
|
|
1704
933
|
setupSteps: [
|
|
1705
|
-
"1.
|
|
1706
|
-
"2.
|
|
934
|
+
"1. Create App Password: Nextcloud → Profile → Security → App passwords.",
|
|
935
|
+
"2. You need the Nextcloud URL, username and App Password.",
|
|
1707
936
|
"",
|
|
1708
937
|
" 🔗 nextcloud.com"
|
|
1709
938
|
],
|
|
@@ -1719,8 +948,8 @@ const CHANNELS = [
|
|
|
1719
948
|
tokenLabel: "Zalo OA Access Token",
|
|
1720
949
|
setupSteps: [
|
|
1721
950
|
"1. Zalo Official Account (OA): developers.zalo.me → My Apps.",
|
|
1722
|
-
"2.
|
|
1723
|
-
"3. Access Token
|
|
951
|
+
"2. Create an app and connect it to your OA.",
|
|
952
|
+
"3. Access Token from Zalo API (OAuth flow or test token for development).",
|
|
1724
953
|
"",
|
|
1725
954
|
" 🔗 developers.zalo.me"
|
|
1726
955
|
],
|
|
@@ -1762,10 +991,10 @@ const CHANNELS = [
|
|
|
1762
991
|
}
|
|
1763
992
|
],
|
|
1764
993
|
setupSteps: [
|
|
1765
|
-
"1.
|
|
1766
|
-
"2. Gmail:
|
|
1767
|
-
"3. SMTP host: smtp.gmail.com, smtp.office365.com,
|
|
1768
|
-
"4.
|
|
994
|
+
"1. You need an SMTP server (Gmail, Outlook, SendGrid, Mailgun, or custom).",
|
|
995
|
+
"2. Gmail: enable 2FA, create App Password (myaccount.google.com/apppasswords).",
|
|
996
|
+
"3. SMTP host: smtp.gmail.com, smtp.office365.com, or your provider host.",
|
|
997
|
+
"4. For IMAP (reading email): imap.gmail.com etc.",
|
|
1769
998
|
"",
|
|
1770
999
|
" 🔗 support.google.com/accounts/answer/185833"
|
|
1771
1000
|
],
|
|
@@ -1816,10 +1045,10 @@ const ZALO_PERSONAL = {
|
|
|
1816
1045
|
tokenLabel: "Zalo Personal cookie token",
|
|
1817
1046
|
tokenHint: "Extract from browser",
|
|
1818
1047
|
setupSteps: [
|
|
1819
|
-
"1. Unofficial API —
|
|
1820
|
-
"2.
|
|
1821
|
-
"3.
|
|
1822
|
-
"4.
|
|
1048
|
+
"1. Unofficial API — uses browser cookies. May break with Zalo updates.",
|
|
1049
|
+
"2. Open Zalo Web in browser, Developer Tools → Application → Cookies.",
|
|
1050
|
+
"3. Look for the token/cookie Zalo uses for auth.",
|
|
1051
|
+
"4. See docs/channels/zalo-personal.md for details.",
|
|
1823
1052
|
"",
|
|
1824
1053
|
" ⚠️ Unofficial — use at your own risk"
|
|
1825
1054
|
],
|
|
@@ -1850,14 +1079,14 @@ async function channelsAdd(channelId) {
|
|
|
1850
1079
|
const ch = getChannel(id);
|
|
1851
1080
|
if (!ch) {
|
|
1852
1081
|
console.log(chalk.default.red(` ✖ Unknown channel: ${id}`));
|
|
1853
|
-
console.log(chalk.default.gray("
|
|
1854
|
-
console.log(chalk.default.gray("
|
|
1082
|
+
console.log(chalk.default.gray(" Available: " + CHANNELS.map((c) => c.id).join(", ")));
|
|
1083
|
+
console.log(chalk.default.gray(" Command: hyperclaw channels add <id>\n"));
|
|
1855
1084
|
return;
|
|
1856
1085
|
}
|
|
1857
1086
|
console.log(chalk.default.cyan(`\n ${ch.emoji} Configuring ${ch.name}\n`));
|
|
1858
1087
|
if (ch.notes) console.log(chalk.default.gray(` ℹ ${ch.notes}\n`));
|
|
1859
1088
|
if (ch.setupSteps && ch.setupSteps.length > 0) {
|
|
1860
|
-
console.log(chalk.default.bold("
|
|
1089
|
+
console.log(chalk.default.bold(" Setup steps:\n"));
|
|
1861
1090
|
for (const step of ch.setupSteps) {
|
|
1862
1091
|
if (step.trim() === "") continue;
|
|
1863
1092
|
if (step.startsWith(" 🔗")) console.log(chalk.default.cyan(step));
|
|
@@ -2267,7 +1496,7 @@ var init_queue = require_chunk.__esm({ "src/delivery/queue.ts"() {
|
|
|
2267
1496
|
//#endregion
|
|
2268
1497
|
//#region src/cli/run-main.ts
|
|
2269
1498
|
const program = new commander.Command();
|
|
2270
|
-
program.name("hyperclaw").description("⚡ HyperClaw — AI Gateway Platform. The Lobster Evolution 🦅").version("4.0.
|
|
1499
|
+
program.name("hyperclaw").description("⚡ HyperClaw — AI Gateway Platform. The Lobster Evolution 🦅").version("4.0.2");
|
|
2271
1500
|
program.command("init").description("Initialize HyperClaw with interactive wizard").option("-a, --auto-config", "Auto-configure with defaults").option("-d, --daemon", "Install as system daemon").option("-s, --start-now", "Start gateway after setup").action(async (opts) => {
|
|
2272
1501
|
await new require_onboard.Banner().showNeonBanner(false);
|
|
2273
1502
|
await new require_onboard.HyperClawWizard().run(opts);
|
|
@@ -2276,22 +1505,22 @@ program.command("init").description("Initialize HyperClaw with interactive wizar
|
|
|
2276
1505
|
program.command("onboard").description("Full onboarding wizard — preferred setup path").option("--install-daemon", "Auto-install system daemon (starts on boot, grants full PC access)").option("--quick", "Use QuickStart mode (skip advanced options)").action(async (opts) => {
|
|
2277
1506
|
await new require_onboard.Banner().showNeonBanner(false);
|
|
2278
1507
|
if (opts.installDaemon) {
|
|
2279
|
-
const chalk$
|
|
2280
|
-
console.log(chalk$
|
|
2281
|
-
console.log(chalk$
|
|
2282
|
-
console.log(chalk$
|
|
2283
|
-
console.log(chalk$
|
|
2284
|
-
console.log(chalk$
|
|
2285
|
-
console.log(chalk$
|
|
2286
|
-
const inquirer$
|
|
2287
|
-
const { confirmed } = await inquirer$
|
|
1508
|
+
const chalk$10 = require("chalk");
|
|
1509
|
+
console.log(chalk$10.yellow("\n ⚠ --install-daemon mode\n"));
|
|
1510
|
+
console.log(chalk$10.gray(" The daemon will run as a background system service and will have:\n"));
|
|
1511
|
+
console.log(chalk$10.white(" • Full shell / command execution on this machine"));
|
|
1512
|
+
console.log(chalk$10.white(" • File system read & write access"));
|
|
1513
|
+
console.log(chalk$10.white(" • Network access (gateway WebSocket)"));
|
|
1514
|
+
console.log(chalk$10.white(" • Auto-start on every system boot\n"));
|
|
1515
|
+
const inquirer$2 = require("inquirer");
|
|
1516
|
+
const { confirmed } = await inquirer$2.prompt([{
|
|
2288
1517
|
type: "confirm",
|
|
2289
1518
|
name: "confirmed",
|
|
2290
1519
|
message: "I understand and want to continue with full PC access:",
|
|
2291
1520
|
default: false
|
|
2292
1521
|
}]);
|
|
2293
1522
|
if (!confirmed) {
|
|
2294
|
-
console.log(chalk$
|
|
1523
|
+
console.log(chalk$10.gray("\n Cancelled. Run without --install-daemon to choose during setup.\n"));
|
|
2295
1524
|
process.exit(0);
|
|
2296
1525
|
}
|
|
2297
1526
|
}
|
|
@@ -2333,7 +1562,7 @@ gatewayCmd.command("restart").description("Restart the gateway service").action(
|
|
|
2333
1562
|
const dm = new require_onboard.DaemonManager();
|
|
2334
1563
|
await dm.restart();
|
|
2335
1564
|
});
|
|
2336
|
-
program.command("daemon").description("Manage HyperClaw system service (alias: gateway)").argument("<action>", "start|stop|restart|status|logs").action(async (action) => {
|
|
1565
|
+
program.command("daemon").description("Manage HyperClaw system service (alias: gateway)").argument("<action>", "start|stop|restart|status|logs|install|uninstall").action(async (action) => {
|
|
2337
1566
|
const dm = new require_onboard.DaemonManager();
|
|
2338
1567
|
if (action === "start") await new require_onboard.Banner().showNeonBanner(true);
|
|
2339
1568
|
await dm.handle(action);
|
|
@@ -2342,20 +1571,20 @@ program.command("daemon").description("Manage HyperClaw system service (alias: g
|
|
|
2342
1571
|
});
|
|
2343
1572
|
const sandboxCmd = program.command("sandbox").description("Debug sandbox and tool policy");
|
|
2344
1573
|
sandboxCmd.command("explain").description("Show effective sandbox mode, tool policy, and allowed tools").option("--json", "Output as JSON").action(async (opts) => {
|
|
2345
|
-
const chalk$
|
|
2346
|
-
const fs$
|
|
2347
|
-
const path$
|
|
2348
|
-
const os$
|
|
1574
|
+
const chalk$10 = require("chalk");
|
|
1575
|
+
const fs$6 = require("fs-extra");
|
|
1576
|
+
const path$6 = require("path");
|
|
1577
|
+
const os$7 = require("os");
|
|
2349
1578
|
const { getConfigPath } = await Promise.resolve().then(() => require("./paths-D-QecARF.js"));
|
|
2350
1579
|
const cfgPath = getConfigPath();
|
|
2351
1580
|
let cfg = {};
|
|
2352
1581
|
try {
|
|
2353
|
-
cfg = await fs$
|
|
1582
|
+
cfg = await fs$6.readJson(cfgPath);
|
|
2354
1583
|
} catch {}
|
|
2355
1584
|
const sandboxMode = cfg?.agents?.defaults?.sandbox?.mode ?? "non-main";
|
|
2356
1585
|
const toolsCfg = cfg?.tools ?? {};
|
|
2357
|
-
const { describeToolPolicy, applyToolPolicy } = await Promise.resolve().then(() => require("./tool-policy-
|
|
2358
|
-
const { getBuiltinTools, getSessionsTools, getPCAccessTools, getBrowserTools, getExtractionTools, getWebsiteWatchTools, getVisionTools } = await Promise.resolve().then(() => require("./src-
|
|
1586
|
+
const { describeToolPolicy, applyToolPolicy } = await Promise.resolve().then(() => require("./tool-policy-DNvNRnve.js"));
|
|
1587
|
+
const { getBuiltinTools, getSessionsTools, getPCAccessTools, getBrowserTools, getExtractionTools, getWebsiteWatchTools, getVisionTools } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
2359
1588
|
const allTools = [
|
|
2360
1589
|
...getBuiltinTools(),
|
|
2361
1590
|
...getSessionsTools(() => null),
|
|
@@ -2383,15 +1612,15 @@ sandboxCmd.command("explain").description("Show effective sandbox mode, tool pol
|
|
|
2383
1612
|
}, null, 2));
|
|
2384
1613
|
process.exit(0);
|
|
2385
1614
|
}
|
|
2386
|
-
console.log(chalk$
|
|
1615
|
+
console.log(chalk$10.bold.hex("#06b6d4")("\n 🔒 SANDBOX EXPLAIN\n"));
|
|
2387
1616
|
console.log(` Sandbox mode: ${sandboxMode} (non-main sessions get restricted pcTools)`);
|
|
2388
1617
|
console.log(` Tool profile: ${policy.profile}`);
|
|
2389
1618
|
console.log(` Policy source: ${policy.source}`);
|
|
2390
1619
|
if (policy.allow?.length) console.log(` Allow: ${policy.allow.join(", ")}`);
|
|
2391
1620
|
if (policy.deny?.length) console.log(` Deny: ${policy.deny.join(", ")}`);
|
|
2392
1621
|
console.log(` Tools: ${filtered.length} / ${allTools.length} allowed`);
|
|
2393
|
-
console.log(chalk$
|
|
2394
|
-
console.log(chalk$
|
|
1622
|
+
console.log(chalk$10.gray("\n Allowed: " + filtered.map((t) => t.name).join(", ")));
|
|
1623
|
+
console.log(chalk$10.gray("\n Elevated: " + ((cfg?.tools?.elevated)?.enabled ? "enabled" : "disabled")));
|
|
2395
1624
|
console.log();
|
|
2396
1625
|
process.exit(0);
|
|
2397
1626
|
});
|
|
@@ -2431,15 +1660,15 @@ hooksCmd.command("install <pack>").description("Install a hook pack").action(asy
|
|
|
2431
1660
|
});
|
|
2432
1661
|
const agentsCmd = program.command("agents").description("Multi-agent routing");
|
|
2433
1662
|
agentsCmd.command("bindings").description("List agent ↔ channel bindings").action(() => {
|
|
2434
|
-
new AgentRouter().listBindings();
|
|
1663
|
+
new require_agents_routing.AgentRouter().listBindings();
|
|
2435
1664
|
process.exit(0);
|
|
2436
1665
|
});
|
|
2437
1666
|
agentsCmd.command("bind").description("Bind a channel to an agent workspace").action(async () => {
|
|
2438
|
-
await new AgentRouter().bind();
|
|
1667
|
+
await new require_agents_routing.AgentRouter().bind();
|
|
2439
1668
|
process.exit(0);
|
|
2440
1669
|
});
|
|
2441
1670
|
agentsCmd.command("unbind").description("Remove channel ↔ agent bindings").action(async () => {
|
|
2442
|
-
await new AgentRouter().unbind();
|
|
1671
|
+
await new require_agents_routing.AgentRouter().unbind();
|
|
2443
1672
|
process.exit(0);
|
|
2444
1673
|
});
|
|
2445
1674
|
const pairingCmd = program.command("pairing").description("DM pairing codes");
|
|
@@ -2457,7 +1686,7 @@ msgCmd.command("send").description("Send a message via a configured channel").op
|
|
|
2457
1686
|
process.exit(0);
|
|
2458
1687
|
});
|
|
2459
1688
|
program.command("hub").description("Skill hub — browse marketplace, install, scan skills").option("-i, --install <id>", "Install skill").option("-s, --scan <id>", "Security scan a skill").option("-m, --marketplace", "ClawHub-style marketplace view (installed + bundled)").option("--force", "Force install (bypass risk block)").option("--hide-suspicious", "Hide suspicious/dangerous skills").action(async (opts) => {
|
|
2460
|
-
const hub = new SkillHub();
|
|
1689
|
+
const hub = new require_hub.SkillHub();
|
|
2461
1690
|
if (opts.scan) await hub.scan(opts.scan);
|
|
2462
1691
|
else if (opts.install) await hub.install(opts.install, opts.force);
|
|
2463
1692
|
else if (opts.marketplace) await hub.showMarketplace({ hideSuspicious: opts.hideSuspicious });
|
|
@@ -2466,7 +1695,7 @@ program.command("hub").description("Skill hub — browse marketplace, install, s
|
|
|
2466
1695
|
});
|
|
2467
1696
|
const skillCmd = program.command("skill").description("ClawHub — search and install skills from registry");
|
|
2468
1697
|
skillCmd.command("search [query]").description("Search ClawHub for skills").option("-c, --category <cat>", "Filter by category").action(async (query, opts) => {
|
|
2469
|
-
const hub = new SkillHub();
|
|
1698
|
+
const hub = new require_hub.SkillHub();
|
|
2470
1699
|
const q = query || "";
|
|
2471
1700
|
const skills = await hub.searchClawHub(q, opts.category);
|
|
2472
1701
|
if (skills.length === 0) {
|
|
@@ -2484,11 +1713,11 @@ skillCmd.command("search [query]").description("Search ClawHub for skills").opti
|
|
|
2484
1713
|
process.exit(0);
|
|
2485
1714
|
});
|
|
2486
1715
|
skillCmd.command("list").description("List installed skills (bundled + ClawHub)").action(async () => {
|
|
2487
|
-
const hub = new SkillHub();
|
|
1716
|
+
const hub = new require_hub.SkillHub();
|
|
2488
1717
|
const installed = await hub.getInstalled();
|
|
2489
1718
|
console.log(chalk.default.bold.hex("#06b6d4")("\n Installed skills:\n"));
|
|
2490
1719
|
for (const s of installed) {
|
|
2491
|
-
const src = SKILL_REGISTRY.some((r) => r.id === s.id) ? "" : " (ClawHub)";
|
|
1720
|
+
const src = require_hub.SKILL_REGISTRY.some((r) => r.id === s.id) ? "" : " (ClawHub)";
|
|
2492
1721
|
console.log(` ${chalk.default.hex("#06b6d4")("✓")} ${s.name} ${chalk.default.gray(`(${s.id})${src}`)}`);
|
|
2493
1722
|
}
|
|
2494
1723
|
if (installed.length === 0) console.log(chalk.default.gray(" No skills installed. Run: hyperclaw hub or hyperclaw skill search <query>\n"));
|
|
@@ -2496,14 +1725,14 @@ skillCmd.command("list").description("List installed skills (bundled + ClawHub)"
|
|
|
2496
1725
|
process.exit(0);
|
|
2497
1726
|
});
|
|
2498
1727
|
skillCmd.command("install <id>").description("Install skill from ClawHub (or bundled when registry unavailable)").option("-v, --version <ver>", "Pin version (e.g. 2.0.0)").option("--force", "Force install (bypass risk block for bundled)").action(async (id, opts) => {
|
|
2499
|
-
const hub = new SkillHub();
|
|
2500
|
-
const ora$
|
|
2501
|
-
const s = ora$
|
|
1728
|
+
const hub = new require_hub.SkillHub();
|
|
1729
|
+
const ora$4 = (await import("ora")).default;
|
|
1730
|
+
const s = ora$4(`Installing ${id}...`).start();
|
|
2502
1731
|
try {
|
|
2503
1732
|
const dest = await hub.installFromClawHub(id, opts.version);
|
|
2504
1733
|
s.succeed(`Installed to ${dest}`);
|
|
2505
1734
|
} catch (e) {
|
|
2506
|
-
const match = SKILL_REGISTRY.find((x) => x.id === id);
|
|
1735
|
+
const match = require_hub.SKILL_REGISTRY.find((x) => x.id === id);
|
|
2507
1736
|
if (match) {
|
|
2508
1737
|
await hub.install(id, !!opts?.force);
|
|
2509
1738
|
s.succeed(`Installed bundled skill: ${match.name}`);
|
|
@@ -2512,13 +1741,13 @@ skillCmd.command("install <id>").description("Install skill from ClawHub (or bun
|
|
|
2512
1741
|
process.exit(0);
|
|
2513
1742
|
});
|
|
2514
1743
|
program.command("menu-bar").description("Launch macOS menu bar companion (Electron tray app)").action(async () => {
|
|
2515
|
-
const path$
|
|
1744
|
+
const path$6 = await import("path");
|
|
2516
1745
|
const { spawn } = await import("child_process");
|
|
2517
|
-
const fs$
|
|
2518
|
-
const root = path$
|
|
2519
|
-
const altRoot = path$
|
|
2520
|
-
const macosDir = await fs$
|
|
2521
|
-
if (!macosDir || !await fs$
|
|
1746
|
+
const fs$6 = await import("fs-extra");
|
|
1747
|
+
const root = path$6.join(process.cwd(), "apps", "macos");
|
|
1748
|
+
const altRoot = path$6.join(__dirname, "..", "..", "apps", "macos");
|
|
1749
|
+
const macosDir = await fs$6.pathExists(root) ? root : await fs$6.pathExists(altRoot) ? altRoot : null;
|
|
1750
|
+
if (!macosDir || !await fs$6.pathExists(path$6.join(macosDir, "package.json"))) {
|
|
2522
1751
|
console.log(chalk.default.gray("\n macOS menu bar app not found."));
|
|
2523
1752
|
console.log(chalk.default.gray(" Run from HyperClaw repo root, or: cd apps/macos && npm start\n"));
|
|
2524
1753
|
process.exit(1);
|
|
@@ -2546,7 +1775,7 @@ program.command("update").description("Update HyperClaw").option("-c, --channel
|
|
|
2546
1775
|
process.exit(0);
|
|
2547
1776
|
});
|
|
2548
1777
|
program.command("doctor").description("Health check — surfaces misconfigs and risky DM policies").option("--fix", "Auto-repair fixable issues").action(async (opts) => {
|
|
2549
|
-
await runDoctor(opts.fix);
|
|
1778
|
+
await require_doctor.runDoctor(opts.fix);
|
|
2550
1779
|
process.exit(0);
|
|
2551
1780
|
});
|
|
2552
1781
|
const memCmd = program.command("memory").description("Agent memory management");
|
|
@@ -2592,12 +1821,12 @@ cfgCmd.command("set-key <KEY=value>").description("Set an API key or config valu
|
|
|
2592
1821
|
process.exit(0);
|
|
2593
1822
|
});
|
|
2594
1823
|
cfgCmd.command("set-service-key <serviceId> [apiKey]").description("Set API key for a service (hackerone, bugcrowd, synack, or custom). Prompts if apiKey omitted.").action(async (serviceId, apiKey) => {
|
|
2595
|
-
const inquirer$
|
|
1824
|
+
const inquirer$2 = (await import("inquirer")).default;
|
|
2596
1825
|
const config = new require_manager.ConfigManager();
|
|
2597
1826
|
const cfg = await config.load();
|
|
2598
1827
|
let key = apiKey;
|
|
2599
1828
|
if (!key || key.trim().length === 0) {
|
|
2600
|
-
const r = await inquirer$
|
|
1829
|
+
const r = await inquirer$2.prompt([{
|
|
2601
1830
|
type: "password",
|
|
2602
1831
|
name: "k",
|
|
2603
1832
|
message: `API key for ${serviceId}:`,
|
|
@@ -2628,7 +1857,7 @@ cfgCmd.command("set-service-key <serviceId> [apiKey]").description("Set API key
|
|
|
2628
1857
|
cfgCmd.command("schema").description("Show configuration schema").action(() => {
|
|
2629
1858
|
console.log(chalk.default.bold.hex("#06b6d4")("\n Config schema: ~/.hyperclaw/config.json\n"));
|
|
2630
1859
|
const schema = {
|
|
2631
|
-
version: "string (e.g. \"4.0.
|
|
1860
|
+
version: "string (e.g. \"4.0.2\")",
|
|
2632
1861
|
workspaceName: "string",
|
|
2633
1862
|
provider: {
|
|
2634
1863
|
providerId: "string",
|
|
@@ -2721,17 +1950,17 @@ program.command("deploy").description("Deploy gateway to cloud (Fly.io or Render
|
|
|
2721
1950
|
program.command("voice-call").description("Start voice call session — terminal mode, talks to gateway").option("-u, --gateway-url <url>", "Gateway URL", "http://localhost:18789").action(async (opts) => {
|
|
2722
1951
|
const axios = (await import("axios")).default;
|
|
2723
1952
|
const readline$2 = await import("readline");
|
|
2724
|
-
const chalk$
|
|
1953
|
+
const chalk$10 = require("chalk");
|
|
2725
1954
|
const url = opts.gatewayUrl || "http://localhost:18789";
|
|
2726
|
-
console.log(chalk$
|
|
2727
|
-
console.log(chalk$
|
|
2728
|
-
console.log(chalk$
|
|
1955
|
+
console.log(chalk$10.bold.cyan("\n 🎙️ HYPERCLAW VOICE CALL\n"));
|
|
1956
|
+
console.log(chalk$10.gray(` Gateway: ${url}`));
|
|
1957
|
+
console.log(chalk$10.gray(" Type a message and press Enter. Ctrl+C to exit.\n"));
|
|
2729
1958
|
const rl = readline$2.createInterface({
|
|
2730
1959
|
input: process.stdin,
|
|
2731
1960
|
output: process.stdout
|
|
2732
1961
|
});
|
|
2733
1962
|
const ask = () => {
|
|
2734
|
-
rl.question(chalk$
|
|
1963
|
+
rl.question(chalk$10.cyan(" You: "), async (input) => {
|
|
2735
1964
|
if (!input?.trim()) {
|
|
2736
1965
|
ask();
|
|
2737
1966
|
return;
|
|
@@ -2741,9 +1970,9 @@ program.command("voice-call").description("Start voice call session — terminal
|
|
|
2741
1970
|
message: input.trim(),
|
|
2742
1971
|
thinking: "none"
|
|
2743
1972
|
}, { timeout: 6e4 });
|
|
2744
|
-
console.log(chalk$
|
|
1973
|
+
console.log(chalk$10.green(` 🦅 Agent: ${(res.data?.response || "").slice(0, 500)}\n`));
|
|
2745
1974
|
} catch (e) {
|
|
2746
|
-
console.log(chalk$
|
|
1975
|
+
console.log(chalk$10.red(` Error: ${e.response?.data?.error || e.message}\n`));
|
|
2747
1976
|
}
|
|
2748
1977
|
ask();
|
|
2749
1978
|
});
|
|
@@ -2810,45 +2039,45 @@ themeCmd.command("preview").description("Preview all themes side-by-side").actio
|
|
|
2810
2039
|
});
|
|
2811
2040
|
const secretsCmd = program.command("secrets").description("External secrets management");
|
|
2812
2041
|
secretsCmd.command("audit").description("Audit all required secrets").option("--required-by <ids>", "Filter by skill/provider IDs (comma-separated)").action(async (opts) => {
|
|
2813
|
-
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-
|
|
2042
|
+
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-DgyF52mg.js"));
|
|
2814
2043
|
const filter = opts.requiredBy?.split(",");
|
|
2815
2044
|
await new SecretsManager().audit(filter);
|
|
2816
2045
|
process.exit(0);
|
|
2817
2046
|
});
|
|
2818
2047
|
secretsCmd.command("set <KEY=value>").description("Set a secret in .env file").action(async (kv) => {
|
|
2819
|
-
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-
|
|
2048
|
+
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-DgyF52mg.js"));
|
|
2820
2049
|
await new SecretsManager().set(kv);
|
|
2821
2050
|
process.exit(0);
|
|
2822
2051
|
});
|
|
2823
2052
|
secretsCmd.command("apply").description("Write secrets from .env to shell config (~/.bashrc, ~/.zshrc)").action(async () => {
|
|
2824
|
-
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-
|
|
2053
|
+
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-DgyF52mg.js"));
|
|
2825
2054
|
await new SecretsManager().apply();
|
|
2826
2055
|
process.exit(0);
|
|
2827
2056
|
});
|
|
2828
2057
|
secretsCmd.command("reload").description("Reload secrets into running gateway").action(async () => {
|
|
2829
|
-
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-
|
|
2058
|
+
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-DgyF52mg.js"));
|
|
2830
2059
|
await new SecretsManager().reload();
|
|
2831
2060
|
process.exit(0);
|
|
2832
2061
|
});
|
|
2833
2062
|
secretsCmd.command("remove <key>").description("Remove a secret from .env").action(async (key) => {
|
|
2834
|
-
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-
|
|
2063
|
+
const { SecretsManager } = await Promise.resolve().then(() => require("./manager-DgyF52mg.js"));
|
|
2835
2064
|
await new SecretsManager().remove(key);
|
|
2836
2065
|
process.exit(0);
|
|
2837
2066
|
});
|
|
2838
2067
|
secretsCmd.command("credentials").description("List provider credential files (credentials/*.json)").action(async () => {
|
|
2839
|
-
const { CredentialsStore } = await Promise.resolve().then(() => require("./credentials-store-
|
|
2068
|
+
const { CredentialsStore } = await Promise.resolve().then(() => require("./credentials-store-BvnMPJwi.js"));
|
|
2840
2069
|
await new CredentialsStore().showList();
|
|
2841
2070
|
process.exit(0);
|
|
2842
2071
|
});
|
|
2843
2072
|
const securityCmd = program.command("security").description("Security tools");
|
|
2844
2073
|
securityCmd.command("audit").description("Security audit — file permissions, DM policies, embedded secrets").option("--deep", "Full deep scan including token entropy and installed skill risks").action(async (opts) => {
|
|
2845
|
-
const { runSecurityAudit } = await Promise.resolve().then(() => require("./audit-
|
|
2074
|
+
const { runSecurityAudit } = await Promise.resolve().then(() => require("./audit-BYxPlnTQ.js"));
|
|
2846
2075
|
await runSecurityAudit(opts.deep);
|
|
2847
2076
|
process.exit(0);
|
|
2848
2077
|
});
|
|
2849
2078
|
const agentRunCmd = program.command("agent").description("Run agent with thinking control");
|
|
2850
2079
|
agentRunCmd.requiredOption("-m, --message <text>", "Message to send to the agent").option("--thinking <level>", "Thinking level: high|medium|low|none", "none").option("--model <model>", "Override model").option("--session <id>", "Session/thread ID").option("--multi-step", "Decompose into steps and run each (sequential)").option("--parallel", "Run sub-agents in parallel for independent subtasks").option("--verbose", "Show thinking blocks and request details").option("--workspace <dir>", "Override workspace directory").action(async (opts) => {
|
|
2851
|
-
const { runAgent } = await Promise.resolve().then(() => require("./src-
|
|
2080
|
+
const { runAgent } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
2852
2081
|
await runAgent({
|
|
2853
2082
|
message: opts.message,
|
|
2854
2083
|
thinking: opts.thinking,
|
|
@@ -2864,7 +2093,7 @@ agentRunCmd.requiredOption("-m, --message <text>", "Message to send to the agent
|
|
|
2864
2093
|
});
|
|
2865
2094
|
const threadsCmd = program.command("threads").description("ACP thread-bound agent sessions");
|
|
2866
2095
|
threadsCmd.command("list").description("List agent threads").option("--channel <id>", "Filter by channel").option("--active", "Show only active threads").action(async (opts) => {
|
|
2867
|
-
const { ACPThreadManager } = await Promise.resolve().then(() => require("./src-
|
|
2096
|
+
const { ACPThreadManager } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
2868
2097
|
const mgr = new ACPThreadManager();
|
|
2869
2098
|
const threads = await mgr.list({
|
|
2870
2099
|
channelId: opts.channel,
|
|
@@ -2874,33 +2103,33 @@ threadsCmd.command("list").description("List agent threads").option("--channel <
|
|
|
2874
2103
|
process.exit(0);
|
|
2875
2104
|
});
|
|
2876
2105
|
threadsCmd.command("terminate <id>").description("Terminate a thread").action(async (id) => {
|
|
2877
|
-
const { ACPThreadManager } = await Promise.resolve().then(() => require("./src-
|
|
2106
|
+
const { ACPThreadManager } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
2878
2107
|
await new ACPThreadManager().terminate(id);
|
|
2879
2108
|
console.log(require("chalk").green(`\n ✔ Thread terminated: ${id}\n`));
|
|
2880
2109
|
process.exit(0);
|
|
2881
2110
|
});
|
|
2882
2111
|
const canvasCmd = program.command("canvas").description("Live AI-driven UI canvas");
|
|
2883
2112
|
canvasCmd.command("show").description("Show current canvas components").action(async () => {
|
|
2884
|
-
const { CanvasRenderer } = await Promise.resolve().then(() => require("./renderer-
|
|
2113
|
+
const { CanvasRenderer } = await Promise.resolve().then(() => require("./renderer-pqlDRKbH.js"));
|
|
2885
2114
|
await new CanvasRenderer().show();
|
|
2886
2115
|
process.exit(0);
|
|
2887
2116
|
});
|
|
2888
2117
|
canvasCmd.command("add <type> <title>").description("Add a canvas component (type: chart|table|form|markdown|image|custom)").action(async (type, title) => {
|
|
2889
|
-
const { CanvasRenderer } = await Promise.resolve().then(() => require("./renderer-
|
|
2118
|
+
const { CanvasRenderer } = await Promise.resolve().then(() => require("./renderer-pqlDRKbH.js"));
|
|
2890
2119
|
await new CanvasRenderer().addComponent(type, title);
|
|
2891
2120
|
process.exit(0);
|
|
2892
2121
|
});
|
|
2893
2122
|
canvasCmd.command("clear").description("Clear all canvas components").action(async () => {
|
|
2894
|
-
const { CanvasRenderer } = await Promise.resolve().then(() => require("./renderer-
|
|
2123
|
+
const { CanvasRenderer } = await Promise.resolve().then(() => require("./renderer-pqlDRKbH.js"));
|
|
2895
2124
|
await new CanvasRenderer().clear();
|
|
2896
2125
|
process.exit(0);
|
|
2897
2126
|
});
|
|
2898
2127
|
canvasCmd.command("export").description("Export canvas as HTML file").action(async () => {
|
|
2899
|
-
const { CanvasRenderer } = await Promise.resolve().then(() => require("./renderer-
|
|
2900
|
-
const fs$
|
|
2128
|
+
const { CanvasRenderer } = await Promise.resolve().then(() => require("./renderer-pqlDRKbH.js"));
|
|
2129
|
+
const fs$6 = require("fs-extra");
|
|
2901
2130
|
const html = await new CanvasRenderer().exportHtml();
|
|
2902
2131
|
const outFile = require("path").join(require("os").homedir(), ".hyperclaw", "canvas", "export.html");
|
|
2903
|
-
await fs$
|
|
2132
|
+
await fs$6.writeFile(outFile, html);
|
|
2904
2133
|
console.log(require("chalk").green(`\n ✔ Canvas exported to ${outFile}\n`));
|
|
2905
2134
|
process.exit(0);
|
|
2906
2135
|
});
|
|
@@ -2917,167 +2146,167 @@ deliveryCmd.command("retry <id>").description("Retry a dead-lettered delivery it
|
|
|
2917
2146
|
});
|
|
2918
2147
|
const mcpCmd = program.command("mcp").description("MCP (Model Context Protocol) server management");
|
|
2919
2148
|
mcpCmd.command("list").action(async () => {
|
|
2920
|
-
const { mcpList } = await Promise.resolve().then(() => require("./mcp-
|
|
2149
|
+
const { mcpList } = await Promise.resolve().then(() => require("./mcp-B_9Ber63.js"));
|
|
2921
2150
|
await mcpList();
|
|
2922
2151
|
process.exit(0);
|
|
2923
2152
|
});
|
|
2924
2153
|
mcpCmd.command("add").action(async () => {
|
|
2925
|
-
const { mcpAdd } = await Promise.resolve().then(() => require("./mcp-
|
|
2154
|
+
const { mcpAdd } = await Promise.resolve().then(() => require("./mcp-B_9Ber63.js"));
|
|
2926
2155
|
await mcpAdd();
|
|
2927
2156
|
process.exit(0);
|
|
2928
2157
|
});
|
|
2929
2158
|
mcpCmd.command("remove <id>").action(async (id) => {
|
|
2930
|
-
const { mcpRemove } = await Promise.resolve().then(() => require("./mcp-
|
|
2159
|
+
const { mcpRemove } = await Promise.resolve().then(() => require("./mcp-B_9Ber63.js"));
|
|
2931
2160
|
await mcpRemove(id);
|
|
2932
2161
|
process.exit(0);
|
|
2933
2162
|
});
|
|
2934
2163
|
mcpCmd.command("probe [id]").action(async (id) => {
|
|
2935
|
-
const { mcpProbe } = await Promise.resolve().then(() => require("./mcp-
|
|
2164
|
+
const { mcpProbe } = await Promise.resolve().then(() => require("./mcp-B_9Ber63.js"));
|
|
2936
2165
|
await mcpProbe(id);
|
|
2937
2166
|
process.exit(0);
|
|
2938
2167
|
});
|
|
2939
2168
|
const nodeCmd = program.command("node").description("HyperClaw node management (local, remote, android)");
|
|
2940
2169
|
nodeCmd.command("list").action(async () => {
|
|
2941
|
-
const { nodeList } = await Promise.resolve().then(() => require("./node-
|
|
2170
|
+
const { nodeList } = await Promise.resolve().then(() => require("./node-pwL6O_KX.js"));
|
|
2942
2171
|
await nodeList();
|
|
2943
2172
|
process.exit(0);
|
|
2944
2173
|
});
|
|
2945
2174
|
nodeCmd.command("add").action(async () => {
|
|
2946
|
-
const { nodeAdd } = await Promise.resolve().then(() => require("./node-
|
|
2175
|
+
const { nodeAdd } = await Promise.resolve().then(() => require("./node-pwL6O_KX.js"));
|
|
2947
2176
|
await nodeAdd();
|
|
2948
2177
|
process.exit(0);
|
|
2949
2178
|
});
|
|
2950
2179
|
nodeCmd.command("probe [id]").action(async (id) => {
|
|
2951
|
-
const { nodeProbe } = await Promise.resolve().then(() => require("./node-
|
|
2180
|
+
const { nodeProbe } = await Promise.resolve().then(() => require("./node-pwL6O_KX.js"));
|
|
2952
2181
|
await nodeProbe(id);
|
|
2953
2182
|
process.exit(0);
|
|
2954
2183
|
});
|
|
2955
2184
|
nodeCmd.command("remove <id>").action(async (id) => {
|
|
2956
|
-
const { nodeRemove } = await Promise.resolve().then(() => require("./node-
|
|
2185
|
+
const { nodeRemove } = await Promise.resolve().then(() => require("./node-pwL6O_KX.js"));
|
|
2957
2186
|
await nodeRemove(id);
|
|
2958
2187
|
process.exit(0);
|
|
2959
2188
|
});
|
|
2960
2189
|
const arCmd = program.command("auto-reply").description("Auto-reply rule engine");
|
|
2961
2190
|
arCmd.command("list").action(async () => {
|
|
2962
|
-
const { AutoReplyEngine } = await Promise.resolve().then(() => require("./rules-
|
|
2191
|
+
const { AutoReplyEngine } = await Promise.resolve().then(() => require("./rules-BooT_qFP.js"));
|
|
2963
2192
|
const e = new AutoReplyEngine();
|
|
2964
2193
|
await e.load();
|
|
2965
2194
|
e.showList();
|
|
2966
2195
|
process.exit(0);
|
|
2967
2196
|
});
|
|
2968
2197
|
arCmd.command("toggle <id>").action(async (id) => {
|
|
2969
|
-
const { AutoReplyEngine } = await Promise.resolve().then(() => require("./rules-
|
|
2198
|
+
const { AutoReplyEngine } = await Promise.resolve().then(() => require("./rules-BooT_qFP.js"));
|
|
2970
2199
|
const e = new AutoReplyEngine();
|
|
2971
2200
|
await e.toggle(id);
|
|
2972
2201
|
process.exit(0);
|
|
2973
2202
|
});
|
|
2974
2203
|
arCmd.command("remove <id>").action(async (id) => {
|
|
2975
|
-
const { AutoReplyEngine } = await Promise.resolve().then(() => require("./rules-
|
|
2204
|
+
const { AutoReplyEngine } = await Promise.resolve().then(() => require("./rules-BooT_qFP.js"));
|
|
2976
2205
|
const e = new AutoReplyEngine();
|
|
2977
2206
|
await e.remove(id);
|
|
2978
2207
|
process.exit(0);
|
|
2979
2208
|
});
|
|
2980
2209
|
const gmailCmd = program.command("gmail").description("Gmail Pub/Sub real-time notifications");
|
|
2981
2210
|
gmailCmd.command("watch-setup").description("Register Gmail watch for push notifications. Requires: hyperclaw auth oauth google-gmail").requiredOption("-t, --topic <name>", "Pub/Sub topic (e.g. projects/myproject/topics/gmail-push)").option("-l, --labels <ids>", "Label IDs to watch (comma-separated)", "INBOX").action(async (opts) => {
|
|
2982
|
-
const chalk$
|
|
2211
|
+
const chalk$10 = require("chalk");
|
|
2983
2212
|
try {
|
|
2984
|
-
const { setupGmailWatch } = await Promise.resolve().then(() => require("./gmail-watch-setup-
|
|
2213
|
+
const { setupGmailWatch } = await Promise.resolve().then(() => require("./gmail-watch-setup-Czt8rXaX.js"));
|
|
2985
2214
|
const labelIds = opts.labels.split(",").map((s) => s.trim()).filter(Boolean);
|
|
2986
2215
|
const result = await setupGmailWatch({
|
|
2987
2216
|
topicName: opts.topic,
|
|
2988
2217
|
labelIds
|
|
2989
2218
|
});
|
|
2990
|
-
console.log(chalk$
|
|
2991
|
-
console.log(chalk$
|
|
2992
|
-
console.log(chalk$
|
|
2993
|
-
console.log(chalk$
|
|
2994
|
-
console.log(chalk$
|
|
2219
|
+
console.log(chalk$10.hex("#06b6d4")("\n ✔ Gmail watch registered"));
|
|
2220
|
+
console.log(chalk$10.gray(` historyId: ${result.historyId}`));
|
|
2221
|
+
console.log(chalk$10.gray(` expiration: ${new Date(parseInt(result.expiration, 10)).toISOString()}`));
|
|
2222
|
+
console.log(chalk$10.gray("\n Push endpoint: https://<your-server>/webhook/gmail-pubsub"));
|
|
2223
|
+
console.log(chalk$10.gray(" Ensure email channel is enabled and gateway is publicly accessible.\n"));
|
|
2995
2224
|
} catch (e) {
|
|
2996
|
-
console.error(chalk$
|
|
2225
|
+
console.error(chalk$10.red("\n ✖ " + e.message + "\n"));
|
|
2997
2226
|
process.exit(1);
|
|
2998
2227
|
}
|
|
2999
2228
|
process.exit(0);
|
|
3000
2229
|
});
|
|
3001
2230
|
const cronCmd = program.command("cron").description("Scheduled tasks (cron → agent prompt)");
|
|
3002
2231
|
cronCmd.command("list").action(async () => {
|
|
3003
|
-
const chalk$
|
|
3004
|
-
const { loadCronTasks } = await Promise.resolve().then(() => require("./cron-tasks-
|
|
2232
|
+
const chalk$10 = require("chalk");
|
|
2233
|
+
const { loadCronTasks } = await Promise.resolve().then(() => require("./cron-tasks-BvDFNyiE.js"));
|
|
3005
2234
|
const tasks = await loadCronTasks();
|
|
3006
|
-
console.log(chalk$
|
|
2235
|
+
console.log(chalk$10.bold.cyan("\n ⏰ CRON TASKS\n"));
|
|
3007
2236
|
if (tasks.length === 0) {
|
|
3008
|
-
console.log(chalk$
|
|
2237
|
+
console.log(chalk$10.gray(" No tasks. Add: hyperclaw cron add \"0 9 * * 1-5\" \"Check calendar\"\n"));
|
|
3009
2238
|
process.exit(0);
|
|
3010
2239
|
return;
|
|
3011
2240
|
}
|
|
3012
2241
|
for (const t of tasks) {
|
|
3013
|
-
const dot = t.enabled ? chalk$
|
|
3014
|
-
console.log(` ${dot} ${chalk$
|
|
3015
|
-
console.log(` ${chalk$
|
|
3016
|
-
console.log(` ${chalk$
|
|
3017
|
-
if (t.lastRunAt) console.log(` ${chalk$
|
|
2242
|
+
const dot = t.enabled ? chalk$10.green("●") : chalk$10.gray("○");
|
|
2243
|
+
console.log(` ${dot} ${chalk$10.white(t.name || t.id)}`);
|
|
2244
|
+
console.log(` ${chalk$10.gray("Schedule:")} ${t.schedule}`);
|
|
2245
|
+
console.log(` ${chalk$10.gray("Prompt:")} ${t.prompt.slice(0, 60)}${t.prompt.length > 60 ? "..." : ""}`);
|
|
2246
|
+
if (t.lastRunAt) console.log(` ${chalk$10.gray("Last run:")} ${t.lastRunAt}`);
|
|
3018
2247
|
console.log();
|
|
3019
2248
|
}
|
|
3020
2249
|
process.exit(0);
|
|
3021
2250
|
});
|
|
3022
2251
|
cronCmd.command("add").arguments("<schedule> <prompt>").option("-n, --name <name>", "Task name").action(async (schedule, prompt, opts) => {
|
|
3023
|
-
const chalk$
|
|
3024
|
-
const { loadCronTasks, addCronTask, saveCronTasks } = await Promise.resolve().then(() => require("./cron-tasks-
|
|
2252
|
+
const chalk$10 = require("chalk");
|
|
2253
|
+
const { loadCronTasks, addCronTask, saveCronTasks } = await Promise.resolve().then(() => require("./cron-tasks-BvDFNyiE.js"));
|
|
3025
2254
|
await loadCronTasks();
|
|
3026
2255
|
addCronTask(schedule, prompt, opts.name);
|
|
3027
2256
|
await saveCronTasks();
|
|
3028
|
-
console.log(chalk$
|
|
3029
|
-
console.log(chalk$
|
|
2257
|
+
console.log(chalk$10.green(`\n ✔ Cron task added: ${schedule} → "${prompt.slice(0, 40)}..."\n`));
|
|
2258
|
+
console.log(chalk$10.gray(" Restart gateway to apply.\n"));
|
|
3030
2259
|
process.exit(0);
|
|
3031
2260
|
});
|
|
3032
2261
|
cronCmd.command("remove <id>").action(async (id) => {
|
|
3033
|
-
const chalk$
|
|
3034
|
-
const { loadCronTasks, removeCronTask, saveCronTasks } = await Promise.resolve().then(() => require("./cron-tasks-
|
|
2262
|
+
const chalk$10 = require("chalk");
|
|
2263
|
+
const { loadCronTasks, removeCronTask, saveCronTasks } = await Promise.resolve().then(() => require("./cron-tasks-BvDFNyiE.js"));
|
|
3035
2264
|
await loadCronTasks();
|
|
3036
2265
|
if (removeCronTask(id)) {
|
|
3037
2266
|
await saveCronTasks();
|
|
3038
|
-
console.log(chalk$
|
|
3039
|
-
} else console.log(chalk$
|
|
2267
|
+
console.log(chalk$10.green(`\n ✔ Task removed\n`));
|
|
2268
|
+
} else console.log(chalk$10.red(`\n ✖ Task not found: ${id}\n`));
|
|
3040
2269
|
process.exit(0);
|
|
3041
2270
|
});
|
|
3042
2271
|
program.command("nodes").description("List connected mobile nodes (iOS/Android Connect tab)").action(async () => {
|
|
3043
|
-
const chalk$
|
|
3044
|
-
const http
|
|
3045
|
-
const fs$
|
|
3046
|
-
const path$
|
|
3047
|
-
const os$
|
|
2272
|
+
const chalk$10 = require("chalk");
|
|
2273
|
+
const http = await import("http");
|
|
2274
|
+
const fs$6 = await import("fs-extra");
|
|
2275
|
+
const path$6 = await import("path");
|
|
2276
|
+
const os$7 = await import("os");
|
|
3048
2277
|
let port = 18789;
|
|
3049
2278
|
try {
|
|
3050
|
-
const cfg = await fs$
|
|
2279
|
+
const cfg = await fs$6.readJson(path$6.join(os$7.homedir(), ".hyperclaw", "hyperclaw.json"));
|
|
3051
2280
|
port = cfg?.gateway?.port ?? 18789;
|
|
3052
2281
|
} catch {}
|
|
3053
2282
|
return new Promise((resolve, reject) => {
|
|
3054
|
-
const req = http
|
|
2283
|
+
const req = http.get(`http://127.0.0.1:${port}/api/nodes`, (res) => {
|
|
3055
2284
|
let data = "";
|
|
3056
2285
|
res.on("data", (c) => data += c);
|
|
3057
2286
|
res.on("end", () => {
|
|
3058
2287
|
try {
|
|
3059
2288
|
const j = JSON.parse(data);
|
|
3060
2289
|
const nodes = j.nodes || [];
|
|
3061
|
-
console.log(chalk$
|
|
2290
|
+
console.log(chalk$10.bold.cyan("\n 📱 CONNECTED NODES\n"));
|
|
3062
2291
|
if (nodes.length === 0) {
|
|
3063
|
-
console.log(chalk$
|
|
3064
|
-
console.log(chalk$
|
|
2292
|
+
console.log(chalk$10.gray(" No mobile nodes. Open iOS/Android app → Connect tab → pair with gateway."));
|
|
2293
|
+
console.log(chalk$10.gray(` Gateway: ws://localhost:${port}\n`));
|
|
3065
2294
|
} else {
|
|
3066
2295
|
for (const n of nodes) {
|
|
3067
|
-
console.log(` ${chalk$
|
|
3068
|
-
console.log(` ${chalk$
|
|
3069
|
-
console.log(` ${chalk$
|
|
2296
|
+
console.log(` ${chalk$10.green("●")} ${n.nodeId} ${chalk$10.gray(`(${n.platform || "?"})`)}`);
|
|
2297
|
+
console.log(` ${chalk$10.gray("Device:")} ${n.deviceName || "—"}`);
|
|
2298
|
+
console.log(` ${chalk$10.gray("Capabilities:")} ${Object.entries(n.capabilities || {}).filter(([, v]) => v).map(([k]) => k).join(", ") || "—"}`);
|
|
3070
2299
|
}
|
|
3071
2300
|
console.log();
|
|
3072
2301
|
}
|
|
3073
2302
|
} catch {
|
|
3074
|
-
console.log(chalk$
|
|
2303
|
+
console.log(chalk$10.red(" Could not reach gateway. Start with: hyperclaw daemon start\n"));
|
|
3075
2304
|
}
|
|
3076
2305
|
resolve();
|
|
3077
2306
|
});
|
|
3078
2307
|
});
|
|
3079
2308
|
req.on("error", () => {
|
|
3080
|
-
console.log(chalk$
|
|
2309
|
+
console.log(chalk$10.red(" Gateway offline. Start with: hyperclaw daemon start\n"));
|
|
3081
2310
|
resolve();
|
|
3082
2311
|
});
|
|
3083
2312
|
req.setTimeout(3e3, () => {
|
|
@@ -3088,20 +2317,20 @@ program.command("nodes").description("List connected mobile nodes (iOS/Android C
|
|
|
3088
2317
|
});
|
|
3089
2318
|
const whCmd = program.command("webhooks").description("Webhook endpoint management");
|
|
3090
2319
|
whCmd.command("list").action(async () => {
|
|
3091
|
-
const { WebhookManager } = await Promise.resolve().then(() => require("./manager-
|
|
2320
|
+
const { WebhookManager } = await Promise.resolve().then(() => require("./manager-DSGhn5i3.js"));
|
|
3092
2321
|
const m = new WebhookManager();
|
|
3093
2322
|
await m.load();
|
|
3094
2323
|
m.showList();
|
|
3095
2324
|
process.exit(0);
|
|
3096
2325
|
});
|
|
3097
2326
|
whCmd.command("remove <id>").action(async (id) => {
|
|
3098
|
-
const { WebhookManager } = await Promise.resolve().then(() => require("./manager-
|
|
2327
|
+
const { WebhookManager } = await Promise.resolve().then(() => require("./manager-DSGhn5i3.js"));
|
|
3099
2328
|
const m = new WebhookManager();
|
|
3100
2329
|
await m.remove(id);
|
|
3101
2330
|
process.exit(0);
|
|
3102
2331
|
});
|
|
3103
2332
|
whCmd.command("toggle <id>").action(async (id) => {
|
|
3104
|
-
const { WebhookManager } = await Promise.resolve().then(() => require("./manager-
|
|
2333
|
+
const { WebhookManager } = await Promise.resolve().then(() => require("./manager-DSGhn5i3.js"));
|
|
3105
2334
|
const m = new WebhookManager();
|
|
3106
2335
|
await m.toggle(id);
|
|
3107
2336
|
process.exit(0);
|
|
@@ -3110,7 +2339,7 @@ const logsCmd = program.command("logs").description("View gateway logs");
|
|
|
3110
2339
|
logsCmd.option("-n, --lines <n>", "Number of lines to show", "50");
|
|
3111
2340
|
logsCmd.option("-f, --follow", "Stream logs in real time");
|
|
3112
2341
|
logsCmd.action(async (opts) => {
|
|
3113
|
-
const { tailLog, streamLog } = await Promise.resolve().then(() => require("./logger-
|
|
2342
|
+
const { tailLog, streamLog } = await Promise.resolve().then(() => require("./logger-8tEtAd3y.js"));
|
|
3114
2343
|
if (opts.follow) await streamLog();
|
|
3115
2344
|
else {
|
|
3116
2345
|
await tailLog(parseInt(opts.lines));
|
|
@@ -3118,7 +2347,7 @@ logsCmd.action(async (opts) => {
|
|
|
3118
2347
|
}
|
|
3119
2348
|
});
|
|
3120
2349
|
program.command("gateway:serve").description("Start the gateway server in the foreground (used by daemon)").action(async () => {
|
|
3121
|
-
const { startGateway } = await Promise.resolve().then(() => require("./server-
|
|
2350
|
+
const { startGateway } = await Promise.resolve().then(() => require("./server-DU9POoWc.js"));
|
|
3122
2351
|
await startGateway();
|
|
3123
2352
|
process.on("SIGINT", () => process.exit(0));
|
|
3124
2353
|
process.on("SIGTERM", () => process.exit(0));
|
|
@@ -3126,15 +2355,15 @@ program.command("gateway:serve").description("Start the gateway server in the fo
|
|
|
3126
2355
|
});
|
|
3127
2356
|
const gatewayCfgCmd = gatewayCmd.command("config").description("Configure gateway settings");
|
|
3128
2357
|
gatewayCfgCmd.option("--set-token <token>", "Set gateway auth token").option("--regenerate-token", "Generate a new random token").option("--set-port <port>", "Set gateway port").option("--set-bind <addr>", "Set gateway bind address").action(async (opts) => {
|
|
3129
|
-
const chalk$
|
|
3130
|
-
const fs$
|
|
3131
|
-
const path$
|
|
3132
|
-
const os$
|
|
2358
|
+
const chalk$10 = require("chalk");
|
|
2359
|
+
const fs$6 = require("fs-extra");
|
|
2360
|
+
const path$6 = require("path");
|
|
2361
|
+
const os$7 = require("os");
|
|
3133
2362
|
const crypto = require("crypto");
|
|
3134
|
-
const cfgFile = path$
|
|
2363
|
+
const cfgFile = path$6.join(os$7.homedir(), ".hyperclaw", "hyperclaw.json");
|
|
3135
2364
|
let cfg = {};
|
|
3136
2365
|
try {
|
|
3137
|
-
cfg = await fs$
|
|
2366
|
+
cfg = await fs$6.readJson(cfgFile);
|
|
3138
2367
|
} catch {}
|
|
3139
2368
|
if (!cfg.gateway) cfg.gateway = {
|
|
3140
2369
|
port: 18789,
|
|
@@ -3146,52 +2375,52 @@ gatewayCfgCmd.option("--set-token <token>", "Set gateway auth token").option("--
|
|
|
3146
2375
|
};
|
|
3147
2376
|
if (opts.regenerateToken) {
|
|
3148
2377
|
cfg.gateway.authToken = crypto.randomBytes(32).toString("hex");
|
|
3149
|
-
console.log(chalk$
|
|
3150
|
-
console.log(chalk$
|
|
2378
|
+
console.log(chalk$10.hex("#06b6d4")("\n ✔ New gateway token generated"));
|
|
2379
|
+
console.log(chalk$10.gray(` Token: ${cfg.gateway.authToken}`));
|
|
3151
2380
|
}
|
|
3152
2381
|
if (opts.setToken) {
|
|
3153
2382
|
cfg.gateway.authToken = opts.setToken;
|
|
3154
|
-
console.log(chalk$
|
|
2383
|
+
console.log(chalk$10.hex("#06b6d4")(`\n ✔ Gateway token set`));
|
|
3155
2384
|
}
|
|
3156
2385
|
if (opts.setPort) {
|
|
3157
2386
|
cfg.gateway.port = parseInt(opts.setPort);
|
|
3158
|
-
console.log(chalk$
|
|
2387
|
+
console.log(chalk$10.hex("#06b6d4")(`\n ✔ Port set to ${cfg.gateway.port}`));
|
|
3159
2388
|
}
|
|
3160
2389
|
if (opts.setBind) {
|
|
3161
2390
|
cfg.gateway.bind = opts.setBind;
|
|
3162
|
-
console.log(chalk$
|
|
2391
|
+
console.log(chalk$10.hex("#06b6d4")(`\n ✔ Bind set to ${cfg.gateway.bind}`));
|
|
3163
2392
|
}
|
|
3164
|
-
await fs$
|
|
3165
|
-
await fs$
|
|
3166
|
-
await fs$
|
|
3167
|
-
console.log(chalk$
|
|
2393
|
+
await fs$6.ensureDir(path$6.dirname(cfgFile));
|
|
2394
|
+
await fs$6.writeJson(cfgFile, cfg, { spaces: 2 });
|
|
2395
|
+
await fs$6.chmod(cfgFile, 384);
|
|
2396
|
+
console.log(chalk$10.gray(` Saved to ${cfgFile}\n`));
|
|
3168
2397
|
process.exit(0);
|
|
3169
2398
|
});
|
|
3170
2399
|
const authCmd = program.command("auth").description("OAuth and provider credentials");
|
|
3171
2400
|
authCmd.command("add <service_id>").description("Add API key for a service (any provider we do not ship). Stored in credentials/ and .env.").option("--key <api_key>", "API key (prompts if omitted)").option("--base-url <url>", "Base URL (optional, e.g. https://api.example.com)").option("--env-var <name>", "Env var name (default: <SERVICE_ID>_API_KEY)").action(async (serviceId, opts) => {
|
|
3172
|
-
const chalk$
|
|
3173
|
-
const inquirer$
|
|
3174
|
-
const { CredentialsStore } = await Promise.resolve().then(() => require("./credentials-store-
|
|
3175
|
-
const { getHyperClawDir
|
|
3176
|
-
const { getApiKeyGuide, GENERIC_API_KEY_STEPS } = await Promise.resolve().then(() => require("./api-keys-guide-
|
|
3177
|
-
const fs$
|
|
3178
|
-
const path$
|
|
2401
|
+
const chalk$10 = require("chalk");
|
|
2402
|
+
const inquirer$2 = require("inquirer");
|
|
2403
|
+
const { CredentialsStore } = await Promise.resolve().then(() => require("./credentials-store-BvnMPJwi.js"));
|
|
2404
|
+
const { getHyperClawDir, getEnvFilePath } = await Promise.resolve().then(() => require("./paths-D-QecARF.js"));
|
|
2405
|
+
const { getApiKeyGuide, GENERIC_API_KEY_STEPS } = await Promise.resolve().then(() => require("./api-keys-guide-Dq5Obbp4.js"));
|
|
2406
|
+
const fs$6 = await import("fs-extra");
|
|
2407
|
+
const path$6 = await import("path");
|
|
3179
2408
|
const guide = getApiKeyGuide(serviceId);
|
|
3180
2409
|
const steps = guide?.setupSteps ?? GENERIC_API_KEY_STEPS;
|
|
3181
|
-
console.log(chalk$
|
|
3182
|
-
console.log(chalk$
|
|
3183
|
-
for (const step of steps) if (step.startsWith(" 🔗")) console.log(chalk$
|
|
3184
|
-
else if (step.startsWith(" 💡")) console.log(chalk$
|
|
3185
|
-
else console.log(chalk$
|
|
2410
|
+
console.log(chalk$10.bold.hex("#06b6d4")(`\n 🔑 Add API key: ${guide?.name ?? serviceId}\n`));
|
|
2411
|
+
console.log(chalk$10.bold(" Steps:\n"));
|
|
2412
|
+
for (const step of steps) if (step.startsWith(" 🔗")) console.log(chalk$10.hex("#06b6d4")(step));
|
|
2413
|
+
else if (step.startsWith(" 💡")) console.log(chalk$10.gray(step));
|
|
2414
|
+
else console.log(chalk$10.gray(` ${step}`));
|
|
3186
2415
|
console.log();
|
|
3187
2416
|
const safeId = serviceId.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase();
|
|
3188
2417
|
if (!safeId) {
|
|
3189
|
-
console.log(chalk$
|
|
2418
|
+
console.log(chalk$10.red("\n ✖ Invalid service ID\n"));
|
|
3190
2419
|
process.exit(1);
|
|
3191
2420
|
}
|
|
3192
2421
|
let apiKey = opts.key || process.env[`${safeId.toUpperCase().replace(/-/g, "_")}_API_KEY`];
|
|
3193
2422
|
if (!apiKey) {
|
|
3194
|
-
const { key } = await inquirer$
|
|
2423
|
+
const { key } = await inquirer$2.prompt([{
|
|
3195
2424
|
type: "password",
|
|
3196
2425
|
name: "key",
|
|
3197
2426
|
message: `API key for ${serviceId}:`,
|
|
@@ -3200,7 +2429,7 @@ authCmd.command("add <service_id>").description("Add API key for a service (any
|
|
|
3200
2429
|
}]);
|
|
3201
2430
|
apiKey = key.trim();
|
|
3202
2431
|
}
|
|
3203
|
-
const creds = new CredentialsStore(getHyperClawDir
|
|
2432
|
+
const creds = new CredentialsStore(getHyperClawDir());
|
|
3204
2433
|
await creds.set(safeId, {
|
|
3205
2434
|
apiKey,
|
|
3206
2435
|
...opts.baseUrl ? { baseUrl: opts.baseUrl } : {},
|
|
@@ -3208,52 +2437,52 @@ authCmd.command("add <service_id>").description("Add API key for a service (any
|
|
|
3208
2437
|
});
|
|
3209
2438
|
const envVar = opts.envVar || `${safeId.toUpperCase().replace(/-/g, "_")}_API_KEY`;
|
|
3210
2439
|
const envPath = getEnvFilePath();
|
|
3211
|
-
await fs$
|
|
2440
|
+
await fs$6.ensureDir(path$6.dirname(envPath));
|
|
3212
2441
|
let envContent = "";
|
|
3213
|
-
if (await fs$
|
|
2442
|
+
if (await fs$6.pathExists(envPath)) envContent = await fs$6.readFile(envPath, "utf8");
|
|
3214
2443
|
const envLine = `${envVar}=${apiKey}`;
|
|
3215
2444
|
const re = new RegExp(`^${envVar}=.*$`, "m");
|
|
3216
2445
|
if (re.test(envContent)) envContent = envContent.replace(re, envLine);
|
|
3217
2446
|
else envContent = envContent.trimEnd() + (envContent ? "\n" : "") + envLine + "\n";
|
|
3218
|
-
await fs$
|
|
3219
|
-
console.log(chalk$
|
|
3220
|
-
console.log(chalk$
|
|
3221
|
-
console.log(chalk$
|
|
3222
|
-
console.log(chalk$
|
|
3223
|
-
console.log(chalk$
|
|
2447
|
+
await fs$6.writeFile(envPath, envContent, { mode: 384 });
|
|
2448
|
+
console.log(chalk$10.hex("#06b6d4")(`\n ✔ Added: ${safeId}`));
|
|
2449
|
+
console.log(chalk$10.gray(` Credentials: ~/.hyperclaw/credentials/${safeId}.json`));
|
|
2450
|
+
console.log(chalk$10.gray(` Env: ${envVar} (in .env — use in skills via process.env.${envVar.replace(/-/g, "_")})`));
|
|
2451
|
+
console.log(chalk$10.gray("\n Run: hyperclaw secrets apply to add to shell"));
|
|
2452
|
+
console.log(chalk$10.gray(" Run: hyperclaw secrets reload to inject into running gateway\n"));
|
|
3224
2453
|
process.exit(0);
|
|
3225
2454
|
});
|
|
3226
2455
|
authCmd.command("remove <service_id>").description("Remove API key for a service from credentials and .env").action(async (serviceId) => {
|
|
3227
|
-
const chalk$
|
|
3228
|
-
const { CredentialsStore } = await Promise.resolve().then(() => require("./credentials-store-
|
|
3229
|
-
const { getHyperClawDir
|
|
3230
|
-
const fs$
|
|
2456
|
+
const chalk$10 = require("chalk");
|
|
2457
|
+
const { CredentialsStore } = await Promise.resolve().then(() => require("./credentials-store-BvnMPJwi.js"));
|
|
2458
|
+
const { getHyperClawDir, getEnvFilePath } = await Promise.resolve().then(() => require("./paths-D-QecARF.js"));
|
|
2459
|
+
const fs$6 = await import("fs-extra");
|
|
3231
2460
|
const safeId = serviceId.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase();
|
|
3232
|
-
const creds = new CredentialsStore(getHyperClawDir
|
|
2461
|
+
const creds = new CredentialsStore(getHyperClawDir());
|
|
3233
2462
|
await creds.remove(safeId);
|
|
3234
2463
|
const envVar = `${safeId.toUpperCase().replace(/-/g, "_")}_API_KEY`;
|
|
3235
2464
|
const envPath = getEnvFilePath();
|
|
3236
|
-
if (await fs$
|
|
3237
|
-
let c = await fs$
|
|
2465
|
+
if (await fs$6.pathExists(envPath)) {
|
|
2466
|
+
let c = await fs$6.readFile(envPath, "utf8");
|
|
3238
2467
|
c = c.replace(new RegExp(`^${envVar}=.*\n?`, "gm"), "");
|
|
3239
|
-
await fs$
|
|
2468
|
+
await fs$6.writeFile(envPath, c);
|
|
3240
2469
|
}
|
|
3241
|
-
console.log(chalk$
|
|
2470
|
+
console.log(chalk$10.hex("#06b6d4")(`\n ✔ Removed: ${safeId}\n`));
|
|
3242
2471
|
process.exit(0);
|
|
3243
2472
|
});
|
|
3244
2473
|
authCmd.command("oauth <provider>").description("Run full OAuth flow. Providers: google, google-gmail (Gmail Pub/Sub), microsoft").option("--client-id <id>", "OAuth client ID (or GOOGLE_OAUTH_CLIENT_ID)").option("--client-secret <secret>", "OAuth client secret (optional for PKCE)").action(async (provider, opts) => {
|
|
3245
|
-
const chalk$
|
|
3246
|
-
const ora$
|
|
2474
|
+
const chalk$10 = require("chalk");
|
|
2475
|
+
const ora$4 = (await import("ora")).default;
|
|
3247
2476
|
try {
|
|
3248
|
-
const { runOAuthFlow } = await Promise.resolve().then(() => require("./oauth-flow-
|
|
3249
|
-
const spinner = ora$
|
|
2477
|
+
const { runOAuthFlow } = await Promise.resolve().then(() => require("./oauth-flow-CpWlgvNB.js"));
|
|
2478
|
+
const spinner = ora$4("Starting OAuth flow...").start();
|
|
3250
2479
|
spinner.text = "Opening browser — complete the consent and return here.";
|
|
3251
2480
|
const tokens = await runOAuthFlow(provider, {
|
|
3252
2481
|
clientId: opts.clientId,
|
|
3253
2482
|
clientSecret: opts.clientSecret
|
|
3254
2483
|
});
|
|
3255
2484
|
spinner.stop();
|
|
3256
|
-
const { writeOAuthToken } = await Promise.resolve().then(() => require("./oauth-provider-
|
|
2485
|
+
const { writeOAuthToken } = await Promise.resolve().then(() => require("./oauth-provider-BZb6qOw5.js"));
|
|
3257
2486
|
const now = Math.floor(Date.now() / 1e3);
|
|
3258
2487
|
const expires_at = tokens.expires_in ? now + tokens.expires_in : void 0;
|
|
3259
2488
|
const tokenUrl = provider === "google" || provider === "google-gmail" ? "https://oauth2.googleapis.com/token" : provider === "microsoft" ? "https://login.microsoftonline.com/common/oauth2/v2.0/token" : void 0;
|
|
@@ -3263,46 +2492,46 @@ authCmd.command("oauth <provider>").description("Run full OAuth flow. Providers:
|
|
|
3263
2492
|
expires_at,
|
|
3264
2493
|
token_url: tokenUrl
|
|
3265
2494
|
});
|
|
3266
|
-
console.log(chalk$
|
|
3267
|
-
console.log(chalk$
|
|
2495
|
+
console.log(chalk$10.hex("#06b6d4")(`\n ✔ OAuth tokens saved for: ${provider}`));
|
|
2496
|
+
console.log(chalk$10.gray(" Set in hyperclaw.json: \"provider\": { \"authType\": \"oauth\", \"providerId\": \"" + provider + "\" }\n"));
|
|
3268
2497
|
} catch (e) {
|
|
3269
|
-
console.error(chalk$
|
|
2498
|
+
console.error(chalk$10.red("\n ✖ OAuth failed: " + e.message + "\n"));
|
|
3270
2499
|
process.exit(1);
|
|
3271
2500
|
}
|
|
3272
2501
|
process.exit(0);
|
|
3273
2502
|
});
|
|
3274
2503
|
authCmd.command("setup-token <provider>").description("Save setup token (Anthropic Claude Pro/Max). Run: claude setup-token, paste result here.").action(async (provider) => {
|
|
3275
|
-
const chalk$
|
|
3276
|
-
const inquirer$
|
|
2504
|
+
const chalk$10 = require("chalk");
|
|
2505
|
+
const inquirer$2 = await import("inquirer");
|
|
3277
2506
|
if (provider !== "anthropic") {
|
|
3278
|
-
console.log(chalk$
|
|
2507
|
+
console.log(chalk$10.yellow(`\n Provider "${provider}" may not support setup-token. Use "hyperclaw auth add" for API keys.\n`));
|
|
3279
2508
|
process.exit(1);
|
|
3280
2509
|
}
|
|
3281
|
-
const { token } = await inquirer$
|
|
2510
|
+
const { token } = await inquirer$2.default.prompt([{
|
|
3282
2511
|
type: "password",
|
|
3283
2512
|
name: "token",
|
|
3284
2513
|
message: "Paste setup token from `claude setup-token`:",
|
|
3285
2514
|
mask: "●"
|
|
3286
2515
|
}]);
|
|
3287
2516
|
if (!token?.trim()) {
|
|
3288
|
-
console.log(chalk$
|
|
2517
|
+
console.log(chalk$10.red("\n ✖ No token provided.\n"));
|
|
3289
2518
|
process.exit(1);
|
|
3290
2519
|
}
|
|
3291
|
-
const { writeOAuthToken } = await Promise.resolve().then(() => require("./oauth-provider-
|
|
2520
|
+
const { writeOAuthToken } = await Promise.resolve().then(() => require("./oauth-provider-BZb6qOw5.js"));
|
|
3292
2521
|
await writeOAuthToken("anthropic-setup", {
|
|
3293
2522
|
access_token: token.trim(),
|
|
3294
2523
|
token_url: "https://api.anthropic.com"
|
|
3295
2524
|
});
|
|
3296
|
-
console.log(chalk$
|
|
3297
|
-
console.log(chalk$
|
|
2525
|
+
console.log(chalk$10.hex("#06b6d4")("\n ✔ Anthropic setup token saved to ~/.hyperclaw/oauth-anthropic-setup.json"));
|
|
2526
|
+
console.log(chalk$10.gray(" Use providerId: anthropic with authType: oauth and oauthTokenPath for Claude Pro/Max.\n"));
|
|
3298
2527
|
process.exit(0);
|
|
3299
2528
|
});
|
|
3300
2529
|
authCmd.command("oauth-set <provider>").description("Save OAuth tokens manually (access_token, refresh_token, etc.) to ~/.hyperclaw/oauth-<provider>.json").option("--token <access_token>", "Access token").option("--refresh <refresh_token>", "Refresh token (optional)").option("--expires-in <seconds>", "Token lifetime in seconds (optional)").option("--token-url <url>", "Refresh endpoint URL (optional)").action(async (provider, opts) => {
|
|
3301
|
-
const chalk$
|
|
3302
|
-
const { writeOAuthToken } = await Promise.resolve().then(() => require("./oauth-provider-
|
|
2530
|
+
const chalk$10 = require("chalk");
|
|
2531
|
+
const { writeOAuthToken } = await Promise.resolve().then(() => require("./oauth-provider-BZb6qOw5.js"));
|
|
3303
2532
|
const access_token = opts.token || process.env.OAUTH_ACCESS_TOKEN;
|
|
3304
2533
|
if (!access_token) {
|
|
3305
|
-
console.log(chalk$
|
|
2534
|
+
console.log(chalk$10.red("\n ✖ Provide --token <access_token> or set OAUTH_ACCESS_TOKEN\n"));
|
|
3306
2535
|
process.exit(1);
|
|
3307
2536
|
}
|
|
3308
2537
|
const expires_at = opts.expiresIn ? Math.floor(Date.now() / 1e3) + parseInt(opts.expiresIn, 10) : void 0;
|
|
@@ -3312,22 +2541,22 @@ authCmd.command("oauth-set <provider>").description("Save OAuth tokens manually
|
|
|
3312
2541
|
expires_at,
|
|
3313
2542
|
token_url: opts.tokenUrl || void 0
|
|
3314
2543
|
});
|
|
3315
|
-
console.log(chalk$
|
|
3316
|
-
console.log(chalk$
|
|
2544
|
+
console.log(chalk$10.hex("#06b6d4")(`\n ✔ OAuth tokens saved for provider: ${provider}`));
|
|
2545
|
+
console.log(chalk$10.gray(" Set in hyperclaw.json: \"provider\": { \"authType\": \"oauth\", \"providerId\": \"" + provider + "\" }\n"));
|
|
3317
2546
|
process.exit(0);
|
|
3318
2547
|
});
|
|
3319
2548
|
const workspaceCmd = program.command("workspace").description("Manage agent workspace files");
|
|
3320
2549
|
workspaceCmd.command("init [dir]").description("Initialize workspace files (SOUL.md, USER.md, TOOLS.md, HEARTBEAT.md, BOOTSTRAP.md) in a directory").action(async (dir) => {
|
|
3321
|
-
const chalk$
|
|
3322
|
-
const fs$
|
|
3323
|
-
const path$
|
|
3324
|
-
const os$
|
|
3325
|
-
const targetDir = dir || path$
|
|
2550
|
+
const chalk$10 = require("chalk");
|
|
2551
|
+
const fs$6 = require("fs-extra");
|
|
2552
|
+
const path$6 = require("path");
|
|
2553
|
+
const os$7 = require("os");
|
|
2554
|
+
const targetDir = dir || path$6.join(os$7.homedir(), ".hyperclaw");
|
|
3326
2555
|
let cfg = {};
|
|
3327
2556
|
try {
|
|
3328
|
-
cfg = await fs$
|
|
2557
|
+
cfg = await fs$6.readJson(path$6.join(os$7.homedir(), ".hyperclaw", "hyperclaw.json"));
|
|
3329
2558
|
} catch {}
|
|
3330
|
-
const { initWorkspaceFiles } = await Promise.resolve().then(() => require("./memory-
|
|
2559
|
+
const { initWorkspaceFiles } = await Promise.resolve().then(() => require("./memory-BI1kPkAN.js"));
|
|
3331
2560
|
await initWorkspaceFiles({
|
|
3332
2561
|
agentName: cfg.identity?.agentName || "Hyper",
|
|
3333
2562
|
personality: cfg.identity?.personality || "helpful and concise",
|
|
@@ -3335,17 +2564,17 @@ workspaceCmd.command("init [dir]").description("Initialize workspace files (SOUL
|
|
|
3335
2564
|
userName: cfg.identity?.userName || "User",
|
|
3336
2565
|
rules: cfg.identity?.rules ?? []
|
|
3337
2566
|
}, targetDir);
|
|
3338
|
-
console.log(chalk$
|
|
3339
|
-
console.log(chalk$
|
|
2567
|
+
console.log(chalk$10.hex("#06b6d4")(`\n ✔ Workspace files initialized in ${targetDir}`));
|
|
2568
|
+
console.log(chalk$10.gray(" Files: SOUL.md USER.md TOOLS.md HEARTBEAT.md BOOTSTRAP.md\n"));
|
|
3340
2569
|
process.exit(0);
|
|
3341
2570
|
});
|
|
3342
2571
|
workspaceCmd.command("show [dir]").description("Show workspace files summary").action(async (dir) => {
|
|
3343
|
-
const chalk$
|
|
3344
|
-
const fs$
|
|
3345
|
-
const path$
|
|
3346
|
-
const os$
|
|
3347
|
-
const targetDir = dir || path$
|
|
3348
|
-
console.log(chalk$
|
|
2572
|
+
const chalk$10 = require("chalk");
|
|
2573
|
+
const fs$6 = require("fs-extra");
|
|
2574
|
+
const path$6 = require("path");
|
|
2575
|
+
const os$7 = require("os");
|
|
2576
|
+
const targetDir = dir || path$6.join(os$7.homedir(), ".hyperclaw");
|
|
2577
|
+
console.log(chalk$10.bold.hex("#06b6d4")("\n 📁 WORKSPACE\n"));
|
|
3349
2578
|
for (const fname of [
|
|
3350
2579
|
"SOUL.md",
|
|
3351
2580
|
"USER.md",
|
|
@@ -3355,45 +2584,45 @@ workspaceCmd.command("show [dir]").description("Show workspace files summary").a
|
|
|
3355
2584
|
"AGENTS.md",
|
|
3356
2585
|
"MEMORY.md"
|
|
3357
2586
|
]) {
|
|
3358
|
-
const fpath = path$
|
|
3359
|
-
const exists = await fs$
|
|
3360
|
-
const size = exists ? (await fs$
|
|
3361
|
-
const dot = exists ? chalk$
|
|
3362
|
-
console.log(` ${dot} ${fname.padEnd(14)} ${exists ? chalk$
|
|
2587
|
+
const fpath = path$6.join(targetDir, fname);
|
|
2588
|
+
const exists = await fs$6.pathExists(fpath);
|
|
2589
|
+
const size = exists ? (await fs$6.stat(fpath)).size : 0;
|
|
2590
|
+
const dot = exists ? chalk$10.hex("#06b6d4")("✔") : chalk$10.gray("○");
|
|
2591
|
+
console.log(` ${dot} ${fname.padEnd(14)} ${exists ? chalk$10.gray(`${size} bytes`) : chalk$10.gray("(missing)")}`);
|
|
3363
2592
|
}
|
|
3364
2593
|
console.log();
|
|
3365
2594
|
process.exit(0);
|
|
3366
2595
|
});
|
|
3367
2596
|
const botCmd = program.command("bot").description("HyperClaw Bot — companion bot for remote gateway control");
|
|
3368
2597
|
botCmd.command("status").action(async () => {
|
|
3369
|
-
const { showBotStatus } = await Promise.resolve().then(() => require("./hyperclawbot-
|
|
2598
|
+
const { showBotStatus } = await Promise.resolve().then(() => require("./hyperclawbot-D9KCtc4P.js"));
|
|
3370
2599
|
await showBotStatus();
|
|
3371
2600
|
process.exit(0);
|
|
3372
2601
|
});
|
|
3373
2602
|
botCmd.command("setup").description("Configure HyperClaw Bot (Telegram token, allowed users)").action(async () => {
|
|
3374
|
-
const inquirer$
|
|
3375
|
-
const { saveBotConfig } = await Promise.resolve().then(() => require("./hyperclawbot-
|
|
3376
|
-
const chalk$
|
|
3377
|
-
console.log(chalk$
|
|
3378
|
-
console.log(chalk$
|
|
3379
|
-
const { platform } = await inquirer$
|
|
2603
|
+
const inquirer$2 = require("inquirer");
|
|
2604
|
+
const { saveBotConfig } = await Promise.resolve().then(() => require("./hyperclawbot-D9KCtc4P.js"));
|
|
2605
|
+
const chalk$10 = require("chalk");
|
|
2606
|
+
console.log(chalk$10.bold.hex("#06b6d4")("\n 🦅 HYPERCLAW BOT SETUP\n"));
|
|
2607
|
+
console.log(chalk$10.gray(" Create a bot at t.me/BotFather, then paste the token below.\n"));
|
|
2608
|
+
const { platform } = await inquirer$2.prompt([{
|
|
3380
2609
|
type: "list",
|
|
3381
2610
|
name: "platform",
|
|
3382
2611
|
message: "Platform:",
|
|
3383
2612
|
choices: ["telegram", "discord"]
|
|
3384
2613
|
}]);
|
|
3385
|
-
const { token } = await inquirer$
|
|
2614
|
+
const { token } = await inquirer$2.prompt([{
|
|
3386
2615
|
type: "input",
|
|
3387
2616
|
name: "token",
|
|
3388
2617
|
message: platform === "telegram" ? "Bot token (from @BotFather):" : "Discord bot token:",
|
|
3389
2618
|
validate: (v) => v.trim().length > 10 || "Required"
|
|
3390
2619
|
}]);
|
|
3391
|
-
const { userIds } = await inquirer$
|
|
2620
|
+
const { userIds } = await inquirer$2.prompt([{
|
|
3392
2621
|
type: "input",
|
|
3393
2622
|
name: "userIds",
|
|
3394
2623
|
message: "Allowed user IDs (comma-separated, leave empty for unrestricted):"
|
|
3395
2624
|
}]);
|
|
3396
|
-
const { gatewayUrl } = await inquirer$
|
|
2625
|
+
const { gatewayUrl } = await inquirer$2.prompt([{
|
|
3397
2626
|
type: "input",
|
|
3398
2627
|
name: "gatewayUrl",
|
|
3399
2628
|
message: "Gateway URL:",
|
|
@@ -3409,20 +2638,20 @@ botCmd.command("setup").description("Configure HyperClaw Bot (Telegram token, al
|
|
|
3409
2638
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3410
2639
|
};
|
|
3411
2640
|
await saveBotConfig(cfg);
|
|
3412
|
-
console.log(chalk$
|
|
2641
|
+
console.log(chalk$10.hex("#06b6d4")("\n ✔ HyperClaw Bot configured"));
|
|
3413
2642
|
if (platform === "discord") try {
|
|
3414
2643
|
require.resolve("discord.js");
|
|
3415
2644
|
} catch {
|
|
3416
|
-
console.log(chalk$
|
|
2645
|
+
console.log(chalk$10.yellow(" ⚠ For Discord: run: npm install discord.js"));
|
|
3417
2646
|
}
|
|
3418
|
-
console.log(chalk$
|
|
2647
|
+
console.log(chalk$10.gray(" Start with: hyperclaw bot start\n"));
|
|
3419
2648
|
process.exit(0);
|
|
3420
2649
|
});
|
|
3421
2650
|
botCmd.command("start").description("Start HyperClaw Bot (foreground or background)").option("--background", "Run bot in background (use hyperclaw bot stop to stop)").action(async (opts) => {
|
|
3422
2651
|
const { spawn } = await import("child_process");
|
|
3423
|
-
const path$
|
|
2652
|
+
const path$6 = await import("path");
|
|
3424
2653
|
if (opts?.background) {
|
|
3425
|
-
const entry = process.argv[1] || path$
|
|
2654
|
+
const entry = process.argv[1] || path$6.join(__dirname, "run-main.js");
|
|
3426
2655
|
const child = spawn(process.execPath, [
|
|
3427
2656
|
entry,
|
|
3428
2657
|
"bot",
|
|
@@ -3434,14 +2663,14 @@ botCmd.command("start").description("Start HyperClaw Bot (foreground or backgrou
|
|
|
3434
2663
|
cwd: process.cwd()
|
|
3435
2664
|
});
|
|
3436
2665
|
child.unref();
|
|
3437
|
-
const { writeBotPid } = await Promise.resolve().then(() => require("./hyperclawbot-
|
|
2666
|
+
const { writeBotPid } = await Promise.resolve().then(() => require("./hyperclawbot-D9KCtc4P.js"));
|
|
3438
2667
|
await writeBotPid(child.pid);
|
|
3439
2668
|
console.log(require("chalk").green(`\n ✔ HyperClaw Bot started in background (PID ${child.pid})`));
|
|
3440
2669
|
console.log(require("chalk").gray(" Stop with: hyperclaw bot stop\n"));
|
|
3441
2670
|
process.exit(0);
|
|
3442
2671
|
return;
|
|
3443
2672
|
}
|
|
3444
|
-
const { loadBotConfig, TelegramHyperClawBot, DiscordHyperClawBot } = await Promise.resolve().then(() => require("./hyperclawbot-
|
|
2673
|
+
const { loadBotConfig, TelegramHyperClawBot, DiscordHyperClawBot } = await Promise.resolve().then(() => require("./hyperclawbot-D9KCtc4P.js"));
|
|
3445
2674
|
const cfg = await loadBotConfig();
|
|
3446
2675
|
if (!cfg) {
|
|
3447
2676
|
console.log(require("chalk").red("\n ✖ HyperClaw Bot not configured. Run: hyperclaw bot setup\n"));
|
|
@@ -3467,42 +2696,42 @@ botCmd.command("start").description("Start HyperClaw Bot (foreground or backgrou
|
|
|
3467
2696
|
}
|
|
3468
2697
|
});
|
|
3469
2698
|
botCmd.command("stop").description("Stop HyperClaw Bot (when running in background)").action(async () => {
|
|
3470
|
-
const chalk$
|
|
3471
|
-
const { stopBotProcess } = await Promise.resolve().then(() => require("./hyperclawbot-
|
|
2699
|
+
const chalk$10 = require("chalk");
|
|
2700
|
+
const { stopBotProcess } = await Promise.resolve().then(() => require("./hyperclawbot-D9KCtc4P.js"));
|
|
3472
2701
|
const stopped = await stopBotProcess();
|
|
3473
|
-
if (stopped) console.log(chalk$
|
|
3474
|
-
else console.log(chalk$
|
|
2702
|
+
if (stopped) console.log(chalk$10.green("\n ✔ HyperClaw Bot stopped\n"));
|
|
2703
|
+
else console.log(chalk$10.gray("\n Bot not running in background (no PID file). Use Ctrl+C to stop foreground bot.\n"));
|
|
3475
2704
|
process.exit(stopped ? 0 : 0);
|
|
3476
2705
|
});
|
|
3477
2706
|
memCmd.command("search <query>").description("Search MEMORY.md").action(async (query) => {
|
|
3478
|
-
const { searchMemory } = await Promise.resolve().then(() => require("./src-
|
|
2707
|
+
const { searchMemory } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
3479
2708
|
await searchMemory(query);
|
|
3480
2709
|
process.exit(0);
|
|
3481
2710
|
});
|
|
3482
2711
|
memCmd.command("auto-show").description("Show auto-extracted memories from MEMORY.md").action(async () => {
|
|
3483
|
-
const { showMemory } = await Promise.resolve().then(() => require("./src-
|
|
2712
|
+
const { showMemory } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
3484
2713
|
await showMemory();
|
|
3485
2714
|
process.exit(0);
|
|
3486
2715
|
});
|
|
3487
2716
|
memCmd.command("clear").description("Clear all auto-extracted memories").action(async () => {
|
|
3488
|
-
const { clearMemory } = await Promise.resolve().then(() => require("./src-
|
|
2717
|
+
const { clearMemory } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
3489
2718
|
await clearMemory();
|
|
3490
2719
|
process.exit(0);
|
|
3491
2720
|
});
|
|
3492
2721
|
memCmd.command("save <text>").description("Manually save a fact to MEMORY.md").action(async (text) => {
|
|
3493
|
-
const { saveMemoryDirect } = await Promise.resolve().then(() => require("./src-
|
|
2722
|
+
const { saveMemoryDirect } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
3494
2723
|
await saveMemoryDirect(text);
|
|
3495
2724
|
console.log(chalk.default.hex("#06b6d4")(` ✅ Saved: ${text}\n`));
|
|
3496
2725
|
process.exit(0);
|
|
3497
2726
|
});
|
|
3498
2727
|
const pcCmd = program.command("pc").description("PC access — give the AI access to your computer");
|
|
3499
2728
|
pcCmd.command("status").description("Show PC access status and config").action(async () => {
|
|
3500
|
-
const { showPCAccessStatus } = await Promise.resolve().then(() => require("./src-
|
|
2729
|
+
const { showPCAccessStatus } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
3501
2730
|
await showPCAccessStatus();
|
|
3502
2731
|
process.exit(0);
|
|
3503
2732
|
});
|
|
3504
2733
|
pcCmd.command("enable").description("Enable PC access for the AI").option("--level <level>", "Access level: read-only | sandboxed | full", "full").option("--paths <paths>", "Comma-separated allowed paths (sandboxed mode)").action(async (opts) => {
|
|
3505
|
-
const { savePCAccessConfig } = await Promise.resolve().then(() => require("./src-
|
|
2734
|
+
const { savePCAccessConfig } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
3506
2735
|
const level = opts.level;
|
|
3507
2736
|
const allowed = [
|
|
3508
2737
|
"read-only",
|
|
@@ -3529,7 +2758,7 @@ pcCmd.command("enable").description("Enable PC access for the AI").option("--lev
|
|
|
3529
2758
|
process.exit(0);
|
|
3530
2759
|
});
|
|
3531
2760
|
pcCmd.command("disable").description("Disable PC access").action(async () => {
|
|
3532
|
-
const { savePCAccessConfig } = await Promise.resolve().then(() => require("./src-
|
|
2761
|
+
const { savePCAccessConfig } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
3533
2762
|
await savePCAccessConfig({ enabled: false });
|
|
3534
2763
|
console.log(chalk.default.hex("#06b6d4")("\n ✅ PC access disabled\n"));
|
|
3535
2764
|
process.exit(0);
|
|
@@ -3553,7 +2782,7 @@ pcCmd.command("log").description("Show PC access audit log").option("-n, --lines
|
|
|
3553
2782
|
process.exit(0);
|
|
3554
2783
|
});
|
|
3555
2784
|
pcCmd.command("run <command>").description("Run a shell command via PC access (must be enabled)").action(async (command) => {
|
|
3556
|
-
const { loadPCAccessConfig, getPCAccessTools } = await Promise.resolve().then(() => require("./src-
|
|
2785
|
+
const { loadPCAccessConfig, getPCAccessTools } = await Promise.resolve().then(() => require("./src-BEVLgaF1.js"));
|
|
3557
2786
|
const cfg = await loadPCAccessConfig();
|
|
3558
2787
|
if (!cfg.enabled) {
|
|
3559
2788
|
console.log(chalk.default.red("\n ✖ PC access disabled. Run: hyperclaw pc enable\n"));
|
|
@@ -3566,14 +2795,42 @@ pcCmd.command("run <command>").description("Run a shell command via PC access (m
|
|
|
3566
2795
|
console.log(result);
|
|
3567
2796
|
process.exit(0);
|
|
3568
2797
|
});
|
|
2798
|
+
function checkForUpdate() {
|
|
2799
|
+
const { execFile: execFile$1 } = require("child_process");
|
|
2800
|
+
const { readFileSync } = require("fs");
|
|
2801
|
+
const path$6 = require("path");
|
|
2802
|
+
try {
|
|
2803
|
+
const pkgPath = path$6.resolve(__dirname, "../../package.json");
|
|
2804
|
+
const current = JSON.parse(readFileSync(pkgPath, "utf8")).version;
|
|
2805
|
+
execFile$1("npm", [
|
|
2806
|
+
"view",
|
|
2807
|
+
"hyperclaw",
|
|
2808
|
+
"version",
|
|
2809
|
+
"--json"
|
|
2810
|
+
], { timeout: 5e3 }, (_err, stdout) => {
|
|
2811
|
+
if (_err || !stdout) return;
|
|
2812
|
+
try {
|
|
2813
|
+
const latest = JSON.parse(stdout.trim());
|
|
2814
|
+
if (latest && latest !== current) {
|
|
2815
|
+
const semver = (v) => v.split(".").map(Number);
|
|
2816
|
+
const [lMaj, lMin, lPat] = semver(latest);
|
|
2817
|
+
const [cMaj, cMin, cPat] = semver(current);
|
|
2818
|
+
const isNewer = lMaj > cMaj || lMaj === cMaj && lMin > cMin || lMaj === cMaj && lMin === cMin && lPat > cPat;
|
|
2819
|
+
if (isNewer) process.stdout.write(chalk.default.yellow(`\n ⬆ Update available: ${chalk.default.dim(current)} → ${chalk.default.green(latest)}\n`) + chalk.default.gray(` npm install -g hyperclaw@latest\n\n`));
|
|
2820
|
+
}
|
|
2821
|
+
} catch {}
|
|
2822
|
+
});
|
|
2823
|
+
} catch {}
|
|
2824
|
+
}
|
|
2825
|
+
checkForUpdate();
|
|
3569
2826
|
if (process.argv.length === 2) (async () => {
|
|
3570
|
-
const { ConfigManager: ConfigManager$1 } = await Promise.resolve().then(() => require("./manager-
|
|
2827
|
+
const { ConfigManager: ConfigManager$1 } = await Promise.resolve().then(() => require("./manager-DLmZI-9R.js"));
|
|
3571
2828
|
const cfg = await new ConfigManager$1().load().catch(() => null);
|
|
3572
2829
|
if (cfg?.provider?.apiKey || cfg?.provider?.providerId) {
|
|
3573
2830
|
await new require_onboard.Banner().showNeonBanner(false);
|
|
3574
2831
|
const { getTheme } = await Promise.resolve().then(() => require("./theme-Iefa3L63.js"));
|
|
3575
2832
|
const t = getTheme(false);
|
|
3576
|
-
const chalk$
|
|
2833
|
+
const chalk$10 = require("chalk");
|
|
3577
2834
|
console.log(t.bold(" Quick actions:\n"));
|
|
3578
2835
|
console.log(` ${t.c("hyperclaw onboard")} — re-run setup wizard`);
|
|
3579
2836
|
console.log(` ${t.c("hyperclaw onboard --install-daemon")} — wizard + daemon (full PC access)`);
|
|
@@ -3585,7 +2842,7 @@ if (process.argv.length === 2) (async () => {
|
|
|
3585
2842
|
console.log(` ${t.c("hyperclaw --help")} — all commands\n`);
|
|
3586
2843
|
} else {
|
|
3587
2844
|
await new require_onboard.Banner().showNeonBanner(false);
|
|
3588
|
-
const { HyperClawWizard: HyperClawWizard$1 } = await Promise.resolve().then(() => require("./onboard-
|
|
2845
|
+
const { HyperClawWizard: HyperClawWizard$1 } = await Promise.resolve().then(() => require("./onboard-aTwlQs-4.js"));
|
|
3589
2846
|
await new HyperClawWizard$1().run({ wizard: true });
|
|
3590
2847
|
}
|
|
3591
2848
|
process.exit(0);
|