engine7 7.1.7 → 7.1.8

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/dist/cli.mjs CHANGED
@@ -1,10 +1,494 @@
1
- // src/cli-init.ts
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // src/cli-travel.ts
12
+ var cli_travel_exports = {};
13
+ __export(cli_travel_exports, {
14
+ doExport: () => doExport,
15
+ doImport: () => doImport,
16
+ loadTravelConfig: () => loadTravelConfig,
17
+ saveTravelConfig: () => saveTravelConfig
18
+ });
2
19
  import * as path from "node:path";
3
20
  import * as fs from "node:fs";
21
+ import * as os from "node:os";
22
+ import { execSync } from "node:child_process";
23
+ function loadTravelConfig() {
24
+ try {
25
+ if (!fs.existsSync(CONFIG_PATH)) return null;
26
+ return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+ function saveTravelConfig(cfg) {
32
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2));
33
+ }
34
+ function sanitizeContent(content, dirs) {
35
+ let result = content;
36
+ for (const { placeholder, getOriginal } of PATH_PLACEHOLDERS) {
37
+ const original = getOriginal(dirs);
38
+ if (original) {
39
+ result = result.split(original).join(placeholder);
40
+ result = result.split(original.replace(/\//g, "\\")).join(placeholder);
41
+ }
42
+ }
43
+ return result;
44
+ }
45
+ function restoreContent(content, dirs) {
46
+ let result = content;
47
+ for (const { placeholder, getOriginal } of PATH_PLACEHOLDERS) {
48
+ const target = getOriginal(dirs);
49
+ if (target) {
50
+ result = result.split(placeholder).join(target);
51
+ }
52
+ }
53
+ return result;
54
+ }
55
+ function isTextFile(filePath) {
56
+ const ext = path.extname(filePath).toLowerCase();
57
+ return TEXT_EXTENSIONS.has(ext);
58
+ }
59
+ function shouldExclude(name) {
60
+ for (const pattern of WORKSPACE_EXCLUDE) {
61
+ if (pattern.startsWith("*")) {
62
+ if (name.includes(pattern.slice(1).replace("*", ""))) return true;
63
+ } else if (name === pattern) {
64
+ return true;
65
+ }
66
+ }
67
+ return false;
68
+ }
69
+ function collectFiles(rootDir, includeSet, optionalSet) {
70
+ const files = [];
71
+ const entries = fs.readdirSync(rootDir, { withFileTypes: true });
72
+ for (const entry of entries) {
73
+ if (shouldExclude(entry.name)) continue;
74
+ const fullPath = path.join(rootDir, entry.name);
75
+ const realPath = fs.realpathSync(fullPath);
76
+ if (realPath !== fullPath) {
77
+ try {
78
+ const lstat = fs.lstatSync(fullPath);
79
+ if (lstat.isSymbolicLink()) {
80
+ continue;
81
+ }
82
+ } catch {
83
+ }
84
+ }
85
+ const isInclude = includeSet.has(entry.name) || optionalSet.has(entry.name);
86
+ if (!isInclude) continue;
87
+ if (entry.isDirectory()) {
88
+ const subFiles = collectAllFiles(fullPath);
89
+ files.push(...subFiles);
90
+ } else {
91
+ files.push(fullPath);
92
+ }
93
+ }
94
+ return files;
95
+ }
96
+ function collectAllFiles(dir) {
97
+ const files = [];
98
+ try {
99
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
100
+ for (const entry of entries) {
101
+ if (shouldExclude(entry.name)) continue;
102
+ const fullPath = path.join(dir, entry.name);
103
+ try {
104
+ if (fs.lstatSync(fullPath).isSymbolicLink()) continue;
105
+ } catch {
106
+ }
107
+ if (entry.isDirectory()) {
108
+ files.push(...collectAllFiles(fullPath));
109
+ } else {
110
+ files.push(fullPath);
111
+ }
112
+ }
113
+ } catch {
114
+ }
115
+ return files;
116
+ }
117
+ function collectRecentSessions(agentsDir, days = 7) {
118
+ const files = [];
119
+ if (!fs.existsSync(agentsDir)) return files;
120
+ const cutoff = Date.now() - days * 24 * 60 * 60 * 1e3;
121
+ try {
122
+ const entries = fs.readdirSync(agentsDir, { withFileTypes: true });
123
+ for (const entry of entries) {
124
+ const fullPath = path.join(agentsDir, entry.name);
125
+ if (entry.isDirectory()) {
126
+ const sub = collectAllFiles(fullPath);
127
+ for (const f of sub) {
128
+ if (!f.endsWith(".jsonl")) continue;
129
+ const stat = fs.statSync(f);
130
+ if (stat.mtimeMs > cutoff) files.push(f);
131
+ }
132
+ } else if (entry.name.endsWith(".jsonl")) {
133
+ const stat = fs.statSync(fullPath);
134
+ if (stat.mtimeMs > cutoff) files.push(fullPath);
135
+ }
136
+ }
137
+ } catch {
138
+ }
139
+ return files;
140
+ }
141
+ async function doExport(opts) {
142
+ const { agentName, stateDir, note, dryRun: dryRun2 } = opts;
143
+ const workspace = opts.workspace || path.join(stateDir, "workspace");
144
+ const engineHome = path.join(os.homedir(), ".openclaw");
145
+ console.log(`\u{1F4E6} engine7 export`);
146
+ console.log(` agent: ${agentName}`);
147
+ console.log(` state: ${stateDir}`);
148
+ console.log(` workspace: ${workspace}`);
149
+ if (!fs.existsSync(workspace)) {
150
+ console.error(`\u274C workspace \u4E0D\u5B58\u5728: ${workspace}`);
151
+ process.exit(1);
152
+ }
153
+ const dirs = { workspace, stateDir, engineHome };
154
+ const wsFiles = collectFiles(workspace, WORKSPACE_INCLUDE, WORKSPACE_OPTIONAL);
155
+ const sessionFiles = collectRecentSessions(path.join(stateDir, "agents"), 7);
156
+ console.log(` workspace \u6587\u4EF6: ${wsFiles.length}`);
157
+ console.log(` session jsonl: ${sessionFiles.length} (\u6700\u8FD17\u5929)`);
158
+ if (dryRun2) {
159
+ console.log(`
160
+ [DRY RUN] \u4F1A\u6253\u5305\u4EE5\u4E0B\u6587\u4EF6:`);
161
+ wsFiles.slice(0, 20).forEach((f) => console.log(` ${path.relative(workspace, f)}`));
162
+ if (wsFiles.length > 20) console.log(` ... \u8FD8\u6709 ${wsFiles.length - 20} \u4E2A\u6587\u4EF6`);
163
+ console.log(`
164
+ [DRY RUN] \u4E0D\u5B9E\u9645\u6253\u5305`);
165
+ return;
166
+ }
167
+ const now = /* @__PURE__ */ new Date();
168
+ const version = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}${String(now.getDate()).padStart(2, "0")}-${String(now.getHours()).padStart(2, "0")}${String(now.getMinutes()).padStart(2, "0")}`;
169
+ const tmpDir = path.join(os.tmpdir(), `engine7-export-${agentName}-${version}`);
170
+ fs.mkdirSync(tmpDir, { recursive: true });
171
+ const stagingDir = path.join(tmpDir, agentName);
172
+ fs.mkdirSync(stagingDir, { recursive: true });
173
+ let fileCount = 0;
174
+ let totalSize = 0;
175
+ for (const srcFile of wsFiles) {
176
+ const relPath = path.relative(workspace, srcFile);
177
+ const destFile = path.join(stagingDir, "workspace", relPath);
178
+ fs.mkdirSync(path.dirname(destFile), { recursive: true });
179
+ if (isTextFile(srcFile)) {
180
+ const content = fs.readFileSync(srcFile, "utf-8");
181
+ fs.writeFileSync(destFile, sanitizeContent(content, dirs));
182
+ } else {
183
+ fs.copyFileSync(srcFile, destFile);
184
+ }
185
+ fileCount++;
186
+ totalSize += fs.statSync(srcFile).size;
187
+ }
188
+ for (const srcFile of sessionFiles) {
189
+ const relPath = path.relative(stateDir, srcFile);
190
+ const destFile = path.join(stagingDir, relPath);
191
+ fs.mkdirSync(path.dirname(destFile), { recursive: true });
192
+ fs.copyFileSync(srcFile, destFile);
193
+ fileCount++;
194
+ totalSize += fs.statSync(srcFile).size;
195
+ }
196
+ const manifest = {
197
+ agentName,
198
+ version,
199
+ createdAt: now.toISOString(),
200
+ engineVersion: "7.x",
201
+ originalPaths: {
202
+ WORKSPACE: workspace,
203
+ STATE_DIR: stateDir,
204
+ ENGINE_HOME: engineHome
205
+ },
206
+ fileCount,
207
+ totalSize,
208
+ note
209
+ };
210
+ fs.writeFileSync(path.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2));
211
+ const tarFile = path.join(tmpDir, `${agentName}-${version}.tar.gz`);
212
+ console.log(`
213
+ \u{1F5DC}\uFE0F \u6253\u5305\u4E2D...`);
214
+ if (process.platform === "win32") {
215
+ const zipFile = tarFile.replace(".tar.gz", ".zip");
216
+ const stagingParent = path.dirname(stagingDir);
217
+ const childName = path.basename(stagingDir);
218
+ execSync(`powershell -Command "Compress-Archive -Path '${stagingParent}/${childName}/*' -DestinationPath '${zipFile}' -Force"`, { stdio: "pipe" });
219
+ fs.renameSync(zipFile, tarFile);
220
+ } else {
221
+ execSync(`tar -czf "${tarFile}" -C "${tmpDir}" ${agentName}`, { stdio: "pipe" });
222
+ }
223
+ const tarSize = fs.statSync(tarFile).size;
224
+ console.log(`\u2705 \u6253\u5305\u5B8C\u6210: ${tarFile} (${(tarSize / 1024 / 1024).toFixed(1)} MB, ${fileCount} \u6587\u4EF6)`);
225
+ const cfg = loadTravelConfig();
226
+ if (!cfg || !cfg.githubToken) {
227
+ console.log(`
228
+ \u26A0\uFE0F \u672A\u914D\u7F6E GitHub\uFF0Ctar.gz \u5DF2\u751F\u6210: ${tarFile}`);
229
+ console.log(` \u914D\u7F6E GitHub: \u7F16\u8F91 ${CONFIG_PATH}`);
230
+ console.log(` \u6216\u624B\u52A8\u4E0A\u4F20\u5230 GitHub private repo release`);
231
+ return;
232
+ }
233
+ await uploadToGitHub(cfg, tarFile, agentName, version, manifest);
234
+ }
235
+ async function doImport(opts) {
236
+ const { agentName, stateDir, version, dryRun: dryRun2 } = opts;
237
+ console.log(`\u{1F4E5} engine7 import`);
238
+ console.log(` agent: ${agentName}`);
239
+ console.log(` target: ${stateDir}`);
240
+ const cfg = loadTravelConfig();
241
+ if (!cfg || !cfg.githubToken) {
242
+ console.error(`\u274C \u672A\u914D\u7F6E GitHub\uFF0C\u65E0\u6CD5\u4E0B\u8F7D`);
243
+ console.error(` \u914D\u7F6E: \u7F16\u8F91 ${CONFIG_PATH}`);
244
+ process.exit(1);
245
+ }
246
+ const tmpDir = path.join(os.tmpdir(), `engine7-import-${agentName}-${Date.now()}`);
247
+ fs.mkdirSync(tmpDir, { recursive: true });
248
+ const tarFile = await downloadFromGitHub(cfg, agentName, version, tmpDir);
249
+ console.log(`\u2705 \u4E0B\u8F7D\u5B8C\u6210: ${tarFile}`);
250
+ if (dryRun2) {
251
+ console.log(`
252
+ [DRY RUN] \u53EA\u4E0B\u8F7D\u4E0D\u6062\u590D`);
253
+ return;
254
+ }
255
+ console.log(`\u{1F4C2} \u89E3\u5305\u4E2D...`);
256
+ if (process.platform === "win32") {
257
+ execSync(`powershell -Command "Expand-Archive -Path '${tarFile}' -DestinationPath '${tmpDir}' -Force"`, { stdio: "pipe" });
258
+ } else {
259
+ execSync(`tar -xzf "${tarFile}" -C "${tmpDir}"`, { stdio: "pipe" });
260
+ }
261
+ const stagingDir = path.join(tmpDir, agentName);
262
+ const manifestPath = path.join(stagingDir, "manifest.json");
263
+ if (!fs.existsSync(manifestPath)) {
264
+ console.error(`\u274C manifest.json \u4E0D\u5B58\u5728\uFF0C\u6587\u4EF6\u53EF\u80FD\u635F\u574F`);
265
+ process.exit(1);
266
+ }
267
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
268
+ const workspace = path.join(stateDir, "workspace");
269
+ const engineHome = path.join(os.homedir(), ".openclaw");
270
+ const dirs = { workspace, stateDir, engineHome };
271
+ console.log(` \u7248\u672C: ${manifest.version}`);
272
+ console.log(` \u521B\u5EFA: ${manifest.createdAt}`);
273
+ console.log(` \u6587\u4EF6\u6570: ${manifest.fileCount}`);
274
+ const wsStaging = path.join(stagingDir, "workspace");
275
+ let restoredCount = 0;
276
+ if (fs.existsSync(wsStaging)) {
277
+ const allFiles = collectAllFiles(wsStaging);
278
+ for (const srcFile of allFiles) {
279
+ const relPath = path.relative(wsStaging, srcFile);
280
+ const destFile = path.join(workspace, relPath);
281
+ fs.mkdirSync(path.dirname(destFile), { recursive: true });
282
+ if (isTextFile(srcFile)) {
283
+ const content = fs.readFileSync(srcFile, "utf-8");
284
+ fs.writeFileSync(destFile, restoreContent(content, dirs));
285
+ } else {
286
+ fs.copyFileSync(srcFile, destFile);
287
+ }
288
+ restoredCount++;
289
+ }
290
+ }
291
+ const agentsStaging = path.join(stagingDir, "agents");
292
+ if (fs.existsSync(agentsStaging)) {
293
+ const sessionFiles = collectAllFiles(agentsStaging);
294
+ for (const srcFile of sessionFiles) {
295
+ const relPath = path.relative(stagingDir, srcFile);
296
+ const destFile = path.join(stateDir, relPath);
297
+ fs.mkdirSync(path.dirname(destFile), { recursive: true });
298
+ fs.copyFileSync(srcFile, destFile);
299
+ restoredCount++;
300
+ }
301
+ }
302
+ console.log(`\u2705 \u6062\u590D\u5B8C\u6210: ${restoredCount} \u6587\u4EF6 \u2192 ${stateDir}`);
303
+ console.log(`
304
+ \u{1F4A1} \u4E0B\u4E00\u6B65: engine7 start --config <path>`);
305
+ fs.rmSync(tmpDir, { recursive: true, force: true });
306
+ }
307
+ async function uploadToGitHub(cfg, tarFile, agentName, version, manifest) {
308
+ const repo = `${cfg.githubOwner}/${cfg.repoName}`;
309
+ const tag = `${agentName}-${version}`;
310
+ console.log(`
311
+ \u{1F4E4} \u4E0A\u4F20\u5230 GitHub: ${repo} release ${tag}`);
312
+ try {
313
+ const releaseBody = Object.entries(manifest).map(([k, v]) => `- **${k}**: ${typeof v === "object" ? JSON.stringify(v) : v}`).join("\n");
314
+ const createRes = await fetch(`https://api.github.com/repos/${repo}/releases`, {
315
+ method: "POST",
316
+ headers: {
317
+ "Authorization": `Bearer ${cfg.githubToken}`,
318
+ "Accept": "application/vnd.github+json",
319
+ "Content-Type": "application/json"
320
+ },
321
+ body: JSON.stringify({
322
+ tag_name: tag,
323
+ name: `${agentName} ${version}`,
324
+ body: releaseBody,
325
+ prerelease: false,
326
+ make_latest: "true"
327
+ })
328
+ });
329
+ if (!createRes.ok) {
330
+ const err = await createRes.text();
331
+ throw new Error(`\u521B\u5EFA release \u5931\u8D25: ${createRes.status} ${err}`);
332
+ }
333
+ const release = await createRes.json();
334
+ const uploadUrl = release.upload_url.replace("{?name,label}", "");
335
+ const fileBuffer = fs.readFileSync(tarFile);
336
+ const fileName = path.basename(tarFile);
337
+ const uploadRes = await fetch(`${uploadUrl}?name=${fileName}`, {
338
+ method: "POST",
339
+ headers: {
340
+ "Authorization": `Bearer ${cfg.githubToken}`,
341
+ "Accept": "application/vnd.github+json",
342
+ "Content-Type": "application/gzip",
343
+ "Content-Length": String(fileBuffer.length)
344
+ },
345
+ body: fileBuffer
346
+ });
347
+ if (!uploadRes.ok) {
348
+ const err = await uploadRes.text();
349
+ throw new Error(`\u4E0A\u4F20 asset \u5931\u8D25: ${uploadRes.status} ${err}`);
350
+ }
351
+ console.log(`\u2705 \u4E0A\u4F20\u6210\u529F!`);
352
+ console.log(` release: ${release.html_url}`);
353
+ } catch (e) {
354
+ console.error(`\u274C GitHub \u4E0A\u4F20\u5931\u8D25: ${e.message}`);
355
+ console.error(` tar.gz \u4ECD\u5728: ${tarFile}`);
356
+ throw e;
357
+ }
358
+ try {
359
+ fs.rmSync(path.dirname(tarFile), { recursive: true, force: true });
360
+ } catch {
361
+ }
362
+ }
363
+ async function downloadFromGitHub(cfg, agentName, version, destDir) {
364
+ const repo = `${cfg.githubOwner}/${cfg.repoName}`;
365
+ const tag = version || await getLatestReleaseTag(cfg, agentName);
366
+ console.log(`\u2B07\uFE0F \u4E0B\u8F7D: ${repo} release ${tag}`);
367
+ const res = await fetch(`https://api.github.com/repos/${repo}/releases/tags/${tag}`, {
368
+ headers: {
369
+ "Authorization": `Bearer ${cfg.githubToken}`,
370
+ "Accept": "application/vnd.github+json"
371
+ }
372
+ });
373
+ if (!res.ok) {
374
+ throw new Error(`\u83B7\u53D6 release \u5931\u8D25: ${res.status}`);
375
+ }
376
+ const release = await res.json();
377
+ const asset = release.assets?.find((a) => a.name.endsWith(".tar.gz"));
378
+ if (!asset) {
379
+ throw new Error(`release ${tag} \u6CA1\u6709 tar.gz asset`);
380
+ }
381
+ const downloadRes = await fetch(asset.url, {
382
+ headers: {
383
+ "Authorization": `Bearer ${cfg.githubToken}`,
384
+ "Accept": "application/octet-stream"
385
+ }
386
+ });
387
+ if (!downloadRes.ok) {
388
+ throw new Error(`\u4E0B\u8F7D asset \u5931\u8D25: ${downloadRes.status}`);
389
+ }
390
+ const buffer = Buffer.from(await downloadRes.arrayBuffer());
391
+ const tarFile = path.join(destDir, asset.name);
392
+ fs.writeFileSync(tarFile, buffer);
393
+ return tarFile;
394
+ }
395
+ async function getLatestReleaseTag(cfg, agentName) {
396
+ const repo = `${cfg.githubOwner}/${cfg.repoName}`;
397
+ const res = await fetch(`https://api.github.com/repos/${repo}/releases?per_page=30`, {
398
+ headers: {
399
+ "Authorization": `Bearer ${cfg.githubToken}`,
400
+ "Accept": "application/vnd.github+json"
401
+ }
402
+ });
403
+ if (!res.ok) {
404
+ throw new Error(`\u83B7\u53D6 release \u5217\u8868\u5931\u8D25: ${res.status}`);
405
+ }
406
+ const releases = await res.json();
407
+ const match = releases.find((r) => r.tag_name?.startsWith(`${agentName}-`));
408
+ if (!match) {
409
+ throw new Error(`\u6CA1\u6709\u627E\u5230 ${agentName} \u7684 release`);
410
+ }
411
+ return match.tag_name;
412
+ }
413
+ var CONFIG_PATH, PATH_PLACEHOLDERS, WORKSPACE_INCLUDE, WORKSPACE_OPTIONAL, WORKSPACE_EXCLUDE, TEXT_EXTENSIONS;
414
+ var init_cli_travel = __esm({
415
+ "src/cli-travel.ts"() {
416
+ "use strict";
417
+ CONFIG_PATH = path.join(os.homedir(), ".engine7-travel.json");
418
+ PATH_PLACEHOLDERS = [
419
+ { placeholder: "{{WORKSPACE}}", getOriginal: (d) => d.workspace },
420
+ { placeholder: "{{ENGINE_HOME}}", getOriginal: (d) => d.engineHome },
421
+ { placeholder: "{{STATE_DIR}}", getOriginal: (d) => d.stateDir }
422
+ ];
423
+ WORKSPACE_INCLUDE = /* @__PURE__ */ new Set([
424
+ // 核心文件
425
+ "AGENTS.md",
426
+ "SOUL.md",
427
+ "MEMORY.md",
428
+ "USER.md",
429
+ "HEARTBEAT.md",
430
+ "INDEX.md",
431
+ "SESSION-STATE.md",
432
+ // 核心目录
433
+ "prompts",
434
+ "topics",
435
+ "memory",
436
+ "inner-voice",
437
+ "docs",
438
+ "skills",
439
+ "voice-chat",
440
+ "scripts",
441
+ "selfie",
442
+ "moodboard",
443
+ // 状态文件
444
+ "calendar.db",
445
+ "nudge-state.json"
446
+ ]);
447
+ WORKSPACE_OPTIONAL = /* @__PURE__ */ new Set([
448
+ "images",
449
+ "tools"
450
+ ]);
451
+ WORKSPACE_EXCLUDE = /* @__PURE__ */ new Set([
452
+ "livestream",
453
+ "content-library",
454
+ "tmp",
455
+ ".git",
456
+ "node_modules",
457
+ "memory_runs",
458
+ "workspace",
459
+ "prompt-archive",
460
+ "aim-archive",
461
+ "test-agent",
462
+ "nul",
463
+ "*.bak*",
464
+ "*.bak-*"
465
+ ]);
466
+ TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
467
+ ".md",
468
+ ".json",
469
+ ".txt",
470
+ ".js",
471
+ ".ts",
472
+ ".mjs",
473
+ ".py",
474
+ ".yaml",
475
+ ".yml",
476
+ ".cmd",
477
+ ".bat",
478
+ ".sh",
479
+ ".csv",
480
+ ".html"
481
+ ]);
482
+ }
483
+ });
484
+
485
+ // src/cli-init.ts
486
+ import * as path2 from "node:path";
487
+ import * as fs2 from "node:fs";
4
488
  import * as readline from "node:readline";
5
489
  import { fileURLToPath } from "node:url";
6
490
  var __filename = fileURLToPath(import.meta.url);
7
- var __dirname = path.dirname(__filename);
491
+ var __dirname = path2.dirname(__filename);
8
492
  var SCHEMA_VERSION = 1;
9
493
  function parseArgs() {
10
494
  const args = process.argv.slice(2);
@@ -26,10 +510,10 @@ function parseArgs() {
26
510
  }
27
511
  }
28
512
  if (!stateDir) {
29
- stateDir = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
513
+ stateDir = path2.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
30
514
  console.log(` \u4F7F\u7528\u9ED8\u8BA4\u76EE\u5F55: ${stateDir}`);
31
515
  }
32
- stateDir = path.resolve(stateDir);
516
+ stateDir = path2.resolve(stateDir);
33
517
  return { stateDir, quick, dryRun: dryRun2 };
34
518
  }
35
519
  function printHelp() {
@@ -41,6 +525,8 @@ Engine 7 \u2014 Self-hosted AI agent engine
41
525
  engine7 start [--config <path>] \u542F\u52A8 Engine
42
526
  engine7 restart [--config <path>] \u91CD\u542F Engine\uFF08\u6740\u65E7\u8FDB\u7A0B+\u542F\u52A8\uFF09
43
527
  engine7 service install|uninstall|status \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
528
+ engine7 export [--state-dir <path>] \u6253\u5305 agent workspace \u2192 GitHub release
529
+ engine7 import --state-dir <path> \u4ECE GitHub release \u6062\u590D agent
44
530
 
45
531
  init \u9009\u9879:
46
532
  --state-dir <path> agent \u6839\u76EE\u5F55\uFF08\u5FC5\u586B\uFF0C\u652F\u6301\u76F8\u5BF9\u8DEF\u5F84\uFF09
@@ -50,11 +536,25 @@ init \u9009\u9879:
50
536
  start \u9009\u9879:
51
537
  --config <path> config \u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4: configs/main7.json\uFF09
52
538
 
539
+ export \u9009\u9879:
540
+ --state-dir <path> agent \u6839\u76EE\u5F55\uFF08\u9ED8\u8BA4: \u5F53\u524D\u76EE\u5F55\u4E0A\u7EA7\uFF09
541
+ --agent <name> agent \u540D\u79F0\uFF08\u9ED8\u8BA4: state-dir basename\uFF09
542
+ --note <text> \u7248\u672C\u5907\u6CE8
543
+ --dry-run \u53EA\u5217\u51FA\u4F1A\u6253\u5305\u4EC0\u4E48\uFF0C\u4E0D\u5B9E\u9645\u4E0A\u4F20
544
+
545
+ import \u9009\u9879:
546
+ --state-dir <path> \u76EE\u6807 agent \u6839\u76EE\u5F55\uFF08\u5FC5\u586B\uFF09
547
+ --agent <name> agent \u540D\u79F0
548
+ --version <tag> \u6307\u5B9A\u7248\u672C\uFF08\u9ED8\u8BA4: \u6700\u65B0\uFF09
549
+ --dry-run \u53EA\u4E0B\u8F7D\u4E0D\u6062\u590D
550
+
53
551
  \u793A\u4F8B:
54
552
  engine7 init --state-dir D:/my-agent
55
553
  engine7 init --state-dir ./my-agent --quick
56
554
  engine7 start
57
555
  engine7 start --config configs/xiaowen.json
556
+ engine7 export --state-dir D:/xiaoke --agent xiaoke --note "travel test"
557
+ engine7 import --state-dir D:/xiaoke --agent xiaoke
58
558
  `);
59
559
  }
60
560
  function createReadline() {
@@ -166,7 +666,7 @@ async function interactiveConfig(rl, defaults) {
166
666
  return v;
167
667
  }
168
668
  function generateConfig(v) {
169
- const workspace = path.join(v.stateDir, "workspace").replace(/\\/g, "/");
669
+ const workspace = path2.join(v.stateDir, "workspace").replace(/\\/g, "/");
170
670
  const config = {
171
671
  schemaVersion: SCHEMA_VERSION,
172
672
  stateDir: v.stateDir.replace(/\\/g, "/"),
@@ -292,45 +792,45 @@ function generateConfig(v) {
292
792
  }
293
793
  function buildDirTree(v) {
294
794
  const d = v.stateDir;
295
- const w = path.join(d, "workspace");
795
+ const w = path2.join(d, "workspace");
296
796
  const now = (/* @__PURE__ */ new Date()).toLocaleString("sv-SE", { timeZone: "Asia/Shanghai", hour12: false });
297
797
  return [
298
798
  // 目录
299
- { path: path.join(d, "configs"), type: "dir" },
300
- { path: path.join(d, "state", "agents", "main", "sessions"), type: "dir" },
301
- { path: path.join(w, "prompts"), type: "dir" },
302
- { path: path.join(w, "memory", "daily"), type: "dir" },
303
- { path: path.join(w, "docs", "research"), type: "dir" },
304
- { path: path.join(w, "docs", "todo"), type: "dir" },
305
- { path: path.join(w, "docs", "decisions"), type: "dir" },
306
- { path: path.join(w, "docs", "knowledge"), type: "dir" },
307
- { path: path.join(w, "docs", "sop"), type: "dir" },
308
- { path: path.join(d, "logs"), type: "dir" },
309
- { path: path.join(d, "media", "inbound"), type: "dir" },
799
+ { path: path2.join(d, "configs"), type: "dir" },
800
+ { path: path2.join(d, "state", "agents", "main", "sessions"), type: "dir" },
801
+ { path: path2.join(w, "prompts"), type: "dir" },
802
+ { path: path2.join(w, "memory", "daily"), type: "dir" },
803
+ { path: path2.join(w, "docs", "research"), type: "dir" },
804
+ { path: path2.join(w, "docs", "todo"), type: "dir" },
805
+ { path: path2.join(w, "docs", "decisions"), type: "dir" },
806
+ { path: path2.join(w, "docs", "knowledge"), type: "dir" },
807
+ { path: path2.join(w, "docs", "sop"), type: "dir" },
808
+ { path: path2.join(d, "logs"), type: "dir" },
809
+ { path: path2.join(d, "media", "inbound"), type: "dir" },
310
810
  // workspace 文件
311
811
  {
312
- path: path.join(w, "SESSION-STATE.md"),
812
+ path: path2.join(w, "SESSION-STATE.md"),
313
813
  type: "file",
314
814
  content: readTemplate("workspace/SESSION-STATE.md").replace("{{CURRENT_TIME}}", now)
315
815
  },
316
- { path: path.join(w, "HEARTBEAT.md"), type: "file", content: readTemplate("workspace/HEARTBEAT.md") },
816
+ { path: path2.join(w, "HEARTBEAT.md"), type: "file", content: readTemplate("workspace/HEARTBEAT.md") },
317
817
  {
318
- path: path.join(w, "SOUL.md"),
818
+ path: path2.join(w, "SOUL.md"),
319
819
  type: "file",
320
820
  content: readTemplate("workspace/SOUL.md").replace(/\{\{AGENT_NAME\}\}/g, v.agentName)
321
821
  },
322
- { path: path.join(w, "AGENTS.md"), type: "file", content: readTemplate("workspace/AGENTS.md") },
822
+ { path: path2.join(w, "AGENTS.md"), type: "file", content: readTemplate("workspace/AGENTS.md") },
323
823
  {
324
- path: path.join(w, "prompts", "contacts.md"),
824
+ path: path2.join(w, "prompts", "contacts.md"),
325
825
  type: "file",
326
826
  content: readTemplate("workspace/prompts/contacts.md").replace("{{DISCORD_USER_ID}}", v.discordUserId || "YOUR_DISCORD_ID").replace("{{FEISHU_OPEN_ID}}", v.feishuOpenId || "YOUR_FEISHU_OPEN_ID")
327
827
  },
328
- { path: path.join(w, "prompts", "auto-memory-instructions.md"), type: "file", content: readTemplate("workspace/prompts/auto-memory-instructions.md") },
329
- { path: path.join(w, "MEMORY.md"), type: "file", content: "# MEMORY.md \u2014 \u8BB0\u5FC6\u6587\u4EF6\u7D22\u5F15\n\n> \u6700\u540E\u66F4\u65B0\uFF1A\u521D\u59CB\u5316\n" },
330
- { path: path.join(w, "USER.md"), type: "file", content: "# USER.md \u2014 \u7528\u6237\u4FE1\u606F\n\n\uFF08\u5728\u8FD9\u91CC\u8BB0\u5F55\u7528\u6237\u7684\u504F\u597D\u3001\u80CC\u666F\u7B49\uFF09\n" },
828
+ { path: path2.join(w, "prompts", "auto-memory-instructions.md"), type: "file", content: readTemplate("workspace/prompts/auto-memory-instructions.md") },
829
+ { path: path2.join(w, "MEMORY.md"), type: "file", content: "# MEMORY.md \u2014 \u8BB0\u5FC6\u6587\u4EF6\u7D22\u5F15\n\n> \u6700\u540E\u66F4\u65B0\uFF1A\u521D\u59CB\u5316\n" },
830
+ { path: path2.join(w, "USER.md"), type: "file", content: "# USER.md \u2014 \u7528\u6237\u4FE1\u606F\n\n\uFF08\u5728\u8FD9\u91CC\u8BB0\u5F55\u7528\u6237\u7684\u504F\u597D\u3001\u80CC\u666F\u7B49\uFF09\n" },
331
831
  // package.json — 让 agent 目录成为独立 npm 项目根,防止 npm hoisting
332
832
  {
333
- path: path.join(d, "package.json"),
833
+ path: path2.join(d, "package.json"),
334
834
  type: "file",
335
835
  content: JSON.stringify({
336
836
  name: v.agentName.toLowerCase().replace(/[^a-z0-9-]/g, "-") || "agent",
@@ -341,7 +841,7 @@ function buildDirTree(v) {
341
841
  },
342
842
  // 启动脚本(根据 OS 生成)
343
843
  ...process.platform === "win32" ? [{
344
- path: path.join(d, "start.cmd"),
844
+ path: path2.join(d, "start.cmd"),
345
845
  type: "file",
346
846
  content: `@echo off
347
847
  rem Engine 7 startup script
@@ -373,7 +873,7 @@ if %ERRORLEVEL% NEQ 0 (
373
873
  )
374
874
  `
375
875
  }] : [{
376
- path: path.join(d, "start.sh"),
876
+ path: path2.join(d, "start.sh"),
377
877
  type: "file",
378
878
  content: `#!/bin/bash
379
879
  # Engine 7 startup script
@@ -406,13 +906,13 @@ node "$ENGINE7_BIN" --engine-config configs/main7.json
406
906
  }
407
907
  function readTemplate(relativePath) {
408
908
  const candidates = [
409
- path.join(__dirname, "..", "templates", relativePath),
410
- path.join(__dirname, "..", "..", "templates", relativePath),
411
- path.join(process.cwd(), "templates", relativePath)
909
+ path2.join(__dirname, "..", "templates", relativePath),
910
+ path2.join(__dirname, "..", "..", "templates", relativePath),
911
+ path2.join(process.cwd(), "templates", relativePath)
412
912
  ];
413
913
  for (const p of candidates) {
414
- if (fs.existsSync(p)) {
415
- return fs.readFileSync(p, "utf-8");
914
+ if (fs2.existsSync(p)) {
915
+ return fs2.readFileSync(p, "utf-8");
416
916
  }
417
917
  }
418
918
  throw new Error(`\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${relativePath}\uFF08\u627E\u4E86: ${candidates.join(", ")}\uFF09`);
@@ -427,11 +927,11 @@ function dryRun(entries) {
427
927
  function execute(entries) {
428
928
  for (const e of entries) {
429
929
  if (e.type === "dir") {
430
- fs.mkdirSync(e.path, { recursive: true });
930
+ fs2.mkdirSync(e.path, { recursive: true });
431
931
  console.log(` \u{1F4C1} ${e.path}`);
432
932
  } else {
433
- fs.mkdirSync(path.dirname(e.path), { recursive: true });
434
- fs.writeFileSync(e.path, e.content || "", "utf-8");
933
+ fs2.mkdirSync(path2.dirname(e.path), { recursive: true });
934
+ fs2.writeFileSync(e.path, e.content || "", "utf-8");
435
935
  console.log(` \u{1F4C4} ${e.path}`);
436
936
  }
437
937
  }
@@ -447,6 +947,43 @@ async function main() {
447
947
  printHelp();
448
948
  process.exit(0);
449
949
  }
950
+ if (subcommand === "export") {
951
+ const { doExport: doExport2 } = await Promise.resolve().then(() => (init_cli_travel(), cli_travel_exports));
952
+ let exportStateDir = "";
953
+ let agentName = "";
954
+ let note = "";
955
+ let dryRun2 = false;
956
+ for (let i = 1; i < args.length; i++) {
957
+ if (args[i] === "--state-dir" && args[i + 1]) exportStateDir = args[++i];
958
+ else if (args[i] === "--agent" && args[i + 1]) agentName = args[++i];
959
+ else if (args[i] === "--note" && args[i + 1]) note = args[++i];
960
+ else if (args[i] === "--dry-run") dryRun2 = true;
961
+ }
962
+ if (!exportStateDir) exportStateDir = path2.resolve(process.cwd());
963
+ if (!agentName) agentName = path2.basename(exportStateDir);
964
+ await doExport2({ agentName, stateDir: exportStateDir, note, dryRun: dryRun2 });
965
+ process.exit(0);
966
+ }
967
+ if (subcommand === "import") {
968
+ const { doImport: doImport2 } = await Promise.resolve().then(() => (init_cli_travel(), cli_travel_exports));
969
+ let importStateDir = "";
970
+ let agentName = "";
971
+ let version = "";
972
+ let dryRun2 = false;
973
+ for (let i = 1; i < args.length; i++) {
974
+ if (args[i] === "--state-dir" && args[i + 1]) importStateDir = args[++i];
975
+ else if (args[i] === "--agent" && args[i + 1]) agentName = args[++i];
976
+ else if (args[i] === "--version" && args[i + 1]) version = args[++i];
977
+ else if (args[i] === "--dry-run") dryRun2 = true;
978
+ }
979
+ if (!importStateDir) {
980
+ console.error("\u274C import \u9700\u8981 --state-dir <path>");
981
+ process.exit(1);
982
+ }
983
+ if (!agentName) agentName = path2.basename(importStateDir);
984
+ await doImport2({ agentName, stateDir: importStateDir, version, dryRun: dryRun2 });
985
+ process.exit(0);
986
+ }
450
987
  if (subcommand === "start" || subcommand === "restart") {
451
988
  const label = subcommand === "restart" ? "\u{1F504} engine7 restart" : "\u{1F680} engine7 start";
452
989
  let configPath2 = "";
@@ -468,18 +1005,18 @@ engine7 start \u2014 \u542F\u52A8 Engine
468
1005
  }
469
1006
  }
470
1007
  if (!configPath2) {
471
- const defaultCfg = path.join("configs", "main7.json");
472
- const homeCfg = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7", "configs", "main7.json");
473
- if (fs.existsSync(defaultCfg)) {
1008
+ const defaultCfg = path2.join("configs", "main7.json");
1009
+ const homeCfg = path2.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7", "configs", "main7.json");
1010
+ if (fs2.existsSync(defaultCfg)) {
474
1011
  configPath2 = defaultCfg;
475
- } else if (fs.existsSync(homeCfg)) {
1012
+ } else if (fs2.existsSync(homeCfg)) {
476
1013
  configPath2 = homeCfg;
477
1014
  console.log(` \u4F7F\u7528\u9ED8\u8BA4 config: ${homeCfg}`);
478
1015
  } else {
479
1016
  const ptr = readHomePointer();
480
1017
  if (ptr?.stateDir) {
481
- const ptrCfg = path.join(ptr.stateDir, "configs", "main7.json");
482
- if (fs.existsSync(ptrCfg)) {
1018
+ const ptrCfg = path2.join(ptr.stateDir, "configs", "main7.json");
1019
+ if (fs2.existsSync(ptrCfg)) {
483
1020
  configPath2 = ptrCfg;
484
1021
  console.log(` \u4F7F\u7528 config: ${ptrCfg}`);
485
1022
  }
@@ -492,21 +1029,21 @@ engine7 start \u2014 \u542F\u52A8 Engine
492
1029
  }
493
1030
  }
494
1031
  }
495
- const { execSync, spawn } = await import("node:child_process");
1032
+ const { execSync: execSync2, spawn } = await import("node:child_process");
496
1033
  let enginePath;
497
- const localPath = path.join("node_modules", "engine7", "dist", "main.mjs");
498
- if (fs.existsSync(localPath)) {
1034
+ const localPath = path2.join("node_modules", "engine7", "dist", "main.mjs");
1035
+ if (fs2.existsSync(localPath)) {
499
1036
  enginePath = localPath;
500
1037
  } else {
501
- const cliPath = path.resolve(process.argv[1]);
502
- const distDir = path.dirname(cliPath);
503
- const candidate = path.join(distDir, "main.mjs");
504
- if (fs.existsSync(candidate)) {
1038
+ const cliPath = path2.resolve(process.argv[1]);
1039
+ const distDir = path2.dirname(cliPath);
1040
+ const candidate = path2.join(distDir, "main.mjs");
1041
+ if (fs2.existsSync(candidate)) {
505
1042
  enginePath = candidate;
506
1043
  } else {
507
1044
  try {
508
- const globalRoot = execSync("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
509
- enginePath = path.join(globalRoot, "engine7", "dist", "main.mjs");
1045
+ const globalRoot = execSync2("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
1046
+ enginePath = path2.join(globalRoot, "engine7", "dist", "main.mjs");
510
1047
  } catch {
511
1048
  console.error("\u274C \u627E\u4E0D\u5230 engine7 main.mjs");
512
1049
  process.exit(1);
@@ -516,17 +1053,17 @@ engine7 start \u2014 \u542F\u52A8 Engine
516
1053
  console.log(label);
517
1054
  console.log(` config: ${configPath2}`);
518
1055
  console.log(` engine: ${enginePath}`);
519
- const configName = path.basename(configPath2);
1056
+ const configName = path2.basename(configPath2);
520
1057
  const myPid = process.pid;
521
1058
  try {
522
1059
  if (process.platform === "win32") {
523
- execSync(`powershell -Command "Get-WmiObject Win32_Process | Where-Object { $_.Name -eq 'node.exe' -and $_.CommandLine -like '*${configName}*' -and $_.CommandLine -like '*dist*' -and $_.ProcessId -ne ${myPid} } | ForEach-Object { Write-Host '[start] Killing PID' $_.ProcessId; Stop-Process -Id $_.ProcessId -Force }"`, { stdio: "inherit" });
1060
+ execSync2(`powershell -Command "Get-WmiObject Win32_Process | Where-Object { $_.Name -eq 'node.exe' -and $_.CommandLine -like '*${configName}*' -and $_.CommandLine -like '*dist*' -and $_.ProcessId -ne ${myPid} } | ForEach-Object { Write-Host '[start] Killing PID' $_.ProcessId; Stop-Process -Id $_.ProcessId -Force }"`, { stdio: "inherit" });
524
1061
  } else {
525
- const pids = execSync(`pgrep -f "dist/main.mjs.*${configName}" 2>/dev/null || true`, { encoding: "utf-8" }).trim();
1062
+ const pids = execSync2(`pgrep -f "dist/main.mjs.*${configName}" 2>/dev/null || true`, { encoding: "utf-8" }).trim();
526
1063
  const otherPids = pids.split("\n").filter((p) => p && p.trim() !== String(myPid)).join("\n").trim();
527
1064
  if (otherPids) {
528
1065
  console.log(`[start] Killing existing engine (PID: ${otherPids})...`);
529
- execSync(`echo "${otherPids}" | xargs kill -9 2>/dev/null || true`);
1066
+ execSync2(`echo "${otherPids}" | xargs kill -9 2>/dev/null || true`);
530
1067
  await new Promise((r) => setTimeout(r, 2e3));
531
1068
  }
532
1069
  }
@@ -564,18 +1101,18 @@ engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
564
1101
  else if (args[i] === "--cwd" && args[i + 1]) cwd = args[++i];
565
1102
  }
566
1103
  if (!configPath2) {
567
- const defaultCfg = path.join(cwd, "configs", "main7.json");
568
- const homeCfg = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7", "configs", "main7.json");
569
- if (fs.existsSync(defaultCfg)) {
1104
+ const defaultCfg = path2.join(cwd, "configs", "main7.json");
1105
+ const homeCfg = path2.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7", "configs", "main7.json");
1106
+ if (fs2.existsSync(defaultCfg)) {
570
1107
  configPath2 = defaultCfg;
571
- } else if (fs.existsSync(homeCfg)) {
1108
+ } else if (fs2.existsSync(homeCfg)) {
572
1109
  configPath2 = homeCfg;
573
- cwd = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
1110
+ cwd = path2.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
574
1111
  } else {
575
1112
  const ptr = readHomePointer();
576
1113
  if (ptr?.stateDir) {
577
- const ptrCfg = path.join(ptr.stateDir, "configs", "main7.json");
578
- if (fs.existsSync(ptrCfg)) {
1114
+ const ptrCfg = path2.join(ptr.stateDir, "configs", "main7.json");
1115
+ if (fs2.existsSync(ptrCfg)) {
579
1116
  configPath2 = ptrCfg;
580
1117
  cwd = ptr.stateDir;
581
1118
  }
@@ -588,22 +1125,22 @@ engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
588
1125
  }
589
1126
  }
590
1127
  }
591
- const { execSync } = await import("node:child_process");
1128
+ const { execSync: execSync2 } = await import("node:child_process");
592
1129
  const engine7Bin = process.argv[1];
593
1130
  if (action === "install") {
594
1131
  if (process.platform === "win32") {
595
1132
  const taskName = "Engine7";
596
1133
  const nodeExe = process.execPath;
597
- const cliMjs = path.resolve(engine7Bin);
598
- const absConfig = path.resolve(configPath2);
599
- const wrapperPath = path.join(cwd, "engine7-start.cmd");
1134
+ const cliMjs = path2.resolve(engine7Bin);
1135
+ const absConfig = path2.resolve(configPath2);
1136
+ const wrapperPath = path2.join(cwd, "engine7-start.cmd");
600
1137
  const wrapperContent = `@echo off\r
601
1138
  cd /d "${cwd}"\r
602
1139
  "${nodeExe}" "${cliMjs}" start --config "${absConfig}"\r
603
1140
  `;
604
- fs.writeFileSync(wrapperPath, wrapperContent);
1141
+ fs2.writeFileSync(wrapperPath, wrapperContent);
605
1142
  try {
606
- execSync(`schtasks /create /tn "${taskName}" /tr "${wrapperPath}" /sc onlogon /rl highest /f`, { stdio: "inherit", shell: true });
1143
+ execSync2(`schtasks /create /tn "${taskName}" /tr "${wrapperPath}" /sc onlogon /rl highest /f`, { stdio: "inherit", shell: true });
607
1144
  console.log(`\u2705 Windows \u8BA1\u5212\u4EFB\u52A1 "${taskName}" \u5DF2\u521B\u5EFA\uFF08\u5F00\u673A\u81EA\u542F\u52A8\uFF09`);
608
1145
  console.log(` wrapper: ${wrapperPath}`);
609
1146
  } catch {
@@ -612,11 +1149,11 @@ cd /d "${cwd}"\r
612
1149
  }
613
1150
  } else if (process.platform === "darwin") {
614
1151
  const label = "com.engine7.agent";
615
- const plistDir = path.join(process.env.HOME, "Library", "LaunchAgents");
616
- fs.mkdirSync(plistDir, { recursive: true });
617
- const plistPath = path.join(plistDir, `${label}.plist`);
618
- const localCli = path.join("node_modules", "engine7", "dist", "cli.mjs");
619
- const cliMjs = fs.existsSync(localCli) ? path.resolve(localCli) : path.join(path.dirname(path.dirname(engine7Bin)), "lib", "node_modules", "engine7", "dist", "cli.mjs");
1152
+ const plistDir = path2.join(process.env.HOME, "Library", "LaunchAgents");
1153
+ fs2.mkdirSync(plistDir, { recursive: true });
1154
+ const plistPath = path2.join(plistDir, `${label}.plist`);
1155
+ const localCli = path2.join("node_modules", "engine7", "dist", "cli.mjs");
1156
+ const cliMjs = fs2.existsSync(localCli) ? path2.resolve(localCli) : path2.join(path2.dirname(path2.dirname(engine7Bin)), "lib", "node_modules", "engine7", "dist", "cli.mjs");
620
1157
  const plist = `<?xml version="1.0" encoding="UTF-8"?>
621
1158
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
622
1159
  <plist version="1.0">
@@ -628,16 +1165,16 @@ cd /d "${cwd}"\r
628
1165
  <string>${cliMjs}</string>
629
1166
  <string>start</string>
630
1167
  <string>--config</string>
631
- <string>${path.resolve(configPath2)}</string>
1168
+ <string>${path2.resolve(configPath2)}</string>
632
1169
  </array>
633
1170
  <key>WorkingDirectory</key><string>${cwd}</string>
634
1171
  <key>RunAtLoad</key><true/>
635
1172
  <key>KeepAlive</key><true/>
636
1173
  </dict>
637
1174
  </plist>`;
638
- fs.writeFileSync(plistPath, plist);
1175
+ fs2.writeFileSync(plistPath, plist);
639
1176
  try {
640
- execSync(`launchctl load "${plistPath}"`, { stdio: "inherit" });
1177
+ execSync2(`launchctl load "${plistPath}"`, { stdio: "inherit" });
641
1178
  console.log(`\u2705 Mac launchd \u670D\u52A1\u5DF2\u521B\u5EFA\uFF08\u5F00\u673A\u81EA\u542F\u52A8\uFF09`);
642
1179
  console.log(` ${plistPath}`);
643
1180
  } catch {
@@ -646,9 +1183,9 @@ cd /d "${cwd}"\r
646
1183
  }
647
1184
  } else {
648
1185
  const svcName = "engine7";
649
- const svcDir = path.join(process.env.HOME, ".config", "systemd", "user");
650
- fs.mkdirSync(svcDir, { recursive: true });
651
- const svcPath = path.join(svcDir, `${svcName}.service`);
1186
+ const svcDir = path2.join(process.env.HOME, ".config", "systemd", "user");
1187
+ fs2.mkdirSync(svcDir, { recursive: true });
1188
+ const svcPath = path2.join(svcDir, `${svcName}.service`);
652
1189
  const svc = `[Unit]
653
1190
  Description=Engine 7 Agent
654
1191
  After=network.target
@@ -656,16 +1193,16 @@ After=network.target
656
1193
  [Service]
657
1194
  Type=simple
658
1195
  WorkingDirectory=${cwd}
659
- ExecStart=${process.execPath} ${engine7Bin} start --config ${path.resolve(configPath2)}
1196
+ ExecStart=${process.execPath} ${engine7Bin} start --config ${path2.resolve(configPath2)}
660
1197
  Restart=on-failure
661
1198
  RestartSec=10
662
1199
 
663
1200
  [Install]
664
1201
  WantedBy=default.target`;
665
- fs.writeFileSync(svcPath, svc);
1202
+ fs2.writeFileSync(svcPath, svc);
666
1203
  try {
667
- execSync(`systemctl --user daemon-reload`, { stdio: "inherit" });
668
- execSync(`systemctl --user enable ${svcName}`, { stdio: "inherit" });
1204
+ execSync2(`systemctl --user daemon-reload`, { stdio: "inherit" });
1205
+ execSync2(`systemctl --user enable ${svcName}`, { stdio: "inherit" });
669
1206
  console.log(`\u2705 systemd \u7528\u6237\u670D\u52A1\u5DF2\u521B\u5EFA\uFF08\u5F00\u673A\u81EA\u542F\u52A8\uFF09`);
670
1207
  console.log(` ${svcPath}`);
671
1208
  } catch {
@@ -676,35 +1213,35 @@ WantedBy=default.target`;
676
1213
  } else if (action === "uninstall") {
677
1214
  if (process.platform === "win32") {
678
1215
  try {
679
- execSync(`schtasks /delete /tn "Engine7" /f`, { stdio: "inherit", shell: true });
1216
+ execSync2(`schtasks /delete /tn "Engine7" /f`, { stdio: "inherit", shell: true });
680
1217
  console.log(`\u2705 Windows \u8BA1\u5212\u4EFB\u52A1\u5DF2\u5220\u9664`);
681
1218
  } catch {
682
1219
  console.error("\u274C \u5220\u9664\u5931\u8D25\uFF0C\u4EFB\u52A1\u53EF\u80FD\u4E0D\u5B58\u5728");
683
1220
  process.exit(1);
684
1221
  }
685
1222
  } else if (process.platform === "darwin") {
686
- const plistPath = path.join(process.env.HOME, "Library", "LaunchAgents", "com.engine7.agent.plist");
1223
+ const plistPath = path2.join(process.env.HOME, "Library", "LaunchAgents", "com.engine7.agent.plist");
687
1224
  try {
688
- execSync(`launchctl unload "${plistPath}"`, { stdio: "inherit" });
1225
+ execSync2(`launchctl unload "${plistPath}"`, { stdio: "inherit" });
689
1226
  } catch {
690
1227
  }
691
1228
  try {
692
- fs.unlinkSync(plistPath);
1229
+ fs2.unlinkSync(plistPath);
693
1230
  } catch {
694
1231
  }
695
1232
  console.log(`\u2705 Mac launchd \u670D\u52A1\u5DF2\u5220\u9664`);
696
1233
  } else {
697
1234
  try {
698
- execSync(`systemctl --user disable engine7`, { stdio: "inherit" });
1235
+ execSync2(`systemctl --user disable engine7`, { stdio: "inherit" });
699
1236
  } catch {
700
1237
  }
701
- const svcPath = path.join(process.env.HOME, ".config", "systemd", "user", "engine7.service");
1238
+ const svcPath = path2.join(process.env.HOME, ".config", "systemd", "user", "engine7.service");
702
1239
  try {
703
- fs.unlinkSync(svcPath);
1240
+ fs2.unlinkSync(svcPath);
704
1241
  } catch {
705
1242
  }
706
1243
  try {
707
- execSync(`systemctl --user daemon-reload`, { stdio: "inherit" });
1244
+ execSync2(`systemctl --user daemon-reload`, { stdio: "inherit" });
708
1245
  } catch {
709
1246
  }
710
1247
  console.log(`\u2705 systemd \u7528\u6237\u670D\u52A1\u5DF2\u5220\u9664`);
@@ -712,20 +1249,20 @@ WantedBy=default.target`;
712
1249
  } else if (action === "status") {
713
1250
  if (process.platform === "win32") {
714
1251
  try {
715
- execSync(`schtasks /query /tn "Engine7"`, { stdio: "inherit", shell: true });
1252
+ execSync2(`schtasks /query /tn "Engine7"`, { stdio: "inherit", shell: true });
716
1253
  } catch {
717
1254
  console.log("\u274C \u672A\u5B89\u88C5");
718
1255
  }
719
1256
  } else if (process.platform === "darwin") {
720
- const plistPath = path.join(process.env.HOME, "Library", "LaunchAgents", "com.engine7.agent.plist");
721
- if (fs.existsSync(plistPath)) {
1257
+ const plistPath = path2.join(process.env.HOME, "Library", "LaunchAgents", "com.engine7.agent.plist");
1258
+ if (fs2.existsSync(plistPath)) {
722
1259
  console.log("\u2705 \u5DF2\u5B89\u88C5\uFF08launchd\uFF09");
723
1260
  } else {
724
1261
  console.log("\u274C \u672A\u5B89\u88C5");
725
1262
  }
726
1263
  } else {
727
1264
  try {
728
- execSync(`systemctl --user is-enabled engine7`, { stdio: "inherit" });
1265
+ execSync2(`systemctl --user is-enabled engine7`, { stdio: "inherit" });
729
1266
  } catch {
730
1267
  console.log("\u274C \u672A\u5B89\u88C5");
731
1268
  }
@@ -741,8 +1278,8 @@ WantedBy=default.target`;
741
1278
  console.log(`
742
1279
  \u{1F680} engine7 init`);
743
1280
  console.log(` state-dir: ${opts.stateDir}`);
744
- if (fs.existsSync(opts.stateDir) && !opts.dryRun) {
745
- const files = fs.readdirSync(opts.stateDir);
1281
+ if (fs2.existsSync(opts.stateDir) && !opts.dryRun) {
1282
+ const files = fs2.readdirSync(opts.stateDir);
746
1283
  if (files.length > 0) {
747
1284
  console.error(`
748
1285
  \u274C \u76EE\u5F55\u5DF2\u5B58\u5728\u4E14\u975E\u7A7A: ${opts.stateDir}`);
@@ -760,7 +1297,7 @@ WantedBy=default.target`;
760
1297
  rl.close();
761
1298
  }
762
1299
  const config = generateConfig(values);
763
- const configPath = path.join(opts.stateDir, "configs", "main7.json");
1300
+ const configPath = path2.join(opts.stateDir, "configs", "main7.json");
764
1301
  const tree = buildDirTree(values);
765
1302
  tree.push({
766
1303
  path: configPath,
@@ -771,9 +1308,9 @@ WantedBy=default.target`;
771
1308
  dryRun(tree);
772
1309
  const skillsSrc = findTemplateDir("skills");
773
1310
  if (skillsSrc) {
774
- const skills = fs.readdirSync(skillsSrc);
1311
+ const skills = fs2.readdirSync(skillsSrc);
775
1312
  for (const s of skills) {
776
- console.log(` \u{1F4C1} ${path.join(opts.stateDir, "workspace", "skills", s)}`);
1313
+ console.log(` \u{1F4C1} ${path2.join(opts.stateDir, "workspace", "skills", s)}`);
777
1314
  }
778
1315
  }
779
1316
  } else {
@@ -781,55 +1318,55 @@ WantedBy=default.target`;
781
1318
  execute(tree);
782
1319
  const skillsSrc = findTemplateDir("skills");
783
1320
  if (skillsSrc) {
784
- const skillsDest = path.join(opts.stateDir, "workspace", "skills");
785
- fs.mkdirSync(skillsDest, { recursive: true });
786
- const skills = fs.readdirSync(skillsSrc);
1321
+ const skillsDest = path2.join(opts.stateDir, "workspace", "skills");
1322
+ fs2.mkdirSync(skillsDest, { recursive: true });
1323
+ const skills = fs2.readdirSync(skillsSrc);
787
1324
  for (const s of skills) {
788
- copyDirRecursive(path.join(skillsSrc, s), path.join(skillsDest, s));
1325
+ copyDirRecursive(path2.join(skillsSrc, s), path2.join(skillsDest, s));
789
1326
  console.log(` \u{1F4E6} skill: ${s}`);
790
1327
  }
791
1328
  }
792
1329
  console.log(`
793
1330
  \u2705 \u521D\u59CB\u5316\u5B8C\u6210\uFF01
794
1331
  `);
795
- const homePointer = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7.json");
1332
+ const homePointer = path2.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7.json");
796
1333
  const pointerData = { stateDir: opts.stateDir };
797
- fs.writeFileSync(homePointer, JSON.stringify(pointerData, null, 2) + "\n");
1334
+ fs2.writeFileSync(homePointer, JSON.stringify(pointerData, null, 2) + "\n");
798
1335
  console.log(` \u{1F4C4} ${homePointer}\uFF08\u4ECE\u4EFB\u610F\u76EE\u5F55\u90FD\u80FD\u627E\u5230\u6B64 agent\uFF09`);
799
1336
  console.log(`\u4E0B\u4E00\u6B65\uFF1A`);
800
1337
  console.log(` 1. \u68C0\u67E5\u5E76\u4FEE\u6539 ${opts.stateDir}/configs/main7.json`);
801
1338
  console.log(` 2. \u542F\u52A8 Engine: engine7 start\uFF08\u5728\u4EFB\u610F\u76EE\u5F55\u90FD\u884C\uFF09`);
802
1339
  console.log(` 3. \u5F00\u673A\u81EA\u542F: engine7 service install\uFF08\u5728\u4EFB\u610F\u76EE\u5F55\u90FD\u884C\uFF09`);
803
- console.log(` 4. \u67E5\u770B workspace: ${path.join(opts.stateDir, "workspace")}`);
1340
+ console.log(` 4. \u67E5\u770B workspace: ${path2.join(opts.stateDir, "workspace")}`);
804
1341
  }
805
1342
  }
806
1343
  function copyDirRecursive(src, dest) {
807
- fs.mkdirSync(dest, { recursive: true });
808
- for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
809
- const srcPath = path.join(src, entry.name);
810
- const destPath = path.join(dest, entry.name);
1344
+ fs2.mkdirSync(dest, { recursive: true });
1345
+ for (const entry of fs2.readdirSync(src, { withFileTypes: true })) {
1346
+ const srcPath = path2.join(src, entry.name);
1347
+ const destPath = path2.join(dest, entry.name);
811
1348
  if (entry.isDirectory()) {
812
1349
  copyDirRecursive(srcPath, destPath);
813
1350
  } else {
814
- fs.copyFileSync(srcPath, destPath);
1351
+ fs2.copyFileSync(srcPath, destPath);
815
1352
  }
816
1353
  }
817
1354
  }
818
1355
  function findTemplateDir(name) {
819
1356
  const candidates = [
820
- path.join(__dirname, "..", "templates", name),
821
- path.join(__dirname, "..", "..", "templates", name),
822
- path.join(process.cwd(), "templates", name)
1357
+ path2.join(__dirname, "..", "templates", name),
1358
+ path2.join(__dirname, "..", "..", "templates", name),
1359
+ path2.join(process.cwd(), "templates", name)
823
1360
  ];
824
1361
  for (const p of candidates) {
825
- if (fs.existsSync(p)) return p;
1362
+ if (fs2.existsSync(p)) return p;
826
1363
  }
827
1364
  return null;
828
1365
  }
829
1366
  function readHomePointer() {
830
- const ptrPath = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7.json");
1367
+ const ptrPath = path2.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7.json");
831
1368
  try {
832
- return JSON.parse(fs.readFileSync(ptrPath, "utf-8"));
1369
+ return JSON.parse(fs2.readFileSync(ptrPath, "utf-8"));
833
1370
  } catch {
834
1371
  return null;
835
1372
  }