@openclaw-cloud/agent-controller 0.2.7 → 0.2.9
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/bin/agent-controller.js +6 -0
- package/dist/commands/backup-cli.d.ts +1 -0
- package/dist/commands/backup-cli.js +66 -0
- package/dist/commands/backup-cli.js.map +1 -0
- package/dist/commands/knowledge-sync-cli.d.ts +1 -0
- package/dist/commands/knowledge-sync-cli.js +61 -0
- package/dist/commands/knowledge-sync-cli.js.map +1 -0
- package/package.json +1 -1
package/bin/agent-controller.js
CHANGED
|
@@ -19,6 +19,12 @@ if (command === '--version' || command === '-v') {
|
|
|
19
19
|
} else if (command === 'self-update' || command === 'update') {
|
|
20
20
|
const { selfUpdate } = await import('../dist/commands/self-update.js');
|
|
21
21
|
await selfUpdate(pkg.version);
|
|
22
|
+
} else if (command === 'backup') {
|
|
23
|
+
const { runBackup } = await import('../dist/commands/backup-cli.js');
|
|
24
|
+
await runBackup();
|
|
25
|
+
} else if (command === 'knowledge_sync' || command === 'knowledge-sync') {
|
|
26
|
+
const { runKnowledgeSync } = await import('../dist/commands/knowledge-sync-cli.js');
|
|
27
|
+
await runKnowledgeSync();
|
|
22
28
|
} else if (command === 'install') {
|
|
23
29
|
const { install } = await import('../dist/commands/install.js');
|
|
24
30
|
await install();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runBackup(): Promise<void>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
function getWorkspaceDir() {
|
|
6
|
+
const stateDir = process.env.OPENCLAW_STATE_DIR?.trim() ?? path.join(os.homedir(), '.openclaw');
|
|
7
|
+
return path.join(stateDir, 'workspace');
|
|
8
|
+
}
|
|
9
|
+
function requireEnv(name) {
|
|
10
|
+
const value = process.env[name];
|
|
11
|
+
if (!value) {
|
|
12
|
+
console.error(`Missing required env: ${name}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
function createArchive(archivePath, workspaceDir) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
exec(`tar -czf ${archivePath} -C ${path.dirname(workspaceDir)} ${path.basename(workspaceDir)}`, { timeout: 120_000 }, (err, _stdout, stderr) => {
|
|
20
|
+
if (err)
|
|
21
|
+
reject(new Error(`tar failed: ${stderr || err.message}`));
|
|
22
|
+
else
|
|
23
|
+
resolve();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export async function runBackup() {
|
|
28
|
+
const backendUrl = requireEnv('BACKEND_INTERNAL_URL');
|
|
29
|
+
const agentToken = requireEnv('AGENT_TOKEN');
|
|
30
|
+
const agentId = requireEnv('AGENT_ID');
|
|
31
|
+
console.log('Initialising backup...');
|
|
32
|
+
// Step 1: Get upload URL from backend
|
|
33
|
+
const initRes = await fetch(`${backendUrl}/api/internal/agents/${agentId}/backup/init`, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: { Authorization: `Bearer ${agentToken}` },
|
|
36
|
+
});
|
|
37
|
+
if (!initRes.ok) {
|
|
38
|
+
const text = await initRes.text().catch(() => '');
|
|
39
|
+
console.error(`Backup init failed: ${initRes.status} ${text}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const { snapshotId, token } = await initRes.json();
|
|
43
|
+
const uploadUrl = `${backendUrl}/api/internal/agents/${agentId}/knowledge/upload?snapshotId=${snapshotId}`;
|
|
44
|
+
// Step 2: Create archive
|
|
45
|
+
const archivePath = path.join('/tmp', `backup-${Date.now()}.tar.gz`);
|
|
46
|
+
console.log('Creating archive...');
|
|
47
|
+
await createArchive(archivePath, getWorkspaceDir());
|
|
48
|
+
// Step 3: Upload
|
|
49
|
+
console.log(`Uploading to ${uploadUrl}...`);
|
|
50
|
+
const fileBuffer = await fs.readFile(archivePath);
|
|
51
|
+
const stat = await fs.stat(archivePath);
|
|
52
|
+
const uploadRes = await fetch(uploadUrl, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers: { 'Content-Type': 'application/gzip', Authorization: `Bearer ${token}` },
|
|
55
|
+
body: fileBuffer,
|
|
56
|
+
signal: AbortSignal.timeout(120_000),
|
|
57
|
+
});
|
|
58
|
+
await fs.unlink(archivePath).catch(() => { });
|
|
59
|
+
if (!uploadRes.ok) {
|
|
60
|
+
const text = await uploadRes.text().catch(() => '');
|
|
61
|
+
console.error(`Upload failed: ${uploadRes.status} ${text}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
console.log(`Backup complete — ${(stat.size / 1024 / 1024).toFixed(2)} MB uploaded.`);
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=backup-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup-cli.js","sourceRoot":"","sources":["../../src/commands/backup-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runKnowledgeSync(): Promise<void>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
const FIXED_FILES = ['SOUL.md', 'MEMORY.md', 'AGENTS.md', 'TOOLS.md', 'HEARTBEAT.md', 'USER.md'];
|
|
5
|
+
function getWorkspaceDir() {
|
|
6
|
+
const stateDir = process.env.OPENCLAW_STATE_DIR?.trim() ?? path.join(os.homedir(), '.openclaw');
|
|
7
|
+
return path.join(stateDir, 'workspace');
|
|
8
|
+
}
|
|
9
|
+
function requireEnv(name) {
|
|
10
|
+
const value = process.env[name];
|
|
11
|
+
if (!value) {
|
|
12
|
+
console.error(`Missing required env: ${name}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
export async function runKnowledgeSync() {
|
|
18
|
+
const backendUrl = requireEnv('BACKEND_INTERNAL_URL');
|
|
19
|
+
const agentToken = requireEnv('AGENT_TOKEN');
|
|
20
|
+
const agentId = requireEnv('AGENT_ID');
|
|
21
|
+
const workspaceDir = getWorkspaceDir();
|
|
22
|
+
const filePaths = [...FIXED_FILES];
|
|
23
|
+
// Scan memory/ directory for .md files
|
|
24
|
+
const memoryDir = path.join(workspaceDir, 'memory');
|
|
25
|
+
try {
|
|
26
|
+
const entries = await fs.readdir(memoryDir);
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
if (entry.endsWith('.md'))
|
|
29
|
+
filePaths.push(`memory/${entry}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch { /* memory/ may not exist */ }
|
|
33
|
+
// Read all files
|
|
34
|
+
console.log(`Reading ${filePaths.length} files from workspace...`);
|
|
35
|
+
const files = [];
|
|
36
|
+
for (const filePath of filePaths) {
|
|
37
|
+
try {
|
|
38
|
+
const content = await fs.readFile(path.join(workspaceDir, filePath), 'utf-8');
|
|
39
|
+
files.push({ path: filePath, content });
|
|
40
|
+
}
|
|
41
|
+
catch { /* skip missing */ }
|
|
42
|
+
}
|
|
43
|
+
console.log(` Found ${files.length} files to sync.`);
|
|
44
|
+
// Push to backend
|
|
45
|
+
const res = await fetch(`${backendUrl}/api/internal/agents/${agentId}/knowledge/push`, {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: {
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
Authorization: `Bearer ${agentToken}`,
|
|
50
|
+
},
|
|
51
|
+
body: JSON.stringify({ files }),
|
|
52
|
+
});
|
|
53
|
+
if (!res.ok) {
|
|
54
|
+
const text = await res.text().catch(() => '');
|
|
55
|
+
console.error(`Knowledge push failed: ${res.status} ${text}`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const { filesUpdated } = await res.json();
|
|
59
|
+
console.log(`Knowledge sync complete — ${filesUpdated}/${files.length} files updated.`);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=knowledge-sync-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-sync-cli.js","sourceRoot":"","sources":["../../src/commands/knowledge-sync-cli.ts"],"names":[],"mappings":"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"}
|