hyperclaw 5.3.0 โ†’ 5.3.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.
Files changed (50) hide show
  1. package/README.md +2 -0
  2. package/dist/banner-7G-bEcQg.js +143 -0
  3. package/dist/banner-B8OcbGCR.js +143 -0
  4. package/dist/banner-BIOxqoND.js +7 -0
  5. package/dist/banner-DXWl0t8M.js +7 -0
  6. package/dist/chat-2cf--psT.js +545 -0
  7. package/dist/chat-CvZyAfqV.js +545 -0
  8. package/dist/daemon-CckV-o_V.js +421 -0
  9. package/dist/daemon-DL5zfvZd.js +7 -0
  10. package/dist/daemon-DkK4j69t.js +421 -0
  11. package/dist/daemon-OqS7Ohda.js +7 -0
  12. package/dist/engine-BUqmNzOL.js +7 -0
  13. package/dist/engine-Co38wljj.js +327 -0
  14. package/dist/engine-EA8vevRJ.js +327 -0
  15. package/dist/engine-SjHViH0c.js +7 -0
  16. package/dist/hyperclawbot-CyIGak-G.js +516 -0
  17. package/dist/hyperclawbot-ukhzbWGk.js +516 -0
  18. package/dist/mcp-loader-DyklUhL2.js +93 -0
  19. package/dist/mcp-loader-u-tt6BEx.js +93 -0
  20. package/dist/onboard-BriaGw6G.js +3812 -0
  21. package/dist/onboard-Bu3xDVur.js +14 -0
  22. package/dist/onboard-D6afaGWd.js +3812 -0
  23. package/dist/onboard-gr80CpYU.js +14 -0
  24. package/dist/orchestrator-BwBZ5iON.js +189 -0
  25. package/dist/orchestrator-C0_UaVsn.js +6 -0
  26. package/dist/orchestrator-CjZos0wH.js +6 -0
  27. package/dist/orchestrator-CqXGMcxd.js +189 -0
  28. package/dist/osint-B6mHZP10.js +283 -0
  29. package/dist/osint-BC5eNzVi.js +283 -0
  30. package/dist/osint-chat-DPHec6BB.js +789 -0
  31. package/dist/osint-chat-myilxKVw.js +789 -0
  32. package/dist/run-main.js +99 -31
  33. package/dist/server-B5wYaa-U.js +4 -0
  34. package/dist/server-CrZ_WVSf.js +1365 -0
  35. package/dist/server-viuRgDlF.js +1365 -0
  36. package/dist/server-zXVY2lfd.js +4 -0
  37. package/dist/skill-runtime-B7U9JxNS.js +5 -0
  38. package/dist/skill-runtime-CxDPbEuj.js +104 -0
  39. package/dist/skill-runtime-DXEKaHRd.js +5 -0
  40. package/dist/skill-runtime-DXKqnJos.js +104 -0
  41. package/dist/src-CSriPfaE.js +63 -0
  42. package/dist/src-CYUaLsXl.js +458 -0
  43. package/dist/src-Czb6-Nkc.js +458 -0
  44. package/dist/src-DSZTfNdO.js +63 -0
  45. package/dist/sub-agent-tools-CFlCWrhp.js +39 -0
  46. package/dist/sub-agent-tools-zyfsZ8k0.js +39 -0
  47. package/dist/update-check-CApy4DTc.js +117 -0
  48. package/dist/update-check-CCMXnjxr.js +7 -0
  49. package/package.json +1 -1
  50. package/static/chat.html +112 -5
@@ -0,0 +1,117 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const chalk = require_chunk.__toESM(require("chalk"));
3
+ const fs_extra = require_chunk.__toESM(require("fs-extra"));
4
+ const path = require_chunk.__toESM(require("path"));
5
+ const https = require_chunk.__toESM(require("https"));
6
+
7
+ //#region src/infra/update-check.ts
8
+ const NPM_REGISTRY = "https://registry.npmjs.org";
9
+ const PACKAGE_NAME = "hyperclaw";
10
+ /** Resolve current package version from package.json (works from repo and global install). */
11
+ async function getCurrentVersion() {
12
+ const candidates = [];
13
+ try {
14
+ candidates.push(require.resolve("hyperclaw/package.json"));
15
+ } catch {}
16
+ candidates.push(path.default.resolve(__dirname, "../../package.json"));
17
+ candidates.push(path.default.resolve(process.cwd(), "package.json"));
18
+ for (const pkgPath of candidates) try {
19
+ const pkg = await fs_extra.default.readJson(pkgPath).catch(() => null);
20
+ const v = pkg?.version;
21
+ if (typeof v === "string" && /^\d+\.\d+\.\d+/.test(v)) return v;
22
+ } catch {}
23
+ return "0.0.0";
24
+ }
25
+ function parseVersion(v) {
26
+ const match = v.replace(/^v/, "").match(/^(\d+)\.(\d+)\.(\d+)/);
27
+ if (!match) return [
28
+ 0,
29
+ 0,
30
+ 0
31
+ ];
32
+ return [
33
+ parseInt(match[1], 10),
34
+ parseInt(match[2], 10),
35
+ parseInt(match[3], 10)
36
+ ];
37
+ }
38
+ function isNewer(latest, current) {
39
+ const a = parseVersion(latest);
40
+ const b = parseVersion(current);
41
+ for (let i = 0; i < 3; i++) {
42
+ if (a[i] > b[i]) return true;
43
+ if (a[i] < b[i]) return false;
44
+ }
45
+ return false;
46
+ }
47
+ async function checkForUpdates(currentVersion) {
48
+ if (process.env.HYPERCLAW_NO_UPDATE_CHECK === "1") return null;
49
+ return new Promise((resolve) => {
50
+ const req = https.default.get(`${NPM_REGISTRY}/${PACKAGE_NAME}/latest`, { timeout: 3e3 }, (res) => {
51
+ let data = "";
52
+ res.on("data", (chunk) => data += chunk);
53
+ res.on("end", () => {
54
+ try {
55
+ const json = JSON.parse(data);
56
+ const latest = json?.version;
57
+ if (!latest || typeof latest !== "string") {
58
+ resolve(null);
59
+ return;
60
+ }
61
+ resolve({
62
+ latest,
63
+ available: isNewer(latest, currentVersion)
64
+ });
65
+ } catch {
66
+ resolve(null);
67
+ }
68
+ });
69
+ });
70
+ req.on("error", () => resolve(null));
71
+ req.on("timeout", () => {
72
+ req.destroy();
73
+ resolve(null);
74
+ });
75
+ });
76
+ }
77
+ function notifyUpdateAvailable(current, latest) {
78
+ console.log(chalk.default.yellow(` ๐Ÿฆ… Update available: ${latest} (you have ${current})`));
79
+ console.log(chalk.default.gray(" Run: npm i -g hyperclaw\n"));
80
+ }
81
+ /** Fire-and-forget: check for updates and notify user if available. Call after banner/startup. */
82
+ function maybeShowUpdateNotice(skipInDaemon = false) {
83
+ if (skipInDaemon) return;
84
+ (async () => {
85
+ try {
86
+ const current = await getCurrentVersion();
87
+ const result = await checkForUpdates(current);
88
+ if (result?.available) notifyUpdateAvailable(current, result.latest);
89
+ } catch {}
90
+ })().catch(() => {});
91
+ }
92
+
93
+ //#endregion
94
+ Object.defineProperty(exports, 'checkForUpdates', {
95
+ enumerable: true,
96
+ get: function () {
97
+ return checkForUpdates;
98
+ }
99
+ });
100
+ Object.defineProperty(exports, 'getCurrentVersion', {
101
+ enumerable: true,
102
+ get: function () {
103
+ return getCurrentVersion;
104
+ }
105
+ });
106
+ Object.defineProperty(exports, 'maybeShowUpdateNotice', {
107
+ enumerable: true,
108
+ get: function () {
109
+ return maybeShowUpdateNotice;
110
+ }
111
+ });
112
+ Object.defineProperty(exports, 'notifyUpdateAvailable', {
113
+ enumerable: true,
114
+ get: function () {
115
+ return notifyUpdateAvailable;
116
+ }
117
+ });
@@ -0,0 +1,7 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const require_update_check = require('./update-check-CApy4DTc.js');
3
+
4
+ exports.checkForUpdates = require_update_check.checkForUpdates;
5
+ exports.getCurrentVersion = require_update_check.getCurrentVersion;
6
+ exports.maybeShowUpdateNotice = require_update_check.maybeShowUpdateNotice;
7
+ exports.notifyUpdateAvailable = require_update_check.notifyUpdateAvailable;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperclaw",
3
- "version": "5.3.0",
3
+ "version": "5.3.2",
4
4
  "description": "โšก HyperClaw โ€” AI Gateway Platform. The Lobster Evolution ๐Ÿฆ…",
5
5
  "main": "dist/run-main.js",
6
6
  "bin": {
package/static/chat.html CHANGED
@@ -99,6 +99,22 @@
99
99
  .welcome-chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 4px; }
100
100
  .chip { background: var(--bg3); border: 1px solid var(--border); color: var(--text2); padding: 7px 14px; border-radius: 20px; font-size: 12px; cursor: pointer; transition: all .2s; }
101
101
  .chip:hover { border-color: var(--accent); color: var(--accent); }
102
+
103
+ /* โ”€โ”€ LOCAL TERMINAL โ”€โ”€โ”€ */
104
+ .terminal-wrap { border-top: 1px solid var(--border); background: rgba(0,0,0,0.4); flex-shrink: 0; }
105
+ .terminal-toggle { width: 100%; display: flex; align-items: center; justify-content: space-between; padding: 8px 16px; font-size: 12px; color: var(--text2); background: transparent; border: none; cursor: pointer; transition: background .2s; }
106
+ .terminal-toggle:hover { background: var(--bg3); }
107
+ .terminal-body { padding: 12px 16px; display: none; }
108
+ .terminal-body.open { display: block; }
109
+ .terminal-btns { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
110
+ .terminal-btn { padding: 6px 12px; font-size: 11px; border-radius: 6px; background: var(--bg3); border: 1px solid var(--border); color: var(--text); cursor: pointer; transition: all .2s; }
111
+ .terminal-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
112
+ .terminal-btn:disabled { opacity: 0.5; cursor: default; }
113
+ .terminal-log { background: rgba(0,0,0,0.7); border: 1px solid var(--border); border-radius: 8px; padding: 10px; height: 140px; overflow-y: auto; font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--text2); white-space: pre-wrap; margin-bottom: 10px; }
114
+ .terminal-log:empty::before { content: 'No commands yet. Use the buttons above or type a command below.'; color: var(--text2); opacity: 0.7; }
115
+ .terminal-input-row { display: flex; gap: 8px; align-items: center; }
116
+ .terminal-input { flex: 1; background: var(--bg3); border: 1px solid var(--border); border-radius: 6px; padding: 8px 12px; font-size: 12px; font-family: 'JetBrains Mono', monospace; color: var(--text); outline: none; }
117
+ .terminal-input:focus { border-color: var(--accent); }
102
118
  </style>
103
119
  </head>
104
120
  <body>
@@ -115,9 +131,16 @@
115
131
  <span class="dot" id="ws-dot"></span>
116
132
  <span id="ws-label" style="color:var(--text2);font-size:13px">Offline</span>
117
133
  </div>
118
- <div class="banner-actions">
134
+ <div class="banner-actions" style="display:flex;align-items:center;gap:8px">
135
+ <select id="prompt-select" style="background:var(--bg3);border:1px solid var(--border);color:var(--text);border-radius:8px;padding:6px 10px;font-size:12px;cursor:pointer">
136
+ <option value="">General</option>
137
+ <option value="ethical-hacker">Ethical Hacker</option>
138
+ <option value="hyperclaw">HyperClaw Dev</option>
139
+ <option value="osint">OSINT</option>
140
+ </select>
141
+ <button class="btn-icon" id="new-chat-btn" title="New chat">๐Ÿ’ฌ</button>
142
+ <button class="btn-icon" id="clear-btn" title="Clear messages">๐Ÿ—‘๏ธ</button>
119
143
  <button class="btn-icon" id="theme-btn" title="Toggle theme">๐ŸŒ™</button>
120
- <button class="btn-icon" id="clear-btn" title="Clear chat">๐Ÿ—‘๏ธ</button>
121
144
  </div>
122
145
  </header>
123
146
 
@@ -145,6 +168,28 @@
145
168
  <div class="input-hint">๐Ÿฆ… HyperClaw ยท <span id="model-hint">โ€”</span></div>
146
169
  </div>
147
170
 
171
+ <!-- LOCAL TERMINAL -->
172
+ <div class="terminal-wrap">
173
+ <button type="button" class="terminal-toggle" id="terminal-toggle">
174
+ <span>โ€บ Local terminal</span>
175
+ <span id="terminal-toggle-label">Show</span>
176
+ </button>
177
+ <div class="terminal-body" id="terminal-body">
178
+ <div class="terminal-btns">
179
+ <button type="button" class="terminal-btn" data-cmd="npm run build">Build</button>
180
+ <button type="button" class="terminal-btn" data-cmd="npm install">Install</button>
181
+ <button type="button" class="terminal-btn" data-cmd="npm test">Test</button>
182
+ <button type="button" class="terminal-btn" data-cmd="npx hyperclaw doctor --fix">Doctor</button>
183
+ <button type="button" class="terminal-btn" data-cmd="npx hyperclaw gateway status">Gateway status</button>
184
+ </div>
185
+ <div class="terminal-log" id="terminal-log"></div>
186
+ <div class="terminal-input-row">
187
+ <input type="text" class="terminal-input" id="terminal-input" placeholder="Run a command in your HyperClaw workspace..." />
188
+ <button type="button" class="terminal-btn" id="terminal-run">Run</button>
189
+ </div>
190
+ </div>
191
+ </div>
192
+
148
193
  <script>
149
194
  const port = location.port || 18789;
150
195
  const wsUrl = `ws://${location.hostname}:${port}`;
@@ -170,7 +215,17 @@
170
215
  themeBtn.textContent = dark ? '๐ŸŒ™' : 'โ˜€๏ธ';
171
216
  };
172
217
 
173
- // โ”€โ”€ Clear โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
218
+ // โ”€โ”€ New chat / Clear โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
219
+ const promptSelect = document.getElementById('prompt-select');
220
+ const PROMPT_PREFIX = {
221
+ 'ethical-hacker': 'Act as an ethical hacker / security researcher. Authorized testing only. ',
222
+ 'hyperclaw': 'You are helping with HyperClaw development. Be concise and code-focused. ',
223
+ 'osint': 'Act as an OSINT analyst. Passive reconnaissance, open-source research. '
224
+ };
225
+ document.getElementById('new-chat-btn').onclick = () => {
226
+ messagesEl.querySelectorAll('.msg-row').forEach(e => e.remove());
227
+ welcomeEl.style.display = 'flex';
228
+ };
174
229
  document.getElementById('clear-btn').onclick = () => {
175
230
  messagesEl.querySelectorAll('.msg-row').forEach(e => e.remove());
176
231
  welcomeEl.style.display = 'flex';
@@ -297,6 +352,9 @@
297
352
  e.preventDefault();
298
353
  const msg = input.value.trim();
299
354
  if (!msg || isStreaming) return;
355
+ const preset = promptSelect?.value || '';
356
+ const prefix = PROMPT_PREFIX[preset] || '';
357
+ const fullMsg = prefix ? prefix + msg : msg;
300
358
  addMsg('user', msg);
301
359
  input.value = '';
302
360
  input.style.height = 'auto';
@@ -305,13 +363,13 @@
305
363
  addTyping();
306
364
 
307
365
  if (ws && ws.readyState === WebSocket.OPEN) {
308
- ws.send(JSON.stringify({ type: 'chat:message', content: msg, source: 'webchat' }));
366
+ ws.send(JSON.stringify({ type: 'chat:message', content: fullMsg, source: 'webchat' }));
309
367
  } else {
310
368
  // REST fallback
311
369
  try {
312
370
  const res = await fetch(apiUrl + '/api/chat', {
313
371
  method: 'POST', headers: {'Content-Type':'application/json'},
314
- body: JSON.stringify({message: msg})
372
+ body: JSON.stringify({message: fullMsg})
315
373
  });
316
374
  const data = await res.json();
317
375
  removeTyping();
@@ -335,6 +393,55 @@
335
393
  if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); form.dispatchEvent(new Event('submit')); }
336
394
  });
337
395
 
396
+ // โ”€โ”€ Local Terminal โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
397
+ const terminalToggle = document.getElementById('terminal-toggle');
398
+ const terminalBody = document.getElementById('terminal-body');
399
+ const terminalLog = document.getElementById('terminal-log');
400
+ const terminalInput = document.getElementById('terminal-input');
401
+ const terminalRun = document.getElementById('terminal-run');
402
+ const toggleLabel = document.getElementById('terminal-toggle-label');
403
+ let terminalRunning = false;
404
+
405
+ terminalToggle.onclick = () => {
406
+ terminalBody.classList.toggle('open', !terminalBody.classList.contains('open'));
407
+ toggleLabel.textContent = terminalBody.classList.contains('open') ? 'Hide' : 'Show';
408
+ };
409
+
410
+ async function runTerminalCmd(cmd) {
411
+ cmd = (cmd || '').trim();
412
+ if (!cmd || terminalRunning) return;
413
+ terminalLog.append('$ ' + cmd + '\n');
414
+ terminalLog.scrollTop = terminalLog.scrollHeight;
415
+ terminalRunning = true;
416
+ terminalRun.disabled = true;
417
+ document.querySelectorAll('.terminal-btn[data-cmd]').forEach(b => b.disabled = true);
418
+ try {
419
+ const res = await fetch(apiUrl + '/api/terminal', {
420
+ method: 'POST', headers: {'Content-Type': 'application/json'},
421
+ body: JSON.stringify({command: cmd})
422
+ });
423
+ const data = await res.json();
424
+ if (data.stdout) terminalLog.append(data.stdout.trimEnd() + '\n');
425
+ if (data.stderr) terminalLog.append('! ' + data.stderr.trimEnd() + '\n');
426
+ terminalLog.append('(exit code ' + (data.code ?? 0) + ')\n');
427
+ } catch (e) {
428
+ terminalLog.append('Error: ' + (e.message || String(e)) + '\n');
429
+ } finally {
430
+ terminalRunning = false;
431
+ terminalRun.disabled = false;
432
+ document.querySelectorAll('.terminal-btn[data-cmd]').forEach(b => b.disabled = false);
433
+ terminalLog.scrollTop = terminalLog.scrollHeight;
434
+ }
435
+ }
436
+
437
+ document.querySelectorAll('.terminal-btn[data-cmd]').forEach(btn => {
438
+ btn.onclick = () => runTerminalCmd(btn.dataset.cmd);
439
+ });
440
+ terminalRun.onclick = () => { runTerminalCmd(terminalInput.value); terminalInput.value = ''; };
441
+ terminalInput.onkeydown = (e) => {
442
+ if (e.key === 'Enter') { runTerminalCmd(terminalInput.value); terminalInput.value = ''; }
443
+ };
444
+
338
445
  // โ”€โ”€ Init โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
339
446
  connectWs();
340
447
  fetch(apiUrl + '/api/status').then(r => r.json()).then(d => {