hyperclaw 4.0.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -3
- package/dist/a2ui-protocol-CfBI44-Q.js +75 -0
- package/dist/agents-routing-ChHiZp36.js +327 -0
- package/dist/agents-routing-ChqZ6l2S.js +4 -0
- package/dist/api-keys-guide-BCcOl0Q7.js +149 -0
- package/dist/audit-BaIiyWFu.js +441 -0
- package/dist/bounty-tools-DWudyZie.js +211 -0
- package/dist/browser-tools-BsTeGMnX.js +5 -0
- package/dist/browser-tools-D8_rLe2p.js +179 -0
- package/dist/claw-tasks-CgTsiNE8.js +80 -0
- package/dist/connector-5N0-X_xs.js +194 -0
- package/dist/connector-B3v0qcXg.js +425 -0
- package/dist/connector-B8R3iBY1.js +280 -0
- package/dist/connector-BAM-08NN.js +189 -0
- package/dist/connector-BC8FIVu4.js +181 -0
- package/dist/connector-BDmwwaVc.js +213 -0
- package/dist/connector-BGjbBy69.js +225 -0
- package/dist/connector-BO2SRzfG.js +218 -0
- package/dist/connector-BfXky0L3.js +167 -0
- package/dist/connector-BiiSJpx3.js +192 -0
- package/dist/connector-BnDmIhIu.js +85 -0
- package/dist/connector-C1HSoUyk.js +189 -0
- package/dist/connector-CKQHZOXg.js +568 -0
- package/dist/connector-CRl-iidy.js +239 -0
- package/dist/connector-Ci9glMD-.js +340 -0
- package/dist/connector-CjtZIEDj.js +181 -0
- package/dist/connector-Ck6JtOsX.js +531 -0
- package/dist/connector-D8Kelee0.js +286 -0
- package/dist/connector-DAnRJ0oP.js +162 -0
- package/dist/connector-DXTp5PE8.js +508 -0
- package/dist/connector-Dih6dUPP.js +173 -0
- package/dist/connector-DqTH_tPX.js +182 -0
- package/dist/connector-DrnEiiyP.js +419 -0
- package/dist/connector-DtR5GGTX.js +167 -0
- package/dist/connector-Tky_qS_K.js +350 -0
- package/dist/connector-ZSc3oTTy.js +305 -0
- package/dist/connector-sW5yhU1m.js +498 -0
- package/dist/connector-u3ICd3Ic.js +552 -0
- package/dist/cost-tracker-DD9wtWsr.js +103 -0
- package/dist/credentials-store-C6ir0Dae.js +4 -0
- package/dist/credentials-store-H13LqOwJ.js +77 -0
- package/dist/cron-tasks-Bli7Kzd2.js +82 -0
- package/dist/daemon-Bg4GtCmc.js +318 -0
- package/dist/daemon-DhmwY8k4.js +5 -0
- package/dist/delivery-BmIYy9VQ.js +4 -0
- package/dist/delivery-pWUPBp1F.js +95 -0
- package/dist/destructive-gate-D6vWOdEl.js +101 -0
- package/dist/developer-keys-CPWT7Q6S.js +8 -0
- package/dist/developer-keys-DrrcUqFa.js +127 -0
- package/dist/doctor-BvCe8BBk.js +230 -0
- package/dist/doctor-CxyPLYsJ.js +6 -0
- package/dist/engine-CEDSqXfw.js +256 -0
- package/dist/engine-Da4JMNpI.js +7 -0
- package/dist/env-resolve-CiXbWYwe.js +10 -0
- package/dist/env-resolve-CmGWhWXJ.js +115 -0
- package/dist/extraction-tools-HOZstZ0y.js +91 -0
- package/dist/extraction-tools-m4lmAv7l.js +5 -0
- package/dist/form_data-Cz040rio.js +8657 -0
- package/dist/gmail-watch-setup-Du7DVV7S.js +40 -0
- package/dist/health-B-asI__D.js +6 -0
- package/dist/health-Ds2YlpTB.js +152 -0
- package/dist/heartbeat-engine-BYT5ayQH.js +83 -0
- package/dist/hub-D0XwdjM-.js +515 -0
- package/dist/hub-LiD5Iztb.js +6 -0
- package/dist/hyperclawbot-zvczQgKx.js +505 -0
- package/dist/inference-BKVkBREb.js +6 -0
- package/dist/inference-DCXH4Q3x.js +922 -0
- package/dist/knowledge-graph-iBG76fvm.js +131 -0
- package/dist/loader-CC45xGpC.js +4 -0
- package/dist/loader-CnEdOyjT.js +400 -0
- package/dist/logger-ybOp7VOC.js +83 -0
- package/dist/manager-03ipO9R0.js +105 -0
- package/dist/manager-BpDfbDjg.js +117 -0
- package/dist/manager-Bxl0sqlh.js +4 -0
- package/dist/manager-CrVDn6eN.js +6 -0
- package/dist/manager-FCgF1plu.js +218 -0
- package/dist/manager-rgCsaWT1.js +40 -0
- package/dist/mcp-CfoSU4Uz.js +139 -0
- package/dist/mcp-loader-DkRBsLpk.js +94 -0
- package/dist/memory-BlHL7JCO.js +4 -0
- package/dist/memory-DsS_eFvJ.js +270 -0
- package/dist/memory-auto-BkvtSFUw.js +5 -0
- package/dist/memory-auto-Bnz_-1wP.js +306 -0
- package/dist/memory-integration-cSYkZyEo.js +91 -0
- package/dist/moltbook-BtLDZTfM.js +81 -0
- package/dist/node-Dw2Gi-cP.js +222 -0
- package/dist/nodes-registry-B8dmrlLv.js +52 -0
- package/dist/oauth-flow-DQPvMHRH.js +150 -0
- package/dist/oauth-provider-Uo4Nib_c.js +110 -0
- package/dist/observability-BV-Yx0V9.js +89 -0
- package/dist/onboard-0WoDxbv_.js +10 -0
- package/dist/onboard-BXNXCQp4.js +4070 -0
- package/dist/orchestrator-DmnEvMaL.js +189 -0
- package/dist/orchestrator-RI3bpqqc.js +6 -0
- package/dist/pairing-6iM27aD8.js +196 -0
- package/dist/pairing-dGoiGepK.js +4 -0
- package/dist/pc-access-CgCsYrpt.js +8 -0
- package/dist/pc-access-_iH2aorG.js +819 -0
- package/dist/pending-approval-CUXjysAo.js +22 -0
- package/dist/reminders-store-Drjed_-h.js +58 -0
- package/dist/renderer-BVQrd0_g.js +225 -0
- package/dist/rules-BE4GV6cV.js +103 -0
- package/dist/run-main.js +1607 -443
- package/dist/runner-DatMMYYE.js +1271 -0
- package/dist/sdk/index.js +2 -2
- package/dist/sdk/index.mjs +2 -2
- package/dist/security-BqNyT4ID.js +4 -0
- package/dist/security-tpgqPWWH.js +73 -0
- package/dist/server-D4wVHiX9.js +4 -0
- package/dist/server-Dh3JlBFB.js +1255 -0
- package/dist/session-store-BUiPz0Vv.js +5 -0
- package/dist/session-store-is4B6qmD.js +113 -0
- package/dist/sessions-tools-CbUTFe4i.js +5 -0
- package/dist/sessions-tools-CeqD7iil.js +95 -0
- package/dist/skill-loader-BaNLVmJy.js +7 -0
- package/dist/skill-loader-HgpF6Vqs.js +159 -0
- package/dist/skill-runtime-CJN24QPW.js +102 -0
- package/dist/skill-runtime-w1ig_lcw.js +5 -0
- package/dist/src-BxPHKO5x.js +63 -0
- package/dist/src-DIc-L2IG.js +20 -0
- package/dist/src-g_rNx5rh.js +458 -0
- package/dist/sub-agent-tools-CHQoHz9c.js +39 -0
- package/dist/theme-DcxwcUgZ.js +180 -0
- package/dist/theme-cx0fkgWC.js +8 -0
- package/dist/tool-policy-CNT-mF2Z.js +189 -0
- package/dist/tts-elevenlabs-BRosZv-f.js +61 -0
- package/dist/update-check-C2Dz85wJ.js +81 -0
- package/dist/vision-BMmiIKy7.js +121 -0
- package/dist/vision-tools-DVuYc17I.js +51 -0
- package/dist/vision-tools-U3YC4L-g.js +5 -0
- package/dist/voice-transcription-B555DbWR.js +138 -0
- package/dist/website-watch-tools-DFMrJU-R.js +139 -0
- package/dist/website-watch-tools-Du3W5sN7.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const fs_extra = require_chunk.__toESM(require("fs-extra"));
|
|
3
|
+
const path = require_chunk.__toESM(require("path"));
|
|
4
|
+
const os = require_chunk.__toESM(require("os"));
|
|
5
|
+
|
|
6
|
+
//#region src/services/mcp-loader.ts
|
|
7
|
+
async function getMCPConfig() {
|
|
8
|
+
try {
|
|
9
|
+
const cfg = await fs_extra.default.readJson(path.default.join(HC_DIR, "hyperclaw.json"));
|
|
10
|
+
const servers = cfg.mcp?.servers ?? [];
|
|
11
|
+
return Array.isArray(servers) ? servers : [];
|
|
12
|
+
} catch {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Load tools from all configured MCP servers. */
|
|
17
|
+
async function loadMCPTools() {
|
|
18
|
+
const servers = await getMCPConfig();
|
|
19
|
+
if (servers.length === 0) return [];
|
|
20
|
+
let Client;
|
|
21
|
+
let StdioClientTransport;
|
|
22
|
+
let StreamableHTTPClientTransport;
|
|
23
|
+
try {
|
|
24
|
+
const sdk = await import("@modelcontextprotocol/sdk");
|
|
25
|
+
Client = sdk.Client;
|
|
26
|
+
StdioClientTransport = sdk.StdioClientTransport;
|
|
27
|
+
StreamableHTTPClientTransport = sdk.StreamableHTTPClientTransport;
|
|
28
|
+
} catch {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
const tools = [];
|
|
32
|
+
for (const srv of servers) try {
|
|
33
|
+
const client = new Client({
|
|
34
|
+
name: "hyperclaw",
|
|
35
|
+
version: "5.0.0"
|
|
36
|
+
});
|
|
37
|
+
if (srv.url) {
|
|
38
|
+
const transport = new StreamableHTTPClientTransport(new URL(srv.url));
|
|
39
|
+
await client.connect(transport);
|
|
40
|
+
} else if (srv.command) {
|
|
41
|
+
const transport = new StdioClientTransport({
|
|
42
|
+
command: srv.command,
|
|
43
|
+
args: srv.args ?? []
|
|
44
|
+
});
|
|
45
|
+
await client.connect(transport);
|
|
46
|
+
} else continue;
|
|
47
|
+
const allTools = [];
|
|
48
|
+
let cursor;
|
|
49
|
+
do {
|
|
50
|
+
const res = await client.listTools?.({ cursor }) ?? {
|
|
51
|
+
tools: [],
|
|
52
|
+
nextCursor: void 0
|
|
53
|
+
};
|
|
54
|
+
allTools.push(...res.tools ?? []);
|
|
55
|
+
cursor = res.nextCursor;
|
|
56
|
+
} while (cursor);
|
|
57
|
+
for (const t of allTools) {
|
|
58
|
+
const toolName = t.name;
|
|
59
|
+
const mcpClient = client;
|
|
60
|
+
tools.push({
|
|
61
|
+
name: `mcp_${srv.name}_${toolName}`.replace(/[^a-z0-9_]/gi, "_"),
|
|
62
|
+
description: (t.description ?? toolName).slice(0, 500),
|
|
63
|
+
input_schema: t.inputSchema && typeof t.inputSchema === "object" && "type" in t.inputSchema && "properties" in t.inputSchema ? t.inputSchema : {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {}
|
|
66
|
+
},
|
|
67
|
+
handler: async (input) => {
|
|
68
|
+
try {
|
|
69
|
+
const result = await mcpClient.callTool?.({
|
|
70
|
+
name: toolName,
|
|
71
|
+
arguments: input
|
|
72
|
+
});
|
|
73
|
+
const content = result?.content;
|
|
74
|
+
if (Array.isArray(content)) return content.map((c) => c?.text ?? JSON.stringify(c)).join("\n");
|
|
75
|
+
return typeof content === "string" ? content : JSON.stringify(result ?? {});
|
|
76
|
+
} catch (e) {
|
|
77
|
+
return `MCP error: ${e.message}`;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.error(`[mcp] Failed to load ${srv.name}:`, e.message);
|
|
84
|
+
}
|
|
85
|
+
return tools;
|
|
86
|
+
}
|
|
87
|
+
var HC_DIR;
|
|
88
|
+
var init_mcp_loader = require_chunk.__esm({ "src/services/mcp-loader.ts"() {
|
|
89
|
+
HC_DIR = path.default.join(os.default.homedir(), ".hyperclaw");
|
|
90
|
+
} });
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
init_mcp_loader();
|
|
94
|
+
exports.loadMCPTools = loadMCPTools;
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const chalk = require_chunk.__toESM(require("chalk"));
|
|
3
|
+
const ora = require_chunk.__toESM(require("ora"));
|
|
4
|
+
const fs_extra = require_chunk.__toESM(require("fs-extra"));
|
|
5
|
+
const path = require_chunk.__toESM(require("path"));
|
|
6
|
+
const os = require_chunk.__toESM(require("os"));
|
|
7
|
+
|
|
8
|
+
//#region src/agents/memory.ts
|
|
9
|
+
var MemoryManager = class {
|
|
10
|
+
baseDir;
|
|
11
|
+
agentsFile;
|
|
12
|
+
memoryFile;
|
|
13
|
+
logFile;
|
|
14
|
+
constructor(workspaceDir) {
|
|
15
|
+
this.baseDir = workspaceDir || path.default.join(os.default.homedir(), ".hyperclaw");
|
|
16
|
+
this.agentsFile = path.default.join(this.baseDir, "AGENTS.md");
|
|
17
|
+
this.memoryFile = path.default.join(this.baseDir, "MEMORY.md");
|
|
18
|
+
this.logFile = path.default.join(this.baseDir, "logs", `${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.md`);
|
|
19
|
+
}
|
|
20
|
+
async init(identity) {
|
|
21
|
+
await fs_extra.default.ensureDir(this.baseDir);
|
|
22
|
+
await fs_extra.default.ensureDir(path.default.join(this.baseDir, "logs"));
|
|
23
|
+
const spinner = (0, ora.default)("Initializing memory and agent identity...").start();
|
|
24
|
+
await this.writeAgentsMd(identity);
|
|
25
|
+
await this.writeMemoryMd(identity);
|
|
26
|
+
await this.initDailyLog();
|
|
27
|
+
spinner.succeed("AGENTS.md, MEMORY.md and daily log created");
|
|
28
|
+
console.log(chalk.default.gray(` 📁 Workspace: ${this.baseDir}`));
|
|
29
|
+
console.log(chalk.default.gray(` 📄 AGENTS.md: ${this.agentsFile}`));
|
|
30
|
+
console.log(chalk.default.gray(` 🧠 MEMORY.md: ${this.memoryFile}`));
|
|
31
|
+
console.log();
|
|
32
|
+
}
|
|
33
|
+
async writeAgentsMd(id) {
|
|
34
|
+
const content = `# AGENTS.md — HyperClaw Global Agent Rules
|
|
35
|
+
> Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
36
|
+
> This file is read by ALL sessions and subagents.
|
|
37
|
+
|
|
38
|
+
## Identity
|
|
39
|
+
- **Agent Name:** ${id.agentName}
|
|
40
|
+
- **User Name:** ${id.userName}
|
|
41
|
+
- **Personality:** ${id.personality}
|
|
42
|
+
- **Language:** ${id.language}
|
|
43
|
+
|
|
44
|
+
## Global Rules
|
|
45
|
+
${id.rules.map((r, i) => `${i + 1}. ${r}`).join("\n")}
|
|
46
|
+
|
|
47
|
+
## Subagent Hierarchy
|
|
48
|
+
- Parent: HyperClaw Core
|
|
49
|
+
- Children: Channel Agents (Telegram, Discord, etc.)
|
|
50
|
+
- All subagents MUST inherit these rules
|
|
51
|
+
- No subagent may override global safety rules
|
|
52
|
+
|
|
53
|
+
## Memory Protocol
|
|
54
|
+
- Write significant events to MEMORY.md
|
|
55
|
+
- Log daily interactions to logs/YYYY-MM-DD.md
|
|
56
|
+
- Always read AGENTS.md at session start
|
|
57
|
+
|
|
58
|
+
## Safety Boundaries
|
|
59
|
+
- Never reveal the auth token
|
|
60
|
+
- Never execute code outside the sandbox skill
|
|
61
|
+
- Always ask for confirmation before irreversible actions
|
|
62
|
+
- Refuse requests that violate user privacy
|
|
63
|
+
|
|
64
|
+
## Cross-Session Persistence
|
|
65
|
+
- Session state is stored in ~/.hyperclaw/sessions/
|
|
66
|
+
- Use memory tools to recall past interactions
|
|
67
|
+
`;
|
|
68
|
+
await fs_extra.default.writeFile(this.agentsFile, content, "utf8");
|
|
69
|
+
}
|
|
70
|
+
async writeMemoryMd(id) {
|
|
71
|
+
const content = `# MEMORY.md — HyperClaw Persistent Memory
|
|
72
|
+
> Initialized: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
73
|
+
|
|
74
|
+
## User Profile
|
|
75
|
+
- Name: ${id.userName}
|
|
76
|
+
- Preferred language: ${id.language}
|
|
77
|
+
- Agent alias: ${id.agentName}
|
|
78
|
+
|
|
79
|
+
## Session History
|
|
80
|
+
*(Populated automatically during sessions)*
|
|
81
|
+
|
|
82
|
+
## Key Facts
|
|
83
|
+
*(Write important information here for future sessions)*
|
|
84
|
+
|
|
85
|
+
## Reminders
|
|
86
|
+
*(Active reminders are listed here)*
|
|
87
|
+
`;
|
|
88
|
+
await fs_extra.default.writeFile(this.memoryFile, content, "utf8");
|
|
89
|
+
}
|
|
90
|
+
async initDailyLog() {
|
|
91
|
+
const today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", {
|
|
92
|
+
weekday: "long",
|
|
93
|
+
year: "numeric",
|
|
94
|
+
month: "long",
|
|
95
|
+
day: "numeric"
|
|
96
|
+
});
|
|
97
|
+
const content = `# Daily Log — ${today}
|
|
98
|
+
|
|
99
|
+
## Sessions
|
|
100
|
+
- ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} — Session initialized
|
|
101
|
+
|
|
102
|
+
## Notes
|
|
103
|
+
`;
|
|
104
|
+
await fs_extra.default.ensureDir(path.default.dirname(this.logFile));
|
|
105
|
+
await fs_extra.default.writeFile(this.logFile, content, "utf8");
|
|
106
|
+
}
|
|
107
|
+
async appendRule(rule) {
|
|
108
|
+
const spinner = (0, ora.default)("Writing rule to AGENTS.md...").start();
|
|
109
|
+
const content = await fs_extra.default.readFile(this.agentsFile, "utf8");
|
|
110
|
+
const updated = content.replace("*(Populated automatically during sessions)*", `*(Populated automatically during sessions)*\n\n### Added Rule\n- ${rule}`);
|
|
111
|
+
await fs_extra.default.writeFile(this.agentsFile, updated, "utf8");
|
|
112
|
+
spinner.succeed(`Rule added to AGENTS.md`);
|
|
113
|
+
}
|
|
114
|
+
async addMemory(fact) {
|
|
115
|
+
const spinner = (0, ora.default)("Writing to MEMORY.md...").start();
|
|
116
|
+
const content = await fs_extra.default.readFile(this.memoryFile, "utf8");
|
|
117
|
+
const entry = `\n- [${(/* @__PURE__ */ new Date()).toISOString()}] ${fact}`;
|
|
118
|
+
const updated = content.replace("*(Write important information here for future sessions)*", `*(Write important information here for future sessions)*${entry}`);
|
|
119
|
+
await fs_extra.default.writeFile(this.memoryFile, updated, "utf8");
|
|
120
|
+
spinner.succeed(`Memory updated`);
|
|
121
|
+
}
|
|
122
|
+
async load() {
|
|
123
|
+
try {
|
|
124
|
+
const agents = await fs_extra.default.readFile(this.agentsFile, "utf8");
|
|
125
|
+
const memory = await fs_extra.default.readFile(this.memoryFile, "utf8");
|
|
126
|
+
return {
|
|
127
|
+
agents,
|
|
128
|
+
memory
|
|
129
|
+
};
|
|
130
|
+
} catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
getBaseDir() {
|
|
135
|
+
return this.baseDir;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
async function initWorkspaceFiles(identity, workspaceDir) {
|
|
139
|
+
const files = {
|
|
140
|
+
"SOUL.md": generateSoul(identity),
|
|
141
|
+
"USER.md": generateUser(identity),
|
|
142
|
+
"TOOLS.md": generateTools(),
|
|
143
|
+
"HEARTBEAT.md": generateHeartbeat(),
|
|
144
|
+
"BOOTSTRAP.md": generateBootstrap(identity)
|
|
145
|
+
};
|
|
146
|
+
await fs_extra.default.ensureDir(workspaceDir);
|
|
147
|
+
for (const [fname, content] of Object.entries(files)) {
|
|
148
|
+
const fpath = path.default.join(workspaceDir, fname);
|
|
149
|
+
if (!await fs_extra.default.pathExists(fpath)) await fs_extra.default.writeFile(fpath, content, "utf8");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function generateSoul(id) {
|
|
153
|
+
return `# SOUL.md — Agent Personality & Values
|
|
154
|
+
> Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
155
|
+
|
|
156
|
+
## Core Identity
|
|
157
|
+
- **Name:** ${id.agentName}
|
|
158
|
+
- **Personality:** ${id.personality}
|
|
159
|
+
- **Primary language:** ${id.language}
|
|
160
|
+
|
|
161
|
+
## Values
|
|
162
|
+
- Honesty over flattery
|
|
163
|
+
- Brevity — get to the point
|
|
164
|
+
- Respect autonomy — suggest, never demand
|
|
165
|
+
- Always confirm before irreversible actions
|
|
166
|
+
|
|
167
|
+
## Boundaries
|
|
168
|
+
- Never reveal gateway tokens or API keys
|
|
169
|
+
- Always ask confirmation before destructive actions
|
|
170
|
+
- Never claim to be human when sincerely asked
|
|
171
|
+
`;
|
|
172
|
+
}
|
|
173
|
+
function generateUser(id) {
|
|
174
|
+
return `# USER.md — About the Person I Work For
|
|
175
|
+
> Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
176
|
+
|
|
177
|
+
## Identity
|
|
178
|
+
- **Name:** ${id.userName}
|
|
179
|
+
- **Preferred language:** ${id.language}
|
|
180
|
+
|
|
181
|
+
## Communication Preferences
|
|
182
|
+
- Tone: casual
|
|
183
|
+
- Response length: auto
|
|
184
|
+
|
|
185
|
+
## What I'm Working On
|
|
186
|
+
*(Update this regularly — agent uses it for context)*
|
|
187
|
+
|
|
188
|
+
## My Stack
|
|
189
|
+
*(Add your tools here)*
|
|
190
|
+
|
|
191
|
+
## Do NOT do these things
|
|
192
|
+
- Pad responses with unnecessary filler
|
|
193
|
+
|
|
194
|
+
## Always do these things
|
|
195
|
+
- Respond in ${id.language} unless I write in another language
|
|
196
|
+
`;
|
|
197
|
+
}
|
|
198
|
+
function generateTools() {
|
|
199
|
+
return `# TOOLS.md — Available Skills & Tools
|
|
200
|
+
> Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
201
|
+
|
|
202
|
+
## Active Skills
|
|
203
|
+
| ID | Name | Status |
|
|
204
|
+
|----|------|--------|
|
|
205
|
+
| reminders | Smart Reminders | ✅ enabled |
|
|
206
|
+
| translator | Real-time Translator | ✅ enabled |
|
|
207
|
+
|
|
208
|
+
## Add More Skills
|
|
209
|
+
\`\`\`
|
|
210
|
+
hyperclaw hub # Browse available skills
|
|
211
|
+
hyperclaw hub --install web-search
|
|
212
|
+
\`\`\`
|
|
213
|
+
|
|
214
|
+
## MCP Servers
|
|
215
|
+
No MCP servers configured. Add with: \`hyperclaw mcp add\`
|
|
216
|
+
`;
|
|
217
|
+
}
|
|
218
|
+
function generateHeartbeat() {
|
|
219
|
+
return `# HEARTBEAT.md — System Health Log
|
|
220
|
+
> Initialized: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
221
|
+
|
|
222
|
+
Auto-written by the gateway-health hook every 5 minutes.
|
|
223
|
+
Enable with: \`hyperclaw hooks enable gateway-health\`
|
|
224
|
+
|
|
225
|
+
## Last Status
|
|
226
|
+
Pending first heartbeat...
|
|
227
|
+
`;
|
|
228
|
+
}
|
|
229
|
+
function generateBootstrap(id) {
|
|
230
|
+
return `# BOOTSTRAP.md β€” Fast Start Context
|
|
231
|
+
> Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
232
|
+
|
|
233
|
+
## Mission
|
|
234
|
+
Help ${id.userName} move the current task forward with minimal setup friction.
|
|
235
|
+
|
|
236
|
+
## First Tasks
|
|
237
|
+
1. Read AGENTS.md, USER.md, TOOLS.md, and MEMORY.md if present.
|
|
238
|
+
2. Confirm the current repo / project shape before editing anything.
|
|
239
|
+
3. Prefer the smallest change that unblocks progress.
|
|
240
|
+
|
|
241
|
+
## Environment
|
|
242
|
+
- Agent: ${id.agentName}
|
|
243
|
+
- User: ${id.userName}
|
|
244
|
+
- Language: ${id.language}
|
|
245
|
+
|
|
246
|
+
## Current Constraints
|
|
247
|
+
- Ask before irreversible actions.
|
|
248
|
+
- Keep secrets out of workspace markdown files.
|
|
249
|
+
- Update docs when behavior changes.
|
|
250
|
+
|
|
251
|
+
## Definition Of Done
|
|
252
|
+
- Requested change is implemented.
|
|
253
|
+
- Relevant checks or verifications are run when available.
|
|
254
|
+
- Important follow-up risks are documented briefly.
|
|
255
|
+
`;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
//#endregion
|
|
259
|
+
Object.defineProperty(exports, 'MemoryManager', {
|
|
260
|
+
enumerable: true,
|
|
261
|
+
get: function () {
|
|
262
|
+
return MemoryManager;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
Object.defineProperty(exports, 'initWorkspaceFiles', {
|
|
266
|
+
enumerable: true,
|
|
267
|
+
get: function () {
|
|
268
|
+
return initWorkspaceFiles;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
@@ -0,0 +1,306 @@
|
|
|
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
|
+
|
|
7
|
+
//#region packages/core/src/agent/memory-auto.ts
|
|
8
|
+
function isSensitive(text) {
|
|
9
|
+
return SENSITIVE_PATTERNS.some((p) => p.test(text));
|
|
10
|
+
}
|
|
11
|
+
function extractFactsLocally(turns) {
|
|
12
|
+
const facts = [];
|
|
13
|
+
const userMessages = turns.filter((t) => t.role === "user").map((t) => t.content);
|
|
14
|
+
for (const msg of userMessages) {
|
|
15
|
+
if (isSensitive(msg)) continue;
|
|
16
|
+
for (const pattern of PREFERENCE_PATTERNS) {
|
|
17
|
+
const m = msg.match(pattern);
|
|
18
|
+
if (m?.[1] && m[1].length > 4) facts.push({
|
|
19
|
+
fact: `User preference: ${m[1].trim()}`,
|
|
20
|
+
category: "preference",
|
|
21
|
+
confidence: "high"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
for (const pattern of IDENTITY_PATTERNS) {
|
|
25
|
+
const m = msg.match(pattern);
|
|
26
|
+
if (m?.[1] && m[1].length > 2) facts.push({
|
|
27
|
+
fact: `About user: ${m[1].trim()}`,
|
|
28
|
+
category: "identity",
|
|
29
|
+
confidence: "high"
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
for (const pattern of GOAL_PATTERNS) {
|
|
33
|
+
const m = msg.match(pattern);
|
|
34
|
+
if (m?.[1] && m[1].length > 8) facts.push({
|
|
35
|
+
fact: `User goal: ${m[1].trim()}`,
|
|
36
|
+
category: "goal",
|
|
37
|
+
confidence: "medium"
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const seen = /* @__PURE__ */ new Set();
|
|
42
|
+
return facts.filter((f) => {
|
|
43
|
+
const key = f.fact.toLowerCase().slice(0, 40);
|
|
44
|
+
if (seen.has(key)) return false;
|
|
45
|
+
seen.add(key);
|
|
46
|
+
return true;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async function readMemory() {
|
|
50
|
+
try {
|
|
51
|
+
return await fs_extra.default.readFile(MEMORY_FILE, "utf8");
|
|
52
|
+
} catch {
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function appendMemory(facts) {
|
|
57
|
+
if (facts.length === 0) return 0;
|
|
58
|
+
const existing = await readMemory();
|
|
59
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
60
|
+
let added = 0;
|
|
61
|
+
const newLines = [];
|
|
62
|
+
const addedFacts = [];
|
|
63
|
+
for (const f of facts) {
|
|
64
|
+
if (existing.toLowerCase().includes(f.fact.toLowerCase().slice(0, 30))) continue;
|
|
65
|
+
newLines.push(`- ${today} [${f.category}] ${f.fact}`);
|
|
66
|
+
addedFacts.push(f);
|
|
67
|
+
added++;
|
|
68
|
+
}
|
|
69
|
+
if (newLines.length === 0) return 0;
|
|
70
|
+
await fs_extra.default.ensureDir(HC_DIR);
|
|
71
|
+
if (!await fs_extra.default.pathExists(MEMORY_FILE)) await fs_extra.default.writeFile(MEMORY_FILE, "# HyperClaw Memory\n\n");
|
|
72
|
+
await fs_extra.default.appendFile(MEMORY_FILE, "\n" + newLines.join("\n") + "\n");
|
|
73
|
+
try {
|
|
74
|
+
const { onMemoryAppended } = await Promise.resolve().then(() => require("./memory-integration-cSYkZyEo.js"));
|
|
75
|
+
await onMemoryAppended(addedFacts.map((f) => ({ fact: f.fact })));
|
|
76
|
+
} catch {}
|
|
77
|
+
return added;
|
|
78
|
+
}
|
|
79
|
+
async function saveMemoryDirect(text) {
|
|
80
|
+
await fs_extra.default.ensureDir(HC_DIR);
|
|
81
|
+
if (!await fs_extra.default.pathExists(MEMORY_FILE)) await fs_extra.default.writeFile(MEMORY_FILE, "# HyperClaw Memory\n\n");
|
|
82
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
83
|
+
await fs_extra.default.appendFile(MEMORY_FILE, `\n- ${today} ${text}\n`);
|
|
84
|
+
try {
|
|
85
|
+
const { onMemoryAppended } = await Promise.resolve().then(() => require("./memory-integration-cSYkZyEo.js"));
|
|
86
|
+
await onMemoryAppended([{ fact: text }]);
|
|
87
|
+
} catch {}
|
|
88
|
+
}
|
|
89
|
+
async function extractFactsWithAI(turns, inferenceOpts) {
|
|
90
|
+
const totalText = turns.map((t) => t.content).join(" ");
|
|
91
|
+
if (totalText.length < 100) return [];
|
|
92
|
+
const localFacts = extractFactsLocally(turns);
|
|
93
|
+
const hasPersonalContext = /\b(I|my|me|mine|myself)\b/i.test(totalText);
|
|
94
|
+
if (!hasPersonalContext) return localFacts;
|
|
95
|
+
try {
|
|
96
|
+
const { InferenceEngine } = await Promise.resolve().then(() => require("./inference-BKVkBREb.js"));
|
|
97
|
+
const engine = new InferenceEngine({
|
|
98
|
+
model: inferenceOpts.model,
|
|
99
|
+
apiKey: inferenceOpts.apiKey,
|
|
100
|
+
provider: inferenceOpts.provider,
|
|
101
|
+
maxTokens: 512,
|
|
102
|
+
tools: []
|
|
103
|
+
});
|
|
104
|
+
const conversationSummary = turns.slice(-6).map((t) => `${t.role === "user" ? "User" : "AI"}: ${t.content.slice(0, 300)}`).join("\n");
|
|
105
|
+
const result = await engine.run([{
|
|
106
|
+
role: "user",
|
|
107
|
+
content: `Extract ONLY concrete, reusable facts about the USER from this conversation.
|
|
108
|
+
Skip: passwords, API keys, one-off questions, assistant responses.
|
|
109
|
+
Include: name, job, preferences, ongoing projects, locations, recurring tasks.
|
|
110
|
+
|
|
111
|
+
Conversation:
|
|
112
|
+
${conversationSummary}
|
|
113
|
+
|
|
114
|
+
Respond with a JSON array of strings, each a short fact starting with "User".
|
|
115
|
+
If nothing worth saving, respond: []
|
|
116
|
+
Example: ["User's name is Alex", "User prefers TypeScript over JavaScript", "User is building a SaaS app"]`
|
|
117
|
+
}]);
|
|
118
|
+
const clean = result.text.replace(/```json|```/g, "").trim();
|
|
119
|
+
const aiFactStrings = JSON.parse(clean);
|
|
120
|
+
const allFacts = [...localFacts];
|
|
121
|
+
const existingFactText = localFacts.map((f) => f.fact.toLowerCase());
|
|
122
|
+
for (const factStr of aiFactStrings) {
|
|
123
|
+
if (!factStr || factStr.length < 5) continue;
|
|
124
|
+
if (isSensitive(factStr)) continue;
|
|
125
|
+
if (existingFactText.some((e) => e.includes(factStr.toLowerCase().slice(0, 20)))) continue;
|
|
126
|
+
const cat = /prefer|like|hate|always|never|don't/i.test(factStr) ? "preference" : /goal|want|trying|working on|building/i.test(factStr) ? "goal" : /name|job|work|role|from|based/i.test(factStr) ? "identity" : "context";
|
|
127
|
+
allFacts.push({
|
|
128
|
+
fact: factStr,
|
|
129
|
+
category: cat,
|
|
130
|
+
confidence: "medium"
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return allFacts;
|
|
134
|
+
} catch {
|
|
135
|
+
return localFacts;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function showMemory() {
|
|
139
|
+
const content = await readMemory();
|
|
140
|
+
if (!content.trim()) {
|
|
141
|
+
console.log(chalk.default.gray("\n 🧠 MEMORY.md is empty\n"));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
console.log(chalk.default.bold.cyan("\n 🧠 MEMORY\n"));
|
|
145
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
146
|
+
for (const line of lines) if (line.startsWith("#")) console.log(chalk.default.bold.white(line));
|
|
147
|
+
else if (line.startsWith("-")) {
|
|
148
|
+
const parts = line.match(/^-\s+(\S+)\s+\[(\w+)\]\s+(.+)$/);
|
|
149
|
+
if (parts) {
|
|
150
|
+
const [, date, cat, fact] = parts;
|
|
151
|
+
const catColor = cat === "preference" ? chalk.default.cyan : cat === "identity" ? chalk.default.yellow : cat === "goal" ? chalk.default.green : chalk.default.gray;
|
|
152
|
+
console.log(` ${chalk.default.gray(date)} ${catColor(`[${cat}]`)} ${fact}`);
|
|
153
|
+
} else console.log(` ${line}`);
|
|
154
|
+
}
|
|
155
|
+
console.log();
|
|
156
|
+
}
|
|
157
|
+
async function clearMemory() {
|
|
158
|
+
await fs_extra.default.writeFile(MEMORY_FILE, "# HyperClaw Memory\n\n");
|
|
159
|
+
console.log(chalk.default.green(" ✅ Memory cleared\n"));
|
|
160
|
+
}
|
|
161
|
+
async function searchMemory(query) {
|
|
162
|
+
const content = await readMemory();
|
|
163
|
+
const lines = content.split("\n").filter((l) => l.toLowerCase().includes(query.toLowerCase()));
|
|
164
|
+
if (lines.length === 0) {
|
|
165
|
+
console.log(chalk.default.gray(` No memories found for: "${query}"\n`));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
console.log(chalk.default.bold.cyan(`\n 🔍 Memory search: "${query}"\n`));
|
|
169
|
+
for (const line of lines) console.log(` ${line}`);
|
|
170
|
+
console.log();
|
|
171
|
+
}
|
|
172
|
+
var HC_DIR, MEMORY_FILE, SOUL_FILE, PREFERENCE_PATTERNS, IDENTITY_PATTERNS, GOAL_PATTERNS, SENSITIVE_PATTERNS, AutoMemory;
|
|
173
|
+
var init_memory_auto = require_chunk.__esm({ "packages/core/src/agent/memory-auto.ts"() {
|
|
174
|
+
HC_DIR = path.default.join(os.default.homedir(), ".hyperclaw");
|
|
175
|
+
MEMORY_FILE = path.default.join(HC_DIR, "MEMORY.md");
|
|
176
|
+
SOUL_FILE = path.default.join(HC_DIR, "SOUL.md");
|
|
177
|
+
PREFERENCE_PATTERNS = [
|
|
178
|
+
/i (?:prefer|like|love|hate|dislike|always|never)\s+(.{5,80})/i,
|
|
179
|
+
/(?:my favorite|my preferred)\s+(.{5,80})/i,
|
|
180
|
+
/(?:please )?always\s+((?:use|do|write|respond|answer|format|reply)\s+.{5,60})/i,
|
|
181
|
+
/don'?t (?:ever )?(.{5,60})/i,
|
|
182
|
+
/(?:i want you to always)\s+(.{5,80})/i
|
|
183
|
+
];
|
|
184
|
+
IDENTITY_PATTERNS = [
|
|
185
|
+
/(?:my name is|i'?m called|call me)\s+([A-ZΑ-Ωa-zα-ω][a-zα-ω]{1,30})/i,
|
|
186
|
+
/i(?:'m| am) (?:a |an )?([A-Za-zΑ-Ωα-ω][\w\s]{3,40}?)(?:\.|,|$)/i,
|
|
187
|
+
/i work (?:at|for|as)\s+(.{5,60})/i,
|
|
188
|
+
/i(?:'m| am) (?:from|in|based in)\s+(.{3,40})/i,
|
|
189
|
+
/my (?:job|role|position|title) is\s+(.{5,60})/i
|
|
190
|
+
];
|
|
191
|
+
GOAL_PATTERNS = [
|
|
192
|
+
/i(?:'m| am) (?:working on|building|creating|developing)\s+(.{10,100})/i,
|
|
193
|
+
/i want to\s+(.{10,100})/i,
|
|
194
|
+
/my goal is (?:to\s+)?(.{10,100})/i,
|
|
195
|
+
/i'?m trying to\s+(.{10,100})/i
|
|
196
|
+
];
|
|
197
|
+
SENSITIVE_PATTERNS = [
|
|
198
|
+
/password/i,
|
|
199
|
+
/passwd/i,
|
|
200
|
+
/secret key/i,
|
|
201
|
+
/api.?key/i,
|
|
202
|
+
/credit.?card/i,
|
|
203
|
+
/\b\d{4}[\s-]\d{4}[\s-]\d{4}[\s-]\d{4}\b/,
|
|
204
|
+
/ssn|social security/i,
|
|
205
|
+
/\b\d{3}-\d{2}-\d{4}\b/
|
|
206
|
+
];
|
|
207
|
+
AutoMemory = class {
|
|
208
|
+
turns = [];
|
|
209
|
+
turnsSinceLastExtract = 0;
|
|
210
|
+
extractEveryNTurns;
|
|
211
|
+
useAI;
|
|
212
|
+
aiOpts;
|
|
213
|
+
constructor(opts = {}) {
|
|
214
|
+
this.extractEveryNTurns = opts.extractEveryNTurns ?? 4;
|
|
215
|
+
this.useAI = opts.useAI ?? false;
|
|
216
|
+
this.aiOpts = opts.aiOpts;
|
|
217
|
+
}
|
|
218
|
+
addTurn(role, content) {
|
|
219
|
+
this.turns.push({
|
|
220
|
+
role,
|
|
221
|
+
content,
|
|
222
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
223
|
+
});
|
|
224
|
+
this.turnsSinceLastExtract++;
|
|
225
|
+
}
|
|
226
|
+
async maybeExtract() {
|
|
227
|
+
if (this.turnsSinceLastExtract < this.extractEveryNTurns) return 0;
|
|
228
|
+
this.turnsSinceLastExtract = 0;
|
|
229
|
+
return this.extract();
|
|
230
|
+
}
|
|
231
|
+
async extract() {
|
|
232
|
+
const facts = this.useAI && this.aiOpts ? await extractFactsWithAI(this.turns, this.aiOpts) : extractFactsLocally(this.turns);
|
|
233
|
+
const saved = await appendMemory(facts);
|
|
234
|
+
if (saved > 0) console.log(chalk.default.gray(` 🧠 Auto-saved ${saved} fact${saved === 1 ? "" : "s"} to MEMORY.md`));
|
|
235
|
+
return saved;
|
|
236
|
+
}
|
|
237
|
+
clearTurns() {
|
|
238
|
+
this.turns = [];
|
|
239
|
+
}
|
|
240
|
+
getTurns() {
|
|
241
|
+
return [...this.turns];
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
} });
|
|
245
|
+
|
|
246
|
+
//#endregion
|
|
247
|
+
Object.defineProperty(exports, 'AutoMemory', {
|
|
248
|
+
enumerable: true,
|
|
249
|
+
get: function () {
|
|
250
|
+
return AutoMemory;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
Object.defineProperty(exports, 'appendMemory', {
|
|
254
|
+
enumerable: true,
|
|
255
|
+
get: function () {
|
|
256
|
+
return appendMemory;
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
Object.defineProperty(exports, 'clearMemory', {
|
|
260
|
+
enumerable: true,
|
|
261
|
+
get: function () {
|
|
262
|
+
return clearMemory;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
Object.defineProperty(exports, 'extractFactsLocally', {
|
|
266
|
+
enumerable: true,
|
|
267
|
+
get: function () {
|
|
268
|
+
return extractFactsLocally;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
Object.defineProperty(exports, 'extractFactsWithAI', {
|
|
272
|
+
enumerable: true,
|
|
273
|
+
get: function () {
|
|
274
|
+
return extractFactsWithAI;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
Object.defineProperty(exports, 'init_memory_auto', {
|
|
278
|
+
enumerable: true,
|
|
279
|
+
get: function () {
|
|
280
|
+
return init_memory_auto;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
Object.defineProperty(exports, 'readMemory', {
|
|
284
|
+
enumerable: true,
|
|
285
|
+
get: function () {
|
|
286
|
+
return readMemory;
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
Object.defineProperty(exports, 'saveMemoryDirect', {
|
|
290
|
+
enumerable: true,
|
|
291
|
+
get: function () {
|
|
292
|
+
return saveMemoryDirect;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
Object.defineProperty(exports, 'searchMemory', {
|
|
296
|
+
enumerable: true,
|
|
297
|
+
get: function () {
|
|
298
|
+
return searchMemory;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
Object.defineProperty(exports, 'showMemory', {
|
|
302
|
+
enumerable: true,
|
|
303
|
+
get: function () {
|
|
304
|
+
return showMemory;
|
|
305
|
+
}
|
|
306
|
+
});
|