clawkittool 0.1.0 → 0.1.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/README.md +24 -0
- package/bin/clawkittool.js +31 -1
- package/lib/get.js +112 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,6 +8,30 @@
|
|
|
8
8
|
clawkittool get product-kit
|
|
9
9
|
clawkittool get hotnews-kit --dir ./my-clawkit
|
|
10
10
|
clawkittool get product-kit --manifest https://example.com/clawkit/manifest.json
|
|
11
|
+
clawkittool get product-kit --config ~/.openclaw
|
|
12
|
+
clawkittool get product-kit --target-name sandbox
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
默认行为:
|
|
16
|
+
|
|
17
|
+
- 下载 `core.zip`
|
|
18
|
+
- 下载指定 kit
|
|
19
|
+
- 自动执行 `npm install`
|
|
20
|
+
- 自动探测本机 OpenClaw 目录并执行 `deploy`
|
|
21
|
+
|
|
22
|
+
自动探测顺序:
|
|
23
|
+
|
|
24
|
+
- `--config <path>`
|
|
25
|
+
- `OPENCLAW_HOME`
|
|
26
|
+
- `OPENCLAW_CONFIG_DIR`
|
|
27
|
+
- `OPENCLAW_CONFIG_PATH`
|
|
28
|
+
- `~/.openclaw/openclaw.json`
|
|
29
|
+
- `~/.config/openclaw/openclaw.json`
|
|
30
|
+
|
|
31
|
+
如果只想下载但不自动部署,可以加:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
clawkittool get product-kit --skip-deploy
|
|
11
35
|
```
|
|
12
36
|
|
|
13
37
|
## manifest 格式
|
package/bin/clawkittool.js
CHANGED
|
@@ -5,7 +5,7 @@ const { installKitFromManifest } = require('../lib/get');
|
|
|
5
5
|
|
|
6
6
|
function printUsage() {
|
|
7
7
|
console.log(`Usage:
|
|
8
|
-
clawkittool get <kit-name> [--dir <path>] [--manifest <url-or-path>] [--force] [--skip-install]
|
|
8
|
+
clawkittool get <kit-name> [--dir <path>] [--manifest <url-or-path>] [--config <path>] [--target-name <name>] [--force] [--skip-install] [--skip-deploy]
|
|
9
9
|
`);
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -29,6 +29,9 @@ async function main(argv) {
|
|
|
29
29
|
let manifestSource = process.env.CLAWKIT_MANIFEST_URL || null;
|
|
30
30
|
let force = false;
|
|
31
31
|
let skipInstall = false;
|
|
32
|
+
let skipDeploy = false;
|
|
33
|
+
let explicitConfigPath = null;
|
|
34
|
+
let targetName = null;
|
|
32
35
|
|
|
33
36
|
for (let index = 0; index < rest.length; index += 1) {
|
|
34
37
|
const arg = rest[index];
|
|
@@ -45,6 +48,18 @@ async function main(argv) {
|
|
|
45
48
|
continue;
|
|
46
49
|
}
|
|
47
50
|
|
|
51
|
+
if (arg === '--config') {
|
|
52
|
+
explicitConfigPath = rest[index + 1] || null;
|
|
53
|
+
index += 1;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (arg === '--target-name') {
|
|
58
|
+
targetName = rest[index + 1] || null;
|
|
59
|
+
index += 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
48
63
|
if (arg === '--force') {
|
|
49
64
|
force = true;
|
|
50
65
|
continue;
|
|
@@ -55,6 +70,11 @@ async function main(argv) {
|
|
|
55
70
|
continue;
|
|
56
71
|
}
|
|
57
72
|
|
|
73
|
+
if (arg === '--skip-deploy') {
|
|
74
|
+
skipDeploy = true;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
58
78
|
throw new Error(`Unknown argument: ${arg}`);
|
|
59
79
|
}
|
|
60
80
|
|
|
@@ -68,9 +88,19 @@ async function main(argv) {
|
|
|
68
88
|
manifestSource,
|
|
69
89
|
force,
|
|
70
90
|
skipInstall,
|
|
91
|
+
explicitConfigPath,
|
|
92
|
+
skipDeploy,
|
|
93
|
+
targetName,
|
|
71
94
|
});
|
|
72
95
|
|
|
73
96
|
console.log(`Installed ${result.kitName} into ${result.targetDir}`);
|
|
97
|
+
if (result.deployed) {
|
|
98
|
+
console.log(`Deployed ${result.kitName} to ${result.detectedConfigPath}`);
|
|
99
|
+
} else if (result.detectedConfigPath) {
|
|
100
|
+
console.log(`Detected OpenClaw config at ${result.detectedConfigPath}, but deployment was skipped.`);
|
|
101
|
+
} else {
|
|
102
|
+
console.log('No OpenClaw config detected. Pass --config to deploy automatically.');
|
|
103
|
+
}
|
|
74
104
|
}
|
|
75
105
|
|
|
76
106
|
main(process.argv.slice(2)).catch((error) => {
|
package/lib/get.js
CHANGED
|
@@ -7,6 +7,70 @@ function ensureDir(dirPath) {
|
|
|
7
7
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
function resolveOpenClawConfigFile(candidatePath) {
|
|
11
|
+
if (!candidatePath) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const resolvedPath = path.resolve(candidatePath);
|
|
16
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const stats = fs.statSync(resolvedPath);
|
|
21
|
+
if (stats.isDirectory()) {
|
|
22
|
+
const configPath = path.join(resolvedPath, 'openclaw.json');
|
|
23
|
+
return fs.existsSync(configPath) ? configPath : null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return path.basename(resolvedPath) === 'openclaw.json' ? resolvedPath : null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function detectOpenClawConfigPath({
|
|
30
|
+
explicitConfigPath = null,
|
|
31
|
+
env = process.env,
|
|
32
|
+
homeDir = os.homedir(),
|
|
33
|
+
platform = process.platform,
|
|
34
|
+
} = {}) {
|
|
35
|
+
const explicitMatch = resolveOpenClawConfigFile(explicitConfigPath);
|
|
36
|
+
if (explicitMatch) {
|
|
37
|
+
return explicitMatch;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const envCandidates = [
|
|
41
|
+
env.OPENCLAW_HOME,
|
|
42
|
+
env.OPENCLAW_CONFIG_DIR,
|
|
43
|
+
env.OPENCLAW_CONFIG_PATH,
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
for (const candidate of envCandidates) {
|
|
47
|
+
const envMatch = resolveOpenClawConfigFile(candidate);
|
|
48
|
+
if (envMatch) {
|
|
49
|
+
return envMatch;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const defaultCandidates =
|
|
54
|
+
platform === 'win32'
|
|
55
|
+
? [
|
|
56
|
+
path.join(homeDir, '.openclaw'),
|
|
57
|
+
env.APPDATA ? path.join(env.APPDATA, 'openclaw') : null,
|
|
58
|
+
]
|
|
59
|
+
: [
|
|
60
|
+
path.join(homeDir, '.openclaw'),
|
|
61
|
+
path.join(homeDir, '.config', 'openclaw'),
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
for (const candidate of defaultCandidates) {
|
|
65
|
+
const defaultMatch = resolveOpenClawConfigFile(candidate);
|
|
66
|
+
if (defaultMatch) {
|
|
67
|
+
return defaultMatch;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
10
74
|
function makeTempDir() {
|
|
11
75
|
return fs.mkdtempSync(path.join(os.tmpdir(), 'clawkittool-'));
|
|
12
76
|
}
|
|
@@ -184,12 +248,40 @@ function runInstall(targetDir) {
|
|
|
184
248
|
}
|
|
185
249
|
}
|
|
186
250
|
|
|
251
|
+
function runDeploy({ targetDir, kitName, configPath, targetName = null, force = false }) {
|
|
252
|
+
const nodeCommand = process.execPath;
|
|
253
|
+
const deployArgs = [path.join(targetDir, 'cli', 'index.js'), 'deploy', kitName, '--config', configPath, '--apply'];
|
|
254
|
+
|
|
255
|
+
if (targetName) {
|
|
256
|
+
deployArgs.push('--target-name', targetName);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (force) {
|
|
260
|
+
deployArgs.push('--force');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const result = spawnSync(nodeCommand, deployArgs, {
|
|
264
|
+
cwd: targetDir,
|
|
265
|
+
stdio: 'inherit',
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
if (result.status !== 0) {
|
|
269
|
+
throw new Error(`clawkit deploy failed for ${kitName}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
187
273
|
async function installKitFromManifest({
|
|
188
274
|
kitName,
|
|
189
275
|
targetDir,
|
|
190
276
|
manifestSource,
|
|
191
277
|
force = false,
|
|
192
278
|
skipInstall = false,
|
|
279
|
+
explicitConfigPath = null,
|
|
280
|
+
skipDeploy = false,
|
|
281
|
+
targetName = null,
|
|
282
|
+
env = process.env,
|
|
283
|
+
homeDir = os.homedir(),
|
|
284
|
+
deployRunner = runDeploy,
|
|
193
285
|
}) {
|
|
194
286
|
const manifest = await loadManifest(manifestSource);
|
|
195
287
|
const kitEntry = manifest.kits[kitName];
|
|
@@ -205,6 +297,11 @@ async function installKitFromManifest({
|
|
|
205
297
|
const coreExtractDir = path.join(tempDir, 'core');
|
|
206
298
|
const kitZipPath = path.join(tempDir, `${kitName}.zip`);
|
|
207
299
|
const kitExtractDir = path.join(tempDir, kitName);
|
|
300
|
+
const detectedConfigPath = detectOpenClawConfigPath({
|
|
301
|
+
explicitConfigPath,
|
|
302
|
+
env,
|
|
303
|
+
homeDir,
|
|
304
|
+
});
|
|
208
305
|
|
|
209
306
|
try {
|
|
210
307
|
await downloadFile(manifest.core.url, coreZipPath);
|
|
@@ -219,9 +316,23 @@ async function installKitFromManifest({
|
|
|
219
316
|
runInstall(targetDir);
|
|
220
317
|
}
|
|
221
318
|
|
|
319
|
+
let deployed = false;
|
|
320
|
+
if (!skipDeploy && detectedConfigPath) {
|
|
321
|
+
deployRunner({
|
|
322
|
+
targetDir,
|
|
323
|
+
kitName,
|
|
324
|
+
configPath: detectedConfigPath,
|
|
325
|
+
targetName,
|
|
326
|
+
force,
|
|
327
|
+
});
|
|
328
|
+
deployed = true;
|
|
329
|
+
}
|
|
330
|
+
|
|
222
331
|
return {
|
|
223
332
|
kitName,
|
|
224
333
|
targetDir,
|
|
334
|
+
detectedConfigPath,
|
|
335
|
+
deployed,
|
|
225
336
|
};
|
|
226
337
|
} finally {
|
|
227
338
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -229,6 +340,7 @@ async function installKitFromManifest({
|
|
|
229
340
|
}
|
|
230
341
|
|
|
231
342
|
module.exports = {
|
|
343
|
+
detectOpenClawConfigPath,
|
|
232
344
|
installKitFromManifest,
|
|
233
345
|
loadManifest,
|
|
234
346
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawkittool",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "On-demand installer for OpenClaw ClawKit workflow kits",
|
|
5
5
|
"bin": {
|
|
6
6
|
"clawkittool": "./bin/clawkittool.js"
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
],
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"engines": {
|
|
15
|
-
"node": ">=
|
|
15
|
+
"node": ">=22.0.0"
|
|
16
16
|
}
|
|
17
17
|
}
|