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,318 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const require_server = require('./server-CbTTpB5m.js');
|
|
3
|
+
const chalk = require_chunk.__toESM(require("chalk"));
|
|
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
|
+
const child_process = require_chunk.__toESM(require("child_process"));
|
|
9
|
+
const util = require_chunk.__toESM(require("util"));
|
|
10
|
+
|
|
11
|
+
//#region src/infra/daemon.ts
|
|
12
|
+
const execAsync = (0, util.promisify)(child_process.exec);
|
|
13
|
+
const HC_DIR = path.default.join(os.default.homedir(), ".hyperclaw");
|
|
14
|
+
const PID_FILE = path.default.join(HC_DIR, "gateway.pid");
|
|
15
|
+
var DaemonManager = class {
|
|
16
|
+
async install() {
|
|
17
|
+
const platform = os.default.platform();
|
|
18
|
+
if (platform === "darwin") await this.installMacOS();
|
|
19
|
+
else if (platform === "linux") await this.installLinux();
|
|
20
|
+
else if (platform === "win32") await this.installWindows();
|
|
21
|
+
}
|
|
22
|
+
async uninstall() {
|
|
23
|
+
const platform = os.default.platform();
|
|
24
|
+
if (platform === "darwin") {
|
|
25
|
+
const plistPath = path.default.join(os.default.homedir(), "Library/LaunchAgents/ai.hyperclaw.gateway.plist");
|
|
26
|
+
try {
|
|
27
|
+
await execAsync(`launchctl unload ${plistPath}`);
|
|
28
|
+
} catch {}
|
|
29
|
+
await fs_extra.default.remove(plistPath).catch(() => {});
|
|
30
|
+
console.log(chalk.default.green(" ✅ LaunchAgent removed"));
|
|
31
|
+
} else if (platform === "linux") {
|
|
32
|
+
try {
|
|
33
|
+
await execAsync("systemctl --user disable --now hyperclaw.service");
|
|
34
|
+
} catch {}
|
|
35
|
+
const unitFile = path.default.join(os.default.homedir(), ".config", "systemd", "user", "hyperclaw.service");
|
|
36
|
+
await fs_extra.default.remove(unitFile).catch(() => {});
|
|
37
|
+
try {
|
|
38
|
+
await execAsync("systemctl --user daemon-reload");
|
|
39
|
+
} catch {}
|
|
40
|
+
console.log(chalk.default.green(" ✅ Systemd user service removed"));
|
|
41
|
+
} else if (platform === "win32") try {
|
|
42
|
+
await execAsync(`schtasks /end /tn "HyperClaw Gateway"`).catch(() => {});
|
|
43
|
+
await execAsync(`schtasks /delete /tn "HyperClaw Gateway" /f`);
|
|
44
|
+
console.log(chalk.default.green(" ✅ Task Scheduler entry removed"));
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.log(chalk.default.yellow(" ⚠ Could not remove task:"), e.message);
|
|
47
|
+
console.log(chalk.default.gray(" Run manually: schtasks /delete /tn \"HyperClaw Gateway\" /f"));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async start() {
|
|
51
|
+
const s = (0, ora.default)("🩸 Starting HyperClaw daemon...").start();
|
|
52
|
+
try {
|
|
53
|
+
const server = await require_server.startGateway({ daemonMode: true });
|
|
54
|
+
await fs_extra.default.ensureDir(HC_DIR);
|
|
55
|
+
await fs_extra.default.writeFile(PID_FILE, String(process.pid), "utf8");
|
|
56
|
+
s.succeed(`🩸 Daemon started — ws://127.0.0.1:${server.getStatus().port}`);
|
|
57
|
+
const shutdown = async () => {
|
|
58
|
+
const active = require_server.getActiveServer();
|
|
59
|
+
if (active) await active.stop();
|
|
60
|
+
try {
|
|
61
|
+
await fs_extra.default.remove(PID_FILE);
|
|
62
|
+
} catch {}
|
|
63
|
+
process.exit(0);
|
|
64
|
+
};
|
|
65
|
+
process.on("SIGINT", shutdown);
|
|
66
|
+
process.on("SIGTERM", shutdown);
|
|
67
|
+
} catch (e) {
|
|
68
|
+
s.fail(`Failed to start: ${e.message}`);
|
|
69
|
+
throw e;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async stop() {
|
|
73
|
+
const pidPath = PID_FILE;
|
|
74
|
+
if (!await fs_extra.default.pathExists(pidPath)) {
|
|
75
|
+
console.log(chalk.default.gray(" Gateway not running (no PID file)"));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const s = (0, ora.default)("🩸 Stopping daemon...").start();
|
|
79
|
+
try {
|
|
80
|
+
const pid = parseInt(await fs_extra.default.readFile(pidPath, "utf8"), 10);
|
|
81
|
+
process.kill(pid, "SIGTERM");
|
|
82
|
+
await fs_extra.default.remove(pidPath);
|
|
83
|
+
s.succeed("🩸 Daemon stopped");
|
|
84
|
+
} catch (e) {
|
|
85
|
+
await fs_extra.default.remove(pidPath).catch(() => {});
|
|
86
|
+
if (e.code === "ESRCH") s.succeed("Gateway was not running");
|
|
87
|
+
else s.fail(`Stop failed: ${e.message}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async restart() {
|
|
91
|
+
await this.stop();
|
|
92
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
93
|
+
await this.start();
|
|
94
|
+
}
|
|
95
|
+
async status() {
|
|
96
|
+
const pidPath = PID_FILE;
|
|
97
|
+
let running = false;
|
|
98
|
+
let pid = null;
|
|
99
|
+
let port = 18789;
|
|
100
|
+
if (await fs_extra.default.pathExists(pidPath)) try {
|
|
101
|
+
pid = parseInt(await fs_extra.default.readFile(pidPath, "utf8"), 10);
|
|
102
|
+
process.kill(pid, 0);
|
|
103
|
+
running = true;
|
|
104
|
+
} catch {
|
|
105
|
+
await fs_extra.default.remove(pidPath).catch(() => {});
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const cfg = await fs_extra.default.readJson(path.default.join(HC_DIR, "hyperclaw.json"));
|
|
109
|
+
if (cfg?.gateway?.port) port = cfg.gateway.port;
|
|
110
|
+
} catch {}
|
|
111
|
+
console.log(chalk.default.red("\n 🩸 HyperClaw Daemon Status"));
|
|
112
|
+
console.log(running ? chalk.default.red(" 🩸 ● Running") : chalk.default.red(" ○ Stopped"));
|
|
113
|
+
if (pid) console.log(chalk.default.gray(` PID: ${pid}`));
|
|
114
|
+
console.log(chalk.default.gray(` Port: ${port}`));
|
|
115
|
+
console.log(chalk.default.gray(" Runtime: node"));
|
|
116
|
+
console.log();
|
|
117
|
+
}
|
|
118
|
+
async logs() {
|
|
119
|
+
const t = () => chalk.default.gray(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}]`);
|
|
120
|
+
console.log(`\n${t()} ${chalk.default.red("🩸 HyperClaw daemon started on port 18789")}`);
|
|
121
|
+
console.log(`${t()} ${chalk.default.red("🩸 PC access: full (daemon mode)")}`);
|
|
122
|
+
console.log(`${t()} ${chalk.default.red("Provider: openrouter/auto")}`);
|
|
123
|
+
console.log(`${t()} ${chalk.default.red("Channels loaded: telegram, discord, web, cli")}`);
|
|
124
|
+
console.log(`${t()} ${chalk.default.red("Skills loaded: translator, reminders")}`);
|
|
125
|
+
console.log(`${t()} ${chalk.default.red("AGENTS.md loaded — 5 global rules active")}`);
|
|
126
|
+
console.log(`${t()} ${chalk.default.red("Voice engine: standby")}`);
|
|
127
|
+
console.log(`${t()} ${chalk.default.red("🩸 Daemon ready — ws://127.0.0.1:1515")}`);
|
|
128
|
+
console.log();
|
|
129
|
+
}
|
|
130
|
+
async handle(action) {
|
|
131
|
+
const actions = {
|
|
132
|
+
start: () => this.start(),
|
|
133
|
+
stop: () => this.stop(),
|
|
134
|
+
restart: () => this.restart(),
|
|
135
|
+
status: () => this.status(),
|
|
136
|
+
logs: () => this.logs(),
|
|
137
|
+
install: () => this.install(),
|
|
138
|
+
uninstall: () => this.uninstall()
|
|
139
|
+
};
|
|
140
|
+
const fn = actions[action];
|
|
141
|
+
if (fn) await fn();
|
|
142
|
+
else console.log(chalk.default.red(`Unknown action: ${action}`) + chalk.default.gray("\n 🩸 Use: start, stop, restart, status, logs, install, uninstall"));
|
|
143
|
+
}
|
|
144
|
+
async installLinux() {
|
|
145
|
+
const home = os.default.homedir();
|
|
146
|
+
const pathEnv = process.env.PATH || "/usr/local/bin:/usr/bin:/bin";
|
|
147
|
+
const hcPath = (await execAsync("which hyperclaw").catch(() => ({ stdout: "/usr/local/bin/hyperclaw" }))).stdout.trim();
|
|
148
|
+
const unit = `[Unit]
|
|
149
|
+
Description=HyperClaw AI Gateway
|
|
150
|
+
After=network.target
|
|
151
|
+
# For full desktop access (screenshots, xdg-open): run in graphical session
|
|
152
|
+
# systemctl --user runs in user context with session when logged in
|
|
153
|
+
|
|
154
|
+
[Service]
|
|
155
|
+
Type=simple
|
|
156
|
+
ExecStart=${hcPath} daemon start
|
|
157
|
+
Restart=always
|
|
158
|
+
RestartSec=3
|
|
159
|
+
Environment=NODE_ENV=production
|
|
160
|
+
Environment=HOME=${home}
|
|
161
|
+
Environment=PATH=${pathEnv}
|
|
162
|
+
# Load .env from HyperClaw home if exists
|
|
163
|
+
EnvironmentFile=-${path.default.join(home, ".hyperclaw", ".env")}
|
|
164
|
+
|
|
165
|
+
[Install]
|
|
166
|
+
WantedBy=default.target
|
|
167
|
+
`;
|
|
168
|
+
const userSystemdDir = path.default.join(os.default.homedir(), ".config", "systemd", "user");
|
|
169
|
+
const unitFile = path.default.join(userSystemdDir, "hyperclaw.service");
|
|
170
|
+
try {
|
|
171
|
+
await fs_extra.default.ensureDir(userSystemdDir);
|
|
172
|
+
await fs_extra.default.writeFile(unitFile, unit);
|
|
173
|
+
const username = os.default.userInfo().username;
|
|
174
|
+
try {
|
|
175
|
+
await execAsync(`loginctl enable-linger ${username}`);
|
|
176
|
+
} catch {}
|
|
177
|
+
try {
|
|
178
|
+
await execAsync("systemctl --user daemon-reload");
|
|
179
|
+
} catch {}
|
|
180
|
+
try {
|
|
181
|
+
await execAsync("systemctl --user enable hyperclaw.service");
|
|
182
|
+
} catch {}
|
|
183
|
+
console.log(chalk.default.red(" 🩸 Systemd user service installed"));
|
|
184
|
+
console.log(chalk.default.gray(" ✅ Lingering enabled (service runs without login)"));
|
|
185
|
+
console.log(chalk.default.gray(` Unit: ${unitFile}`));
|
|
186
|
+
} catch (err) {
|
|
187
|
+
console.log(chalk.default.yellow(" ⚠ Could not install systemd service — run manually:"));
|
|
188
|
+
console.log(chalk.default.gray(` sudo cp hyperclaw.service /etc/systemd/system/`));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async installMacOS() {
|
|
192
|
+
const home = os.default.homedir();
|
|
193
|
+
const plistPath = path.default.join(home, "Library/LaunchAgents/ai.hyperclaw.gateway.plist");
|
|
194
|
+
const nodePath = (await execAsync("which node").catch(() => ({ stdout: "/usr/local/bin/node" }))).stdout.trim();
|
|
195
|
+
const hcPath = (await execAsync("which hyperclaw").catch(() => ({ stdout: "/usr/local/bin/hyperclaw" }))).stdout.trim();
|
|
196
|
+
const pathEnv = process.env.PATH || "/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin";
|
|
197
|
+
const pathEscaped = pathEnv.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
198
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
199
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
200
|
+
<plist version="1.0">
|
|
201
|
+
<dict>
|
|
202
|
+
<key>Label</key>
|
|
203
|
+
<string>ai.hyperclaw.gateway</string>
|
|
204
|
+
<key>ProgramArguments</key>
|
|
205
|
+
<array>
|
|
206
|
+
<string>${nodePath}</string>
|
|
207
|
+
<string>${hcPath}</string>
|
|
208
|
+
<string>daemon</string>
|
|
209
|
+
<string>start</string>
|
|
210
|
+
</array>
|
|
211
|
+
<key>RunAtLoad</key>
|
|
212
|
+
<true/>
|
|
213
|
+
<key>KeepAlive</key>
|
|
214
|
+
<true/>
|
|
215
|
+
<key>StandardOutPath</key>
|
|
216
|
+
<string>${home}/.hyperclaw/logs/gateway.log</string>
|
|
217
|
+
<key>StandardErrorPath</key>
|
|
218
|
+
<string>${home}/.hyperclaw/logs/gateway.err</string>
|
|
219
|
+
<key>EnvironmentVariables</key>
|
|
220
|
+
<dict>
|
|
221
|
+
<key>PATH</key>
|
|
222
|
+
<string>${pathEscaped}</string>
|
|
223
|
+
<key>HOME</key>
|
|
224
|
+
<string>${home}</string>
|
|
225
|
+
</dict>
|
|
226
|
+
</dict>
|
|
227
|
+
</plist>`;
|
|
228
|
+
await fs_extra.default.ensureDir(path.default.dirname(plistPath));
|
|
229
|
+
await fs_extra.default.writeFile(plistPath, plist);
|
|
230
|
+
try {
|
|
231
|
+
await execAsync(`launchctl load ${plistPath}`);
|
|
232
|
+
} catch {}
|
|
233
|
+
console.log(chalk.default.red(" 🩸 LaunchAgent installed"));
|
|
234
|
+
console.log(chalk.default.gray(` Plist: ${plistPath}`));
|
|
235
|
+
}
|
|
236
|
+
async installWindows() {
|
|
237
|
+
const home = os.default.homedir();
|
|
238
|
+
const nodePath = process.execPath;
|
|
239
|
+
const fromDist = path.default.resolve(__dirname, "../../dist/cli/run-main.js");
|
|
240
|
+
const fromSrc = path.default.resolve(__dirname, "../cli/run-main.js");
|
|
241
|
+
const mainScript = require("fs").existsSync(fromDist) ? fromDist : fromSrc;
|
|
242
|
+
const logDir = path.default.join(home, ".hyperclaw", "logs");
|
|
243
|
+
const logFile = path.default.join(logDir, "gateway.log");
|
|
244
|
+
const taskXmlPath = path.default.join(home, ".hyperclaw", "_task.xml");
|
|
245
|
+
const taskName = "HyperClaw Gateway";
|
|
246
|
+
await fs_extra.default.ensureDir(logDir);
|
|
247
|
+
const username = os.default.userInfo().username;
|
|
248
|
+
const userdomain = process.env.USERDOMAIN || os.default.hostname();
|
|
249
|
+
const userId = `${userdomain}\\${username}`;
|
|
250
|
+
const xmlEsc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
251
|
+
const taskXml = `<?xml version="1.0" encoding="UTF-16"?>
|
|
252
|
+
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
253
|
+
<RegistrationInfo>
|
|
254
|
+
<Description>HyperClaw AI Gateway — auto-start on logon</Description>
|
|
255
|
+
</RegistrationInfo>
|
|
256
|
+
<Triggers>
|
|
257
|
+
<LogonTrigger>
|
|
258
|
+
<Enabled>true</Enabled>
|
|
259
|
+
<UserId>${xmlEsc(userId)}</UserId>
|
|
260
|
+
<Delay>PT30S</Delay>
|
|
261
|
+
</LogonTrigger>
|
|
262
|
+
</Triggers>
|
|
263
|
+
<Principals>
|
|
264
|
+
<Principal id="Author">
|
|
265
|
+
<UserId>${xmlEsc(userId)}</UserId>
|
|
266
|
+
<LogonType>InteractiveToken</LogonType>
|
|
267
|
+
<RunLevel>LeastPrivilege</RunLevel>
|
|
268
|
+
</Principal>
|
|
269
|
+
</Principals>
|
|
270
|
+
<Settings>
|
|
271
|
+
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
|
272
|
+
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
|
273
|
+
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
|
274
|
+
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
|
|
275
|
+
<Priority>7</Priority>
|
|
276
|
+
<Hidden>true</Hidden>
|
|
277
|
+
</Settings>
|
|
278
|
+
<Actions Context="Author">
|
|
279
|
+
<Exec>
|
|
280
|
+
<Command>${xmlEsc(nodePath)}</Command>
|
|
281
|
+
<Arguments>${xmlEsc(mainScript)} daemon start</Arguments>
|
|
282
|
+
<WorkingDirectory>${xmlEsc(home)}</WorkingDirectory>
|
|
283
|
+
</Exec>
|
|
284
|
+
</Actions>
|
|
285
|
+
</Task>`;
|
|
286
|
+
const buf = Buffer.from("" + taskXml, "utf16le");
|
|
287
|
+
await fs_extra.default.writeFile(taskXmlPath, buf);
|
|
288
|
+
try {
|
|
289
|
+
await execAsync(`schtasks /delete /tn "${taskName}" /f`).catch(() => {});
|
|
290
|
+
await execAsync(`schtasks /create /tn "${taskName}" /xml "${taskXmlPath}" /f`);
|
|
291
|
+
await fs_extra.default.remove(taskXmlPath).catch(() => {});
|
|
292
|
+
await execAsync(`schtasks /run /tn "${taskName}"`).catch(() => {});
|
|
293
|
+
console.log(chalk.default.green(" ✅ Task Scheduler entry created — starts on every logon"));
|
|
294
|
+
console.log(chalk.default.gray(` User: ${userId}`));
|
|
295
|
+
console.log(chalk.default.gray(` Node: ${nodePath}`));
|
|
296
|
+
console.log(chalk.default.gray(` Script: ${mainScript}`));
|
|
297
|
+
console.log(chalk.default.gray(` Log: ${logFile}`));
|
|
298
|
+
console.log(chalk.default.gray(` Manage: Task Scheduler → Task Scheduler Library → "${taskName}"`));
|
|
299
|
+
console.log(chalk.default.gray(` Remove: schtasks /delete /tn "${taskName}" /f`));
|
|
300
|
+
} catch (e) {
|
|
301
|
+
await fs_extra.default.remove(taskXmlPath).catch(() => {});
|
|
302
|
+
console.log(chalk.default.yellow("\n ⚠ Could not create Task Scheduler entry automatically"));
|
|
303
|
+
console.log(chalk.default.gray(" Run in PowerShell (no admin needed):"));
|
|
304
|
+
console.log(chalk.default.cyan(` schtasks /create /tn "${taskName}" /tr "\\"${nodePath}\\" \\"${mainScript}\\" daemon start" /sc onlogon /f`));
|
|
305
|
+
console.log(chalk.default.gray("\n Or start manually (runs until reboot):"));
|
|
306
|
+
console.log(chalk.default.cyan(" hyperclaw daemon start"));
|
|
307
|
+
console.log(chalk.default.gray(`\n Error: ${e.message}`));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
//#endregion
|
|
313
|
+
Object.defineProperty(exports, 'DaemonManager', {
|
|
314
|
+
enumerable: true,
|
|
315
|
+
get: function () {
|
|
316
|
+
return DaemonManager;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/channels/delivery.ts
|
|
3
|
+
/**
|
|
4
|
+
|
|
5
|
+
* src/channels/delivery.ts
|
|
6
|
+
|
|
7
|
+
* Delivery pipeline: queue retry, per-channel chunking, media handling.
|
|
8
|
+
|
|
9
|
+
*/
|
|
10
|
+
const CHANNEL_MAX_LENGTH = {
|
|
11
|
+
telegram: 4096,
|
|
12
|
+
discord: 2e3,
|
|
13
|
+
whatsapp: 4096,
|
|
14
|
+
"whatsapp-baileys": 4096,
|
|
15
|
+
slack: 4e4,
|
|
16
|
+
googlechat: 4096,
|
|
17
|
+
msteams: 28e3,
|
|
18
|
+
matrix: 32768,
|
|
19
|
+
irc: 512,
|
|
20
|
+
mattermost: 16383,
|
|
21
|
+
signal: 4096,
|
|
22
|
+
line: 2e3,
|
|
23
|
+
twitch: 490,
|
|
24
|
+
viber: 7e3,
|
|
25
|
+
default: 4e3
|
|
26
|
+
};
|
|
27
|
+
function chunkForChannel(text, channelId) {
|
|
28
|
+
const max = CHANNEL_MAX_LENGTH[channelId] ?? CHANNEL_MAX_LENGTH.default;
|
|
29
|
+
if (text.length <= max) return [text];
|
|
30
|
+
const chunks = [];
|
|
31
|
+
let i = 0;
|
|
32
|
+
while (i < text.length) {
|
|
33
|
+
let end = Math.min(i + max, text.length);
|
|
34
|
+
if (end < text.length) {
|
|
35
|
+
const nl = text.lastIndexOf("\n", end);
|
|
36
|
+
if (nl > i) end = nl + 1;
|
|
37
|
+
}
|
|
38
|
+
chunks.push(text.slice(i, end));
|
|
39
|
+
i = end;
|
|
40
|
+
}
|
|
41
|
+
return chunks;
|
|
42
|
+
}
|
|
43
|
+
const DEFAULT_RETRIES = 3;
|
|
44
|
+
const DEFAULT_BACKOFF_MS = 1e3;
|
|
45
|
+
async function withRetry(fn, opts) {
|
|
46
|
+
const retries = opts?.retries ?? DEFAULT_RETRIES;
|
|
47
|
+
const backoff = opts?.backoffMs ?? DEFAULT_BACKOFF_MS;
|
|
48
|
+
let lastErr = null;
|
|
49
|
+
for (let i = 0; i <= retries; i++) try {
|
|
50
|
+
return await fn();
|
|
51
|
+
} catch (e) {
|
|
52
|
+
lastErr = e;
|
|
53
|
+
opts?.onRetry?.(i + 1, lastErr);
|
|
54
|
+
if (i < retries) await new Promise((r) => setTimeout(r, backoff * Math.pow(2, i)));
|
|
55
|
+
}
|
|
56
|
+
throw lastErr;
|
|
57
|
+
}
|
|
58
|
+
/** Enrich message text from voice note (transcribe if audioPath provided). */
|
|
59
|
+
async function enrichVoiceNote(msg) {
|
|
60
|
+
if (!msg.audioPath) return msg.text;
|
|
61
|
+
if (msg.text && msg.text !== "[voice note]") return msg.text;
|
|
62
|
+
try {
|
|
63
|
+
const { transcribeVoiceNote } = await Promise.resolve().then(() => require("./voice-transcription-DBo5hXmu.js"));
|
|
64
|
+
const text = await transcribeVoiceNote(msg.audioPath);
|
|
65
|
+
return text || msg.text;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return `[Voice note — transcription failed: ${e.message}]`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
Object.defineProperty(exports, 'CHANNEL_MAX_LENGTH', {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return CHANNEL_MAX_LENGTH;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, 'chunkForChannel', {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return chunkForChannel;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, 'enrichVoiceNote', {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return enrichVoiceNote;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(exports, 'withRetry', {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return withRetry;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/channels/delivery.ts
|
|
3
|
+
/**
|
|
4
|
+
|
|
5
|
+
* src/channels/delivery.ts
|
|
6
|
+
|
|
7
|
+
* Delivery pipeline: queue retry, per-channel chunking, media handling.
|
|
8
|
+
|
|
9
|
+
*/
|
|
10
|
+
const CHANNEL_MAX_LENGTH = {
|
|
11
|
+
telegram: 4096,
|
|
12
|
+
discord: 2e3,
|
|
13
|
+
whatsapp: 4096,
|
|
14
|
+
"whatsapp-baileys": 4096,
|
|
15
|
+
slack: 4e4,
|
|
16
|
+
googlechat: 4096,
|
|
17
|
+
msteams: 28e3,
|
|
18
|
+
matrix: 32768,
|
|
19
|
+
irc: 512,
|
|
20
|
+
mattermost: 16383,
|
|
21
|
+
signal: 4096,
|
|
22
|
+
line: 2e3,
|
|
23
|
+
twitch: 490,
|
|
24
|
+
viber: 7e3,
|
|
25
|
+
default: 4e3
|
|
26
|
+
};
|
|
27
|
+
function chunkForChannel(text, channelId) {
|
|
28
|
+
const max = CHANNEL_MAX_LENGTH[channelId] ?? CHANNEL_MAX_LENGTH.default;
|
|
29
|
+
if (text.length <= max) return [text];
|
|
30
|
+
const chunks = [];
|
|
31
|
+
let i = 0;
|
|
32
|
+
while (i < text.length) {
|
|
33
|
+
let end = Math.min(i + max, text.length);
|
|
34
|
+
if (end < text.length) {
|
|
35
|
+
const nl = text.lastIndexOf("\n", end);
|
|
36
|
+
if (nl > i) end = nl + 1;
|
|
37
|
+
}
|
|
38
|
+
chunks.push(text.slice(i, end));
|
|
39
|
+
i = end;
|
|
40
|
+
}
|
|
41
|
+
return chunks;
|
|
42
|
+
}
|
|
43
|
+
const DEFAULT_RETRIES = 3;
|
|
44
|
+
const DEFAULT_BACKOFF_MS = 1e3;
|
|
45
|
+
async function withRetry(fn, opts) {
|
|
46
|
+
const retries = opts?.retries ?? DEFAULT_RETRIES;
|
|
47
|
+
const backoff = opts?.backoffMs ?? DEFAULT_BACKOFF_MS;
|
|
48
|
+
let lastErr = null;
|
|
49
|
+
for (let i = 0; i <= retries; i++) try {
|
|
50
|
+
return await fn();
|
|
51
|
+
} catch (e) {
|
|
52
|
+
lastErr = e;
|
|
53
|
+
opts?.onRetry?.(i + 1, lastErr);
|
|
54
|
+
if (i < retries) await new Promise((r) => setTimeout(r, backoff * Math.pow(2, i)));
|
|
55
|
+
}
|
|
56
|
+
throw lastErr;
|
|
57
|
+
}
|
|
58
|
+
/** Enrich message text from voice note (transcribe if audioPath provided). */
|
|
59
|
+
async function enrichVoiceNote(msg) {
|
|
60
|
+
if (!msg.audioPath) return msg.text;
|
|
61
|
+
if (msg.text && msg.text !== "[voice note]") return msg.text;
|
|
62
|
+
try {
|
|
63
|
+
const { transcribeVoiceNote } = await Promise.resolve().then(() => require("./voice-transcription-B6RtplmN.js"));
|
|
64
|
+
const text = await transcribeVoiceNote(msg.audioPath);
|
|
65
|
+
return text || msg.text;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return `[Voice note — transcription failed: ${e.message}]`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
Object.defineProperty(exports, 'CHANNEL_MAX_LENGTH', {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return CHANNEL_MAX_LENGTH;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, 'chunkForChannel', {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return chunkForChannel;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, 'enrichVoiceNote', {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return enrichVoiceNote;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(exports, 'withRetry', {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return withRetry;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
|
|
3
|
+
//#region src/infra/destructive-gate.ts
|
|
4
|
+
function isDangerousShellCommand(cmd) {
|
|
5
|
+
const c = (cmd || "").trim();
|
|
6
|
+
for (const re of DANGEROUS_SHELL_PATTERNS) if (re.test(c)) return true;
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
|
|
11
|
+
* Wrap tools so destructive ones are gated. When sessionId set, stores pending for confirm flow.
|
|
12
|
+
|
|
13
|
+
*/
|
|
14
|
+
function applyDestructiveGate(tools, opts) {
|
|
15
|
+
const { elevated, source, sessionId } = opts;
|
|
16
|
+
const fromChannel = source && CHANNEL_SOURCES.has(source);
|
|
17
|
+
if (!fromChannel || elevated) return tools;
|
|
18
|
+
return tools.map((t) => {
|
|
19
|
+
if (DESTRUCTIVE_TOOLS.includes(t.name)) {
|
|
20
|
+
const orig = t.handler;
|
|
21
|
+
return {
|
|
22
|
+
...t,
|
|
23
|
+
handler: async (input) => {
|
|
24
|
+
if (sessionId) {
|
|
25
|
+
const { setPending } = await Promise.resolve().then(() => require("./pending-approval-C_HkX1QL.js"));
|
|
26
|
+
setPending(sessionId, {
|
|
27
|
+
toolName: t.name,
|
|
28
|
+
input,
|
|
29
|
+
execute: () => orig(input)
|
|
30
|
+
});
|
|
31
|
+
return PENDING_MSG;
|
|
32
|
+
}
|
|
33
|
+
return BLOCKED_MSG;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (t.name === "run_shell") {
|
|
38
|
+
const orig = t.handler;
|
|
39
|
+
return {
|
|
40
|
+
...t,
|
|
41
|
+
handler: async (input) => {
|
|
42
|
+
const cmd = input.command || "";
|
|
43
|
+
if (isDangerousShellCommand(cmd)) {
|
|
44
|
+
if (sessionId) {
|
|
45
|
+
const { setPending } = await Promise.resolve().then(() => require("./pending-approval-C_HkX1QL.js"));
|
|
46
|
+
setPending(sessionId, {
|
|
47
|
+
toolName: "run_shell",
|
|
48
|
+
input,
|
|
49
|
+
execute: () => orig(input)
|
|
50
|
+
});
|
|
51
|
+
return PENDING_MSG;
|
|
52
|
+
}
|
|
53
|
+
return BLOCKED_MSG;
|
|
54
|
+
}
|
|
55
|
+
return orig(input);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return t;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
var DESTRUCTIVE_TOOLS, DANGEROUS_SHELL_PATTERNS, CHANNEL_SOURCES, BLOCKED_MSG, PENDING_MSG;
|
|
63
|
+
var init_destructive_gate = require_chunk.__esm({ "src/infra/destructive-gate.ts"() {
|
|
64
|
+
DESTRUCTIVE_TOOLS = ["delete_file", "kill_process"];
|
|
65
|
+
DANGEROUS_SHELL_PATTERNS = [
|
|
66
|
+
/\brm\s+-[rf]\b|\brm\s+--recursive|\brm\s+-rf\b/,
|
|
67
|
+
/\bmkfs\.|format\s+/i,
|
|
68
|
+
/\bdd\s+if=/,
|
|
69
|
+
/\b>\/dev\/sd[a-z]/,
|
|
70
|
+
/\bshutdown\s+-/,
|
|
71
|
+
/\breboot\b/i,
|
|
72
|
+
/\b:\(\)\s*\{\s*:\s*\|\s*:\s*&\s*\}/,
|
|
73
|
+
/\bcurl\s+.*\s*\|\s*sh\b/,
|
|
74
|
+
/\bwget\s+.*\s*\|\s*(bash|sh)\b/
|
|
75
|
+
];
|
|
76
|
+
CHANNEL_SOURCES = new Set([
|
|
77
|
+
"telegram",
|
|
78
|
+
"discord",
|
|
79
|
+
"whatsapp",
|
|
80
|
+
"slack",
|
|
81
|
+
"signal",
|
|
82
|
+
"matrix",
|
|
83
|
+
"line",
|
|
84
|
+
"nostr",
|
|
85
|
+
"feishu",
|
|
86
|
+
"msteams",
|
|
87
|
+
"teams",
|
|
88
|
+
"instagram",
|
|
89
|
+
"messenger",
|
|
90
|
+
"twitter",
|
|
91
|
+
"viber",
|
|
92
|
+
"zalo",
|
|
93
|
+
"webhook:inbound"
|
|
94
|
+
]);
|
|
95
|
+
BLOCKED_MSG = "Blocked: destructive action requires elevated session. Use \"elevate\" or run from CLI with full access.";
|
|
96
|
+
PENDING_MSG = "This action requires confirmation. Ask the user to reply \"confirm\" to proceed.";
|
|
97
|
+
} });
|
|
98
|
+
|
|
99
|
+
//#endregion
|
|
100
|
+
init_destructive_gate();
|
|
101
|
+
exports.applyDestructiveGate = applyDestructiveGate;
|