@okclaw-build/cli 1.0.0-beta.40 → 1.0.0-beta.42
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 +48 -0
- package/dist/commands/backup.d.ts +16 -0
- package/dist/commands/backup.js +72 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/migration.d.ts +1 -0
- package/dist/commands/migration.js +205 -0
- package/dist/commands/migration.js.map +1 -0
- package/dist/commands/restore.d.ts +16 -0
- package/dist/commands/restore.js +67 -0
- package/dist/commands/restore.js.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/installers/openclaw.d.ts +1 -14
- package/dist/installers/openclaw.js +4 -60
- package/dist/installers/openclaw.js.map +1 -1
- package/dist/installers/skill.d.ts +1 -0
- package/dist/installers/skill.js +24 -4
- package/dist/installers/skill.js.map +1 -1
- package/dist/migration/archive.d.ts +14 -0
- package/dist/migration/archive.js +84 -0
- package/dist/migration/archive.js.map +1 -0
- package/dist/migration/crypto.d.ts +16 -0
- package/dist/migration/crypto.js +56 -0
- package/dist/migration/crypto.js.map +1 -0
- package/dist/migration/manifest.d.ts +39 -0
- package/dist/migration/manifest.js +140 -0
- package/dist/migration/manifest.js.map +1 -0
- package/dist/openclaw-user-data.d.ts +63 -0
- package/dist/openclaw-user-data.js +246 -0
- package/dist/openclaw-user-data.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/installers/openclaw.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/installers/openclaw.ts"],"names":[],"mappings":"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"}
|
package/dist/installers/skill.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, rmSync } from 'node:fs';
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, rmSync, statSync } from 'node:fs';
|
|
2
2
|
import { shell, shellCapture } from '../utils/shell.js';
|
|
3
3
|
import { checkDiskSpace, ensureCommand } from '../utils/deps.js';
|
|
4
4
|
import { info, warn } from '../utils/logger.js';
|
|
5
5
|
import { OKCLAW_TMP_DIR, OPENCLAW_WORKSPACE } from '../utils/constants.js';
|
|
6
6
|
const SKILLS_DIR = `${OPENCLAW_WORKSPACE}/skills`;
|
|
7
|
+
// 与 okclaw-skill-api SkillUploadServiceImpl.hasSkillMdAtAcceptedRoot 对齐:上传端接受
|
|
8
|
+
// (a) SKILL.md 在 zip 根;(b) SKILL.md 在唯一顶层目录下。CLI 解压必须同样支持,
|
|
9
|
+
// 否则 ClawHub-style 包会落到 ~/.openclaw/skills/<name>/<name>/SKILL.md,openclaw 找不到。
|
|
10
|
+
export function findEffectiveSkillRoot(extractDir) {
|
|
11
|
+
const entries = readdirSync(extractDir);
|
|
12
|
+
if (entries.length === 1) {
|
|
13
|
+
const candidate = `${extractDir}/${entries[0]}`;
|
|
14
|
+
if (statSync(candidate).isDirectory() && existsSync(`${candidate}/SKILL.md`)) {
|
|
15
|
+
return candidate;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return extractDir;
|
|
19
|
+
}
|
|
7
20
|
export class SkillInstaller {
|
|
8
21
|
skillName;
|
|
9
22
|
constructor(skillName) {
|
|
@@ -37,13 +50,20 @@ export class SkillInstaller {
|
|
|
37
50
|
info(`Overwriting existing skill at ${skillDir}...`);
|
|
38
51
|
rmSync(skillDir, { recursive: true, force: true });
|
|
39
52
|
}
|
|
40
|
-
// Extract
|
|
41
|
-
|
|
53
|
+
// Extract to staging dir, then move effective root into skillDir
|
|
54
|
+
// (handles ClaudeCode-style 和 ClawHub-style 两种布局,与后端上传接受范围一致)
|
|
55
|
+
const stageDir = `${OKCLAW_TMP_DIR}/${this.skillName}-extract`;
|
|
56
|
+
rmSync(stageDir, { recursive: true, force: true });
|
|
57
|
+
mkdirSync(stageDir, { recursive: true });
|
|
42
58
|
info(`Extracting skill to ${skillDir}...`);
|
|
43
|
-
const unzipResult = await shellCapture(`unzip -o "${archive}" -d "${
|
|
59
|
+
const unzipResult = await shellCapture(`unzip -o "${archive}" -d "${stageDir}"`);
|
|
44
60
|
if (unzipResult.code > 1) {
|
|
45
61
|
throw new Error(`unzip failed (exit ${unzipResult.code}): ${unzipResult.stderr}`);
|
|
46
62
|
}
|
|
63
|
+
const sourceDir = findEffectiveSkillRoot(stageDir);
|
|
64
|
+
mkdirSync(skillDir, { recursive: true });
|
|
65
|
+
await shell(`find "${sourceDir}" -mindepth 1 -maxdepth 1 -exec mv {} "${skillDir}/" \\;`);
|
|
66
|
+
rmSync(stageDir, { recursive: true, force: true });
|
|
47
67
|
// Cleanup
|
|
48
68
|
await shell(`rm -f "${archive}"`).catch(() => { });
|
|
49
69
|
info(`Skill ${this.skillName} installed at ${skillDir}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/installers/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/installers/skill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const ARCHIVE_MANIFEST_NAME = "migration-manifest.json";
|
|
2
|
+
export interface TarCreateOptions {
|
|
3
|
+
tarPath: string;
|
|
4
|
+
manifestPath: string;
|
|
5
|
+
existingIncludePaths: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function buildTarCreateArgs(options: TarCreateOptions): string[];
|
|
8
|
+
export declare function buildTarExtractArgs(tarPath: string): string[];
|
|
9
|
+
export declare function buildTarListArgs(tarPath: string): string[];
|
|
10
|
+
export declare function validateTarEntries(entries: string[], allowedAbsoluteRoots: string[]): void;
|
|
11
|
+
export declare function buildTarExtractManifestArgs(tarPath: string, outDir: string): string[];
|
|
12
|
+
export declare function buildTarCommand(args: string[]): string;
|
|
13
|
+
export declare function buildCreateEncryptedArchiveCommand(keyFile: string, inputTarPath: string, outputArchivePath: string): string;
|
|
14
|
+
export declare function buildDecryptArchiveCommand(keyFile: string, inputArchivePath: string, outputTarPath: string): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { basename, dirname } from 'node:path';
|
|
2
|
+
import { excludePatterns } from './manifest.js';
|
|
3
|
+
import { buildAgeCommand, buildAgeDecryptArgs, buildAgeEncryptArgs, quoteShellArg } from './crypto.js';
|
|
4
|
+
export const ARCHIVE_MANIFEST_NAME = 'migration-manifest.json';
|
|
5
|
+
export function buildTarCreateArgs(options) {
|
|
6
|
+
return [
|
|
7
|
+
'--create',
|
|
8
|
+
'--file',
|
|
9
|
+
options.tarPath,
|
|
10
|
+
'--xattrs',
|
|
11
|
+
'--acls',
|
|
12
|
+
'--numeric-owner',
|
|
13
|
+
...excludePatterns.map((pattern) => `--exclude=${pattern}`),
|
|
14
|
+
'-C',
|
|
15
|
+
dirname(options.manifestPath),
|
|
16
|
+
basename(options.manifestPath),
|
|
17
|
+
'-C',
|
|
18
|
+
'/',
|
|
19
|
+
...options.existingIncludePaths.map(toTarRelativePath),
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
export function buildTarExtractArgs(tarPath) {
|
|
23
|
+
return [
|
|
24
|
+
'--extract',
|
|
25
|
+
'--file',
|
|
26
|
+
tarPath,
|
|
27
|
+
'--same-owner',
|
|
28
|
+
'--preserve-permissions',
|
|
29
|
+
'--numeric-owner',
|
|
30
|
+
'-C',
|
|
31
|
+
'/',
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
export function buildTarListArgs(tarPath) {
|
|
35
|
+
return [
|
|
36
|
+
'--list',
|
|
37
|
+
'--file',
|
|
38
|
+
tarPath,
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
export function validateTarEntries(entries, allowedAbsoluteRoots) {
|
|
42
|
+
const allowed = new Set([
|
|
43
|
+
ARCHIVE_MANIFEST_NAME,
|
|
44
|
+
...allowedAbsoluteRoots.map(toTarRelativePath).map(stripTrailingSlash),
|
|
45
|
+
]);
|
|
46
|
+
for (const raw of entries) {
|
|
47
|
+
const entry = stripTrailingSlash(raw.trim());
|
|
48
|
+
if (!entry)
|
|
49
|
+
continue;
|
|
50
|
+
if (entry.startsWith('/') || entry.split('/').includes('..')) {
|
|
51
|
+
throw new Error(`Unsafe archive entry: ${raw}`);
|
|
52
|
+
}
|
|
53
|
+
const ok = [...allowed].some((root) => entry === root || entry.startsWith(`${root}/`));
|
|
54
|
+
if (!ok) {
|
|
55
|
+
throw new Error(`Archive entry outside manifest paths: ${raw}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function buildTarExtractManifestArgs(tarPath, outDir) {
|
|
60
|
+
return [
|
|
61
|
+
'--extract',
|
|
62
|
+
'--file',
|
|
63
|
+
tarPath,
|
|
64
|
+
'-C',
|
|
65
|
+
outDir,
|
|
66
|
+
ARCHIVE_MANIFEST_NAME,
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
export function buildTarCommand(args) {
|
|
70
|
+
return ['tar', ...args.map(quoteShellArg)].join(' ');
|
|
71
|
+
}
|
|
72
|
+
export function buildCreateEncryptedArchiveCommand(keyFile, inputTarPath, outputArchivePath) {
|
|
73
|
+
return buildAgeCommand(buildAgeEncryptArgs(keyFile, inputTarPath, outputArchivePath));
|
|
74
|
+
}
|
|
75
|
+
export function buildDecryptArchiveCommand(keyFile, inputArchivePath, outputTarPath) {
|
|
76
|
+
return buildAgeCommand(buildAgeDecryptArgs(keyFile, inputArchivePath, outputTarPath));
|
|
77
|
+
}
|
|
78
|
+
function toTarRelativePath(path) {
|
|
79
|
+
return path.replace(/^\/+/, '');
|
|
80
|
+
}
|
|
81
|
+
function stripTrailingSlash(path) {
|
|
82
|
+
return path.replace(/\/+$/, '');
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/migration/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const AUTHENTICATED_ENCRYPTION_TOOL = "age";
|
|
2
|
+
export declare const AUTHENTICATED_ENCRYPTION_CONTRACT = "age-v1-X25519-ChaCha20Poly1305";
|
|
3
|
+
export declare function buildAgeEncryptArgs(keyFile: string, inputPath: string, outputPath: string): string[];
|
|
4
|
+
export declare function buildAgeDecryptArgs(keyFile: string, inputPath: string, outputPath: string): string[];
|
|
5
|
+
export declare function buildAgeCommand(args: string[]): string;
|
|
6
|
+
export declare function assertAuthenticatedEncryptionAvailable(): Promise<void>;
|
|
7
|
+
export declare function quoteShellArg(value: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* export 用 `--recipient-file`,必须是 age 公钥;若误传私钥(identity),age 会在运行期才报错。
|
|
10
|
+
* 提前在 CLI 层显式校验,避免操作人把私钥当公钥用。
|
|
11
|
+
*/
|
|
12
|
+
export declare function assertAgeRecipientContent(content: string, keyFile: string): void;
|
|
13
|
+
/**
|
|
14
|
+
* restore 用 `--identity`,必须是 age 私钥;若误传只含公钥的文件,提前报错而不是等 age 运行期失败。
|
|
15
|
+
*/
|
|
16
|
+
export declare function assertAgeIdentityContent(content: string, keyFile: string): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { commandExists } from '../utils/shell.js';
|
|
2
|
+
export const AUTHENTICATED_ENCRYPTION_TOOL = 'age';
|
|
3
|
+
export const AUTHENTICATED_ENCRYPTION_CONTRACT = 'age-v1-X25519-ChaCha20Poly1305';
|
|
4
|
+
export function buildAgeEncryptArgs(keyFile, inputPath, outputPath) {
|
|
5
|
+
return [
|
|
6
|
+
'--encrypt',
|
|
7
|
+
'--recipient-file',
|
|
8
|
+
keyFile,
|
|
9
|
+
'--output',
|
|
10
|
+
outputPath,
|
|
11
|
+
inputPath,
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
export function buildAgeDecryptArgs(keyFile, inputPath, outputPath) {
|
|
15
|
+
return [
|
|
16
|
+
'--decrypt',
|
|
17
|
+
'--identity',
|
|
18
|
+
keyFile,
|
|
19
|
+
'--output',
|
|
20
|
+
outputPath,
|
|
21
|
+
inputPath,
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
export function buildAgeCommand(args) {
|
|
25
|
+
return [AUTHENTICATED_ENCRYPTION_TOOL, ...args.map(quoteShellArg)].join(' ');
|
|
26
|
+
}
|
|
27
|
+
export async function assertAuthenticatedEncryptionAvailable() {
|
|
28
|
+
if (!await commandExists(AUTHENTICATED_ENCRYPTION_TOOL)) {
|
|
29
|
+
throw new Error('Missing authenticated encryption tool: age');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function quoteShellArg(value) {
|
|
33
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
34
|
+
}
|
|
35
|
+
const AGE_SECRET_KEY_MARKER = /AGE-SECRET-KEY-/;
|
|
36
|
+
const OPENSSH_PRIVATE_KEY_MARKER = /BEGIN OPENSSH PRIVATE KEY/;
|
|
37
|
+
const AGE_RECIPIENT_MARKER = /(^|\n)\s*age1[0-9a-z]/;
|
|
38
|
+
/**
|
|
39
|
+
* export 用 `--recipient-file`,必须是 age 公钥;若误传私钥(identity),age 会在运行期才报错。
|
|
40
|
+
* 提前在 CLI 层显式校验,避免操作人把私钥当公钥用。
|
|
41
|
+
*/
|
|
42
|
+
export function assertAgeRecipientContent(content, keyFile) {
|
|
43
|
+
if (AGE_SECRET_KEY_MARKER.test(content)) {
|
|
44
|
+
throw new Error(`--key-file 应为 age 公钥(recipient)文件,但 ${keyFile} 含 age 私钥;export 加密只需公钥`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* restore 用 `--identity`,必须是 age 私钥;若误传只含公钥的文件,提前报错而不是等 age 运行期失败。
|
|
49
|
+
*/
|
|
50
|
+
export function assertAgeIdentityContent(content, keyFile) {
|
|
51
|
+
const hasIdentity = AGE_SECRET_KEY_MARKER.test(content) || OPENSSH_PRIVATE_KEY_MARKER.test(content);
|
|
52
|
+
if (!hasIdentity && AGE_RECIPIENT_MARKER.test(content)) {
|
|
53
|
+
throw new Error(`--key-file 应为 age 私钥(identity)文件,但 ${keyFile} 仅含 age 公钥;restore 解密需要私钥`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/migration/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;AACnD,MAAM,CAAC,MAAM,iCAAiC,GAAG,gCAAgC,CAAC;AAElF,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,SAAiB,EAAE,UAAkB;IACxF,OAAO;QACL,WAAW;QACX,kBAAkB;QAClB,OAAO;QACP,UAAU;QACV,UAAU;QACV,SAAS;KACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,SAAiB,EAAE,UAAkB;IACxF,OAAO;QACL,WAAW;QACX,YAAY;QACZ,OAAO;QACP,UAAU;QACV,UAAU;QACV,SAAS;KACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAc;IAC5C,OAAO,CAAC,6BAA6B,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sCAAsC;IAC1D,IAAI,CAAC,MAAM,aAAa,CAAC,6BAA6B,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AAC7C,CAAC;AAED,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AAChD,MAAM,0BAA0B,GAAG,2BAA2B,CAAC;AAC/D,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AAErD;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAe,EAAE,OAAe;IACxE,IAAI,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,yBAAyB,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe,EAAE,OAAe;IACvE,MAAM,WAAW,GAAG,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpG,IAAI,CAAC,WAAW,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,sCAAsC,OAAO,2BAA2B,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const MIGRATION_MANIFEST_VERSION = "openclaw-runtime-v1";
|
|
2
|
+
export declare const LEGACY_OPENCLAW_WORKSPACE = "/root/openclaw/workspace";
|
|
3
|
+
export declare const includePaths: string[];
|
|
4
|
+
export declare const excludePatterns: string[];
|
|
5
|
+
export declare const requiredRuntimeFiles: string[];
|
|
6
|
+
export interface MigrationManifestPath {
|
|
7
|
+
path: string;
|
|
8
|
+
status: 'included' | 'missing';
|
|
9
|
+
type?: 'file' | 'directory' | 'symlink' | 'other';
|
|
10
|
+
mode?: number;
|
|
11
|
+
uid?: number;
|
|
12
|
+
gid?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface MigrationManifest {
|
|
15
|
+
version: typeof MIGRATION_MANIFEST_VERSION;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
taskId: string;
|
|
18
|
+
shrimpId: string;
|
|
19
|
+
sourceHostId: string;
|
|
20
|
+
targetHostId: string;
|
|
21
|
+
includePaths: string[];
|
|
22
|
+
excludePatterns: string[];
|
|
23
|
+
requiredRuntimeFiles: string[];
|
|
24
|
+
missingPaths: string[];
|
|
25
|
+
paths: MigrationManifestPath[];
|
|
26
|
+
}
|
|
27
|
+
export interface MigrationIdentity {
|
|
28
|
+
taskId: string;
|
|
29
|
+
shrimpId: string;
|
|
30
|
+
sourceHostId: string;
|
|
31
|
+
targetHostId: string;
|
|
32
|
+
}
|
|
33
|
+
export interface BuildManifestOptions extends MigrationIdentity {
|
|
34
|
+
rootDir?: string;
|
|
35
|
+
createdAt?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function buildMigrationManifest(options: BuildManifestOptions): MigrationManifest;
|
|
38
|
+
export declare function existingManifestPaths(manifest: MigrationManifest): string[];
|
|
39
|
+
export declare function validateMigrationManifest(value: unknown, expected: MigrationIdentity): MigrationManifest;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { existsSync, lstatSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { OKCLAW_BACKUP_DIR, OKCLAW_CONFIG_DIR, OPENCLAW_HOME, OPENCLAW_WORKSPACE, OPENVIKING_HOME, } from '../utils/constants.js';
|
|
4
|
+
export const MIGRATION_MANIFEST_VERSION = 'openclaw-runtime-v1';
|
|
5
|
+
export const LEGACY_OPENCLAW_WORKSPACE = '/root/openclaw/workspace';
|
|
6
|
+
export const includePaths = [
|
|
7
|
+
OPENCLAW_HOME,
|
|
8
|
+
OPENCLAW_WORKSPACE,
|
|
9
|
+
LEGACY_OPENCLAW_WORKSPACE,
|
|
10
|
+
OKCLAW_CONFIG_DIR,
|
|
11
|
+
OKCLAW_BACKUP_DIR,
|
|
12
|
+
OPENVIKING_HOME,
|
|
13
|
+
];
|
|
14
|
+
export const excludePatterns = [
|
|
15
|
+
'**/*.sock',
|
|
16
|
+
'**/*.pid',
|
|
17
|
+
'**/*.lock',
|
|
18
|
+
'**/tmp/**',
|
|
19
|
+
'**/.cache/**',
|
|
20
|
+
'**/node_modules/.cache/**',
|
|
21
|
+
];
|
|
22
|
+
export const requiredRuntimeFiles = [
|
|
23
|
+
`${OPENCLAW_HOME}/openclaw.json`,
|
|
24
|
+
];
|
|
25
|
+
export function buildMigrationManifest(options) {
|
|
26
|
+
const rootDir = options.rootDir ?? '/';
|
|
27
|
+
const missingCritical = requiredRuntimeFiles.filter((path) => !existsSync(toHostPath(rootDir, path)));
|
|
28
|
+
if (missingCritical.length > 0) {
|
|
29
|
+
throw new Error(`Missing critical runtime file: ${missingCritical.join(', ')}`);
|
|
30
|
+
}
|
|
31
|
+
const paths = includePaths.map((path) => {
|
|
32
|
+
const hostPath = toHostPath(rootDir, path);
|
|
33
|
+
if (!existsSync(hostPath)) {
|
|
34
|
+
return { path, status: 'missing' };
|
|
35
|
+
}
|
|
36
|
+
const stat = lstatSync(hostPath);
|
|
37
|
+
return {
|
|
38
|
+
path,
|
|
39
|
+
status: 'included',
|
|
40
|
+
type: stat.isDirectory() ? 'directory' : stat.isFile() ? 'file' : stat.isSymbolicLink() ? 'symlink' : 'other',
|
|
41
|
+
mode: stat.mode,
|
|
42
|
+
uid: stat.uid,
|
|
43
|
+
gid: stat.gid,
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
version: MIGRATION_MANIFEST_VERSION,
|
|
48
|
+
createdAt: options.createdAt ?? new Date().toISOString(),
|
|
49
|
+
taskId: options.taskId,
|
|
50
|
+
shrimpId: options.shrimpId,
|
|
51
|
+
sourceHostId: options.sourceHostId,
|
|
52
|
+
targetHostId: options.targetHostId,
|
|
53
|
+
includePaths: [...includePaths],
|
|
54
|
+
excludePatterns: [...excludePatterns],
|
|
55
|
+
requiredRuntimeFiles: [...requiredRuntimeFiles],
|
|
56
|
+
missingPaths: paths.filter((item) => item.status === 'missing').map((item) => item.path),
|
|
57
|
+
paths,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function existingManifestPaths(manifest) {
|
|
61
|
+
return manifest.paths.filter((item) => item.status === 'included').map((item) => item.path);
|
|
62
|
+
}
|
|
63
|
+
export function validateMigrationManifest(value, expected) {
|
|
64
|
+
if (!isManifest(value)) {
|
|
65
|
+
throw new Error('Invalid migration manifest');
|
|
66
|
+
}
|
|
67
|
+
if (value.version !== MIGRATION_MANIFEST_VERSION) {
|
|
68
|
+
throw new Error(`Unsupported manifest version: ${value.version}`);
|
|
69
|
+
}
|
|
70
|
+
assertEqual('taskId', value.taskId, expected.taskId);
|
|
71
|
+
assertEqual('shrimpId', value.shrimpId, expected.shrimpId);
|
|
72
|
+
assertEqual('sourceHostId', value.sourceHostId, expected.sourceHostId);
|
|
73
|
+
assertEqual('targetHostId', value.targetHostId, expected.targetHostId);
|
|
74
|
+
/*
|
|
75
|
+
* Restore cannot trust the archive's manifest to define its own allowed roots.
|
|
76
|
+
* The tar safety check extracts to /, so a malicious package that declares /etc
|
|
77
|
+
* as an included path would otherwise turn the manifest into an allow-list bypass.
|
|
78
|
+
* Keep the manifest useful for audit, but require every path list to match the
|
|
79
|
+
* hard-coded runtime contract compiled into this CLI version.
|
|
80
|
+
*/
|
|
81
|
+
assertStringArrayEqual('includePaths', value.includePaths, includePaths);
|
|
82
|
+
assertStringArrayEqual('excludePatterns', value.excludePatterns, excludePatterns);
|
|
83
|
+
assertStringArrayEqual('requiredRuntimeFiles', value.requiredRuntimeFiles, requiredRuntimeFiles);
|
|
84
|
+
validateManifestPathSet(value);
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
function assertEqual(field, actual, expected) {
|
|
88
|
+
if (actual !== expected) {
|
|
89
|
+
throw new Error(`Manifest ${field} mismatch: expected ${expected}, got ${actual}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function isManifest(value) {
|
|
93
|
+
if (typeof value !== 'object' || value === null)
|
|
94
|
+
return false;
|
|
95
|
+
const candidate = value;
|
|
96
|
+
return typeof candidate.version === 'string'
|
|
97
|
+
&& typeof candidate.taskId === 'string'
|
|
98
|
+
&& typeof candidate.shrimpId === 'string'
|
|
99
|
+
&& typeof candidate.sourceHostId === 'string'
|
|
100
|
+
&& typeof candidate.targetHostId === 'string'
|
|
101
|
+
&& Array.isArray(candidate.includePaths)
|
|
102
|
+
&& Array.isArray(candidate.excludePatterns)
|
|
103
|
+
&& Array.isArray(candidate.requiredRuntimeFiles)
|
|
104
|
+
&& Array.isArray(candidate.missingPaths)
|
|
105
|
+
&& Array.isArray(candidate.paths);
|
|
106
|
+
}
|
|
107
|
+
function assertStringArrayEqual(field, actual, expected) {
|
|
108
|
+
if (!Array.isArray(actual) || actual.length !== expected.length
|
|
109
|
+
|| actual.some((item, index) => item !== expected[index])) {
|
|
110
|
+
throw new Error(`Manifest ${field} does not match CLI runtime contract`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function validateManifestPathSet(manifest) {
|
|
114
|
+
const allowed = new Set(includePaths);
|
|
115
|
+
const seen = new Set();
|
|
116
|
+
const missing = new Set();
|
|
117
|
+
for (const item of manifest.paths) {
|
|
118
|
+
if (!item || typeof item.path !== 'string' || !allowed.has(item.path)) {
|
|
119
|
+
throw new Error(`Manifest path outside CLI runtime contract: ${item?.path ?? '<invalid>'}`);
|
|
120
|
+
}
|
|
121
|
+
if (seen.has(item.path)) {
|
|
122
|
+
throw new Error(`Manifest path duplicated: ${item.path}`);
|
|
123
|
+
}
|
|
124
|
+
seen.add(item.path);
|
|
125
|
+
if (item.status !== 'included' && item.status !== 'missing') {
|
|
126
|
+
throw new Error(`Manifest path has invalid status: ${item.path}`);
|
|
127
|
+
}
|
|
128
|
+
if (item.status === 'missing') {
|
|
129
|
+
missing.add(item.path);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (manifest.missingPaths.length !== missing.size
|
|
133
|
+
|| manifest.missingPaths.some((path) => !missing.has(path))) {
|
|
134
|
+
throw new Error('Manifest missingPaths does not match path statuses');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function toHostPath(rootDir, absolutePath) {
|
|
138
|
+
return join(rootDir, absolutePath.replace(/^\/+/, ''));
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/migration/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export declare const OPENCLAW_USER_DATA_FILES: readonly ["MEMORY.md", "USER.md", "IDENTITY.md", "SOUL.md", "TOOLS.md", "AGENTS.md", "HEARTBEAT.md"];
|
|
2
|
+
export declare const LEGACY_OPENCLAW_WORKSPACE = "/root/openclaw/workspace";
|
|
3
|
+
export type BackupFs = {
|
|
4
|
+
existsSync(path: string): boolean;
|
|
5
|
+
mkdirSync(path: string, options?: {
|
|
6
|
+
recursive?: boolean;
|
|
7
|
+
}): unknown;
|
|
8
|
+
cpSync(src: string, dest: string, options?: {
|
|
9
|
+
recursive?: boolean;
|
|
10
|
+
}): unknown;
|
|
11
|
+
statSync(path: string): {
|
|
12
|
+
isDirectory(): boolean;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export type ArchiveFs = BackupFs & {
|
|
16
|
+
readdirSync(path: string, options?: {
|
|
17
|
+
withFileTypes?: boolean;
|
|
18
|
+
}): Array<DirentLike>;
|
|
19
|
+
};
|
|
20
|
+
export type RestoreFs = BackupFs & {
|
|
21
|
+
rmSync(path: string, options?: {
|
|
22
|
+
recursive?: boolean;
|
|
23
|
+
force?: boolean;
|
|
24
|
+
}): unknown;
|
|
25
|
+
chmodSync(path: string, mode: number): unknown;
|
|
26
|
+
readdirSync(path: string, options?: {
|
|
27
|
+
withFileTypes?: boolean;
|
|
28
|
+
}): Array<DirentLike>;
|
|
29
|
+
};
|
|
30
|
+
type DirentLike = {
|
|
31
|
+
name: string;
|
|
32
|
+
isDirectory(): boolean;
|
|
33
|
+
isFile(): boolean;
|
|
34
|
+
};
|
|
35
|
+
export type ArchiveResult = {
|
|
36
|
+
backupDir: string | null;
|
|
37
|
+
archivePath: string | null;
|
|
38
|
+
includedFiles: string[];
|
|
39
|
+
};
|
|
40
|
+
export type RestoreResult = {
|
|
41
|
+
stagingDir: string;
|
|
42
|
+
archivePath: string;
|
|
43
|
+
restoredFiles: string[];
|
|
44
|
+
};
|
|
45
|
+
type ShellOps = {
|
|
46
|
+
shell(command: string): Promise<void>;
|
|
47
|
+
capture?(command: string): Promise<string>;
|
|
48
|
+
};
|
|
49
|
+
export declare function formatBackupTimestamp(now: Date): string;
|
|
50
|
+
export declare function backupOpenclawUserData(now?: Date, fsOps?: BackupFs): string | null;
|
|
51
|
+
export declare function createOpenclawUserDataArchive(options?: {
|
|
52
|
+
archivePath?: string;
|
|
53
|
+
now?: Date;
|
|
54
|
+
fsOps?: ArchiveFs;
|
|
55
|
+
shellOps?: ShellOps;
|
|
56
|
+
}): Promise<ArchiveResult>;
|
|
57
|
+
export declare function restoreOpenclawUserDataArchive(options: {
|
|
58
|
+
archivePath: string;
|
|
59
|
+
now?: Date;
|
|
60
|
+
fsOps?: RestoreFs;
|
|
61
|
+
shellOps?: ShellOps;
|
|
62
|
+
}): Promise<RestoreResult>;
|
|
63
|
+
export {};
|