@okclaw-build/cli 1.0.0-beta.6 → 1.0.0-beta.61

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.
Files changed (130) hide show
  1. package/dist/bridge/daemon/channel-auth-runtime.d.ts +16 -0
  2. package/dist/bridge/daemon/channel-auth-runtime.js +2 -0
  3. package/dist/bridge/daemon/channel-auth-runtime.js.map +1 -0
  4. package/dist/bridge/daemon/config.d.ts +24 -0
  5. package/dist/bridge/daemon/config.js +96 -0
  6. package/dist/bridge/daemon/config.js.map +1 -0
  7. package/dist/bridge/daemon/daemon.d.ts +7 -0
  8. package/dist/bridge/daemon/daemon.js +32 -0
  9. package/dist/bridge/daemon/daemon.js.map +1 -0
  10. package/dist/bridge/daemon/event-id.d.ts +2 -0
  11. package/dist/bridge/daemon/event-id.js +18 -0
  12. package/dist/bridge/daemon/event-id.js.map +1 -0
  13. package/dist/bridge/daemon/frames.d.ts +81 -0
  14. package/dist/bridge/daemon/frames.js +64 -0
  15. package/dist/bridge/daemon/frames.js.map +1 -0
  16. package/dist/bridge/daemon/openclaw-chat-runtime.d.ts +80 -0
  17. package/dist/bridge/daemon/openclaw-chat-runtime.js +1222 -0
  18. package/dist/bridge/daemon/openclaw-chat-runtime.js.map +1 -0
  19. package/dist/bridge/daemon/openclaw-gateway-client.d.ts +58 -0
  20. package/dist/bridge/daemon/openclaw-gateway-client.js +251 -0
  21. package/dist/bridge/daemon/openclaw-gateway-client.js.map +1 -0
  22. package/dist/bridge/daemon/openclaw-weixin-auth-runtime.d.ts +28 -0
  23. package/dist/bridge/daemon/openclaw-weixin-auth-runtime.js +266 -0
  24. package/dist/bridge/daemon/openclaw-weixin-auth-runtime.js.map +1 -0
  25. package/dist/bridge/daemon/openclaw-weixin-plugin.d.ts +67 -0
  26. package/dist/bridge/daemon/openclaw-weixin-plugin.js +196 -0
  27. package/dist/bridge/daemon/openclaw-weixin-plugin.js.map +1 -0
  28. package/dist/bridge/daemon/relay-client.d.ts +79 -0
  29. package/dist/bridge/daemon/relay-client.js +396 -0
  30. package/dist/bridge/daemon/relay-client.js.map +1 -0
  31. package/dist/bridge/daemon/stub-chat-runtime.d.ts +4 -0
  32. package/dist/bridge/daemon/stub-chat-runtime.js +91 -0
  33. package/dist/bridge/daemon/stub-chat-runtime.js.map +1 -0
  34. package/dist/bridge/service.d.ts +12 -0
  35. package/dist/bridge/service.js +86 -0
  36. package/dist/bridge/service.js.map +1 -0
  37. package/dist/commands/backup.d.ts +16 -0
  38. package/dist/commands/backup.js +99 -0
  39. package/dist/commands/backup.js.map +1 -0
  40. package/dist/commands/bridge.d.ts +7 -0
  41. package/dist/commands/bridge.js +100 -0
  42. package/dist/commands/bridge.js.map +1 -0
  43. package/dist/commands/check.js +22 -6
  44. package/dist/commands/check.js.map +1 -1
  45. package/dist/commands/edit.d.ts +2 -7
  46. package/dist/commands/edit.js +28 -16
  47. package/dist/commands/edit.js.map +1 -1
  48. package/dist/commands/feed.js +48 -16
  49. package/dist/commands/feed.js.map +1 -1
  50. package/dist/commands/install.js +99 -18
  51. package/dist/commands/install.js.map +1 -1
  52. package/dist/commands/migration.d.ts +1 -0
  53. package/dist/commands/migration.js +205 -0
  54. package/dist/commands/migration.js.map +1 -0
  55. package/dist/commands/openclaw-channel-login.d.ts +54 -0
  56. package/dist/commands/openclaw-channel-login.js +334 -0
  57. package/dist/commands/openclaw-channel-login.js.map +1 -0
  58. package/dist/commands/restore.d.ts +16 -0
  59. package/dist/commands/restore.js +94 -0
  60. package/dist/commands/restore.js.map +1 -0
  61. package/dist/commands/service.js +56 -13
  62. package/dist/commands/service.js.map +1 -1
  63. package/dist/commands/show.d.ts +13 -0
  64. package/dist/commands/show.js +70 -0
  65. package/dist/commands/show.js.map +1 -0
  66. package/dist/commands/skill.d.ts +1 -0
  67. package/dist/commands/skill.js +137 -0
  68. package/dist/commands/skill.js.map +1 -0
  69. package/dist/commands/uninstall.d.ts +1 -0
  70. package/dist/commands/uninstall.js +46 -0
  71. package/dist/commands/uninstall.js.map +1 -0
  72. package/dist/index.js +116 -12
  73. package/dist/index.js.map +1 -1
  74. package/dist/installers/base.d.ts +3 -1
  75. package/dist/installers/channel.d.ts +10 -2
  76. package/dist/installers/channel.js +143 -24
  77. package/dist/installers/channel.js.map +1 -1
  78. package/dist/installers/openclaw.d.ts +20 -2
  79. package/dist/installers/openclaw.js +201 -55
  80. package/dist/installers/openclaw.js.map +1 -1
  81. package/dist/installers/openviking-purge.d.ts +52 -0
  82. package/dist/installers/openviking-purge.js +380 -0
  83. package/dist/installers/openviking-purge.js.map +1 -0
  84. package/dist/installers/openviking.js +1 -2
  85. package/dist/installers/openviking.js.map +1 -1
  86. package/dist/installers/skill.d.ts +5 -2
  87. package/dist/installers/skill.js +67 -18
  88. package/dist/installers/skill.js.map +1 -1
  89. package/dist/migration/archive.d.ts +14 -0
  90. package/dist/migration/archive.js +84 -0
  91. package/dist/migration/archive.js.map +1 -0
  92. package/dist/migration/crypto.d.ts +16 -0
  93. package/dist/migration/crypto.js +56 -0
  94. package/dist/migration/crypto.js.map +1 -0
  95. package/dist/migration/manifest.d.ts +39 -0
  96. package/dist/migration/manifest.js +140 -0
  97. package/dist/migration/manifest.js.map +1 -0
  98. package/dist/openclaw-user-data.d.ts +86 -0
  99. package/dist/openclaw-user-data.js +422 -0
  100. package/dist/openclaw-user-data.js.map +1 -0
  101. package/dist/output/mode.d.ts +11 -0
  102. package/dist/output/mode.js +27 -0
  103. package/dist/output/mode.js.map +1 -0
  104. package/dist/output/ndjson.d.ts +57 -0
  105. package/dist/output/ndjson.js +136 -0
  106. package/dist/output/ndjson.js.map +1 -0
  107. package/dist/utils/constants.d.ts +14 -13
  108. package/dist/utils/constants.js +40 -21
  109. package/dist/utils/constants.js.map +1 -1
  110. package/dist/utils/deps.d.ts +34 -3
  111. package/dist/utils/deps.js +62 -100
  112. package/dist/utils/deps.js.map +1 -1
  113. package/dist/utils/install-safety.d.ts +25 -0
  114. package/dist/utils/install-safety.js +97 -0
  115. package/dist/utils/install-safety.js.map +1 -0
  116. package/dist/utils/logger.d.ts +10 -0
  117. package/dist/utils/logger.js +31 -4
  118. package/dist/utils/logger.js.map +1 -1
  119. package/dist/utils/mirror.js +14 -0
  120. package/dist/utils/mirror.js.map +1 -1
  121. package/dist/utils/openclaw-config-cli.d.ts +19 -0
  122. package/dist/utils/openclaw-config-cli.js +81 -0
  123. package/dist/utils/openclaw-config-cli.js.map +1 -0
  124. package/dist/utils/openclaw-daemon.d.ts +58 -0
  125. package/dist/utils/openclaw-daemon.js +154 -0
  126. package/dist/utils/openclaw-daemon.js.map +1 -0
  127. package/dist/utils/shell.d.ts +23 -2
  128. package/dist/utils/shell.js +138 -5
  129. package/dist/utils/shell.js.map +1 -1
  130. package/package.json +6 -4
@@ -0,0 +1,422 @@
1
+ import { existsSync, cpSync, mkdirSync, rmSync, statSync, lstatSync, chmodSync, readdirSync, readlinkSync, } from 'node:fs';
2
+ import { posix as pathPosix } from 'node:path';
3
+ import { shell, shellCapture } from './utils/shell.js';
4
+ import { warn } from './utils/logger.js';
5
+ import { OKCLAW_BACKUP_DIR, OPENCLAW_WORKSPACE } from './utils/constants.js';
6
+ export const OPENCLAW_USER_DATA_FILES = [
7
+ 'MEMORY.md',
8
+ 'USER.md',
9
+ 'IDENTITY.md',
10
+ 'SOUL.md',
11
+ 'TOOLS.md',
12
+ 'AGENTS.md',
13
+ 'HEARTBEAT.md',
14
+ ];
15
+ export const OPENCLAW_CLONE_USER_DATA_FILES = [
16
+ 'IDENTITY.md',
17
+ 'SOUL.md',
18
+ 'TOOLS.md',
19
+ 'AGENTS.md',
20
+ ];
21
+ export const LEGACY_OPENCLAW_WORKSPACE = '/root/openclaw/workspace';
22
+ const WORKSPACE_BACKUP_DIR = 'workspace';
23
+ const LEGACY_WORKSPACE_BACKUP_DIR = 'workspace-root-openclaw';
24
+ const SKILLS_DIR = 'skills';
25
+ const realBackupFs = {
26
+ existsSync,
27
+ mkdirSync,
28
+ cpSync,
29
+ statSync,
30
+ readdirSync: readdirSync,
31
+ readlinkSync,
32
+ };
33
+ const realArchiveFs = { ...realBackupFs, readdirSync: readdirSync };
34
+ const realRestoreFs = {
35
+ ...realBackupFs,
36
+ rmSync,
37
+ chmodSync,
38
+ lstatSync,
39
+ readdirSync: readdirSync,
40
+ };
41
+ export function formatBackupTimestamp(now) {
42
+ return now.toISOString().replace(/\.\d{3}Z$/, 'Z').replace(/:/g, '');
43
+ }
44
+ function copyIfExists(fsOps, src, dest, recursive = false) {
45
+ if (!fsOps.existsSync(src))
46
+ return false;
47
+ fsOps.cpSync(src, dest, recursive ? { recursive: true } : undefined);
48
+ return true;
49
+ }
50
+ export function backupOpenclawUserData(now = new Date(), fsOps = realBackupFs, options = {}) {
51
+ const files = getUserDataFilesForScope(options.scope);
52
+ const backupDir = `${OKCLAW_BACKUP_DIR}/openclaw-user-data-${formatBackupTimestamp(now)}`;
53
+ const workspaces = Array.from(new Set([OPENCLAW_WORKSPACE, LEGACY_OPENCLAW_WORKSPACE]));
54
+ let copiedItems = 0;
55
+ let copiedWorkspaces = 0;
56
+ for (const workspace of workspaces) {
57
+ if (!fsOps.existsSync(workspace))
58
+ continue;
59
+ const workspaceBackupName = options.includeWorkspaceExtra
60
+ ? (workspace === OPENCLAW_WORKSPACE ? WORKSPACE_BACKUP_DIR : LEGACY_WORKSPACE_BACKUP_DIR)
61
+ : (copiedWorkspaces === 0 ? WORKSPACE_BACKUP_DIR : LEGACY_WORKSPACE_BACKUP_DIR);
62
+ const workspaceBackupDir = `${backupDir}/${workspaceBackupName}`;
63
+ let workspaceDirCreated = false;
64
+ const copiedRootEntries = new Set();
65
+ const ensureWorkspaceBackupDir = () => {
66
+ if (workspaceDirCreated)
67
+ return;
68
+ fsOps.mkdirSync(workspaceBackupDir, { recursive: true });
69
+ workspaceDirCreated = true;
70
+ };
71
+ for (const file of files) {
72
+ const src = `${workspace}/${file}`;
73
+ if (!fsOps.existsSync(src))
74
+ continue;
75
+ ensureWorkspaceBackupDir();
76
+ if (copyIfExists(fsOps, src, `${workspaceBackupDir}/${file}`)) {
77
+ copiedItems += 1;
78
+ copiedRootEntries.add(file);
79
+ }
80
+ }
81
+ const skillsDir = `${workspace}/${SKILLS_DIR}`;
82
+ if (fsOps.existsSync(skillsDir) && fsOps.statSync(skillsDir).isDirectory()) {
83
+ ensureWorkspaceBackupDir();
84
+ if (copyIfExists(fsOps, skillsDir, `${workspaceBackupDir}/${SKILLS_DIR}`, true)) {
85
+ copiedItems += 1;
86
+ copiedRootEntries.add(SKILLS_DIR);
87
+ }
88
+ }
89
+ if (options.scope !== 'clone' && options.includeWorkspaceExtra) {
90
+ copiedItems += copyWorkspaceExtraEntries(fsOps, workspace, workspaceBackupDir, copiedRootEntries, ensureWorkspaceBackupDir, options.onSkip ?? defaultBackupSkip);
91
+ }
92
+ if (workspaceDirCreated) {
93
+ copiedWorkspaces += 1;
94
+ }
95
+ }
96
+ return copiedItems > 0 ? backupDir : null;
97
+ }
98
+ function getUserDataFilesForScope(scope = 'user-data') {
99
+ return scope === 'clone' ? OPENCLAW_CLONE_USER_DATA_FILES : OPENCLAW_USER_DATA_FILES;
100
+ }
101
+ function defaultBackupSkip(relativePath, reason) {
102
+ warn(`全量迁移跳过不可移植条目 ${relativePath}: ${reason}`);
103
+ }
104
+ // 全量模式只把"可移植"条目纳入归档,让归档天生可在目标主机还原:
105
+ // 普通文件、目录、以及目标仍落在 workspace 内的软链都保留;指向 workspace 之外的软链
106
+ // 和 socket/fifo 等特殊文件在 backup 阶段就跳过并告警,而不是搬进去等 restore 整包失败。
107
+ function copyWorkspaceExtraEntries(fsOps, workspace, workspaceBackupDir, copiedRootEntries, ensureWorkspaceBackupDir, onSkip) {
108
+ if (!fsOps.readdirSync) {
109
+ throw new Error('backup fs does not support readdirSync for full workspace backup');
110
+ }
111
+ let copied = 0;
112
+ for (const entry of fsOps.readdirSync(workspace, { withFileTypes: true })) {
113
+ if (copiedRootEntries.has(entry.name))
114
+ continue;
115
+ const src = `${workspace}/${entry.name}`;
116
+ const dest = `${workspaceBackupDir}/${entry.name}`;
117
+ const rel = entry.name;
118
+ if (entry.isSymbolicLink?.()) {
119
+ if (!isPortableSymlink(fsOps, src, rel, onSkip))
120
+ continue;
121
+ ensureWorkspaceBackupDir();
122
+ fsOps.cpSync(src, dest);
123
+ copied += 1;
124
+ copiedRootEntries.add(entry.name);
125
+ continue;
126
+ }
127
+ if (entry.isDirectory()) {
128
+ ensureWorkspaceBackupDir();
129
+ copyPortableTree(fsOps, src, dest, rel, onSkip);
130
+ copied += 1;
131
+ copiedRootEntries.add(entry.name);
132
+ continue;
133
+ }
134
+ if (entry.isFile()) {
135
+ ensureWorkspaceBackupDir();
136
+ fsOps.cpSync(src, dest);
137
+ copied += 1;
138
+ copiedRootEntries.add(entry.name);
139
+ continue;
140
+ }
141
+ onSkip(rel, '不支持的文件类型');
142
+ }
143
+ return copied;
144
+ }
145
+ // 递归拷贝目录,逐项套用与 restore 校验一致的"可移植"判定,使嵌套软链/特殊文件也被过滤。
146
+ function copyPortableTree(fsOps, srcDir, destDir, relDir, onSkip) {
147
+ if (!fsOps.readdirSync) {
148
+ throw new Error('backup fs does not support readdirSync for full workspace backup');
149
+ }
150
+ fsOps.mkdirSync(destDir, { recursive: true });
151
+ for (const entry of fsOps.readdirSync(srcDir, { withFileTypes: true })) {
152
+ const src = `${srcDir}/${entry.name}`;
153
+ const dest = `${destDir}/${entry.name}`;
154
+ const rel = relDir ? `${relDir}/${entry.name}` : entry.name;
155
+ if (entry.isSymbolicLink?.()) {
156
+ if (isPortableSymlink(fsOps, src, rel, onSkip)) {
157
+ fsOps.cpSync(src, dest);
158
+ }
159
+ continue;
160
+ }
161
+ if (entry.isDirectory()) {
162
+ copyPortableTree(fsOps, src, dest, rel, onSkip);
163
+ continue;
164
+ }
165
+ if (entry.isFile()) {
166
+ fsOps.cpSync(src, dest);
167
+ continue;
168
+ }
169
+ onSkip(rel, '不支持的文件类型');
170
+ }
171
+ }
172
+ function isPortableSymlink(fsOps, src, rel, onSkip) {
173
+ if (!fsOps.readlinkSync) {
174
+ throw new Error('backup fs does not support readlinkSync for full workspace backup');
175
+ }
176
+ const target = fsOps.readlinkSync(src);
177
+ if (symlinkTargetWithinWorkspace(rel, target))
178
+ return true;
179
+ onSkip(rel, `软链目标逃逸 workspace: ${target}`);
180
+ return false;
181
+ }
182
+ export async function createOpenclawUserDataArchive(options = {}) {
183
+ const now = options.now ?? new Date();
184
+ const fsOps = options.fsOps ?? realArchiveFs;
185
+ const shellOps = options.shellOps ?? { shell };
186
+ const backupDir = backupOpenclawUserData(now, fsOps, {
187
+ scope: options.scope,
188
+ includeWorkspaceExtra: options.includeWorkspaceExtra,
189
+ onSkip: options.onSkip,
190
+ });
191
+ if (!backupDir) {
192
+ return { backupDir: null, archivePath: null, includedFiles: [] };
193
+ }
194
+ const includedFiles = listRelativeFiles(fsOps, backupDir);
195
+ validateArchiveEntries(includedFiles);
196
+ const archivePath = options.archivePath ?? `/tmp/openclaw-user-data-${formatBackupTimestamp(now)}.tar.gz`;
197
+ try {
198
+ await shellOps.shell(`tar -czf ${shellSingleQuote(archivePath)} -C ${shellSingleQuote(backupDir)} .`);
199
+ }
200
+ catch (error) {
201
+ attachContext(error, { backupDir, archivePath });
202
+ throw error;
203
+ }
204
+ return { backupDir, archivePath, includedFiles };
205
+ }
206
+ export async function restoreOpenclawUserDataArchive(options) {
207
+ const now = options.now ?? new Date();
208
+ const fsOps = options.fsOps ?? realRestoreFs;
209
+ const shellOps = options.shellOps ?? { shell };
210
+ const stagingDir = `/tmp/openclaw-user-data-restore-${formatBackupTimestamp(now)}`;
211
+ try {
212
+ fsOps.rmSync(stagingDir, { recursive: true, force: true });
213
+ fsOps.mkdirSync(stagingDir, { recursive: true });
214
+ const tarEntries = await listArchiveEntries(shellOps, options.archivePath);
215
+ validateArchiveEntries(tarEntries.map((entry) => entry.path));
216
+ validateArchiveEntryTypes(tarEntries);
217
+ await shellOps.shell(`tar -xzf ${shellSingleQuote(options.archivePath)} -C ${shellSingleQuote(stagingDir)}`);
218
+ const entries = listRelativeFiles(fsOps, stagingDir);
219
+ validateArchiveEntries(entries);
220
+ fsOps.mkdirSync(OPENCLAW_WORKSPACE, { recursive: true });
221
+ fsOps.chmodSync(OPENCLAW_WORKSPACE, 0o755);
222
+ const restored = new Map();
223
+ restoreWorkspaceBackup(fsOps, `${stagingDir}/${WORKSPACE_BACKUP_DIR}`, restored, options.scope);
224
+ restoreWorkspaceBackup(fsOps, `${stagingDir}/${LEGACY_WORKSPACE_BACKUP_DIR}`, restored, options.scope);
225
+ if (options.scope !== 'clone' && options.includeWorkspaceExtra) {
226
+ restoreWorkspaceExtraEntries(fsOps, `${stagingDir}/${WORKSPACE_BACKUP_DIR}`, restored);
227
+ restoreWorkspaceExtraEntries(fsOps, `${stagingDir}/${LEGACY_WORKSPACE_BACKUP_DIR}`, restored);
228
+ }
229
+ const restoredFiles = Array.from(restored.keys()).sort();
230
+ for (const file of restoredFiles) {
231
+ const path = `${OPENCLAW_WORKSPACE}/${file}`;
232
+ const type = restored.get(file);
233
+ if (type === 'directory') {
234
+ applyRestoredPermissions(fsOps, path);
235
+ }
236
+ else if (type === 'file') {
237
+ fsOps.chmodSync(path, 0o644);
238
+ }
239
+ }
240
+ await shellOps.shell(`chown -R root:root ${shellSingleQuote(OPENCLAW_WORKSPACE)}`);
241
+ return { stagingDir, archivePath: options.archivePath, restoredFiles };
242
+ }
243
+ catch (error) {
244
+ attachContext(error, { stagingDir, archivePath: options.archivePath });
245
+ throw error;
246
+ }
247
+ }
248
+ async function listArchiveEntries(shellOps, archivePath) {
249
+ if (shellOps.capture) {
250
+ const stdout = await shellOps.capture(`tar -tvzf ${shellSingleQuote(archivePath)}`);
251
+ return parseTarVerboseEntries(stdout);
252
+ }
253
+ const result = await shellCapture(`tar -tvzf ${shellSingleQuote(archivePath)}`);
254
+ if (result.code !== 0) {
255
+ throw new Error(`Command failed (exit ${result.code}): tar -tvzf ${archivePath}`);
256
+ }
257
+ return parseTarVerboseEntries(result.stdout);
258
+ }
259
+ function parseTarVerboseEntries(stdout) {
260
+ return stdout.split(/\r?\n/)
261
+ .map((line) => line.trim())
262
+ .filter(Boolean)
263
+ .map((line) => {
264
+ const modeType = line[0];
265
+ const tokens = line.split(/\s+/);
266
+ const rawPath = tokens.slice(5).join(' ');
267
+ const type = modeType === '-' ? 'file'
268
+ : modeType === 'd' ? 'directory'
269
+ : modeType === 'l' ? 'symlink'
270
+ : 'unsupported';
271
+ const linkIndex = type === 'symlink' ? rawPath.indexOf(' -> ') : -1;
272
+ const path = linkIndex >= 0 ? rawPath.slice(0, linkIndex) : rawPath;
273
+ const linkTarget = linkIndex >= 0 ? rawPath.slice(linkIndex + ' -> '.length) : undefined;
274
+ return { type, path, linkTarget, raw: line };
275
+ });
276
+ }
277
+ function validateArchiveEntryTypes(entries) {
278
+ for (const entry of entries) {
279
+ if (entry.type === 'unsupported') {
280
+ throw new Error(`unsupported archive entry type: ${entry.raw}`);
281
+ }
282
+ // 备份会把 skills 目录整包打进归档,其中的 node_modules/.bin/* 是符号链接。
283
+ // 放行指向 workspace 内部的软链(迁移需要它们原样还原),仍拒绝逃逸到 workspace 之外的软链。
284
+ if (entry.type === 'symlink') {
285
+ assertSymlinkWithinWorkspace(entry);
286
+ }
287
+ }
288
+ }
289
+ function assertSymlinkWithinWorkspace(entry) {
290
+ const relative = workspaceRelativePath(entry.path);
291
+ const target = entry.linkTarget ?? '';
292
+ if (relative === null || !target) {
293
+ throw new Error(`unsafe archive symlink: ${entry.raw}`);
294
+ }
295
+ if (!symlinkTargetWithinWorkspace(relative, target)) {
296
+ throw new Error(`unsafe archive symlink target: ${entry.raw}`);
297
+ }
298
+ }
299
+ // backup 过滤与 restore 校验共用的判定:软链在还原到 OPENCLAW_WORKSPACE 后,
300
+ // 其目标是否仍落在 workspace 内。relativePath 是软链相对 workspace 根的路径。
301
+ function symlinkTargetWithinWorkspace(relativePath, target) {
302
+ if (!target)
303
+ return false;
304
+ const linkDir = pathPosix.dirname(`${OPENCLAW_WORKSPACE}/${relativePath}`);
305
+ const resolvedTarget = target.startsWith('/')
306
+ ? pathPosix.normalize(target)
307
+ : pathPosix.normalize(pathPosix.join(linkDir, target));
308
+ return resolvedTarget === OPENCLAW_WORKSPACE || resolvedTarget.startsWith(`${OPENCLAW_WORKSPACE}/`);
309
+ }
310
+ function workspaceRelativePath(entryPath) {
311
+ const normalized = normalizeArchiveEntry(entryPath);
312
+ for (const prefix of [WORKSPACE_BACKUP_DIR, LEGACY_WORKSPACE_BACKUP_DIR]) {
313
+ if (normalized === prefix)
314
+ return '';
315
+ if (normalized.startsWith(`${prefix}/`))
316
+ return normalized.slice(prefix.length + 1);
317
+ }
318
+ return null;
319
+ }
320
+ function restoreWorkspaceBackup(fsOps, backupWorkspaceDir, restored, scope = 'user-data') {
321
+ if (!fsOps.existsSync(backupWorkspaceDir))
322
+ return;
323
+ for (const file of getUserDataFilesForScope(scope)) {
324
+ if (restored.has(file))
325
+ continue;
326
+ const src = `${backupWorkspaceDir}/${file}`;
327
+ if (!fsOps.existsSync(src))
328
+ continue;
329
+ fsOps.cpSync(src, `${OPENCLAW_WORKSPACE}/${file}`);
330
+ restored.set(file, 'file');
331
+ }
332
+ const skillsSrc = `${backupWorkspaceDir}/${SKILLS_DIR}`;
333
+ if (!restored.has(SKILLS_DIR) && fsOps.existsSync(skillsSrc) && fsOps.statSync(skillsSrc).isDirectory()) {
334
+ fsOps.rmSync(`${OPENCLAW_WORKSPACE}/${SKILLS_DIR}`, { recursive: true, force: true });
335
+ fsOps.cpSync(skillsSrc, `${OPENCLAW_WORKSPACE}/${SKILLS_DIR}`, { recursive: true });
336
+ restored.set(SKILLS_DIR, 'directory');
337
+ }
338
+ }
339
+ function restoreWorkspaceExtraEntries(fsOps, backupWorkspaceDir, restored) {
340
+ if (!fsOps.existsSync(backupWorkspaceDir))
341
+ return;
342
+ for (const entry of fsOps.readdirSync(backupWorkspaceDir, { withFileTypes: true })) {
343
+ if (restored.has(entry.name))
344
+ continue;
345
+ const src = `${backupWorkspaceDir}/${entry.name}`;
346
+ const dest = `${OPENCLAW_WORKSPACE}/${entry.name}`;
347
+ fsOps.rmSync(dest, { recursive: true, force: true });
348
+ if (entry.isDirectory()) {
349
+ fsOps.cpSync(src, dest, { recursive: true });
350
+ restored.set(entry.name, 'directory');
351
+ continue;
352
+ }
353
+ fsOps.cpSync(src, dest);
354
+ restored.set(entry.name, entry.isSymbolicLink?.() ? 'symlink' : 'file');
355
+ }
356
+ }
357
+ function applyRestoredPermissions(fsOps, path) {
358
+ if (!fsOps.existsSync(path))
359
+ return;
360
+ // 不跟随符号链接:软链自身权限在 Linux 上无意义,跟随会 chmod 到 target,
361
+ // 且指向祖先目录的 workspace 内软链(如 skills/loop -> skills)会让 statSync+readdir 递归死循环。
362
+ if (fsOps.lstatSync(path).isSymbolicLink())
363
+ return;
364
+ if (fsOps.statSync(path).isDirectory()) {
365
+ fsOps.chmodSync(path, 0o755);
366
+ for (const entry of fsOps.readdirSync(path, { withFileTypes: true })) {
367
+ applyRestoredPermissions(fsOps, `${path}/${entry.name}`);
368
+ }
369
+ return;
370
+ }
371
+ fsOps.chmodSync(path, 0o644);
372
+ }
373
+ function listRelativeFiles(fsOps, root) {
374
+ if (!fsOps.existsSync(root))
375
+ return [];
376
+ const files = [];
377
+ const visit = (dir, prefix) => {
378
+ for (const entry of fsOps.readdirSync(dir, { withFileTypes: true })) {
379
+ const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
380
+ const path = `${dir}/${entry.name}`;
381
+ if (entry.isDirectory()) {
382
+ visit(path, relative);
383
+ }
384
+ else if (entry.isFile()) {
385
+ files.push(relative);
386
+ }
387
+ }
388
+ };
389
+ visit(root, '');
390
+ return files.sort();
391
+ }
392
+ function validateArchiveEntries(entries) {
393
+ for (const entry of entries) {
394
+ const normalized = normalizeArchiveEntry(entry);
395
+ if (!normalized)
396
+ continue;
397
+ const parts = normalized.split('/');
398
+ if (entry.startsWith('/') ||
399
+ parts.includes('..')) {
400
+ throw new Error(`unsafe archive entry: ${entry}`);
401
+ }
402
+ }
403
+ }
404
+ function normalizeArchiveEntry(entry) {
405
+ let normalized = entry.trim();
406
+ while (normalized.startsWith('./')) {
407
+ normalized = normalized.slice(2);
408
+ }
409
+ while (normalized.endsWith('/')) {
410
+ normalized = normalized.slice(0, -1);
411
+ }
412
+ return normalized === '.' ? '' : normalized;
413
+ }
414
+ function shellSingleQuote(value) {
415
+ return `'${value.replace(/'/g, `'\\''`)}'`;
416
+ }
417
+ function attachContext(error, context) {
418
+ if (error && typeof error === 'object') {
419
+ Object.assign(error, context);
420
+ }
421
+ }
422
+ //# sourceMappingURL=openclaw-user-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-user-data.js","sourceRoot":"","sources":["../src/openclaw-user-data.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * CLI 输出模式全局状态。index.ts 解析 --output / --op-id 后注入;
3
+ * ndjson.ts 与 logger.ts 读取以决定行为。
4
+ */
5
+ export type OutputMode = 'text' | 'ndjson';
6
+ export declare function setOutputMode(mode: OutputMode, opId?: string): void;
7
+ export declare function setNdjsonPath(path: string | undefined): void;
8
+ export declare function getOutputMode(): OutputMode;
9
+ export declare function getOpId(): string | undefined;
10
+ export declare function getNdjsonPath(): string | undefined;
11
+ export declare function isNdjson(): boolean;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * CLI 输出模式全局状态。index.ts 解析 --output / --op-id 后注入;
3
+ * ndjson.ts 与 logger.ts 读取以决定行为。
4
+ */
5
+ let currentMode = 'text';
6
+ let currentOpId;
7
+ let currentNdjsonPath;
8
+ export function setOutputMode(mode, opId) {
9
+ currentMode = mode;
10
+ currentOpId = opId;
11
+ }
12
+ export function setNdjsonPath(path) {
13
+ currentNdjsonPath = path;
14
+ }
15
+ export function getOutputMode() {
16
+ return currentMode;
17
+ }
18
+ export function getOpId() {
19
+ return currentOpId;
20
+ }
21
+ export function getNdjsonPath() {
22
+ return currentNdjsonPath;
23
+ }
24
+ export function isNdjson() {
25
+ return currentMode === 'ndjson';
26
+ }
27
+ //# sourceMappingURL=mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode.js","sourceRoot":"","sources":["../../src/output/mode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,IAAI,WAAW,GAAe,MAAM,CAAC;AACrC,IAAI,WAA+B,CAAC;AACpC,IAAI,iBAAqC,CAAC;AAE1C,MAAM,UAAU,aAAa,CAAC,IAAgB,EAAE,IAAa;IAC3D,WAAW,GAAG,IAAI,CAAC;IACnB,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAwB;IACpD,iBAAiB,GAAG,IAAI,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,WAAW,KAAK,QAAQ,CAAC;AAClC,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Envelope 字段说明见 docs/superpowers/specs/2026-04-19-host-operation-refactor-design.md
3
+ * §okclaw-cli ndjson 输出契约。
4
+ */
5
+ export type OpPhase = 'start' | 'step_start' | 'progress' | 'step_done' | 'log' | 'end';
6
+ export type Level = 'debug' | 'info' | 'warn' | 'error';
7
+ export interface NdjsonEvent {
8
+ ts: string;
9
+ seq: number;
10
+ op: string;
11
+ phase: OpPhase;
12
+ step?: string;
13
+ level: Level;
14
+ progress?: number;
15
+ msg?: string;
16
+ fields?: Record<string, unknown>;
17
+ code?: string;
18
+ }
19
+ export type NdjsonWriter = (line: string) => void;
20
+ /**
21
+ * 单 op 的事件发射器。在 text 模式下所有方法都是 no-op;ndjson 模式才写出。
22
+ *
23
+ * 约定:
24
+ * - seq 单调递增,同一 emitter 实例内唯一
25
+ * - end() 只能发一次,重复调用忽略
26
+ * - 非正常退出(exception/signal)由 registerExitHandlers 兜底补 end
27
+ */
28
+ export declare class NdjsonEmitter {
29
+ private seq;
30
+ private readonly op;
31
+ private readonly writer;
32
+ private ended;
33
+ constructor(op: string, writer?: NdjsonWriter);
34
+ start(msg?: string, fields?: Record<string, unknown>): void;
35
+ stepStart(step: string, msg: string, fields?: Record<string, unknown>): void;
36
+ progress(step: string, progress: number, msg?: string, fields?: Record<string, unknown>): void;
37
+ stepDone(step: string, msg: string, fields?: Record<string, unknown>): void;
38
+ /**
39
+ * 通用日志事件。走独立 phase="log"(bug#7 修:之前借用 phase="progress" 会
40
+ * 污染"取 max(progress) 作为当前进度"的聚合逻辑)。用 level 区分严重度。
41
+ */
42
+ log(level: Level, msg: string, fields?: Record<string, unknown>): void;
43
+ /**
44
+ * 终态事件;必发。ok=false 时 fields 里加 errorCode(可选)。
45
+ * end 事件的 fields 可承载 op-specific 返回值(如 FILE_READ 的 content)。
46
+ */
47
+ end(ok: boolean, exitCode: number, code?: string, fields?: Record<string, unknown>): void;
48
+ hasEnded(): boolean;
49
+ private emit;
50
+ }
51
+ export declare function getActiveEmitter(): NdjsonEmitter | null;
52
+ export declare function clearActiveEmitter(): void;
53
+ /**
54
+ * 注册进程兜底,确保 ndjson 模式下 end 事件必发(plan P1 风险:忘 flush → os-api 卡死)。
55
+ * 只在 ndjson 模式生效。
56
+ */
57
+ export declare function registerExitHandlers(emitter: NdjsonEmitter): void;