@okclaw-build/cli 1.0.0-beta.1
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/okclaw.js +2 -0
- package/dist/commands/check.d.ts +1 -0
- package/dist/commands/check.js +11 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/edit.d.ts +10 -0
- package/dist/commands/edit.js +44 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/feed.d.ts +10 -0
- package/dist/commands/feed.js +158 -0
- package/dist/commands/feed.js.map +1 -0
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +72 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/service.d.ts +4 -0
- package/dist/commands/service.js +23 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/installers/base.d.ts +5 -0
- package/dist/installers/base.js +2 -0
- package/dist/installers/base.js.map +1 -0
- package/dist/installers/channel.d.ts +17 -0
- package/dist/installers/channel.js +129 -0
- package/dist/installers/channel.js.map +1 -0
- package/dist/installers/openclaw.d.ts +18 -0
- package/dist/installers/openclaw.js +104 -0
- package/dist/installers/openclaw.js.map +1 -0
- package/dist/installers/openviking.d.ts +28 -0
- package/dist/installers/openviking.js +236 -0
- package/dist/installers/openviking.js.map +1 -0
- package/dist/utils/constants.d.ts +26 -0
- package/dist/utils/constants.js +45 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/deps.d.ts +18 -0
- package/dist/utils/deps.js +177 -0
- package/dist/utils/deps.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.js +5 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mirror.d.ts +1 -0
- package/dist/utils/mirror.js +15 -0
- package/dist/utils/mirror.js.map +1 -0
- package/dist/utils/shell.d.ts +24 -0
- package/dist/utils/shell.js +86 -0
- package/dist/utils/shell.js.map +1 -0
- package/package.json +28 -0
package/bin/okclaw.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function checkCommand(): Promise<void>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ensureNodeVersion, ensurePython } from '../utils/deps.js';
|
|
2
|
+
import { configureMirrors } from '../utils/mirror.js';
|
|
3
|
+
import { info, success } from '../utils/logger.js';
|
|
4
|
+
export async function checkCommand() {
|
|
5
|
+
info('Checking system dependencies...');
|
|
6
|
+
await ensureNodeVersion();
|
|
7
|
+
await ensurePython();
|
|
8
|
+
await configureMirrors();
|
|
9
|
+
success('All dependencies satisfied.');
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IACxC,MAAM,iBAAiB,EAAE,CAAC;IAC1B,MAAM,YAAY,EAAE,CAAC;IACrB,MAAM,gBAAgB,EAAE,CAAC;IACzB,OAAO,CAAC,6BAA6B,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* okclaw edit <target> --file <path>
|
|
3
|
+
*
|
|
4
|
+
* Copies a file to the openclaw workspace directory.
|
|
5
|
+
* user → ~/.openclaw/workspace/USER.md
|
|
6
|
+
* identity → ~/.openclaw/workspace/IDENTITY.md
|
|
7
|
+
* soul → ~/.openclaw/workspace/SOUL.md
|
|
8
|
+
* agents → ~/.openclaw/workspace/AGENTS.md
|
|
9
|
+
*/
|
|
10
|
+
export declare function editCommand(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { shell } from '../utils/shell.js';
|
|
3
|
+
import { info, error } from '../utils/logger.js';
|
|
4
|
+
import { OPENCLAW_WORKSPACE } from '../utils/constants.js';
|
|
5
|
+
/**
|
|
6
|
+
* All targets are plain files under ~/.openclaw/workspace/.
|
|
7
|
+
*/
|
|
8
|
+
const TARGETS = {
|
|
9
|
+
user: `${OPENCLAW_WORKSPACE}/USER.md`,
|
|
10
|
+
identity: `${OPENCLAW_WORKSPACE}/IDENTITY.md`,
|
|
11
|
+
soul: `${OPENCLAW_WORKSPACE}/SOUL.md`,
|
|
12
|
+
agents: `${OPENCLAW_WORKSPACE}/AGENTS.md`,
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* okclaw edit <target> --file <path>
|
|
16
|
+
*
|
|
17
|
+
* Copies a file to the openclaw workspace directory.
|
|
18
|
+
* user → ~/.openclaw/workspace/USER.md
|
|
19
|
+
* identity → ~/.openclaw/workspace/IDENTITY.md
|
|
20
|
+
* soul → ~/.openclaw/workspace/SOUL.md
|
|
21
|
+
* agents → ~/.openclaw/workspace/AGENTS.md
|
|
22
|
+
*/
|
|
23
|
+
export async function editCommand(args) {
|
|
24
|
+
const target = args[0];
|
|
25
|
+
if (!target || !TARGETS[target]) {
|
|
26
|
+
error(`Usage: okclaw edit <${Object.keys(TARGETS).join('|')}> --file <path>`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const fileIdx = args.indexOf('--file');
|
|
30
|
+
const filePath = fileIdx >= 0 ? args[fileIdx + 1] : undefined;
|
|
31
|
+
if (!filePath) {
|
|
32
|
+
error('Missing --file argument');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
if (!existsSync(filePath)) {
|
|
36
|
+
error(`File not found: ${filePath}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
const dest = TARGETS[target];
|
|
40
|
+
mkdirSync(OPENCLAW_WORKSPACE, { recursive: true });
|
|
41
|
+
await shell(`cp -f '${filePath}' '${dest}'`);
|
|
42
|
+
info(`Written to ${dest}`);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;GAEG;AACH,MAAM,OAAO,GAA2B;IACtC,IAAI,EAAM,GAAG,kBAAkB,UAAU;IACzC,QAAQ,EAAE,GAAG,kBAAkB,cAAc;IAC7C,IAAI,EAAM,GAAG,kBAAkB,UAAU;IACzC,MAAM,EAAI,GAAG,kBAAkB,YAAY;CAC5C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAc;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,uBAAuB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,KAAK,CAAC,UAAU,QAAQ,MAAM,IAAI,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* okclaw feed --file <path>
|
|
3
|
+
*
|
|
4
|
+
* Feeds file content into OpenViking's memory system.
|
|
5
|
+
*
|
|
6
|
+
* - If the file is a .zip/.tar.gz, extract first then process each file.
|
|
7
|
+
* - For each text file, submit the entire file content as one session and extract memories.
|
|
8
|
+
* - Non-text files are added as resources (ov add-resource).
|
|
9
|
+
*/
|
|
10
|
+
export declare function feedCommand(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, readdirSync, statSync, mkdirSync, rmSync, unlinkSync } from 'node:fs';
|
|
2
|
+
import { join, extname } from 'node:path';
|
|
3
|
+
import { shell, shellCapture } from '../utils/shell.js';
|
|
4
|
+
import { info, warn, error, success } from '../utils/logger.js';
|
|
5
|
+
const OV_API = 'http://localhost:1933';
|
|
6
|
+
const TEXT_EXTENSIONS = new Set(['.md', '.txt', '.text', '.csv', '.json', '.xml', '.yaml', '.yml', '.log']);
|
|
7
|
+
/**
|
|
8
|
+
* okclaw feed --file <path>
|
|
9
|
+
*
|
|
10
|
+
* Feeds file content into OpenViking's memory system.
|
|
11
|
+
*
|
|
12
|
+
* - If the file is a .zip/.tar.gz, extract first then process each file.
|
|
13
|
+
* - For each text file, submit the entire file content as one session and extract memories.
|
|
14
|
+
* - Non-text files are added as resources (ov add-resource).
|
|
15
|
+
*/
|
|
16
|
+
export async function feedCommand(args) {
|
|
17
|
+
const fileIdx = args.indexOf('--file');
|
|
18
|
+
const filePath = fileIdx >= 0 ? args[fileIdx + 1] : undefined;
|
|
19
|
+
if (!filePath) {
|
|
20
|
+
error('Usage: okclaw feed --file <path>');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
if (!existsSync(filePath)) {
|
|
24
|
+
error(`File not found: ${filePath}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const ext = extname(filePath).toLowerCase();
|
|
28
|
+
if (ext === '.zip' || ext === '.gz' || ext === '.tgz' || filePath.endsWith('.tar.gz')) {
|
|
29
|
+
await feedArchive(filePath);
|
|
30
|
+
}
|
|
31
|
+
else if (isTextFile(ext)) {
|
|
32
|
+
await feedTextFile(filePath);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
info(`Non-text file, adding as resource: ${filePath}`);
|
|
36
|
+
await shell(`ov add-resource '${filePath}' -o json`);
|
|
37
|
+
success('Resource added.');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function feedArchive(archivePath) {
|
|
41
|
+
const tmpDir = '/tmp/okclaw_feed_extract_' + process.pid;
|
|
42
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
43
|
+
try {
|
|
44
|
+
const ext = extname(archivePath).toLowerCase();
|
|
45
|
+
if (ext === '.zip') {
|
|
46
|
+
await shell(`unzip -o '${archivePath}' -d '${tmpDir}'`);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
await shell(`tar xzf '${archivePath}' -C '${tmpDir}'`);
|
|
50
|
+
}
|
|
51
|
+
const files = collectFiles(tmpDir);
|
|
52
|
+
info(`Extracted ${files.length} file(s) from archive`);
|
|
53
|
+
for (let i = 0; i < files.length; i++) {
|
|
54
|
+
const file = files[i];
|
|
55
|
+
const fileExt = extname(file).toLowerCase();
|
|
56
|
+
info(`[${i + 1}/${files.length}] Processing: ${file.replace(tmpDir + '/', '')}`);
|
|
57
|
+
if (isTextFile(fileExt)) {
|
|
58
|
+
await feedTextFile(file);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
await shell(`ov add-resource '${file}' -o json`);
|
|
62
|
+
info(' Added as resource');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
success(`All ${files.length} file(s) processed.`);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Feed an entire text file as one session → extract memories.
|
|
73
|
+
* Whole-file submission gives LLM full context for better memory extraction.
|
|
74
|
+
*/
|
|
75
|
+
async function feedTextFile(filePath) {
|
|
76
|
+
const content = readFileSync(filePath, 'utf-8').trim();
|
|
77
|
+
if (!content) {
|
|
78
|
+
warn(`Skipping empty file: ${filePath}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
info(` Feeding file content (${content.length} chars)...`);
|
|
82
|
+
// 1. Create session
|
|
83
|
+
const createResult = await curlJson('POST', `${OV_API}/api/v1/sessions`, {});
|
|
84
|
+
const sessionId = createResult?.result?.session_id;
|
|
85
|
+
if (!sessionId) {
|
|
86
|
+
throw new Error('Failed to create session');
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
// 2. Add entire file as one user message
|
|
90
|
+
await curlJson('POST', `${OV_API}/api/v1/sessions/${sessionId}/messages`, {
|
|
91
|
+
role: 'user',
|
|
92
|
+
content,
|
|
93
|
+
});
|
|
94
|
+
// 3. Extract memories (sync — waits for LLM to analyze and extract, may take minutes)
|
|
95
|
+
const extractResult = await curlJson('POST', `${OV_API}/api/v1/sessions/${sessionId}/extract`, {});
|
|
96
|
+
const memories = Array.isArray(extractResult?.result) ? extractResult.result : [];
|
|
97
|
+
info(` Extracted ${memories.length} memories`);
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
// 4. Cleanup session (ignore errors — best effort)
|
|
101
|
+
try {
|
|
102
|
+
await curlJson('DELETE', `${OV_API}/api/v1/sessions/${sessionId}`, null);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// session cleanup is best-effort
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
|
+
async function curlJson(method, url, body) {
|
|
111
|
+
let cmd;
|
|
112
|
+
let tmpFile = null;
|
|
113
|
+
if (body === null) {
|
|
114
|
+
cmd = `curl -s -X ${method} '${url}'`;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
tmpFile = `/tmp/okclaw_curl_${process.pid}_${Date.now()}.json`;
|
|
118
|
+
writeFileSync(tmpFile, JSON.stringify(body), 'utf-8');
|
|
119
|
+
cmd = `curl -s -X ${method} '${url}' -H 'Content-Type: application/json' -d @'${tmpFile}'`;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
const result = await shellCapture(cmd);
|
|
123
|
+
if (result.code !== 0) {
|
|
124
|
+
throw new Error(`curl failed: ${result.stderr}`);
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
return JSON.parse(result.stdout);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
throw new Error(`Invalid JSON response: ${result.stdout}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
if (tmpFile && existsSync(tmpFile)) {
|
|
135
|
+
unlinkSync(tmpFile);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function isTextFile(ext) {
|
|
140
|
+
return TEXT_EXTENSIONS.has(ext);
|
|
141
|
+
}
|
|
142
|
+
function collectFiles(dir) {
|
|
143
|
+
const files = [];
|
|
144
|
+
for (const entry of readdirSync(dir)) {
|
|
145
|
+
if (entry.startsWith('.'))
|
|
146
|
+
continue;
|
|
147
|
+
const fullPath = join(dir, entry);
|
|
148
|
+
const stat = statSync(fullPath);
|
|
149
|
+
if (stat.isDirectory()) {
|
|
150
|
+
files.push(...collectFiles(fullPath));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
files.push(fullPath);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return files;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=feed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feed.js","sourceRoot":"","sources":["../../src/commands/feed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function installCommand(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { OpenclawInstaller } from '../installers/openclaw.js';
|
|
3
|
+
import { OpenvikingInstaller } from '../installers/openviking.js';
|
|
4
|
+
import { ChannelInstaller } from '../installers/channel.js';
|
|
5
|
+
import { configureMirrors } from '../utils/mirror.js';
|
|
6
|
+
import { info, error, success } from '../utils/logger.js';
|
|
7
|
+
function getInstaller(component) {
|
|
8
|
+
switch (component) {
|
|
9
|
+
case 'openclaw': return new OpenclawInstaller();
|
|
10
|
+
case 'openviking': return new OpenvikingInstaller();
|
|
11
|
+
default: return new ChannelInstaller(component);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function installCommand(args) {
|
|
15
|
+
const component = args[0];
|
|
16
|
+
if (!component) {
|
|
17
|
+
error('Usage: okclaw install <component> --version <ver> [--config <json>] [--config-file <path>] [--package-url <url>]');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
let version = '';
|
|
21
|
+
let config;
|
|
22
|
+
let packageUrl;
|
|
23
|
+
for (let i = 1; i < args.length; i++) {
|
|
24
|
+
const arg = args[i];
|
|
25
|
+
if ((arg === '--version' || arg.startsWith('--version=')) && !version) {
|
|
26
|
+
version = arg.includes('=') ? arg.split('=')[1] : args[++i];
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (arg === '--config' && args[i + 1]) {
|
|
30
|
+
try {
|
|
31
|
+
config = JSON.parse(args[++i]);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
error('Invalid --config JSON');
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if ((arg === '--config-file' || arg.startsWith('--config-file=')) && !config) {
|
|
40
|
+
const filePath = arg.includes('=') ? arg.split('=')[1] : args[++i];
|
|
41
|
+
try {
|
|
42
|
+
config = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
error(`Failed to read config file: ${e}`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if ((arg === '--package-url' || arg.startsWith('--package-url=')) && !packageUrl) {
|
|
51
|
+
packageUrl = arg.includes('=') ? arg.split('=')[1] : args[++i];
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!version) {
|
|
56
|
+
error('--version is required');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
info(`Installing ${component}@${version}...`);
|
|
60
|
+
const installer = getInstaller(component);
|
|
61
|
+
await installer.checkDeps();
|
|
62
|
+
await configureMirrors();
|
|
63
|
+
await installer.install(version, packageUrl);
|
|
64
|
+
if (config) {
|
|
65
|
+
await installer.configure(config);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
info('No config provided, keeping existing configuration.');
|
|
69
|
+
}
|
|
70
|
+
success(`${component}@${version} installed.`);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { shell, shellCapture } from '../utils/shell.js';
|
|
2
|
+
import { info, success } from '../utils/logger.js';
|
|
3
|
+
import { OPENVIKING_ENV } from '../utils/constants.js';
|
|
4
|
+
export async function startCommand() {
|
|
5
|
+
info('Starting openclaw gateway...');
|
|
6
|
+
await shell(`source ${OPENVIKING_ENV} 2>/dev/null || true; openclaw gateway start`);
|
|
7
|
+
success('Gateway started.');
|
|
8
|
+
}
|
|
9
|
+
export async function stopCommand() {
|
|
10
|
+
info('Stopping openclaw gateway...');
|
|
11
|
+
await shell('openclaw gateway stop 2>/dev/null || true');
|
|
12
|
+
success('Gateway stopped.');
|
|
13
|
+
}
|
|
14
|
+
export async function restartCommand() {
|
|
15
|
+
info('Restarting openclaw gateway...');
|
|
16
|
+
await shell(`source ${OPENVIKING_ENV} 2>/dev/null || true; openclaw gateway restart`);
|
|
17
|
+
success('Gateway restarted.');
|
|
18
|
+
}
|
|
19
|
+
export async function statusCommand() {
|
|
20
|
+
const result = await shellCapture('openclaw gateway status 2>&1 || true');
|
|
21
|
+
console.log(result.stdout || result.stderr || 'No output');
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/commands/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACrC,MAAM,KAAK,CAAC,UAAU,cAAc,8CAA8C,CAAC,CAAC;IACpF,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACrC,MAAM,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IACvC,MAAM,KAAK,CAAC,UAAU,cAAc,gDAAgD,CAAC,CAAC;IACtF,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,sCAAsC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC;AAC7D,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { installCommand } from './commands/install.js';
|
|
2
|
+
import { checkCommand } from './commands/check.js';
|
|
3
|
+
import { editCommand } from './commands/edit.js';
|
|
4
|
+
import { feedCommand } from './commands/feed.js';
|
|
5
|
+
import { startCommand, stopCommand, restartCommand, statusCommand } from './commands/service.js';
|
|
6
|
+
import { ensureRoot } from './utils/shell.js';
|
|
7
|
+
import { error } from './utils/logger.js';
|
|
8
|
+
const [command, ...args] = process.argv.slice(2);
|
|
9
|
+
async function main() {
|
|
10
|
+
// All commands require root (or auto-sudo)
|
|
11
|
+
if (command && command !== '--help' && command !== '-h' && command !== '--version' && command !== '-v') {
|
|
12
|
+
ensureRoot();
|
|
13
|
+
}
|
|
14
|
+
switch (command) {
|
|
15
|
+
case 'install':
|
|
16
|
+
await installCommand(args);
|
|
17
|
+
break;
|
|
18
|
+
case 'check':
|
|
19
|
+
await checkCommand();
|
|
20
|
+
break;
|
|
21
|
+
case 'start':
|
|
22
|
+
await startCommand();
|
|
23
|
+
break;
|
|
24
|
+
case 'stop':
|
|
25
|
+
await stopCommand();
|
|
26
|
+
break;
|
|
27
|
+
case 'restart':
|
|
28
|
+
await restartCommand();
|
|
29
|
+
break;
|
|
30
|
+
case 'status':
|
|
31
|
+
await statusCommand();
|
|
32
|
+
break;
|
|
33
|
+
case 'edit':
|
|
34
|
+
await editCommand(args);
|
|
35
|
+
break;
|
|
36
|
+
case 'feed':
|
|
37
|
+
await feedCommand(args);
|
|
38
|
+
break;
|
|
39
|
+
case '--version':
|
|
40
|
+
case '-v':
|
|
41
|
+
console.log('1.0.0');
|
|
42
|
+
break;
|
|
43
|
+
case '--help':
|
|
44
|
+
case '-h':
|
|
45
|
+
case undefined:
|
|
46
|
+
printHelp();
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
error(`Unknown command: ${command}`);
|
|
50
|
+
printHelp();
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function printHelp() {
|
|
55
|
+
console.log(`
|
|
56
|
+
okclaw - OKClaw Deployment CLI
|
|
57
|
+
|
|
58
|
+
Usage: okclaw <command> [args...]
|
|
59
|
+
|
|
60
|
+
okclaw install <component> --version <ver> [--config '<json>'] [--config-file <path>] [--package-url <url>]
|
|
61
|
+
okclaw check Check & install system dependencies
|
|
62
|
+
okclaw start Start openclaw gateway
|
|
63
|
+
okclaw stop Stop openclaw gateway
|
|
64
|
+
okclaw restart Restart openclaw gateway
|
|
65
|
+
okclaw status Show gateway status
|
|
66
|
+
okclaw edit <target> --file <path> Write config file (user/identity/soul/agents)
|
|
67
|
+
okclaw feed --file <path> Feed file into knowledge base
|
|
68
|
+
|
|
69
|
+
Components:
|
|
70
|
+
openclaw Core AI Agent framework (npm install)
|
|
71
|
+
openviking Long-term memory plugin (pip + openclaw plugin, needs --package-url)
|
|
72
|
+
dingtalk DingTalk channel (npm: @largezhou/ddingtalk)
|
|
73
|
+
feishu Feishu/Lark channel (npm: @openclaw/feishu)
|
|
74
|
+
wechat WeChat channel (npm: @tencent-weixin/openclaw-weixin)
|
|
75
|
+
s3 S3 IM channel (needs --package-url)
|
|
76
|
+
|
|
77
|
+
Examples:
|
|
78
|
+
okclaw install openclaw --version 2026.3.24 --config-file /root/okclaw/config/openclaw.json
|
|
79
|
+
okclaw install openviking --version 0.2.15 --package-url /tmp/ov-plugin.tar.gz --config-file /root/okclaw/config/openviking.json
|
|
80
|
+
okclaw install dingtalk --version 2.0.1 --config '{"clientId":"xxx","clientSecret":"xxx"}'
|
|
81
|
+
okclaw install s3 --version 1.0.0 --package-url /tmp/channel-s3.tar.gz
|
|
82
|
+
okclaw restart
|
|
83
|
+
okclaw status
|
|
84
|
+
|
|
85
|
+
Notes:
|
|
86
|
+
- All commands auto-elevate to root via sudo if needed
|
|
87
|
+
- All paths are anchored to /root/ (forced HOME=/root)
|
|
88
|
+
- npm uses npmmirror, pip uses tsinghua mirror (China acceleration)
|
|
89
|
+
- Node.js >= 22.16 and Python >= 3.11 are auto-installed if missing
|
|
90
|
+
`);
|
|
91
|
+
}
|
|
92
|
+
main().catch((err) => {
|
|
93
|
+
error(String(err.message || err));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEjD,KAAK,UAAU,IAAI;IACjB,2CAA2C;IAC3C,IAAI,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACvG,UAAU,EAAE,CAAC;IACf,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,EAAE,CAAC;YACrB,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,EAAE,CAAC;YACrB,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,cAAc,EAAE,CAAC;YACvB,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,aAAa,EAAE,CAAC;YACtB,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YACxB,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YACxB,MAAM;QACR,KAAK,WAAW,CAAC;QACjB,KAAK,IAAI;YACP,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACrB,MAAM;QACR,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI,CAAC;QACV,KAAK,SAAS;YACZ,SAAS,EAAE,CAAC;YACZ,MAAM;QACR;YACE,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YACrC,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCb,CAAC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/installers/base.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Installer } from './base.js';
|
|
2
|
+
export declare class ChannelInstaller implements Installer {
|
|
3
|
+
private channelName;
|
|
4
|
+
constructor(channelName: string);
|
|
5
|
+
checkDeps(): Promise<void>;
|
|
6
|
+
install(version: string, packageUrl?: string): Promise<void>;
|
|
7
|
+
configure(config: Record<string, unknown>): Promise<void>;
|
|
8
|
+
private removeExistingPlugin;
|
|
9
|
+
private installFromLocalPackage;
|
|
10
|
+
/**
|
|
11
|
+
* Download tgz from npm (npmmirror) first, then install locally.
|
|
12
|
+
* This bypasses ClawHub rate limiting (429 errors).
|
|
13
|
+
*/
|
|
14
|
+
private installViaNpmPack;
|
|
15
|
+
private addToPluginsAllow;
|
|
16
|
+
private applyConfig;
|
|
17
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, rmSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { shell, shellCapture } from '../utils/shell.js';
|
|
3
|
+
import { ensureCommand, checkDiskSpace } from '../utils/deps.js';
|
|
4
|
+
import { info, warn } from '../utils/logger.js';
|
|
5
|
+
import { CHANNEL_NPM_PACKAGES, BUNDLED_PLUGINS, OKCLAW_TMP_DIR, OPENCLAW_HOME, NPM_REGISTRY } from '../utils/constants.js';
|
|
6
|
+
export class ChannelInstaller {
|
|
7
|
+
channelName;
|
|
8
|
+
constructor(channelName) {
|
|
9
|
+
this.channelName = channelName;
|
|
10
|
+
}
|
|
11
|
+
async checkDeps() {
|
|
12
|
+
await checkDiskSpace(200);
|
|
13
|
+
await ensureCommand('openclaw');
|
|
14
|
+
}
|
|
15
|
+
async install(version, packageUrl) {
|
|
16
|
+
if (BUNDLED_PLUGINS.has(this.channelName)) {
|
|
17
|
+
info(`${this.channelName} is bundled with openclaw, skipping install (config only).`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
// Remove existing plugin to avoid "plugin already exists" error
|
|
21
|
+
this.removeExistingPlugin();
|
|
22
|
+
if (packageUrl) {
|
|
23
|
+
await this.installFromLocalPackage(packageUrl);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
await this.installViaNpmPack(version);
|
|
27
|
+
}
|
|
28
|
+
// Add to plugins.allow so openclaw trusts this plugin
|
|
29
|
+
await this.addToPluginsAllow();
|
|
30
|
+
info(`${this.channelName}@${version} installed.`);
|
|
31
|
+
}
|
|
32
|
+
async configure(config) {
|
|
33
|
+
if (!config || Object.keys(config).length === 0)
|
|
34
|
+
return;
|
|
35
|
+
// All channel configs go to channels.<name> (both bundled and external plugins)
|
|
36
|
+
// plugins.entries is managed by openclaw plugins install, we don't touch it
|
|
37
|
+
const configPrefix = `channels.${this.channelName}`;
|
|
38
|
+
info(`Configuring ${this.channelName} at ${configPrefix}...`);
|
|
39
|
+
await this.applyConfig(config, configPrefix);
|
|
40
|
+
info(`${this.channelName} configured.`);
|
|
41
|
+
}
|
|
42
|
+
// ---- private ----
|
|
43
|
+
removeExistingPlugin() {
|
|
44
|
+
const pluginDir = `${OPENCLAW_HOME}/extensions/${this.channelName}`;
|
|
45
|
+
if (existsSync(pluginDir)) {
|
|
46
|
+
info(`Removing existing plugin at ${pluginDir}...`);
|
|
47
|
+
rmSync(pluginDir, { recursive: true, force: true });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async installFromLocalPackage(packageUrl) {
|
|
51
|
+
mkdirSync(OKCLAW_TMP_DIR, { recursive: true });
|
|
52
|
+
const archive = `${OKCLAW_TMP_DIR}/${this.channelName}-plugin.tgz`;
|
|
53
|
+
if (packageUrl.startsWith('http')) {
|
|
54
|
+
info(`Downloading ${this.channelName} from ${packageUrl}...`);
|
|
55
|
+
await shell(`curl -fsSL --connect-timeout 30 --retry 3 -o "${archive}" "${packageUrl}"`);
|
|
56
|
+
}
|
|
57
|
+
else if (existsSync(packageUrl)) {
|
|
58
|
+
await shell(`cp "${packageUrl}" "${archive}"`);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
throw new Error(`Package not found: ${packageUrl}`);
|
|
62
|
+
}
|
|
63
|
+
info(`Installing ${this.channelName} from local package...`);
|
|
64
|
+
await shell(`openclaw plugins install "${archive}"`);
|
|
65
|
+
await shell(`rm -f "${archive}"`).catch(() => { });
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Download tgz from npm (npmmirror) first, then install locally.
|
|
69
|
+
* This bypasses ClawHub rate limiting (429 errors).
|
|
70
|
+
*/
|
|
71
|
+
async installViaNpmPack(version) {
|
|
72
|
+
const npmPkg = CHANNEL_NPM_PACKAGES[this.channelName];
|
|
73
|
+
if (!npmPkg) {
|
|
74
|
+
throw new Error(`No npm package mapping for '${this.channelName}'. ` +
|
|
75
|
+
`Use --package-url to install from a local package.`);
|
|
76
|
+
}
|
|
77
|
+
const pkgSpec = `${npmPkg}@${version}`;
|
|
78
|
+
mkdirSync(OKCLAW_TMP_DIR, { recursive: true });
|
|
79
|
+
info(`Downloading ${pkgSpec} from npm...`);
|
|
80
|
+
const packResult = await shellCapture(`cd "${OKCLAW_TMP_DIR}" && npm pack "${pkgSpec}" --registry ${NPM_REGISTRY} 2>&1 | tail -1`);
|
|
81
|
+
if (packResult.code !== 0) {
|
|
82
|
+
throw new Error(`npm pack failed for ${pkgSpec}: ${packResult.stderr}`);
|
|
83
|
+
}
|
|
84
|
+
const tgzFile = `${OKCLAW_TMP_DIR}/${packResult.stdout.trim()}`;
|
|
85
|
+
if (!existsSync(tgzFile)) {
|
|
86
|
+
throw new Error(`npm pack did not produce expected file: ${tgzFile}`);
|
|
87
|
+
}
|
|
88
|
+
info(`Installing ${this.channelName} from ${tgzFile}...`);
|
|
89
|
+
await shell(`openclaw plugins install "${tgzFile}"`);
|
|
90
|
+
await shell(`rm -f "${tgzFile}"`).catch(() => { });
|
|
91
|
+
}
|
|
92
|
+
async addToPluginsAllow() {
|
|
93
|
+
const configFile = `${OPENCLAW_HOME}/openclaw.json`;
|
|
94
|
+
if (!existsSync(configFile))
|
|
95
|
+
return;
|
|
96
|
+
try {
|
|
97
|
+
const cfg = JSON.parse(readFileSync(configFile, 'utf8'));
|
|
98
|
+
if (!cfg.plugins)
|
|
99
|
+
cfg.plugins = {};
|
|
100
|
+
if (!Array.isArray(cfg.plugins.allow))
|
|
101
|
+
cfg.plugins.allow = [];
|
|
102
|
+
if (!cfg.plugins.allow.includes(this.channelName)) {
|
|
103
|
+
cfg.plugins.allow.push(this.channelName);
|
|
104
|
+
writeFileSync(configFile, JSON.stringify(cfg, null, 2) + '\n', 'utf8');
|
|
105
|
+
info(`Added ${this.channelName} to plugins.allow`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
warn(`Failed to update plugins.allow: ${e}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async applyConfig(obj, prefix) {
|
|
113
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
114
|
+
if (value === null || value === undefined)
|
|
115
|
+
continue;
|
|
116
|
+
const path = `${prefix}.${key}`;
|
|
117
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
118
|
+
await this.applyConfig(value, path);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
const strVal = String(value).replace(/'/g, "'\\''");
|
|
122
|
+
await shell(`openclaw config set '${path}' '${strVal}'`).catch(() => {
|
|
123
|
+
warn(`Failed to set ${path}`);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=channel.js.map
|