@agentplugged/claw 0.1.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/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +111 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +94 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/capture.d.ts +13 -0
- package/dist/memory/capture.d.ts.map +1 -0
- package/dist/memory/capture.js +102 -0
- package/dist/memory/capture.js.map +1 -0
- package/dist/memory/db.d.ts +56 -0
- package/dist/memory/db.d.ts.map +1 -0
- package/dist/memory/db.js +206 -0
- package/dist/memory/db.js.map +1 -0
- package/dist/memory/index.d.ts +8 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +42 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/llm-extract.d.ts +13 -0
- package/dist/memory/llm-extract.d.ts.map +1 -0
- package/dist/memory/llm-extract.js +135 -0
- package/dist/memory/llm-extract.js.map +1 -0
- package/dist/memory/recall.d.ts +16 -0
- package/dist/memory/recall.d.ts.map +1 -0
- package/dist/memory/recall.js +131 -0
- package/dist/memory/recall.js.map +1 -0
- package/dist/observability/collector.d.ts +40 -0
- package/dist/observability/collector.d.ts.map +1 -0
- package/dist/observability/collector.js +119 -0
- package/dist/observability/collector.js.map +1 -0
- package/dist/observability/db.d.ts +60 -0
- package/dist/observability/db.d.ts.map +1 -0
- package/dist/observability/db.js +189 -0
- package/dist/observability/db.js.map +1 -0
- package/dist/observability/index.d.ts +7 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +35 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/queries.d.ts +54 -0
- package/dist/observability/queries.d.ts.map +1 -0
- package/dist/observability/queries.js +181 -0
- package/dist/observability/queries.js.map +1 -0
- package/dist/router/classifier.d.ts +8 -0
- package/dist/router/classifier.d.ts.map +1 -0
- package/dist/router/classifier.js +90 -0
- package/dist/router/classifier.js.map +1 -0
- package/dist/router/fallback.d.ts +18 -0
- package/dist/router/fallback.d.ts.map +1 -0
- package/dist/router/fallback.js +102 -0
- package/dist/router/fallback.js.map +1 -0
- package/dist/router/index.d.ts +5 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +214 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/leak-detector.d.ts +33 -0
- package/dist/router/leak-detector.d.ts.map +1 -0
- package/dist/router/leak-detector.js +320 -0
- package/dist/router/leak-detector.js.map +1 -0
- package/dist/router/logger.d.ts +18 -0
- package/dist/router/logger.d.ts.map +1 -0
- package/dist/router/logger.js +130 -0
- package/dist/router/logger.js.map +1 -0
- package/dist/router/models.d.ts +5 -0
- package/dist/router/models.d.ts.map +1 -0
- package/dist/router/models.js +96 -0
- package/dist/router/models.js.map +1 -0
- package/dist/router/providers.d.ts +4 -0
- package/dist/router/providers.d.ts.map +1 -0
- package/dist/router/providers.js +323 -0
- package/dist/router/providers.js.map +1 -0
- package/dist/router/strategy.d.ts +29 -0
- package/dist/router/strategy.d.ts.map +1 -0
- package/dist/router/strategy.js +169 -0
- package/dist/router/strategy.js.map +1 -0
- package/dist/router/types.d.ts +63 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +3 -0
- package/dist/router/types.js.map +1 -0
- package/dist/sidecar/auth.d.ts +7 -0
- package/dist/sidecar/auth.d.ts.map +1 -0
- package/dist/sidecar/auth.js +36 -0
- package/dist/sidecar/auth.js.map +1 -0
- package/dist/sidecar/index.d.ts +2 -0
- package/dist/sidecar/index.d.ts.map +1 -0
- package/dist/sidecar/index.js +336 -0
- package/dist/sidecar/index.js.map +1 -0
- package/dist/sidecar/routes/addons.d.ts +6 -0
- package/dist/sidecar/routes/addons.d.ts.map +1 -0
- package/dist/sidecar/routes/addons.js +332 -0
- package/dist/sidecar/routes/addons.js.map +1 -0
- package/dist/sidecar/routes/backup.d.ts +7 -0
- package/dist/sidecar/routes/backup.d.ts.map +1 -0
- package/dist/sidecar/routes/backup.js +204 -0
- package/dist/sidecar/routes/backup.js.map +1 -0
- package/dist/sidecar/routes/channels.d.ts +4 -0
- package/dist/sidecar/routes/channels.d.ts.map +1 -0
- package/dist/sidecar/routes/channels.js +120 -0
- package/dist/sidecar/routes/channels.js.map +1 -0
- package/dist/sidecar/routes/health.d.ts +5 -0
- package/dist/sidecar/routes/health.d.ts.map +1 -0
- package/dist/sidecar/routes/health.js +28 -0
- package/dist/sidecar/routes/health.js.map +1 -0
- package/dist/sidecar/routes/memory.d.ts +7 -0
- package/dist/sidecar/routes/memory.d.ts.map +1 -0
- package/dist/sidecar/routes/memory.js +234 -0
- package/dist/sidecar/routes/memory.js.map +1 -0
- package/dist/sidecar/routes/metrics.d.ts +5 -0
- package/dist/sidecar/routes/metrics.d.ts.map +1 -0
- package/dist/sidecar/routes/metrics.js +273 -0
- package/dist/sidecar/routes/metrics.js.map +1 -0
- package/dist/sidecar/routes/restart.d.ts +4 -0
- package/dist/sidecar/routes/restart.d.ts.map +1 -0
- package/dist/sidecar/routes/restart.js +81 -0
- package/dist/sidecar/routes/restart.js.map +1 -0
- package/dist/sidecar/routes/router-config.d.ts +5 -0
- package/dist/sidecar/routes/router-config.d.ts.map +1 -0
- package/dist/sidecar/routes/router-config.js +150 -0
- package/dist/sidecar/routes/router-config.js.map +1 -0
- package/dist/sidecar/routes/security.d.ts +8 -0
- package/dist/sidecar/routes/security.d.ts.map +1 -0
- package/dist/sidecar/routes/security.js +308 -0
- package/dist/sidecar/routes/security.js.map +1 -0
- package/dist/sidecar/routes/skills.d.ts +5 -0
- package/dist/sidecar/routes/skills.d.ts.map +1 -0
- package/dist/sidecar/routes/skills.js +146 -0
- package/dist/sidecar/routes/skills.js.map +1 -0
- package/dist/sidecar/routes/soul.d.ts +4 -0
- package/dist/sidecar/routes/soul.d.ts.map +1 -0
- package/dist/sidecar/routes/soul.js +115 -0
- package/dist/sidecar/routes/soul.js.map +1 -0
- package/dist/sidecar/routes/team.d.ts +4 -0
- package/dist/sidecar/routes/team.d.ts.map +1 -0
- package/dist/sidecar/routes/team.js +139 -0
- package/dist/sidecar/routes/team.js.map +1 -0
- package/dist/sidecar/routes/update.d.ts +4 -0
- package/dist/sidecar/routes/update.d.ts.map +1 -0
- package/dist/sidecar/routes/update.js +96 -0
- package/dist/sidecar/routes/update.js.map +1 -0
- package/dist/sidecar/utils.d.ts +9 -0
- package/dist/sidecar/utils.d.ts.map +1 -0
- package/dist/sidecar/utils.js +57 -0
- package/dist/sidecar/utils.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleListAddons = handleListAddons;
|
|
37
|
+
exports.handleEnableAddon = handleEnableAddon;
|
|
38
|
+
exports.handleDisableAddon = handleDisableAddon;
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
const utils_1 = require("../utils");
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Constants
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
const N8N_SERVICE_FILE = "/etc/systemd/system/n8n.service";
|
|
46
|
+
const N8N_PORT = 5678;
|
|
47
|
+
const MIN_RAM_BYTES = 3 * 1024 * 1024; // 3 GB in KB (MemTotal in /proc/meminfo is in kB)
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Helpers
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
/**
|
|
52
|
+
* Read MemTotal from /proc/meminfo. Returns value in kB.
|
|
53
|
+
* Returns 0 if the file cannot be read.
|
|
54
|
+
*/
|
|
55
|
+
function readMemTotalKb() {
|
|
56
|
+
try {
|
|
57
|
+
const meminfo = fs.readFileSync("/proc/meminfo", "utf-8");
|
|
58
|
+
const match = meminfo.match(/^MemTotal:\s+(\d+)\s+kB/m);
|
|
59
|
+
if (!match)
|
|
60
|
+
return 0;
|
|
61
|
+
return parseInt(match[1], 10);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extract the primary domain from the existing Caddyfile.
|
|
69
|
+
* Looks for the first bare hostname block (e.g. `example.com {`).
|
|
70
|
+
*/
|
|
71
|
+
function readDomainFromCaddyfile(caddyfilePath) {
|
|
72
|
+
try {
|
|
73
|
+
const content = fs.readFileSync(caddyfilePath, "utf-8");
|
|
74
|
+
// Match lines like: example.com { or https://example.com {
|
|
75
|
+
const match = content.match(/^(?:https?:\/\/)?([a-z0-9][\w.-]+\.[a-z]{2,})\s*\{/m);
|
|
76
|
+
if (match)
|
|
77
|
+
return match[1];
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// ignore
|
|
81
|
+
}
|
|
82
|
+
return "localhost";
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Generate a cryptographically random password of `length` characters
|
|
86
|
+
* using only alphanumerics + a few specials that are safe in env files.
|
|
87
|
+
*/
|
|
88
|
+
function generatePassword(length = 16) {
|
|
89
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#%^&*";
|
|
90
|
+
// Use crypto.getRandomValues via the global crypto object (Node 19+) or a
|
|
91
|
+
// simple fallback using Math.random for older environments.
|
|
92
|
+
const array = new Uint8Array(length);
|
|
93
|
+
if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.getRandomValues) {
|
|
94
|
+
globalThis.crypto.getRandomValues(array);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Fallback — acceptable for server-side only use
|
|
98
|
+
for (let i = 0; i < length; i++) {
|
|
99
|
+
array[i] = Math.floor(Math.random() * 256);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return Array.from(array)
|
|
103
|
+
.map((b) => chars[b % chars.length])
|
|
104
|
+
.join("");
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Build the systemd unit content for n8n.
|
|
108
|
+
*/
|
|
109
|
+
function buildSystemdUnit(dataDir, domain) {
|
|
110
|
+
return `[Unit]
|
|
111
|
+
Description=n8n Workflow Automation
|
|
112
|
+
After=network.target
|
|
113
|
+
|
|
114
|
+
[Service]
|
|
115
|
+
Type=simple
|
|
116
|
+
User=agentplugged
|
|
117
|
+
Group=agentplugged
|
|
118
|
+
EnvironmentFile=${dataDir}/n8n.env
|
|
119
|
+
Environment=N8N_PORT=${N8N_PORT}
|
|
120
|
+
Environment=N8N_PROTOCOL=http
|
|
121
|
+
Environment=N8N_HOST=localhost
|
|
122
|
+
Environment=WEBHOOK_URL=https://${domain}/n8n/
|
|
123
|
+
Environment=N8N_PATH=/n8n/
|
|
124
|
+
ExecStart=/usr/bin/env n8n start
|
|
125
|
+
Restart=always
|
|
126
|
+
RestartSec=5
|
|
127
|
+
|
|
128
|
+
[Install]
|
|
129
|
+
WantedBy=multi-user.target
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Build the Caddy reverse-proxy block for n8n.
|
|
134
|
+
*/
|
|
135
|
+
const N8N_CADDY_BLOCK = `
|
|
136
|
+
\thandle /n8n/* {
|
|
137
|
+
\t\treverse_proxy localhost:${N8N_PORT} {
|
|
138
|
+
\t\t\theader_up X-Forwarded-For {remote_host}
|
|
139
|
+
\t\t}
|
|
140
|
+
\t}
|
|
141
|
+
`;
|
|
142
|
+
/**
|
|
143
|
+
* Insert the n8n block into the Caddyfile, immediately before the first
|
|
144
|
+
* `handle` or `handle_path` directive (i.e. before the catch-all handler).
|
|
145
|
+
* If the marker is already present, do nothing.
|
|
146
|
+
*/
|
|
147
|
+
function addCaddyBlock(caddyfilePath) {
|
|
148
|
+
const content = fs.readFileSync(caddyfilePath, "utf-8");
|
|
149
|
+
if (content.includes("handle /n8n/*")) {
|
|
150
|
+
return; // already present
|
|
151
|
+
}
|
|
152
|
+
// Insert before the first `\thandle ` or `\thandle_path ` line
|
|
153
|
+
const insertBefore = /(\n\t(?:handle|handle_path)\s)/;
|
|
154
|
+
if (insertBefore.test(content)) {
|
|
155
|
+
const updated = content.replace(insertBefore, `${N8N_CADDY_BLOCK}$1`);
|
|
156
|
+
fs.writeFileSync(caddyfilePath, updated, "utf-8");
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// Fallback: append before the closing brace of the first server block
|
|
160
|
+
const updated = content.replace(/(\n\}[^\S\n]*$)/, `${N8N_CADDY_BLOCK}\n}`);
|
|
161
|
+
fs.writeFileSync(caddyfilePath, updated, "utf-8");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Remove the n8n block from the Caddyfile.
|
|
166
|
+
*/
|
|
167
|
+
function removeCaddyBlock(caddyfilePath) {
|
|
168
|
+
const content = fs.readFileSync(caddyfilePath, "utf-8");
|
|
169
|
+
if (!content.includes("handle /n8n/*")) {
|
|
170
|
+
return; // not present
|
|
171
|
+
}
|
|
172
|
+
// Remove the block (multiline — everything between handle /n8n/* { ... })
|
|
173
|
+
const blockRegex = /\n\t+handle \/n8n\/\*\s*\{[^}]*\}\n/g;
|
|
174
|
+
const updated = content.replace(blockRegex, "\n");
|
|
175
|
+
fs.writeFileSync(caddyfilePath, updated, "utf-8");
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Run a shell command synchronously, throwing on non-zero exit.
|
|
179
|
+
* Uses a 120 s timeout for long operations like npm install.
|
|
180
|
+
*/
|
|
181
|
+
function run(cmd, timeoutMs = 30_000) {
|
|
182
|
+
(0, child_process_1.execSync)(cmd, { stdio: "pipe", timeout: timeoutMs });
|
|
183
|
+
}
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// Route handlers
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
function handleListAddons(config) {
|
|
188
|
+
return async (_req, res) => {
|
|
189
|
+
const memTotalKb = readMemTotalKb();
|
|
190
|
+
const memTotalGb = memTotalKb / 1024 / 1024;
|
|
191
|
+
const isCompatible = memTotalKb >= MIN_RAM_BYTES;
|
|
192
|
+
const n8nInstalled = fs.existsSync(N8N_SERVICE_FILE);
|
|
193
|
+
let n8nStatus;
|
|
194
|
+
if (!isCompatible) {
|
|
195
|
+
n8nStatus = "unavailable";
|
|
196
|
+
}
|
|
197
|
+
else if (n8nInstalled) {
|
|
198
|
+
// Check if the service is actually active
|
|
199
|
+
try {
|
|
200
|
+
run("systemctl is-active --quiet n8n");
|
|
201
|
+
n8nStatus = "enabled";
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// Service file exists but not running — consider it disabled
|
|
205
|
+
n8nStatus = "disabled";
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
n8nStatus = "disabled";
|
|
210
|
+
}
|
|
211
|
+
(0, utils_1.sendJson)(res, 200, {
|
|
212
|
+
addons: [
|
|
213
|
+
{
|
|
214
|
+
id: "n8n",
|
|
215
|
+
name: "n8n Workflow Automation",
|
|
216
|
+
status: n8nStatus,
|
|
217
|
+
description: "Visual workflow automation. Connect your AI agent to 400+ apps without code.",
|
|
218
|
+
minRamGB: 3,
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
instanceRamGb: Math.round(memTotalGb * 10) / 10,
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function handleEnableAddon(config) {
|
|
226
|
+
return async (_req, res) => {
|
|
227
|
+
// 1. Check RAM
|
|
228
|
+
const memTotalKb = readMemTotalKb();
|
|
229
|
+
if (memTotalKb > 0 && memTotalKb < MIN_RAM_BYTES) {
|
|
230
|
+
(0, utils_1.sendError)(res, 409, `Insufficient RAM: n8n requires at least 3 GB (instance has ${Math.round(memTotalKb / 1024)} MB)`);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// 2. Check not already installed and running
|
|
234
|
+
if (fs.existsSync(N8N_SERVICE_FILE)) {
|
|
235
|
+
try {
|
|
236
|
+
run("systemctl is-active --quiet n8n");
|
|
237
|
+
(0, utils_1.sendError)(res, 409, "n8n is already enabled on this instance");
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
// Service file exists but not running — allow re-enable
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const caddyfilePath = `${config.runtimeDir}/Caddyfile`;
|
|
245
|
+
const domain = readDomainFromCaddyfile(caddyfilePath);
|
|
246
|
+
// 3. Generate credentials
|
|
247
|
+
const n8nUser = "admin";
|
|
248
|
+
const n8nPassword = generatePassword(16);
|
|
249
|
+
try {
|
|
250
|
+
// 3a. Install n8n globally
|
|
251
|
+
run("npm install -g n8n", 120_000);
|
|
252
|
+
// 3b. Write env file
|
|
253
|
+
const envContent = [
|
|
254
|
+
`N8N_BASIC_AUTH_ACTIVE=true`,
|
|
255
|
+
`N8N_BASIC_AUTH_USER=${n8nUser}`,
|
|
256
|
+
`N8N_BASIC_AUTH_PASSWORD=${n8nPassword}`,
|
|
257
|
+
`N8N_USER_FOLDER=${config.dataDir}/n8n`,
|
|
258
|
+
].join("\n") + "\n";
|
|
259
|
+
fs.mkdirSync(config.dataDir, { recursive: true });
|
|
260
|
+
fs.writeFileSync(`${config.dataDir}/n8n.env`, envContent, {
|
|
261
|
+
mode: 0o600,
|
|
262
|
+
encoding: "utf-8",
|
|
263
|
+
});
|
|
264
|
+
// 3c. Write systemd unit
|
|
265
|
+
const unitContent = buildSystemdUnit(config.dataDir, domain);
|
|
266
|
+
fs.writeFileSync(N8N_SERVICE_FILE, unitContent, "utf-8");
|
|
267
|
+
// 3d. Patch Caddyfile
|
|
268
|
+
if (fs.existsSync(caddyfilePath)) {
|
|
269
|
+
addCaddyBlock(caddyfilePath);
|
|
270
|
+
}
|
|
271
|
+
// 3e. Enable and start
|
|
272
|
+
run("systemctl daemon-reload");
|
|
273
|
+
run("systemctl enable n8n");
|
|
274
|
+
run("systemctl start n8n");
|
|
275
|
+
// 3f. Reload Caddy
|
|
276
|
+
run("systemctl reload caddy");
|
|
277
|
+
(0, utils_1.sendJson)(res, 200, {
|
|
278
|
+
ok: true,
|
|
279
|
+
credentials: {
|
|
280
|
+
user: n8nUser,
|
|
281
|
+
password: n8nPassword,
|
|
282
|
+
},
|
|
283
|
+
url: `https://${domain}/n8n/`,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
288
|
+
console.error("[addons] n8n enable failed:", err);
|
|
289
|
+
(0, utils_1.sendError)(res, 500, `Failed to enable n8n: ${message}`);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function handleDisableAddon(config) {
|
|
294
|
+
return async (_req, res) => {
|
|
295
|
+
const caddyfilePath = `${config.runtimeDir}/Caddyfile`;
|
|
296
|
+
try {
|
|
297
|
+
// 1. Stop and disable the service (do not fail if already stopped)
|
|
298
|
+
try {
|
|
299
|
+
run("systemctl stop n8n");
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// Acceptable — service may already be stopped
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
run("systemctl disable n8n");
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
// Acceptable — service may not be enabled
|
|
309
|
+
}
|
|
310
|
+
// 2. Remove the Caddy block
|
|
311
|
+
if (fs.existsSync(caddyfilePath)) {
|
|
312
|
+
removeCaddyBlock(caddyfilePath);
|
|
313
|
+
}
|
|
314
|
+
// 3. Reload Caddy
|
|
315
|
+
try {
|
|
316
|
+
run("systemctl reload caddy");
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
// Non-fatal
|
|
320
|
+
}
|
|
321
|
+
// Note: n8n binary and data (/opt/agentplugged/n8n) are intentionally
|
|
322
|
+
// preserved so that re-enabling restores the previous workflows.
|
|
323
|
+
(0, utils_1.sendJson)(res, 200, { ok: true });
|
|
324
|
+
}
|
|
325
|
+
catch (err) {
|
|
326
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
327
|
+
console.error("[addons] n8n disable failed:", err);
|
|
328
|
+
(0, utils_1.sendError)(res, 500, `Failed to disable n8n: ${message}`);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=addons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addons.js","sourceRoot":"","sources":["../../../src/sidecar/routes/addons.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ClawConfig } from "../../config";
|
|
2
|
+
import { RouteHandler } from "./health";
|
|
3
|
+
export declare function handleListBackups(config: ClawConfig): RouteHandler;
|
|
4
|
+
export declare function handleCreateBackup(config: ClawConfig): RouteHandler;
|
|
5
|
+
export declare function handleRestoreBackup(config: ClawConfig): RouteHandler;
|
|
6
|
+
export declare function handleCleanupBackups(config: ClawConfig): RouteHandler;
|
|
7
|
+
//# sourceMappingURL=backup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../../src/sidecar/routes/backup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAgBxC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CA+BlE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAyDnE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAuDpE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAmCrE"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleListBackups = handleListBackups;
|
|
37
|
+
exports.handleCreateBackup = handleCreateBackup;
|
|
38
|
+
exports.handleRestoreBackup = handleRestoreBackup;
|
|
39
|
+
exports.handleCleanupBackups = handleCleanupBackups;
|
|
40
|
+
const fs = __importStar(require("fs/promises"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const utils_1 = require("../utils");
|
|
43
|
+
function getBackupDir(config) {
|
|
44
|
+
return path.join(config.dataDir, "backups");
|
|
45
|
+
}
|
|
46
|
+
function handleListBackups(config) {
|
|
47
|
+
return async (_req, res) => {
|
|
48
|
+
const backupDir = getBackupDir(config);
|
|
49
|
+
try {
|
|
50
|
+
await fs.mkdir(backupDir, { recursive: true });
|
|
51
|
+
const entries = await fs.readdir(backupDir, { withFileTypes: true });
|
|
52
|
+
const backups = [];
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
if (!entry.isFile())
|
|
55
|
+
continue;
|
|
56
|
+
if (!entry.name.endsWith(".tar.gz") && !entry.name.endsWith(".sql"))
|
|
57
|
+
continue;
|
|
58
|
+
const filePath = path.join(backupDir, entry.name);
|
|
59
|
+
const stat = await fs.stat(filePath);
|
|
60
|
+
backups.push({
|
|
61
|
+
name: entry.name,
|
|
62
|
+
size: stat.size,
|
|
63
|
+
createdAt: stat.mtime.toISOString(),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
backups.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
67
|
+
(0, utils_1.sendJson)(res, 200, { backups, total: backups.length, directory: backupDir });
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
(0, utils_1.sendError)(res, 500, `Failed to list backups: ${err.message}`);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function handleCreateBackup(config) {
|
|
75
|
+
return async (_req, res) => {
|
|
76
|
+
const backupDir = getBackupDir(config);
|
|
77
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
78
|
+
const backupName = `backup-${timestamp}.tar.gz`;
|
|
79
|
+
const backupPath = path.join(backupDir, backupName);
|
|
80
|
+
try {
|
|
81
|
+
await fs.mkdir(backupDir, { recursive: true });
|
|
82
|
+
// Directories to backup
|
|
83
|
+
const dirsToBackup = [
|
|
84
|
+
path.join(config.runtimeDir, "workspace"),
|
|
85
|
+
path.join(config.dataDir, "data"),
|
|
86
|
+
path.join(config.dataDir, "observability"),
|
|
87
|
+
];
|
|
88
|
+
// Filter to existing directories
|
|
89
|
+
const existingDirs = [];
|
|
90
|
+
for (const dir of dirsToBackup) {
|
|
91
|
+
try {
|
|
92
|
+
await fs.access(dir);
|
|
93
|
+
existingDirs.push(dir);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Skip non-existent directories
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (existingDirs.length === 0) {
|
|
100
|
+
(0, utils_1.sendJson)(res, 200, {
|
|
101
|
+
created: false,
|
|
102
|
+
reason: "No data directories to backup",
|
|
103
|
+
});
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const tarDirs = existingDirs.join(" ");
|
|
107
|
+
const { stdout, stderr } = await (0, utils_1.execCommand)(`tar -czf "${backupPath}" ${tarDirs} 2>&1`);
|
|
108
|
+
const stat = await fs.stat(backupPath);
|
|
109
|
+
(0, utils_1.sendJson)(res, 201, {
|
|
110
|
+
created: true,
|
|
111
|
+
backup: {
|
|
112
|
+
name: backupName,
|
|
113
|
+
size: stat.size,
|
|
114
|
+
createdAt: stat.mtime.toISOString(),
|
|
115
|
+
path: backupPath,
|
|
116
|
+
},
|
|
117
|
+
output: stdout || stderr || "ok",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
(0, utils_1.sendError)(res, 500, `Backup failed: ${err.message}`);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function handleRestoreBackup(config) {
|
|
126
|
+
return async (req, res) => {
|
|
127
|
+
let body;
|
|
128
|
+
try {
|
|
129
|
+
body = (await (0, utils_1.parseBody)(req));
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
(0, utils_1.sendError)(res, 400, "Invalid JSON body");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (!body.backupName || typeof body.backupName !== "string") {
|
|
136
|
+
(0, utils_1.sendError)(res, 422, "backupName is required");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
// Prevent path traversal
|
|
140
|
+
if (body.backupName.includes("..") || body.backupName.includes("/")) {
|
|
141
|
+
(0, utils_1.sendError)(res, 422, "Invalid backup name");
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const backupDir = getBackupDir(config);
|
|
145
|
+
const backupPath = path.join(backupDir, body.backupName);
|
|
146
|
+
try {
|
|
147
|
+
await fs.access(backupPath);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
(0, utils_1.sendError)(res, 404, `Backup not found: ${body.backupName}`);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
// Stop services before restore
|
|
155
|
+
await (0, utils_1.execCommand)("systemctl stop openclaw claw-router 2>/dev/null || true");
|
|
156
|
+
// Extract backup
|
|
157
|
+
const { stdout, stderr } = await (0, utils_1.execCommand)(`tar -xzf "${backupPath}" -C / 2>&1`);
|
|
158
|
+
// Restart services
|
|
159
|
+
await (0, utils_1.execCommand)("systemctl start openclaw claw-router 2>/dev/null || true");
|
|
160
|
+
(0, utils_1.sendJson)(res, 200, {
|
|
161
|
+
restored: true,
|
|
162
|
+
backupName: body.backupName,
|
|
163
|
+
output: stdout || stderr || "ok",
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
// Try to restart services even if restore failed
|
|
168
|
+
await (0, utils_1.execCommand)("systemctl start openclaw claw-router 2>/dev/null || true").catch(() => { });
|
|
169
|
+
(0, utils_1.sendError)(res, 500, `Restore failed: ${err.message}`);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function handleCleanupBackups(config) {
|
|
174
|
+
return async (_req, res) => {
|
|
175
|
+
const backupDir = getBackupDir(config);
|
|
176
|
+
const MAX_BACKUPS = 7;
|
|
177
|
+
try {
|
|
178
|
+
await fs.mkdir(backupDir, { recursive: true });
|
|
179
|
+
const entries = await fs.readdir(backupDir, { withFileTypes: true });
|
|
180
|
+
const backupFiles = entries
|
|
181
|
+
.filter((e) => e.isFile() && (e.name.endsWith(".tar.gz") || e.name.endsWith(".sql")))
|
|
182
|
+
.map((e) => e.name);
|
|
183
|
+
if (backupFiles.length <= MAX_BACKUPS) {
|
|
184
|
+
(0, utils_1.sendJson)(res, 200, { cleaned: 0, remaining: backupFiles.length });
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// Sort by name (timestamps) — oldest first
|
|
188
|
+
backupFiles.sort();
|
|
189
|
+
const toDelete = backupFiles.slice(0, backupFiles.length - MAX_BACKUPS);
|
|
190
|
+
for (const file of toDelete) {
|
|
191
|
+
await fs.unlink(path.join(backupDir, file));
|
|
192
|
+
}
|
|
193
|
+
(0, utils_1.sendJson)(res, 200, {
|
|
194
|
+
cleaned: toDelete.length,
|
|
195
|
+
remaining: MAX_BACKUPS,
|
|
196
|
+
deleted: toDelete,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
(0, utils_1.sendError)(res, 500, `Cleanup failed: ${err.message}`);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../../../src/sidecar/routes/backup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../../src/sidecar/routes/channels.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA8BxC,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CA8FxE"}
|