hyperclaw 5.0.2 → 5.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +126 -0
  2. package/bin/hyperclaw.js +3 -0
  3. package/dist/chat-BweTUpH2.js +258 -0
  4. package/dist/chat-GGvIJUVJ.js +258 -0
  5. package/dist/daemon-BpKOVkT1.js +5 -0
  6. package/dist/daemon-CIlECXTb.js +318 -0
  7. package/dist/daemon-DwrkIl5o.js +5 -0
  8. package/dist/daemon-MtT2Tqkp.js +318 -0
  9. package/dist/engine-C713U1K_.js +7 -0
  10. package/dist/engine-DAS8lres.js +305 -0
  11. package/dist/engine-DxVqkali.js +305 -0
  12. package/dist/engine-R0howgUa.js +7 -0
  13. package/dist/hyperclawbot-BHrzgnRc.js +505 -0
  14. package/dist/hyperclawbot-CnNeGJ-M.js +505 -0
  15. package/dist/mcp-loader-C5ruuDlw.js +94 -0
  16. package/dist/mcp-loader-nkCSFwxV.js +94 -0
  17. package/dist/onboard-B2V24zkc.js +11 -0
  18. package/dist/onboard-B963fZXV.js +3959 -0
  19. package/dist/onboard-CdJCHc1l.js +3959 -0
  20. package/dist/onboard-CrZK-8Lu.js +11 -0
  21. package/dist/orchestrator-D5spLJYq.js +189 -0
  22. package/dist/orchestrator-DZKfDwbu.js +189 -0
  23. package/dist/orchestrator-JMJXUA6c.js +6 -0
  24. package/dist/orchestrator-dpAJPGSS.js +6 -0
  25. package/dist/run-main.js +26 -26
  26. package/dist/server-B31aM6eh.js +1255 -0
  27. package/dist/server-Bt_lNoj3.js +4 -0
  28. package/dist/server-D2KyJXOC.js +4 -0
  29. package/dist/server-T3J_d1Cu.js +1255 -0
  30. package/dist/skill-runtime-BEtVm4Hl.js +5 -0
  31. package/dist/skill-runtime-B_PxIyXb.js +102 -0
  32. package/dist/skill-runtime-C-TGLn1X.js +102 -0
  33. package/dist/skill-runtime-Cgo0CKKU.js +5 -0
  34. package/dist/src-Bnw5V6w0.js +63 -0
  35. package/dist/src-C5enhnSg.js +458 -0
  36. package/dist/src-CTL-8bjt.js +63 -0
  37. package/dist/src-z9Dgzg9L.js +458 -0
  38. package/dist/sub-agent-tools-B7Z6MP8P.js +39 -0
  39. package/dist/sub-agent-tools-BRH2D_AO.js +39 -0
  40. package/package.json +4 -3
  41. package/scripts/postinstall.js +50 -42
package/README.md CHANGED
@@ -100,6 +100,8 @@ hyperclaw doctor
100
100
 
101
101
  > **Windows**: No WSL2, no admin rights needed. The daemon uses Task Scheduler and runs as your account.
102
102
 
103
+ > **Linux**: If you get an `EACCES: permission denied` error during `npm install -g`, see the [Linux install fix](#-linux-permission-fix) below.
104
+
103
105
  <details>
104
106
  <summary>More install options</summary>
105
107
 
@@ -118,6 +120,84 @@ rm -rf ~/.hyperclaw # optional — removes config and data
118
120
 
119
121
  </details>
120
122
 
123
+ <details>
124
+ <summary id="-linux-permission-fix">🐧 Linux / macOS permission fix (EACCES error)</summary>
125
+
126
+ If `npm install -g hyperclaw@latest` fails with `EACCES: permission denied`, it means npm is trying to write to a system directory it doesn't own. This can happen on **any Linux distro or macOS** depending on how Node.js was installed.
127
+
128
+ ---
129
+
130
+ ### ✅ Universal fix — user-local npm prefix (works on ALL distros + macOS)
131
+
132
+ This is the **recommended permanent solution** — works on Ubuntu, Debian, Arch, Fedora, Kali, openSUSE, macOS, and any other Unix system:
133
+
134
+ ```bash
135
+ # 1. Create a user-owned npm directory
136
+ mkdir -p ~/.npm-global
137
+
138
+ # 2. Tell npm to use it
139
+ npm config set prefix '~/.npm-global'
140
+
141
+ # 3. Add it to your PATH
142
+ # bash users:
143
+ echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc && source ~/.bashrc
144
+ # zsh users (macOS default, Kali zsh, etc.):
145
+ echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc && source ~/.zshrc
146
+ # fish users:
147
+ echo 'set -x PATH ~/.npm-global/bin $PATH' >> ~/.config/fish/config.fish
148
+
149
+ # 4. Install (no sudo needed)
150
+ npm install -g hyperclaw@latest
151
+ ```
152
+
153
+ ---
154
+
155
+ ### Distro-specific notes
156
+
157
+ | Distro | Node install method | Typical fix |
158
+ |--------|-------------------|-------------|
159
+ | Ubuntu / Debian | `apt install nodejs` | User-local prefix (above) |
160
+ | **Arch / Manjaro** | `pacman -S nodejs npm` | User-local prefix — **do NOT use sudo** with pacman-installed npm |
161
+ | Fedora / RHEL | `dnf install nodejs` | User-local prefix (above) |
162
+ | Kali Linux | `apt install nodejs` | User-local prefix (above) |
163
+ | openSUSE | `zypper install nodejs` | User-local prefix (above) |
164
+ | **Any distro** via `nvm` | `nvm install 22` | ✅ No fix needed — nvm installs to `~/.nvm`, no permissions issue |
165
+ | macOS via Homebrew | `brew install node` | ✅ Usually works out of the box |
166
+ | macOS via system Node | (not recommended) | User-local prefix (above) |
167
+
168
+ > **Arch Linux note**: `sudo npm install -g` can break your system's npm installation because pacman manages `/usr/lib/node_modules`. Always use the user-local prefix on Arch.
169
+
170
+ ---
171
+
172
+ ### Alternative: Use nvm (Node Version Manager)
173
+
174
+ [nvm](https://github.com/nvm-sh/nvm) manages Node per-user with no root access needed — the cleanest long-term solution:
175
+
176
+ ```bash
177
+ # Install nvm
178
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
179
+ source ~/.bashrc # or ~/.zshrc
180
+
181
+ # Install Node 22
182
+ nvm install 22
183
+ nvm use 22
184
+
185
+ # Install HyperClaw (no sudo, no prefix config needed)
186
+ npm install -g hyperclaw@latest
187
+ ```
188
+
189
+ ---
190
+
191
+ ### macOS: Quick fix with sudo (if all else fails)
192
+
193
+ ```bash
194
+ sudo npm install -g hyperclaw@latest
195
+ ```
196
+
197
+ > On macOS with **Homebrew Node**, `sudo` is usually not needed. If it is, prefer the user-local prefix or nvm approach above.
198
+
199
+ </details>
200
+
121
201
  ---
122
202
 
123
203
  ## Channels
@@ -444,6 +524,52 @@ Example — ask the agent:
444
524
  "What's playing on my Sonos?"
445
525
  ```
446
526
 
527
+ ### How to add integration API keys
528
+
529
+ **Option 1 — During onboarding wizard** (recommended for first setup):
530
+ ```bash
531
+ hyperclaw onboard
532
+ # At the end of the wizard, you'll be asked:
533
+ # "Configure integrations now? (Spotify, Home Assistant, GitHub, Trello, etc.)"
534
+ # Select the ones you want and enter your keys interactively.
535
+ ```
536
+
537
+ **Option 2 — Tell the agent** (easiest after setup):
538
+ ```
539
+ You › Save my Spotify keys:
540
+ CLIENT_ID: abc123
541
+ CLIENT_SECRET: xyz456
542
+ REFRESH_TOKEN: def789
543
+ ```
544
+
545
+ **Option 3 — CLI command**:
546
+ ```bash
547
+ hyperclaw config set-key SPOTIFY_CLIENT_ID abc123
548
+ hyperclaw config set-key SPOTIFY_CLIENT_SECRET xyz456
549
+ hyperclaw config set-key GITHUB_TOKEN ghp_xxxx
550
+ hyperclaw config set-key HA_URL http://homeassistant.local:8123
551
+ hyperclaw config set-key HA_TOKEN your-long-lived-token
552
+ ```
553
+
554
+ **Option 4 — Edit directly** `~/.hyperclaw/.env`:
555
+ ```bash
556
+ SPOTIFY_CLIENT_ID=abc123
557
+ SPOTIFY_CLIENT_SECRET=xyz456
558
+ GITHUB_TOKEN=ghp_xxxx
559
+ HA_URL=http://homeassistant.local:8123
560
+ HA_TOKEN=your-token
561
+ TRELLO_API_KEY=abc
562
+ TRELLO_TOKEN=xyz
563
+ OBSIDIAN_API_KEY=abc
564
+ HUE_BRIDGE_IP=192.168.1.100
565
+ HUE_USERNAME=your-username
566
+ SONOS_IP=192.168.1.50
567
+ GIPHY_API_KEY=abc
568
+ OP_SERVICE_ACCOUNT_TOKEN=ops_xxxx
569
+ ```
570
+
571
+ All keys are stored locally in `~/.hyperclaw/.env` — never sent anywhere except the respective service.
572
+
447
573
  ---
448
574
 
449
575
  ## Agent-to-Agent (sessions tools)
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ require('../dist/run-main.js');
@@ -0,0 +1,258 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const require_paths = require('./paths-AIyBxIzm.js');
3
+ require('./browser-tools-JZ9ji6AW.js');
4
+ require('./src-CGQjRI4N.js');
5
+ const require_engine = require('./engine-DxVqkali.js');
6
+ require('./extraction-tools-Dg7AHS35.js');
7
+ const require_inference = require('./inference-DhA8jpfH.js');
8
+ require('./memory-auto-D-L2q21G.js');
9
+ require('./orchestrator-D5spLJYq.js');
10
+ require('./pc-access-B0KocJNe.js');
11
+ require('./session-store-DCTQIVur.js');
12
+ require('./sessions-tools-BdlN6Pb6.js');
13
+ require('./skill-loader-Wf3brNOj.js');
14
+ require('./skill-runtime-B_PxIyXb.js');
15
+ require('./vision-tools-dwn9p4el.js');
16
+ require('./website-watch-tools-B-jRAeTe.js');
17
+ const require_src$1 = require('./src-z9Dgzg9L.js');
18
+ const chalk = require_chunk.__toESM(require("chalk"));
19
+ const ora = require_chunk.__toESM(require("ora"));
20
+ const fs_extra = require_chunk.__toESM(require("fs-extra"));
21
+ const readline = require_chunk.__toESM(require("readline"));
22
+
23
+ //#region src/cli/chat.ts
24
+ require_src$1.init_src();
25
+ const DIVIDER = chalk.default.gray(" " + "─".repeat(56));
26
+ function printHeader(model, sessionId) {
27
+ console.log();
28
+ console.log(DIVIDER);
29
+ console.log(chalk.default.bold.cyan(" 🦅 HYPERCLAW CHAT"));
30
+ console.log(chalk.default.gray(` Model: ${model} · Session: ${sessionId}`));
31
+ console.log(DIVIDER);
32
+ console.log(chalk.default.gray(" Type your message and press Enter."));
33
+ console.log(chalk.default.gray(" Commands: /exit /clear /model /skills /help"));
34
+ console.log(DIVIDER);
35
+ console.log();
36
+ }
37
+ function printHelp() {
38
+ console.log();
39
+ console.log(chalk.default.bold(" Commands:"));
40
+ console.log(` ${chalk.default.cyan("/exit")} — quit the chat`);
41
+ console.log(` ${chalk.default.cyan("/clear")} — clear conversation history`);
42
+ console.log(` ${chalk.default.cyan("/model")} — show current model`);
43
+ console.log(` ${chalk.default.cyan("/skills")} — list installed skills + how to add more`);
44
+ console.log(` ${chalk.default.cyan("/help")} — show this help`);
45
+ console.log();
46
+ console.log(chalk.default.gray(" Tip: you can also tell the agent to install a skill:"));
47
+ console.log(chalk.default.gray(" \"Install the web-search skill\" or paste a clawhub.ai link"));
48
+ console.log();
49
+ }
50
+ async function printSkills() {
51
+ console.log();
52
+ try {
53
+ const { loadSkills } = await Promise.resolve().then(() => require("./src-CTL-8bjt.js"));
54
+ const skills = await loadSkills();
55
+ if (skills.length === 0) console.log(chalk.default.gray(" No skills installed yet."));
56
+ else {
57
+ console.log(chalk.default.bold(" Installed skills:"));
58
+ for (const s of skills) {
59
+ console.log(` ${chalk.default.cyan("•")} ${chalk.default.bold(s.title || s.id)} ${chalk.default.gray(`(${s.id})`)}`);
60
+ if (s.capabilities) console.log(chalk.default.gray(` ${s.capabilities}`));
61
+ }
62
+ }
63
+ } catch {
64
+ console.log(chalk.default.gray(" Could not load skills list."));
65
+ }
66
+ console.log();
67
+ console.log(chalk.default.bold(" How to add a skill:"));
68
+ console.log(` ${chalk.default.gray("1.")} Tell the agent: ${chalk.default.cyan("\"Install the web-search skill\"")}`);
69
+ console.log(` ${chalk.default.gray("2.")} Paste a link: ${chalk.default.cyan("\"Install this: https://clawhub.ai/user/skill-name\"")}`);
70
+ console.log(` ${chalk.default.gray("3.")} CLI (outside chat): ${chalk.default.cyan("hyperclaw skill install <name>")}`);
71
+ console.log(` ${chalk.default.gray("4.")} Re-run wizard: ${chalk.default.cyan("hyperclaw onboard")}`);
72
+ console.log();
73
+ }
74
+ function makeSessionId() {
75
+ return Math.random().toString(36).slice(2, 9);
76
+ }
77
+ async function runChat(opts) {
78
+ const cfg = await fs_extra.default.readJson(require_paths.getConfigPath()).catch(() => null);
79
+ if (!cfg) {
80
+ console.log(chalk.default.red("\n No configuration found. Run: hyperclaw onboard\n"));
81
+ return;
82
+ }
83
+ const { getProviderCredentialAsync } = await Promise.resolve().then(() => require("./env-resolve-bDYssfih.js"));
84
+ const apiKey = await getProviderCredentialAsync(cfg).catch(() => null);
85
+ const isLocal = [
86
+ "local",
87
+ "ollama",
88
+ "lmstudio"
89
+ ].includes(cfg?.provider?.providerId ?? "");
90
+ if (!apiKey && !isLocal) {
91
+ console.log(chalk.default.red("\n No API key configured. Run: hyperclaw config set-key\n"));
92
+ return;
93
+ }
94
+ const { getProvider } = await Promise.resolve().then(() => require("./providers-DxiamZSL.js"));
95
+ const providerMeta = getProvider(cfg?.provider?.providerId ?? "");
96
+ const CUSTOM_IDS = new Set([
97
+ "groq",
98
+ "mistral",
99
+ "deepseek",
100
+ "perplexity",
101
+ "huggingface",
102
+ "ollama",
103
+ "lmstudio",
104
+ "local",
105
+ "xai",
106
+ "openai",
107
+ "google",
108
+ "minimax",
109
+ "moonshot",
110
+ "qwen",
111
+ "zai",
112
+ "litellm",
113
+ "cloudflare",
114
+ "copilot",
115
+ "vercel-ai",
116
+ "opencode-zen"
117
+ ]);
118
+ const isAnthropicVariant = [
119
+ "anthropic",
120
+ "anthropic-oauth",
121
+ "anthropic-setup-token"
122
+ ].includes(cfg?.provider?.providerId ?? "");
123
+ const provider = isAnthropicVariant ? "anthropic" : cfg?.provider?.providerId === "custom" || isLocal || CUSTOM_IDS.has(cfg?.provider?.providerId ?? "") ? "custom" : "openrouter";
124
+ const rawModel = opts.model || cfg?.provider?.modelId || "claude-sonnet-4-5";
125
+ const model = rawModel.startsWith("ollama/") ? rawModel.slice(7) : rawModel;
126
+ const resolvedBaseUrl = cfg?.provider?.baseUrl || providerMeta?.baseUrl || (isLocal ? "http://localhost:11434/v1" : void 0);
127
+ const THINKING_BUDGET = {
128
+ high: 1e4,
129
+ medium: 4e3,
130
+ low: 1e3,
131
+ none: 0
132
+ };
133
+ const thinkingBudget = THINKING_BUDGET[opts.thinking ?? "none"] ?? 0;
134
+ const maxTokens = thinkingBudget > 0 ? thinkingBudget + 4096 : 4096;
135
+ const context = await require_engine.loadWorkspaceContext(opts.workspace) + await require_engine.loadSkillsContext();
136
+ const tools = await require_engine.resolveTools({
137
+ config: cfg,
138
+ source: "cli",
139
+ elevated: true,
140
+ daemonMode: false
141
+ });
142
+ const engineOpts = {
143
+ model,
144
+ apiKey,
145
+ provider,
146
+ system: context || void 0,
147
+ tools,
148
+ maxTokens,
149
+ onToken: () => {},
150
+ ...provider === "custom" ? { baseUrl: resolvedBaseUrl || "" } : {},
151
+ ...thinkingBudget > 0 && model.includes("claude") ? { thinking: { budget_tokens: thinkingBudget } } : {}
152
+ };
153
+ const sessionId = opts.sessionId ?? makeSessionId();
154
+ const messages = [];
155
+ printHeader(rawModel, sessionId);
156
+ const rl = readline.default.createInterface({
157
+ input: process.stdin,
158
+ output: process.stdout,
159
+ terminal: true
160
+ });
161
+ rl.on("SIGINT", () => {
162
+ console.log(chalk.default.gray("\n\n Bye!\n"));
163
+ rl.close();
164
+ process.exit(0);
165
+ });
166
+ const prompt = () => {
167
+ rl.question(chalk.default.bold.green(" You › "), async (input) => {
168
+ const text = input.trim();
169
+ if (!text) {
170
+ prompt();
171
+ return;
172
+ }
173
+ if ([
174
+ "/exit",
175
+ "/quit",
176
+ "/bye",
177
+ "exit",
178
+ "quit",
179
+ "bye"
180
+ ].includes(text.toLowerCase())) {
181
+ console.log(chalk.default.gray("\n Bye!\n"));
182
+ rl.close();
183
+ process.exit(0);
184
+ }
185
+ if (text === "/help") {
186
+ printHelp();
187
+ prompt();
188
+ return;
189
+ }
190
+ if (text === "/skills") {
191
+ await printSkills();
192
+ prompt();
193
+ return;
194
+ }
195
+ if (text === "/model") {
196
+ console.log(chalk.default.gray(`\n Model: ${rawModel}\n`));
197
+ prompt();
198
+ return;
199
+ }
200
+ if (text === "/clear") {
201
+ messages.length = 0;
202
+ console.log(chalk.default.gray("\n Conversation cleared.\n"));
203
+ prompt();
204
+ return;
205
+ }
206
+ messages.push({
207
+ role: "user",
208
+ content: text
209
+ });
210
+ const spinner = (0, ora.default)({
211
+ text: chalk.default.gray("Thinking..."),
212
+ color: "cyan",
213
+ prefixText: " "
214
+ }).start();
215
+ let responseText = "";
216
+ try {
217
+ const engine = new require_inference.InferenceEngine({
218
+ ...engineOpts,
219
+ onToken: (token) => {
220
+ if (spinner.isSpinning) spinner.stop();
221
+ process.stdout.write(token);
222
+ },
223
+ onToolCall: (name) => {
224
+ if (spinner.isSpinning) spinner.stop();
225
+ console.log(chalk.default.gray(`\n [tool: ${name}]`));
226
+ }
227
+ });
228
+ spinner.stop();
229
+ process.stdout.write(chalk.default.bold.blue("\n Agent › "));
230
+ const result = await engine.run(messages);
231
+ responseText = result.text || "";
232
+ if (!responseText && !result.text) process.stdout.write(chalk.default.gray("(empty)"));
233
+ console.log("\n");
234
+ if (result.usage) console.log(chalk.default.gray(` Tokens — in: ${result.usage.input} out: ${result.usage.output}\n`));
235
+ } catch (e) {
236
+ spinner.stop();
237
+ responseText = `Error: ${e.message}`;
238
+ console.log(chalk.default.red(`\n Error: ${e.message}\n`));
239
+ }
240
+ if (responseText) messages.push({
241
+ role: "assistant",
242
+ content: responseText
243
+ });
244
+ try {
245
+ const { AutoMemory } = await Promise.resolve().then(() => require("./src-CTL-8bjt.js"));
246
+ const mem = new AutoMemory({ extractEveryNTurns: 3 });
247
+ mem.addTurn("user", text);
248
+ if (responseText) mem.addTurn("assistant", responseText);
249
+ mem.extract().catch(() => {});
250
+ } catch {}
251
+ prompt();
252
+ });
253
+ };
254
+ prompt();
255
+ }
256
+
257
+ //#endregion
258
+ exports.runChat = runChat;
@@ -0,0 +1,258 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const require_paths = require('./paths-AIyBxIzm.js');
3
+ require('./browser-tools-JZ9ji6AW.js');
4
+ require('./src-CGQjRI4N.js');
5
+ const require_engine = require('./engine-DAS8lres.js');
6
+ require('./extraction-tools-Dg7AHS35.js');
7
+ const require_inference = require('./inference-DhA8jpfH.js');
8
+ require('./memory-auto-D-L2q21G.js');
9
+ require('./orchestrator-DZKfDwbu.js');
10
+ require('./pc-access-B0KocJNe.js');
11
+ require('./session-store-DCTQIVur.js');
12
+ require('./sessions-tools-BdlN6Pb6.js');
13
+ require('./skill-loader-Wf3brNOj.js');
14
+ require('./skill-runtime-C-TGLn1X.js');
15
+ require('./vision-tools-dwn9p4el.js');
16
+ require('./website-watch-tools-B-jRAeTe.js');
17
+ const require_src$1 = require('./src-C5enhnSg.js');
18
+ const chalk = require_chunk.__toESM(require("chalk"));
19
+ const ora = require_chunk.__toESM(require("ora"));
20
+ const fs_extra = require_chunk.__toESM(require("fs-extra"));
21
+ const readline = require_chunk.__toESM(require("readline"));
22
+
23
+ //#region src/cli/chat.ts
24
+ require_src$1.init_src();
25
+ const DIVIDER = chalk.default.gray(" " + "─".repeat(56));
26
+ function printHeader(model, sessionId) {
27
+ console.log();
28
+ console.log(DIVIDER);
29
+ console.log(chalk.default.bold.cyan(" 🦅 HYPERCLAW CHAT"));
30
+ console.log(chalk.default.gray(` Model: ${model} · Session: ${sessionId}`));
31
+ console.log(DIVIDER);
32
+ console.log(chalk.default.gray(" Type your message and press Enter."));
33
+ console.log(chalk.default.gray(" Commands: /exit /clear /model /skills /help"));
34
+ console.log(DIVIDER);
35
+ console.log();
36
+ }
37
+ function printHelp() {
38
+ console.log();
39
+ console.log(chalk.default.bold(" Commands:"));
40
+ console.log(` ${chalk.default.cyan("/exit")} — quit the chat`);
41
+ console.log(` ${chalk.default.cyan("/clear")} — clear conversation history`);
42
+ console.log(` ${chalk.default.cyan("/model")} — show current model`);
43
+ console.log(` ${chalk.default.cyan("/skills")} — list installed skills + how to add more`);
44
+ console.log(` ${chalk.default.cyan("/help")} — show this help`);
45
+ console.log();
46
+ console.log(chalk.default.gray(" Tip: you can also tell the agent to install a skill:"));
47
+ console.log(chalk.default.gray(" \"Install the web-search skill\" or paste a clawhub.ai link"));
48
+ console.log();
49
+ }
50
+ async function printSkills() {
51
+ console.log();
52
+ try {
53
+ const { loadSkills } = await Promise.resolve().then(() => require("./src-Bnw5V6w0.js"));
54
+ const skills = await loadSkills();
55
+ if (skills.length === 0) console.log(chalk.default.gray(" No skills installed yet."));
56
+ else {
57
+ console.log(chalk.default.bold(" Installed skills:"));
58
+ for (const s of skills) {
59
+ console.log(` ${chalk.default.cyan("•")} ${chalk.default.bold(s.title || s.id)} ${chalk.default.gray(`(${s.id})`)}`);
60
+ if (s.capabilities) console.log(chalk.default.gray(` ${s.capabilities}`));
61
+ }
62
+ }
63
+ } catch {
64
+ console.log(chalk.default.gray(" Could not load skills list."));
65
+ }
66
+ console.log();
67
+ console.log(chalk.default.bold(" How to add a skill:"));
68
+ console.log(` ${chalk.default.gray("1.")} Tell the agent: ${chalk.default.cyan("\"Install the web-search skill\"")}`);
69
+ console.log(` ${chalk.default.gray("2.")} Paste a link: ${chalk.default.cyan("\"Install this: https://clawhub.ai/user/skill-name\"")}`);
70
+ console.log(` ${chalk.default.gray("3.")} CLI (outside chat): ${chalk.default.cyan("hyperclaw skill install <name>")}`);
71
+ console.log(` ${chalk.default.gray("4.")} Re-run wizard: ${chalk.default.cyan("hyperclaw onboard")}`);
72
+ console.log();
73
+ }
74
+ function makeSessionId() {
75
+ return Math.random().toString(36).slice(2, 9);
76
+ }
77
+ async function runChat(opts) {
78
+ const cfg = await fs_extra.default.readJson(require_paths.getConfigPath()).catch(() => null);
79
+ if (!cfg) {
80
+ console.log(chalk.default.red("\n No configuration found. Run: hyperclaw onboard\n"));
81
+ return;
82
+ }
83
+ const { getProviderCredentialAsync } = await Promise.resolve().then(() => require("./env-resolve-bDYssfih.js"));
84
+ const apiKey = await getProviderCredentialAsync(cfg).catch(() => null);
85
+ const isLocal = [
86
+ "local",
87
+ "ollama",
88
+ "lmstudio"
89
+ ].includes(cfg?.provider?.providerId ?? "");
90
+ if (!apiKey && !isLocal) {
91
+ console.log(chalk.default.red("\n No API key configured. Run: hyperclaw config set-key\n"));
92
+ return;
93
+ }
94
+ const { getProvider } = await Promise.resolve().then(() => require("./providers-DxiamZSL.js"));
95
+ const providerMeta = getProvider(cfg?.provider?.providerId ?? "");
96
+ const CUSTOM_IDS = new Set([
97
+ "groq",
98
+ "mistral",
99
+ "deepseek",
100
+ "perplexity",
101
+ "huggingface",
102
+ "ollama",
103
+ "lmstudio",
104
+ "local",
105
+ "xai",
106
+ "openai",
107
+ "google",
108
+ "minimax",
109
+ "moonshot",
110
+ "qwen",
111
+ "zai",
112
+ "litellm",
113
+ "cloudflare",
114
+ "copilot",
115
+ "vercel-ai",
116
+ "opencode-zen"
117
+ ]);
118
+ const isAnthropicVariant = [
119
+ "anthropic",
120
+ "anthropic-oauth",
121
+ "anthropic-setup-token"
122
+ ].includes(cfg?.provider?.providerId ?? "");
123
+ const provider = isAnthropicVariant ? "anthropic" : cfg?.provider?.providerId === "custom" || isLocal || CUSTOM_IDS.has(cfg?.provider?.providerId ?? "") ? "custom" : "openrouter";
124
+ const rawModel = opts.model || cfg?.provider?.modelId || "claude-sonnet-4-5";
125
+ const model = rawModel.startsWith("ollama/") ? rawModel.slice(7) : rawModel;
126
+ const resolvedBaseUrl = cfg?.provider?.baseUrl || providerMeta?.baseUrl || (isLocal ? "http://localhost:11434/v1" : void 0);
127
+ const THINKING_BUDGET = {
128
+ high: 1e4,
129
+ medium: 4e3,
130
+ low: 1e3,
131
+ none: 0
132
+ };
133
+ const thinkingBudget = THINKING_BUDGET[opts.thinking ?? "none"] ?? 0;
134
+ const maxTokens = thinkingBudget > 0 ? thinkingBudget + 4096 : 4096;
135
+ const context = await require_engine.loadWorkspaceContext(opts.workspace) + await require_engine.loadSkillsContext();
136
+ const tools = await require_engine.resolveTools({
137
+ config: cfg,
138
+ source: "cli",
139
+ elevated: true,
140
+ daemonMode: false
141
+ });
142
+ const engineOpts = {
143
+ model,
144
+ apiKey,
145
+ provider,
146
+ system: context || void 0,
147
+ tools,
148
+ maxTokens,
149
+ onToken: () => {},
150
+ ...provider === "custom" ? { baseUrl: resolvedBaseUrl || "" } : {},
151
+ ...thinkingBudget > 0 && model.includes("claude") ? { thinking: { budget_tokens: thinkingBudget } } : {}
152
+ };
153
+ const sessionId = opts.sessionId ?? makeSessionId();
154
+ const messages = [];
155
+ printHeader(rawModel, sessionId);
156
+ const rl = readline.default.createInterface({
157
+ input: process.stdin,
158
+ output: process.stdout,
159
+ terminal: true
160
+ });
161
+ rl.on("SIGINT", () => {
162
+ console.log(chalk.default.gray("\n\n Bye!\n"));
163
+ rl.close();
164
+ process.exit(0);
165
+ });
166
+ const prompt = () => {
167
+ rl.question(chalk.default.bold.green(" You › "), async (input) => {
168
+ const text = input.trim();
169
+ if (!text) {
170
+ prompt();
171
+ return;
172
+ }
173
+ if ([
174
+ "/exit",
175
+ "/quit",
176
+ "/bye",
177
+ "exit",
178
+ "quit",
179
+ "bye"
180
+ ].includes(text.toLowerCase())) {
181
+ console.log(chalk.default.gray("\n Bye!\n"));
182
+ rl.close();
183
+ process.exit(0);
184
+ }
185
+ if (text === "/help") {
186
+ printHelp();
187
+ prompt();
188
+ return;
189
+ }
190
+ if (text === "/skills") {
191
+ await printSkills();
192
+ prompt();
193
+ return;
194
+ }
195
+ if (text === "/model") {
196
+ console.log(chalk.default.gray(`\n Model: ${rawModel}\n`));
197
+ prompt();
198
+ return;
199
+ }
200
+ if (text === "/clear") {
201
+ messages.length = 0;
202
+ console.log(chalk.default.gray("\n Conversation cleared.\n"));
203
+ prompt();
204
+ return;
205
+ }
206
+ messages.push({
207
+ role: "user",
208
+ content: text
209
+ });
210
+ const spinner = (0, ora.default)({
211
+ text: chalk.default.gray("Thinking..."),
212
+ color: "cyan",
213
+ prefixText: " "
214
+ }).start();
215
+ let responseText = "";
216
+ try {
217
+ const engine = new require_inference.InferenceEngine({
218
+ ...engineOpts,
219
+ onToken: (token) => {
220
+ if (spinner.isSpinning) spinner.stop();
221
+ process.stdout.write(token);
222
+ },
223
+ onToolCall: (name) => {
224
+ if (spinner.isSpinning) spinner.stop();
225
+ console.log(chalk.default.gray(`\n [tool: ${name}]`));
226
+ }
227
+ });
228
+ spinner.stop();
229
+ process.stdout.write(chalk.default.bold.blue("\n Agent › "));
230
+ const result = await engine.run(messages);
231
+ responseText = result.text || "";
232
+ if (!responseText && !result.text) process.stdout.write(chalk.default.gray("(empty)"));
233
+ console.log("\n");
234
+ if (result.usage) console.log(chalk.default.gray(` Tokens — in: ${result.usage.input} out: ${result.usage.output}\n`));
235
+ } catch (e) {
236
+ spinner.stop();
237
+ responseText = `Error: ${e.message}`;
238
+ console.log(chalk.default.red(`\n Error: ${e.message}\n`));
239
+ }
240
+ if (responseText) messages.push({
241
+ role: "assistant",
242
+ content: responseText
243
+ });
244
+ try {
245
+ const { AutoMemory } = await Promise.resolve().then(() => require("./src-Bnw5V6w0.js"));
246
+ const mem = new AutoMemory({ extractEveryNTurns: 3 });
247
+ mem.addTurn("user", text);
248
+ if (responseText) mem.addTurn("assistant", responseText);
249
+ mem.extract().catch(() => {});
250
+ } catch {}
251
+ prompt();
252
+ });
253
+ };
254
+ prompt();
255
+ }
256
+
257
+ //#endregion
258
+ exports.runChat = runChat;
@@ -0,0 +1,5 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ require('./server-B31aM6eh.js');
3
+ const require_daemon = require('./daemon-MtT2Tqkp.js');
4
+
5
+ exports.DaemonManager = require_daemon.DaemonManager;