hyperclaw 5.0.0 → 5.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/LICENSE +2 -1
- package/README.md +449 -99
- package/dist/a2ui-protocol-Gzm29Gaw.js +75 -0
- package/dist/agents-routing-Biy5ew4a.js +4 -0
- package/dist/agents-routing-CL3HQNoM.js +327 -0
- package/dist/api-keys-guide-CGn5BSF7.js +149 -0
- package/dist/api-keys-guide-ChbThbPj.js +149 -0
- package/dist/audit-BJohI_vC.js +441 -0
- package/dist/audit-NPIMmOSq.js +441 -0
- package/dist/bounty-tools-BUqUKjt0.js +211 -0
- package/dist/bounty-tools-CY_i91DU.js +211 -0
- package/dist/browser-tools-CxJY6pAn.js +5 -0
- package/dist/browser-tools-JZ9ji6AW.js +179 -0
- package/dist/chat-qVuqhlPu.js +258 -0
- package/dist/claw-tasks-B-8RRMdq.js +80 -0
- package/dist/claw-tasks-Cyzdbhz_.js +80 -0
- package/dist/connector-1x1rCBHz.js +162 -0
- package/dist/connector-B4jeCULG.js +305 -0
- package/dist/connector-B7qngfkT.js +286 -0
- package/dist/connector-B8BK0GBo.js +531 -0
- package/dist/connector-BE9eJs8-.js +182 -0
- package/dist/connector-BEe-DTGQ.js +189 -0
- package/dist/connector-BU7p5ZgB.js +167 -0
- package/dist/connector-BUzzq7Ij.js +568 -0
- package/dist/connector-BpDqLgnW.js +419 -0
- package/dist/connector-BpW88ut2.js +189 -0
- package/dist/connector-Bxv-gy8U.js +167 -0
- package/dist/connector-Bz14zcJv.js +213 -0
- package/dist/connector-C1zP5-5q.js +85 -0
- package/dist/connector-CAcpcovF.js +498 -0
- package/dist/connector-CJgVjS58.js +181 -0
- package/dist/connector-Cf53D6qV.js +425 -0
- package/dist/connector-CyHmlbNz.js +508 -0
- package/dist/connector-D22mJGVu.js +340 -0
- package/dist/connector-D6RtMmlL.js +225 -0
- package/dist/connector-D9EnT8A4.js +280 -0
- package/dist/connector-DNDwIh37.js +239 -0
- package/dist/connector-Di27MeO4.js +350 -0
- package/dist/connector-Do0BPiHt.js +194 -0
- package/dist/connector-DvLwOfJy.js +192 -0
- package/dist/connector-DvU83NSq.js +181 -0
- package/dist/connector-DxskpDc_.js +173 -0
- package/dist/connector-byy3eISx.js +552 -0
- package/dist/connector-vV89hsyd.js +218 -0
- package/dist/cost-tracker-Ca1UPZ33.js +103 -0
- package/dist/cost-tracker-fnaj_6M9.js +103 -0
- package/dist/credentials-store-BxijEirw.js +77 -0
- package/dist/credentials-store-CA8UtK0T.js +77 -0
- package/dist/credentials-store-CPkVO6-z.js +4 -0
- package/dist/credentials-store-Cm7DH-kh.js +4 -0
- package/dist/cron-tasks-L0mz1yyU.js +82 -0
- package/dist/cron-tasks-_pqQCmxc.js +82 -0
- package/dist/daemon-7ViroziB.js +5 -0
- package/dist/daemon-BfyKmZhr.js +318 -0
- package/dist/daemon-CNyunwkR.js +5 -0
- package/dist/daemon-CindY8OK.js +318 -0
- package/dist/delivery-DVHmv1IR.js +4 -0
- package/dist/delivery-DgiZcJBp.js +4 -0
- package/dist/delivery-DpMX0Yyc.js +95 -0
- package/dist/delivery-otAU4alM.js +95 -0
- package/dist/destructive-gate-CA0DtA5K.js +101 -0
- package/dist/destructive-gate-DZt71UZR.js +101 -0
- package/dist/developer-keys-Cnd1kswV.js +127 -0
- package/dist/developer-keys-DENo3ZA6.js +8 -0
- package/dist/doctor-Dgjoc3DG.js +230 -0
- package/dist/doctor-RwsOhtAl.js +6 -0
- package/dist/engine-B0kLfRL0.js +256 -0
- package/dist/engine-BJUpRUOv.js +7 -0
- package/dist/engine-D_VeoZHw.js +305 -0
- package/dist/engine-JjRnhlsE.js +7 -0
- package/dist/env-resolve-17ekEU6p.js +10 -0
- package/dist/env-resolve-BFJXWl94.js +115 -0
- package/dist/env-resolve-Z2XF6leB.js +115 -0
- package/dist/env-resolve-bDYssfih.js +10 -0
- package/dist/extraction-tools-DbxnxIco.js +5 -0
- package/dist/extraction-tools-Dg7AHS35.js +91 -0
- package/dist/form_data-CGAy4HE0.js +8657 -0
- package/dist/gmail-watch-setup-C3uSWznp.js +40 -0
- package/dist/health-DUjluWHQ.js +6 -0
- package/dist/health-DVfkpUQW.js +152 -0
- package/dist/heartbeat-engine-CrgL4mrP.js +83 -0
- package/dist/heartbeat-engine-Ut6pXBD6.js +83 -0
- package/dist/hub-9LaKnLjY.js +6 -0
- package/dist/hub-BO6bj8Yj.js +515 -0
- package/dist/hub-Bu52YZqW.js +6 -0
- package/dist/hub-CfwUz9YW.js +515 -0
- package/dist/hyperclawbot-BrcoYLOp.js +505 -0
- package/dist/hyperclawbot-CBiDSKsa.js +505 -0
- package/dist/inference-0mlFQqIm.js +922 -0
- package/dist/inference-DHR82Gh7.js +6 -0
- package/dist/inference-DhA8jpfH.js +2692 -0
- package/dist/inference-SzqFe_nk.js +6 -0
- package/dist/knowledge-graph-BrYpSgxW.js +131 -0
- package/dist/knowledge-graph-DE5lSF02.js +131 -0
- package/dist/loader-9JqY6Nlq.js +4 -0
- package/dist/loader-BkDi8MD9.js +400 -0
- package/dist/loader-Cjdd1kw4.js +400 -0
- package/dist/loader-DI2qDRPC.js +4 -0
- package/dist/logger-Cp8wC7F8.js +83 -0
- package/dist/logger-DCT2l9GV.js +83 -0
- package/dist/manager-3cq3DydI.js +4 -0
- package/dist/manager-B2Gls5RG.js +218 -0
- package/dist/manager-BUrFrPuq.js +117 -0
- package/dist/manager-Bi9UYyVR.js +105 -0
- package/dist/manager-Biz9ixWJ.js +40 -0
- package/dist/manager-CBUHJiY7.js +6 -0
- package/dist/manager-CVLLaKmq.js +218 -0
- package/dist/manager-CWNSML5D.js +117 -0
- package/dist/manager-SJe9gt-q.js +4 -0
- package/dist/mcp-CUoTCMw-.js +139 -0
- package/dist/mcp-loader-BIz-450x.js +94 -0
- package/dist/mcp-loader-CvxRDtPC.js +94 -0
- package/dist/memory-OL77OMOr.js +270 -0
- package/dist/memory-auto-CpQHZlEJ.js +306 -0
- package/dist/memory-auto-D-L2q21G.js +306 -0
- package/dist/memory-auto-DTcy5VBy.js +5 -0
- package/dist/memory-auto-Z6LCf-iK.js +5 -0
- package/dist/memory-gUi4VaIf.js +4 -0
- package/dist/memory-integration-B8RSN4pr.js +91 -0
- package/dist/memory-integration-g2vxwgoE.js +91 -0
- package/dist/moltbook-B-40gQOL.js +81 -0
- package/dist/moltbook-Cl8cQfxJ.js +81 -0
- package/dist/node-TWxRm84k.js +222 -0
- package/dist/nodes-registry-C9dCFwjh.js +52 -0
- package/dist/nodes-registry-DKRtsbNg.js +52 -0
- package/dist/oauth-flow-CeaaGAz0.js +150 -0
- package/dist/oauth-flow-JCfporKq.js +150 -0
- package/dist/oauth-provider-4R0EJlsT.js +110 -0
- package/dist/oauth-provider-B4dzn56l.js +110 -0
- package/dist/observability-CDZmeHfa.js +89 -0
- package/dist/observability-nZ3CBIxG.js +89 -0
- package/dist/onboard-BBBWcfhp.js +10 -0
- package/dist/onboard-BVOtKQdh.js +3641 -0
- package/dist/onboard-Bw28IRQ3.js +4070 -0
- package/dist/onboard-CGNIw27w.js +11 -0
- package/dist/orchestrator-BovkM63z.js +6 -0
- package/dist/orchestrator-CcKx1Ovk.js +189 -0
- package/dist/orchestrator-DSbpkP1X.js +189 -0
- package/dist/orchestrator-DcFfDLTX.js +6 -0
- package/dist/osint-B4_m3VHQ.js +277 -0
- package/dist/osint-B6BZKQAD.js +277 -0
- package/dist/pairing-B6RArWhD.js +196 -0
- package/dist/pairing-BsQ08DLq.js +4 -0
- package/dist/pc-access-B0KocJNe.js +819 -0
- package/dist/pc-access-DkzmugZ7.js +8 -0
- package/dist/pending-approval-BgNjjuI2.js +22 -0
- package/dist/pending-approval-C_HkX1QL.js +22 -0
- package/dist/providers-DxiamZSL.js +5 -0
- package/dist/providers-Dy15rDb7.js +657 -0
- package/dist/reminders-store-CzUY0zYx.js +58 -0
- package/dist/renderer-ANNfXsHn.js +225 -0
- package/dist/rules-BSQwwAYC.js +103 -0
- package/dist/run-main.js +142 -132
- package/dist/runner-BHRSOPEU.js +1271 -0
- package/dist/runner-CJFJUtPm.js +1271 -0
- package/dist/sdk/index.js +2 -2
- package/dist/sdk/index.mjs +2 -2
- package/dist/security--oQObeJO.js +4 -0
- package/dist/security-wBOg0TA8.js +73 -0
- package/dist/server-Brl_HQUB.js +1255 -0
- package/dist/server-CbTTpB5m.js +1255 -0
- package/dist/server-DP_bPzvI.js +4 -0
- package/dist/server-DhfipkwN.js +4 -0
- package/dist/session-store-B09r5HgB.js +5 -0
- package/dist/session-store-DCTQIVur.js +113 -0
- package/dist/sessions-tools-BdlN6Pb6.js +95 -0
- package/dist/sessions-tools-JVLDKSJ_.js +5 -0
- package/dist/skill-loader-B5oeliGu.js +7 -0
- package/dist/skill-loader-Wf3brNOj.js +160 -0
- package/dist/skill-runtime-BGlvly2s.js +102 -0
- package/dist/skill-runtime-BXWd-Ktf.js +102 -0
- package/dist/skill-runtime-DhL2T76p.js +5 -0
- package/dist/skill-runtime-jgklm02e.js +5 -0
- package/dist/src-BbPa6Q8p.js +63 -0
- package/dist/src-BeXtfkK2.js +458 -0
- package/dist/src-Bhybpk1J.js +63 -0
- package/dist/src-CGQjRI4N.js +20 -0
- package/dist/src-DMJ4-uqk.js +458 -0
- package/dist/sub-agent-tools-CmE345s_.js +39 -0
- package/dist/sub-agent-tools-DHY-4WWM.js +39 -0
- package/dist/theme-D0smfC_l.js +8 -0
- package/dist/theme-DajRRZbA.js +180 -0
- package/dist/tool-policy-DZvF8xlQ.js +189 -0
- package/dist/tool-policy-DgNqFWYn.js +189 -0
- package/dist/tts-elevenlabs-C06nUxMK.js +61 -0
- package/dist/tts-elevenlabs-JeFaGNJU.js +61 -0
- package/dist/update-check-BVEqHhFY.js +83 -0
- package/dist/update-check-w4XuxVl7.js +81 -0
- package/dist/vision-JOtOS1Br.js +121 -0
- package/dist/vision-fky3elEo.js +121 -0
- package/dist/vision-tools-C8B3776g.js +5 -0
- package/dist/vision-tools-CB28ZCO_.js +5 -0
- package/dist/vision-tools-dwn9p4el.js +51 -0
- package/dist/vision-tools-vPPwQ-0N.js +51 -0
- package/dist/voice-transcription-B6RtplmN.js +138 -0
- package/dist/voice-transcription-DBo5hXmu.js +138 -0
- package/dist/website-watch-tools-B-jRAeTe.js +139 -0
- package/dist/website-watch-tools-BC9xAL67.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const chalk = require_chunk.__toESM(require("chalk"));
|
|
3
|
+
const inquirer = require_chunk.__toESM(require("inquirer"));
|
|
4
|
+
const ora = require_chunk.__toESM(require("ora"));
|
|
5
|
+
const fs_extra = require_chunk.__toESM(require("fs-extra"));
|
|
6
|
+
const path = require_chunk.__toESM(require("path"));
|
|
7
|
+
const os = require_chunk.__toESM(require("os"));
|
|
8
|
+
|
|
9
|
+
//#region src/commands/osint.ts
|
|
10
|
+
const HC_DIR = path.default.join(os.default.homedir(), ".hyperclaw");
|
|
11
|
+
const CONFIG_FILE = path.default.join(HC_DIR, "hyperclaw.json");
|
|
12
|
+
const OSINT_PROFILE_FILE = path.default.join(HC_DIR, "osint-profile.json");
|
|
13
|
+
const MODE_DESCRIPTIONS = {
|
|
14
|
+
recon: "Passive reconnaissance — WHOIS, DNS, subdomains, public info gathering",
|
|
15
|
+
bugbounty: "Bug bounty workflow — target scope, vulnerability research, report drafting",
|
|
16
|
+
pentest: "Penetration testing — active recon, service enumeration, exploit research",
|
|
17
|
+
footprint: "Digital footprint — social media, email leaks, username tracking",
|
|
18
|
+
custom: "Custom — configure your own tools and system prompt"
|
|
19
|
+
};
|
|
20
|
+
const MODE_SYSTEM_PROMPTS = {
|
|
21
|
+
recon: `You are a professional OSINT analyst specializing in passive reconnaissance.
|
|
22
|
+
Your goal is to gather publicly available information about the target without triggering detection.
|
|
23
|
+
Use DNS lookups, WHOIS data, web scraping, and public databases.
|
|
24
|
+
Always cite sources and stay within legal boundaries.
|
|
25
|
+
Never attempt active exploitation — only passive information gathering.`,
|
|
26
|
+
bugbounty: `You are an experienced bug bounty hunter working within an authorized scope.
|
|
27
|
+
Your goal is to identify security vulnerabilities in web applications and infrastructure.
|
|
28
|
+
Follow responsible disclosure principles. Report findings clearly with reproduction steps.
|
|
29
|
+
Focus on: XSS, SQLi, SSRF, authentication issues, business logic flaws, IDOR.
|
|
30
|
+
Use tools methodically. Document everything for your report.`,
|
|
31
|
+
pentest: `You are a professional penetration tester with explicit written authorization.
|
|
32
|
+
Conduct a thorough security assessment following the PTES methodology.
|
|
33
|
+
Phases: Intelligence Gathering → Scanning → Exploitation → Post-Exploitation → Reporting.
|
|
34
|
+
Document all findings with CVSS scores. Stay within defined scope at all times.
|
|
35
|
+
Never exfiltrate real data — only demonstrate access.`,
|
|
36
|
+
footprint: `You are a digital forensics investigator mapping a target's online presence.
|
|
37
|
+
Your goal is to build a comprehensive profile using only public sources.
|
|
38
|
+
Search social media, data breach databases (HaveIBeenPwned, Dehashed), LinkedIn, GitHub.
|
|
39
|
+
Create a timeline of online activity. Identify connected accounts, email patterns, usernames.
|
|
40
|
+
This is for defensive intelligence gathering and authorized investigations only.`,
|
|
41
|
+
custom: `You are a security researcher with access to OSINT and analysis tools.
|
|
42
|
+
Use available tools to assist with the research task.`
|
|
43
|
+
};
|
|
44
|
+
const MODE_MCP_SERVERS = {
|
|
45
|
+
recon: ["mcp-browser", "mcp-filesystem"],
|
|
46
|
+
bugbounty: [
|
|
47
|
+
"mcp-browser",
|
|
48
|
+
"mcp-filesystem",
|
|
49
|
+
"mcp-github"
|
|
50
|
+
],
|
|
51
|
+
pentest: [
|
|
52
|
+
"mcp-browser",
|
|
53
|
+
"mcp-filesystem",
|
|
54
|
+
"mcp-terminal",
|
|
55
|
+
"mcp-github"
|
|
56
|
+
],
|
|
57
|
+
footprint: ["mcp-browser", "mcp-filesystem"],
|
|
58
|
+
custom: ["mcp-browser", "mcp-filesystem"]
|
|
59
|
+
};
|
|
60
|
+
function printBanner() {
|
|
61
|
+
console.log();
|
|
62
|
+
console.log(chalk.default.red.bold(" ██████╗ ███████╗██╗███╗ ██╗████████╗"));
|
|
63
|
+
console.log(chalk.default.red.bold(" ██╔═══██╗██╔════╝██║████╗ ██║╚══██╔══╝"));
|
|
64
|
+
console.log(chalk.default.yellow.bold(" ██║ ██║███████╗██║██╔██╗ ██║ ██║ "));
|
|
65
|
+
console.log(chalk.default.yellow.bold(" ██║ ██║╚════██║██║██║╚██╗██║ ██║ "));
|
|
66
|
+
console.log(chalk.default.red.bold(" ╚██████╔╝███████║██║██║ ╚████║ ██║ "));
|
|
67
|
+
console.log(chalk.default.red.bold(" ╚═════╝ ╚══════╝╚═╝╚═╝ ╚═══╝ ╚═╝ "));
|
|
68
|
+
console.log();
|
|
69
|
+
console.log(chalk.default.gray(" HyperClaw OSINT / Ethical Hacking Mode"));
|
|
70
|
+
console.log(chalk.default.gray(" ────────────────────────────────────────────"));
|
|
71
|
+
console.log(chalk.default.yellow(" ⚠️ For authorized security research only."));
|
|
72
|
+
console.log(chalk.default.yellow(" ⚠️ Always have explicit written permission."));
|
|
73
|
+
console.log();
|
|
74
|
+
}
|
|
75
|
+
async function osintSetup(options) {
|
|
76
|
+
printBanner();
|
|
77
|
+
if (options.show) {
|
|
78
|
+
try {
|
|
79
|
+
const profile$1 = await fs_extra.default.readJson(OSINT_PROFILE_FILE);
|
|
80
|
+
console.log(chalk.default.cyan.bold(" Current OSINT Profile:\n"));
|
|
81
|
+
console.log(` Mode: ${chalk.default.yellow(profile$1.mode)}`);
|
|
82
|
+
console.log(` Target: ${chalk.default.white(profile$1.target || "(not set)")}`);
|
|
83
|
+
console.log(` Type: ${profile$1.targetType || "N/A"}`);
|
|
84
|
+
console.log(` MCP: ${profile$1.mcpServers.join(", ")}`);
|
|
85
|
+
console.log(` Created: ${profile$1.createdAt}`);
|
|
86
|
+
if (profile$1.notes) console.log(` Notes: ${profile$1.notes}`);
|
|
87
|
+
console.log();
|
|
88
|
+
} catch {
|
|
89
|
+
console.log(chalk.default.gray(" No OSINT profile saved yet. Run: hyperclaw osint setup\n"));
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (options.reset) {
|
|
94
|
+
await fs_extra.default.remove(OSINT_PROFILE_FILE);
|
|
95
|
+
console.log(chalk.default.green(" ✔ OSINT profile cleared.\n"));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
console.log(chalk.default.bold(" Select OSINT workflow:\n"));
|
|
99
|
+
for (const [mode$1, desc] of Object.entries(MODE_DESCRIPTIONS)) console.log(` ${chalk.default.cyan(mode$1.padEnd(12))} ${chalk.default.gray(desc)}`);
|
|
100
|
+
console.log();
|
|
101
|
+
const { mode } = await inquirer.default.prompt([{
|
|
102
|
+
type: "list",
|
|
103
|
+
name: "mode",
|
|
104
|
+
message: "Workflow:",
|
|
105
|
+
choices: Object.keys(MODE_DESCRIPTIONS).map((m) => ({
|
|
106
|
+
name: `${m.padEnd(12)} — ${MODE_DESCRIPTIONS[m]}`,
|
|
107
|
+
value: m
|
|
108
|
+
})),
|
|
109
|
+
default: options.mode || "recon"
|
|
110
|
+
}]);
|
|
111
|
+
const { hasTarget } = await inquirer.default.prompt([{
|
|
112
|
+
type: "confirm",
|
|
113
|
+
name: "hasTarget",
|
|
114
|
+
message: "Set a target for this session?",
|
|
115
|
+
default: true
|
|
116
|
+
}]);
|
|
117
|
+
let target;
|
|
118
|
+
let targetType;
|
|
119
|
+
if (hasTarget) {
|
|
120
|
+
const resp = await inquirer.default.prompt([{
|
|
121
|
+
type: "list",
|
|
122
|
+
name: "targetType",
|
|
123
|
+
message: "Target type:",
|
|
124
|
+
choices: [
|
|
125
|
+
"domain",
|
|
126
|
+
"ip",
|
|
127
|
+
"username",
|
|
128
|
+
"email",
|
|
129
|
+
"org",
|
|
130
|
+
"custom"
|
|
131
|
+
]
|
|
132
|
+
}, {
|
|
133
|
+
type: "input",
|
|
134
|
+
name: "target",
|
|
135
|
+
message: "Target value (e.g. example.com):",
|
|
136
|
+
validate: (v) => v.trim().length > 0 || "Required"
|
|
137
|
+
}]);
|
|
138
|
+
target = resp.target.trim();
|
|
139
|
+
targetType = resp.targetType;
|
|
140
|
+
}
|
|
141
|
+
const { notes } = await inquirer.default.prompt([{
|
|
142
|
+
type: "input",
|
|
143
|
+
name: "notes",
|
|
144
|
+
message: "Session notes (optional, e.g. \"HackerOne program XYZ\"):"
|
|
145
|
+
}]);
|
|
146
|
+
console.log();
|
|
147
|
+
const { confirmed } = await inquirer.default.prompt([{
|
|
148
|
+
type: "confirm",
|
|
149
|
+
name: "confirmed",
|
|
150
|
+
message: chalk.default.yellow("I confirm I have explicit written authorization to test this target."),
|
|
151
|
+
default: false
|
|
152
|
+
}]);
|
|
153
|
+
if (!confirmed) {
|
|
154
|
+
console.log(chalk.default.red("\n Aborted. OSINT mode requires authorization confirmation.\n"));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const spinner = (0, ora.default)("Applying OSINT configuration...").start();
|
|
158
|
+
const mcpServers = MODE_MCP_SERVERS[mode];
|
|
159
|
+
const systemPrompt = MODE_SYSTEM_PROMPTS[mode];
|
|
160
|
+
const profile = {
|
|
161
|
+
mode,
|
|
162
|
+
target,
|
|
163
|
+
targetType,
|
|
164
|
+
notes: notes || void 0,
|
|
165
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
166
|
+
mcpServers,
|
|
167
|
+
systemPromptOverride: systemPrompt
|
|
168
|
+
};
|
|
169
|
+
await fs_extra.default.ensureDir(HC_DIR);
|
|
170
|
+
await fs_extra.default.writeJson(OSINT_PROFILE_FILE, profile, { spaces: 2 });
|
|
171
|
+
let config = {};
|
|
172
|
+
try {
|
|
173
|
+
config = await fs_extra.default.readJson(CONFIG_FILE);
|
|
174
|
+
} catch {}
|
|
175
|
+
if (!config.agent) config.agent = {};
|
|
176
|
+
const agent = config.agent;
|
|
177
|
+
agent.systemPromptOverride = systemPrompt;
|
|
178
|
+
agent.osintMode = mode;
|
|
179
|
+
if (target) agent.osintTarget = `${targetType}: ${target}`;
|
|
180
|
+
const mcpFile = path.default.join(HC_DIR, "mcp-servers.json");
|
|
181
|
+
let mcpServersJson = [];
|
|
182
|
+
try {
|
|
183
|
+
mcpServersJson = await fs_extra.default.readJson(mcpFile);
|
|
184
|
+
} catch {}
|
|
185
|
+
const extensionsDir = path.default.join(path.default.dirname(CONFIG_FILE), "..", "..");
|
|
186
|
+
const serverDefs = {
|
|
187
|
+
"mcp-filesystem": {
|
|
188
|
+
command: `node ${path.default.join(process.cwd(), "extensions/mcp-filesystem/server.mjs")}`,
|
|
189
|
+
label: "Filesystem (OSINT)"
|
|
190
|
+
},
|
|
191
|
+
"mcp-browser": {
|
|
192
|
+
command: `node ${path.default.join(process.cwd(), "extensions/mcp-browser/server.mjs")}`,
|
|
193
|
+
label: "Browser/Web (OSINT)"
|
|
194
|
+
},
|
|
195
|
+
"mcp-terminal": {
|
|
196
|
+
command: `node ${path.default.join(process.cwd(), "extensions/mcp-terminal/server.mjs")}`,
|
|
197
|
+
label: "Terminal (OSINT)"
|
|
198
|
+
},
|
|
199
|
+
"mcp-github": {
|
|
200
|
+
command: `node ${path.default.join(process.cwd(), "extensions/mcp-github/server.mjs")}`,
|
|
201
|
+
label: "GitHub (OSINT)"
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
for (const serverId of mcpServers) {
|
|
205
|
+
const already = mcpServersJson.find((s) => s.id === serverId);
|
|
206
|
+
if (!already && serverDefs[serverId]) mcpServersJson.push({
|
|
207
|
+
id: serverId,
|
|
208
|
+
name: serverDefs[serverId].label,
|
|
209
|
+
transport: "stdio",
|
|
210
|
+
command: serverDefs[serverId].command,
|
|
211
|
+
enabled: true,
|
|
212
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
213
|
+
});
|
|
214
|
+
else if (already) already.enabled = true;
|
|
215
|
+
}
|
|
216
|
+
await fs_extra.default.ensureDir(path.default.dirname(mcpFile));
|
|
217
|
+
await fs_extra.default.writeJson(mcpFile, mcpServersJson, { spaces: 2 });
|
|
218
|
+
await fs_extra.default.writeJson(CONFIG_FILE, config, { spaces: 2 });
|
|
219
|
+
spinner.succeed("OSINT configuration applied");
|
|
220
|
+
console.log();
|
|
221
|
+
console.log(chalk.default.bold.cyan(" ✔ HyperClaw is now in OSINT mode:\n"));
|
|
222
|
+
console.log(` Workflow: ${chalk.default.yellow(mode)}`);
|
|
223
|
+
if (target) console.log(` Target: ${chalk.default.white(target)} ${chalk.default.gray(`(${targetType})`)}`);
|
|
224
|
+
console.log(` MCP: ${chalk.default.cyan(mcpServers.join(", "))}`);
|
|
225
|
+
console.log();
|
|
226
|
+
console.log(chalk.default.bold(" Start your session:"));
|
|
227
|
+
console.log(` ${chalk.default.cyan("hyperclaw daemon start")} — start the assistant`);
|
|
228
|
+
console.log(` ${chalk.default.cyan("hyperclaw agent --message \"...\"")} — send a message from CLI`);
|
|
229
|
+
console.log();
|
|
230
|
+
console.log(chalk.default.bold(" Example prompts:"));
|
|
231
|
+
if (mode === "recon" && target) {
|
|
232
|
+
console.log(chalk.default.gray(` "Perform passive recon on ${target}: WHOIS, DNS, subdomains"`));
|
|
233
|
+
console.log(chalk.default.gray(` "Find all public GitHub repos for ${target}"`));
|
|
234
|
+
console.log(chalk.default.gray(` "Search for email addresses associated with ${target}"`));
|
|
235
|
+
} else if (mode === "bugbounty") {
|
|
236
|
+
console.log(chalk.default.gray(` "What are common vulnerabilities in web login forms?"`));
|
|
237
|
+
console.log(chalk.default.gray(` "Draft a bug bounty report for an XSS vulnerability"`));
|
|
238
|
+
console.log(chalk.default.gray(` "Help me test for SSRF on the /api/fetch endpoint"`));
|
|
239
|
+
} else if (mode === "pentest") {
|
|
240
|
+
console.log(chalk.default.gray(` "Create a pentest report template for a web application"`));
|
|
241
|
+
console.log(chalk.default.gray(` "What ports should I check on a Linux server?"`));
|
|
242
|
+
console.log(chalk.default.gray(` "Explain how to test for SQLi safely in a controlled environment"`));
|
|
243
|
+
} else if (mode === "footprint") {
|
|
244
|
+
console.log(chalk.default.gray(` "Search for the digital footprint of the username 'target_user'"`));
|
|
245
|
+
console.log(chalk.default.gray(` "Check HaveIBeenPwned for emails from domain example.com"`));
|
|
246
|
+
}
|
|
247
|
+
console.log();
|
|
248
|
+
console.log(chalk.default.gray(" To view profile: hyperclaw osint --show"));
|
|
249
|
+
console.log(chalk.default.gray(" To reset: hyperclaw osint --reset"));
|
|
250
|
+
console.log();
|
|
251
|
+
}
|
|
252
|
+
async function osintQuickStart(mode) {
|
|
253
|
+
printBanner();
|
|
254
|
+
console.log(chalk.default.bold(" Available OSINT workflows:\n"));
|
|
255
|
+
for (const [m, desc] of Object.entries(MODE_DESCRIPTIONS)) {
|
|
256
|
+
const isActive = m === mode;
|
|
257
|
+
const bullet = isActive ? chalk.default.green("▶") : chalk.default.gray("○");
|
|
258
|
+
console.log(` ${bullet} ${chalk.default.cyan(m.padEnd(12))} ${chalk.default.white(desc)}`);
|
|
259
|
+
}
|
|
260
|
+
console.log();
|
|
261
|
+
console.log(chalk.default.bold(" Commands:\n"));
|
|
262
|
+
console.log(` ${chalk.default.cyan("hyperclaw osint setup")} — interactive OSINT session setup`);
|
|
263
|
+
console.log(` ${chalk.default.cyan("hyperclaw osint --show")} — show current profile`);
|
|
264
|
+
console.log(` ${chalk.default.cyan("hyperclaw osint --reset")} — clear OSINT profile`);
|
|
265
|
+
console.log();
|
|
266
|
+
console.log(chalk.default.bold(" MCP servers for OSINT:\n"));
|
|
267
|
+
console.log(` ${chalk.default.cyan("mcp-browser")} — web_fetch, web_search, dns_lookup, whois_lookup, extract_links`);
|
|
268
|
+
console.log(` ${chalk.default.cyan("mcp-filesystem")} — read_file, write_file, search_files (for saving reports)`);
|
|
269
|
+
console.log(` ${chalk.default.cyan("mcp-github")} — list_repos, search_code, get_file`);
|
|
270
|
+
console.log(` ${chalk.default.cyan("mcp-terminal")} — run_command (pentest mode only, requires authorization)`);
|
|
271
|
+
console.log();
|
|
272
|
+
console.log(chalk.default.yellow(" ⚠️ Always operate within authorized scope and applicable laws.\n"));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
//#endregion
|
|
276
|
+
exports.osintQuickStart = osintQuickStart;
|
|
277
|
+
exports.osintSetup = osintSetup;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const chalk = require_chunk.__toESM(require("chalk"));
|
|
3
|
+
const fs_extra = require_chunk.__toESM(require("fs-extra"));
|
|
4
|
+
const path = require_chunk.__toESM(require("path"));
|
|
5
|
+
const os = require_chunk.__toESM(require("os"));
|
|
6
|
+
const crypto = require_chunk.__toESM(require("crypto"));
|
|
7
|
+
|
|
8
|
+
//#region src/channels/pairing.ts
|
|
9
|
+
const CREDENTIALS_DIR = path.default.join(os.default.homedir(), ".hyperclaw", "credentials");
|
|
10
|
+
const CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
11
|
+
const CODE_LENGTH = 8;
|
|
12
|
+
const EXPIRY_MS = 60 * 60 * 1e3;
|
|
13
|
+
const MAX_PENDING_PER_CHANNEL = 3;
|
|
14
|
+
function generateCode() {
|
|
15
|
+
const bytes = crypto.default.randomBytes(CODE_LENGTH);
|
|
16
|
+
return Array.from(bytes).map((b) => CODE_ALPHABET[b % CODE_ALPHABET.length]).join("");
|
|
17
|
+
}
|
|
18
|
+
function pendingFile(channelId) {
|
|
19
|
+
return path.default.join(CREDENTIALS_DIR, `${channelId}-pairing.json`);
|
|
20
|
+
}
|
|
21
|
+
function allowFromFile(channelId, accountId = "default") {
|
|
22
|
+
const suffix = accountId === "default" ? "" : `-${accountId}`;
|
|
23
|
+
return path.default.join(CREDENTIALS_DIR, `${channelId}${suffix}-allowFrom.json`);
|
|
24
|
+
}
|
|
25
|
+
async function readPending(channelId) {
|
|
26
|
+
try {
|
|
27
|
+
const data = await fs_extra.default.readJson(pendingFile(channelId));
|
|
28
|
+
return Array.isArray(data) ? data : [];
|
|
29
|
+
} catch {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function writePending(channelId, entries) {
|
|
34
|
+
await fs_extra.default.ensureDir(CREDENTIALS_DIR);
|
|
35
|
+
await fs_extra.default.writeJson(pendingFile(channelId), entries, {
|
|
36
|
+
spaces: 2,
|
|
37
|
+
mode: 384
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async function readAllowFrom(channelId, accountId = "default") {
|
|
41
|
+
try {
|
|
42
|
+
return await fs_extra.default.readJson(allowFromFile(channelId, accountId));
|
|
43
|
+
} catch {
|
|
44
|
+
return {
|
|
45
|
+
senderIds: [],
|
|
46
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function writeAllowFrom(channelId, store, accountId = "default") {
|
|
51
|
+
await fs_extra.default.ensureDir(CREDENTIALS_DIR);
|
|
52
|
+
await fs_extra.default.writeJson(allowFromFile(channelId, accountId), store, {
|
|
53
|
+
spaces: 2,
|
|
54
|
+
mode: 384
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
var PairingStore = class {
|
|
58
|
+
channelId;
|
|
59
|
+
accountId;
|
|
60
|
+
constructor(channelId, accountId = "default") {
|
|
61
|
+
this.channelId = channelId;
|
|
62
|
+
this.accountId = accountId;
|
|
63
|
+
}
|
|
64
|
+
async isApproved(senderId) {
|
|
65
|
+
const store = await readAllowFrom(this.channelId, this.accountId);
|
|
66
|
+
return store.senderIds.includes(senderId);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Returns the pairing code to send to the user, or null if already pending
|
|
70
|
+
* (code is resent only once per hour per sender).
|
|
71
|
+
*/
|
|
72
|
+
async createRequest(senderId) {
|
|
73
|
+
const now = Date.now();
|
|
74
|
+
const entries = (await readPending(this.channelId)).filter((e) => {
|
|
75
|
+
return new Date(e.expiresAt).getTime() > now;
|
|
76
|
+
});
|
|
77
|
+
const existing = entries.find((e) => e.senderId === senderId && e.channelId === this.channelId);
|
|
78
|
+
if (existing) return existing.code;
|
|
79
|
+
const channelPending = entries.filter((e) => e.channelId === this.channelId && e.accountId === this.accountId);
|
|
80
|
+
if (channelPending.length >= MAX_PENDING_PER_CHANNEL) return null;
|
|
81
|
+
const code = generateCode();
|
|
82
|
+
const entry = {
|
|
83
|
+
code,
|
|
84
|
+
channelId: this.channelId,
|
|
85
|
+
accountId: this.accountId,
|
|
86
|
+
senderId,
|
|
87
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
88
|
+
expiresAt: new Date(now + EXPIRY_MS).toISOString()
|
|
89
|
+
};
|
|
90
|
+
entries.push(entry);
|
|
91
|
+
await writePending(this.channelId, entries);
|
|
92
|
+
return code;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Called when a sender submits a code.
|
|
96
|
+
* Returns true if the code was valid and the sender is now approved.
|
|
97
|
+
*/
|
|
98
|
+
async verify(code, senderId) {
|
|
99
|
+
const now = Date.now();
|
|
100
|
+
const entries = await readPending(this.channelId);
|
|
101
|
+
const idx = entries.findIndex((e) => e.code === code.toUpperCase() && e.channelId === this.channelId && e.accountId === this.accountId && new Date(e.expiresAt).getTime() > now);
|
|
102
|
+
if (idx === -1) return false;
|
|
103
|
+
const entry = entries[idx];
|
|
104
|
+
entries.splice(idx, 1);
|
|
105
|
+
await writePending(this.channelId, entries);
|
|
106
|
+
const store = await readAllowFrom(this.channelId, this.accountId);
|
|
107
|
+
if (!store.senderIds.includes(entry.senderId)) store.senderIds.push(entry.senderId);
|
|
108
|
+
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
109
|
+
await writeAllowFrom(this.channelId, store, this.accountId);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
async listPending() {
|
|
113
|
+
const now = Date.now();
|
|
114
|
+
const entries = await readPending(this.channelId);
|
|
115
|
+
return entries.filter((e) => e.channelId === this.channelId && e.accountId === this.accountId && new Date(e.expiresAt).getTime() > now);
|
|
116
|
+
}
|
|
117
|
+
async cliApprove(code) {
|
|
118
|
+
const now = Date.now();
|
|
119
|
+
const entries = await readPending(this.channelId);
|
|
120
|
+
const idx = entries.findIndex((e) => e.code === code.toUpperCase() && e.channelId === this.channelId && e.accountId === this.accountId && new Date(e.expiresAt).getTime() > now);
|
|
121
|
+
if (idx === -1) return false;
|
|
122
|
+
const entry = entries[idx];
|
|
123
|
+
entries.splice(idx, 1);
|
|
124
|
+
await writePending(this.channelId, entries);
|
|
125
|
+
const store = await readAllowFrom(this.channelId, this.accountId);
|
|
126
|
+
if (!store.senderIds.includes(entry.senderId)) store.senderIds.push(entry.senderId);
|
|
127
|
+
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
128
|
+
await writeAllowFrom(this.channelId, store, this.accountId);
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const SUPPORTED_CHANNELS = [
|
|
133
|
+
"telegram",
|
|
134
|
+
"whatsapp",
|
|
135
|
+
"signal",
|
|
136
|
+
"imessage",
|
|
137
|
+
"discord",
|
|
138
|
+
"slack",
|
|
139
|
+
"feishu"
|
|
140
|
+
];
|
|
141
|
+
var GlobalPairingManager = class {
|
|
142
|
+
async showList(channelFilter) {
|
|
143
|
+
const now = Date.now();
|
|
144
|
+
const channels = channelFilter ? [channelFilter] : SUPPORTED_CHANNELS;
|
|
145
|
+
console.log(chalk.default.bold.cyan("\n 🔑 PAIRING CODES\n"));
|
|
146
|
+
let total = 0;
|
|
147
|
+
for (const ch of channels) {
|
|
148
|
+
let pending = [];
|
|
149
|
+
try {
|
|
150
|
+
const raw = await readPending(ch);
|
|
151
|
+
pending = raw.filter((e) => new Date(e.expiresAt).getTime() > now);
|
|
152
|
+
} catch {}
|
|
153
|
+
if (pending.length === 0) continue;
|
|
154
|
+
total += pending.length;
|
|
155
|
+
console.log(chalk.default.yellow(` ─── ${ch} ───`));
|
|
156
|
+
for (const e of pending) {
|
|
157
|
+
const expiresIn = Math.round((new Date(e.expiresAt).getTime() - now) / 6e4);
|
|
158
|
+
const acctSuffix = e.accountId !== "default" ? chalk.default.gray(` [${e.accountId}]`) : "";
|
|
159
|
+
console.log(` ${chalk.default.yellow("○")} ${chalk.default.bold(e.code)} sender: ${chalk.default.white(e.senderId)}${acctSuffix} expires: ${chalk.default.gray(`${expiresIn}m`)}`);
|
|
160
|
+
}
|
|
161
|
+
console.log();
|
|
162
|
+
}
|
|
163
|
+
if (total === 0) console.log(chalk.default.gray(` No pending pairing requests${channelFilter ? ` for ${channelFilter}` : ""}.\n`));
|
|
164
|
+
}
|
|
165
|
+
async cliApprove(channelId, code, accountId = "default") {
|
|
166
|
+
if (!SUPPORTED_CHANNELS.includes(channelId)) {
|
|
167
|
+
console.log(chalk.default.red(`\n ✖ Unknown channel: ${channelId}`));
|
|
168
|
+
console.log(chalk.default.gray(` Supported: ${SUPPORTED_CHANNELS.join(", ")}\n`));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const store = new PairingStore(channelId, accountId);
|
|
172
|
+
const ok = await store.cliApprove(code);
|
|
173
|
+
if (ok) {
|
|
174
|
+
console.log(chalk.default.green(`\n ✔ Pairing approved — ${channelId} code ${code.toUpperCase()}`));
|
|
175
|
+
console.log(chalk.default.gray(` Sender added to ${channelId}${accountId !== "default" ? `-${accountId}` : ""}-allowFrom.json\n`));
|
|
176
|
+
} else console.log(chalk.default.red(`\n ✖ Code not found, expired, or already used: ${channelId} ${code.toUpperCase()}\n`));
|
|
177
|
+
}
|
|
178
|
+
async getApprovedSenders(channelId, accountId = "default") {
|
|
179
|
+
const store = await readAllowFrom(channelId, accountId);
|
|
180
|
+
return store.senderIds;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
//#endregion
|
|
185
|
+
Object.defineProperty(exports, 'GlobalPairingManager', {
|
|
186
|
+
enumerable: true,
|
|
187
|
+
get: function () {
|
|
188
|
+
return GlobalPairingManager;
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
Object.defineProperty(exports, 'PairingStore', {
|
|
192
|
+
enumerable: true,
|
|
193
|
+
get: function () {
|
|
194
|
+
return PairingStore;
|
|
195
|
+
}
|
|
196
|
+
});
|