@okclaw-build/cli 1.0.0-beta.5 → 1.0.0-beta.52

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 (88) hide show
  1. package/dist/commands/backup.d.ts +16 -0
  2. package/dist/commands/backup.js +80 -0
  3. package/dist/commands/backup.js.map +1 -0
  4. package/dist/commands/check.js +22 -6
  5. package/dist/commands/check.js.map +1 -1
  6. package/dist/commands/edit.d.ts +2 -7
  7. package/dist/commands/edit.js +27 -15
  8. package/dist/commands/edit.js.map +1 -1
  9. package/dist/commands/feed.js +63 -19
  10. package/dist/commands/feed.js.map +1 -1
  11. package/dist/commands/install.js +79 -18
  12. package/dist/commands/install.js.map +1 -1
  13. package/dist/commands/migration.d.ts +1 -0
  14. package/dist/commands/migration.js +205 -0
  15. package/dist/commands/migration.js.map +1 -0
  16. package/dist/commands/restore.d.ts +16 -0
  17. package/dist/commands/restore.js +75 -0
  18. package/dist/commands/restore.js.map +1 -0
  19. package/dist/commands/service.js +56 -13
  20. package/dist/commands/service.js.map +1 -1
  21. package/dist/commands/show.d.ts +13 -0
  22. package/dist/commands/show.js +70 -0
  23. package/dist/commands/show.js.map +1 -0
  24. package/dist/commands/skill.d.ts +1 -0
  25. package/dist/commands/skill.js +137 -0
  26. package/dist/commands/skill.js.map +1 -0
  27. package/dist/commands/uninstall.d.ts +1 -0
  28. package/dist/commands/uninstall.js +46 -0
  29. package/dist/commands/uninstall.js.map +1 -0
  30. package/dist/index.js +102 -9
  31. package/dist/index.js.map +1 -1
  32. package/dist/installers/base.d.ts +3 -1
  33. package/dist/installers/channel.d.ts +19 -3
  34. package/dist/installers/channel.js +170 -30
  35. package/dist/installers/channel.js.map +1 -1
  36. package/dist/installers/openclaw.d.ts +10 -2
  37. package/dist/installers/openclaw.js +154 -52
  38. package/dist/installers/openclaw.js.map +1 -1
  39. package/dist/installers/openviking-purge.d.ts +52 -0
  40. package/dist/installers/openviking-purge.js +380 -0
  41. package/dist/installers/openviking-purge.js.map +1 -0
  42. package/dist/installers/openviking.js +1 -2
  43. package/dist/installers/openviking.js.map +1 -1
  44. package/dist/installers/skill.d.ts +5 -2
  45. package/dist/installers/skill.js +67 -18
  46. package/dist/installers/skill.js.map +1 -1
  47. package/dist/migration/archive.d.ts +14 -0
  48. package/dist/migration/archive.js +84 -0
  49. package/dist/migration/archive.js.map +1 -0
  50. package/dist/migration/crypto.d.ts +16 -0
  51. package/dist/migration/crypto.js +56 -0
  52. package/dist/migration/crypto.js.map +1 -0
  53. package/dist/migration/manifest.d.ts +39 -0
  54. package/dist/migration/manifest.js +140 -0
  55. package/dist/migration/manifest.js.map +1 -0
  56. package/dist/openclaw-user-data.d.ts +81 -0
  57. package/dist/openclaw-user-data.js +411 -0
  58. package/dist/openclaw-user-data.js.map +1 -0
  59. package/dist/output/mode.d.ts +11 -0
  60. package/dist/output/mode.js +27 -0
  61. package/dist/output/mode.js.map +1 -0
  62. package/dist/output/ndjson.d.ts +57 -0
  63. package/dist/output/ndjson.js +136 -0
  64. package/dist/output/ndjson.js.map +1 -0
  65. package/dist/utils/constants.d.ts +8 -13
  66. package/dist/utils/constants.js +31 -20
  67. package/dist/utils/constants.js.map +1 -1
  68. package/dist/utils/deps.d.ts +34 -3
  69. package/dist/utils/deps.js +62 -100
  70. package/dist/utils/deps.js.map +1 -1
  71. package/dist/utils/install-safety.d.ts +25 -0
  72. package/dist/utils/install-safety.js +95 -0
  73. package/dist/utils/install-safety.js.map +1 -0
  74. package/dist/utils/logger.d.ts +10 -0
  75. package/dist/utils/logger.js +31 -4
  76. package/dist/utils/logger.js.map +1 -1
  77. package/dist/utils/mirror.js +14 -0
  78. package/dist/utils/mirror.js.map +1 -1
  79. package/dist/utils/openclaw-config-cli.d.ts +19 -0
  80. package/dist/utils/openclaw-config-cli.js +81 -0
  81. package/dist/utils/openclaw-config-cli.js.map +1 -0
  82. package/dist/utils/openclaw-daemon.d.ts +58 -0
  83. package/dist/utils/openclaw-daemon.js +154 -0
  84. package/dist/utils/openclaw-daemon.js.map +1 -0
  85. package/dist/utils/shell.d.ts +23 -2
  86. package/dist/utils/shell.js +138 -5
  87. package/dist/utils/shell.js.map +1 -1
  88. package/package.json +5 -4
@@ -0,0 +1,205 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync, } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { dirname, join } from 'node:path';
5
+ import { ARCHIVE_MANIFEST_NAME, buildCreateEncryptedArchiveCommand, buildDecryptArchiveCommand, buildTarCommand, buildTarCreateArgs, buildTarExtractArgs, buildTarExtractManifestArgs, buildTarListArgs, validateTarEntries, } from '../migration/archive.js';
6
+ import { buildMigrationManifest, existingManifestPaths, validateMigrationManifest, } from '../migration/manifest.js';
7
+ import { assertAgeIdentityContent, assertAgeRecipientContent, assertAuthenticatedEncryptionAvailable, } from '../migration/crypto.js';
8
+ import { NdjsonEmitter, registerExitHandlers } from '../output/ndjson.js';
9
+ import { error, info, success } from '../utils/logger.js';
10
+ import { commandExists, shell, shellCapture } from '../utils/shell.js';
11
+ export async function migrationCommand(args) {
12
+ const emitter = new NdjsonEmitter('migration');
13
+ registerExitHandlers(emitter);
14
+ let parsed;
15
+ try {
16
+ parsed = parseMigrationArgs(args);
17
+ }
18
+ catch (e) {
19
+ const msg = e instanceof Error ? e.message : String(e);
20
+ error(msg);
21
+ emitter.end(false, 1, 'E_USAGE', { error: msg });
22
+ process.exit(1);
23
+ return;
24
+ }
25
+ emitter.start(`migration ${parsed.action}`, migrationFields('start', `migration ${parsed.action}`, {
26
+ taskId: parsed.taskId,
27
+ shrimpId: parsed.shrimpId,
28
+ sourceHostId: parsed.sourceHostId,
29
+ targetHostId: parsed.targetHostId,
30
+ }));
31
+ try {
32
+ switch (parsed.action) {
33
+ case 'export':
34
+ await exportRuntime(parsed, emitter);
35
+ break;
36
+ case 'restore':
37
+ await restoreRuntime(parsed, emitter);
38
+ break;
39
+ case 'verify':
40
+ verifyManifest(parsed, emitter);
41
+ break;
42
+ }
43
+ emitter.end(true, 0, undefined, { taskId: parsed.taskId, action: parsed.action });
44
+ }
45
+ catch (e) {
46
+ const msg = e instanceof Error ? e.message : String(e);
47
+ error(msg);
48
+ emitter.end(false, 1, 'E_MIGRATION_FAILED', { error: msg, taskId: parsed.taskId, action: parsed.action });
49
+ process.exit(1);
50
+ }
51
+ }
52
+ async function exportRuntime(args, emitter) {
53
+ if (!args.out || !args.keyFile)
54
+ throw new Error('export requires --out and --key-file');
55
+ await assertRequiredTools(['tar']);
56
+ await assertAuthenticatedEncryptionAvailable();
57
+ assertAgeRecipientContent(readFileSync(args.keyFile, 'utf8'), args.keyFile);
58
+ const workDir = mkdtempSync(join(tmpdir(), 'okclaw-migration-export-'));
59
+ const tarPath = join(workDir, 'runtime.tar');
60
+ const manifestPath = join(workDir, ARCHIVE_MANIFEST_NAME);
61
+ try {
62
+ emitter.stepStart('manifest', 'building migration manifest', migrationFields('manifest', 'building migration manifest'));
63
+ const manifest = buildMigrationManifest(identityFromArgs(args));
64
+ writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
65
+ emitter.stepDone('manifest', 'migration manifest built', migrationFields('manifest', 'migration manifest built', {
66
+ missingPaths: manifest.missingPaths,
67
+ }));
68
+ emitter.stepStart('archive', 'creating runtime tar archive', migrationFields('archive', 'creating runtime tar archive'));
69
+ await shell(buildTarCommand(buildTarCreateArgs({
70
+ tarPath,
71
+ manifestPath,
72
+ existingIncludePaths: existingManifestPaths(manifest),
73
+ })));
74
+ emitter.stepDone('archive', 'runtime tar archive created', migrationFields('archive', 'runtime tar archive created'));
75
+ mkdirSync(dirname(args.out), { recursive: true });
76
+ emitter.stepStart('encrypt', 'encrypting runtime archive with age', migrationFields('encrypt', 'encrypting runtime archive'));
77
+ await shell(buildCreateEncryptedArchiveCommand(args.keyFile, tarPath, args.out));
78
+ emitter.stepDone('encrypt', 'encrypted runtime archive created', migrationFields('encrypt', 'encrypted runtime archive created', {
79
+ sha256: sha256File(args.out),
80
+ archive: args.out,
81
+ }));
82
+ success(`Migration archive exported: ${args.out}`);
83
+ }
84
+ finally {
85
+ rmSync(workDir, { recursive: true, force: true });
86
+ }
87
+ }
88
+ async function restoreRuntime(args, emitter) {
89
+ if (!args.archive || !args.keyFile)
90
+ throw new Error('restore requires --archive and --key-file');
91
+ await assertRequiredTools(['tar']);
92
+ await assertAuthenticatedEncryptionAvailable();
93
+ if (!existsSync(args.archive))
94
+ throw new Error(`Archive not found: ${args.archive}`);
95
+ assertAgeIdentityContent(readFileSync(args.keyFile, 'utf8'), args.keyFile);
96
+ const workDir = mkdtempSync(join(tmpdir(), 'okclaw-migration-restore-'));
97
+ const tarPath = join(workDir, 'runtime.tar');
98
+ try {
99
+ emitter.stepStart('decrypt', 'decrypting runtime archive with age', migrationFields('decrypt', 'decrypting runtime archive'));
100
+ await shell(buildDecryptArchiveCommand(args.keyFile, args.archive, tarPath));
101
+ emitter.stepDone('decrypt', 'runtime archive decrypted', migrationFields('decrypt', 'runtime archive decrypted'));
102
+ emitter.stepStart('manifest', 'validating migration manifest', migrationFields('manifest', 'validating migration manifest'));
103
+ await shell(buildTarCommand(buildTarExtractManifestArgs(tarPath, workDir)));
104
+ const manifest = validateMigrationManifest(JSON.parse(readFileSync(join(workDir, ARCHIVE_MANIFEST_NAME), 'utf8')), identityFromArgs(args));
105
+ emitter.stepDone('manifest', 'migration manifest validated', migrationFields('manifest', 'migration manifest validated'));
106
+ emitter.stepStart('archive-safety', 'validating archive entry paths', migrationFields('archive-safety', 'validating archive entry paths'));
107
+ const listing = await shellCapture(buildTarCommand(buildTarListArgs(tarPath)));
108
+ if (listing.code !== 0)
109
+ throw new Error(`Unable to list migration archive: ${listing.stderr}`);
110
+ validateTarEntries(listing.stdout.split(/\r?\n/), existingManifestPaths(manifest));
111
+ emitter.stepDone('archive-safety', 'archive entries validated', migrationFields('archive-safety', 'archive entries validated'));
112
+ emitter.stepStart('restore', 'restoring runtime files', migrationFields('restore', 'restoring runtime files'));
113
+ await shell(buildTarCommand(buildTarExtractArgs(tarPath)));
114
+ emitter.stepDone('restore', 'runtime files restored', migrationFields('restore', 'runtime files restored'));
115
+ success(`Migration archive restored: ${args.archive}`);
116
+ }
117
+ finally {
118
+ rmSync(workDir, { recursive: true, force: true });
119
+ }
120
+ }
121
+ function verifyManifest(args, emitter) {
122
+ if (!args.manifest)
123
+ throw new Error('verify requires --manifest');
124
+ emitter.stepStart('verify', 'validating migration manifest', migrationFields('verify', 'validating migration manifest'));
125
+ const manifest = validateMigrationManifest(JSON.parse(readFileSync(args.manifest, 'utf8')), identityFromArgs(args));
126
+ emitter.stepDone('verify', 'migration manifest valid', migrationFields('verify', 'migration manifest valid', {
127
+ missingPaths: manifest.missingPaths,
128
+ }));
129
+ info('Migration manifest is valid.');
130
+ }
131
+ function parseMigrationArgs(args) {
132
+ const action = args[0];
133
+ if (action !== 'export' && action !== 'restore' && action !== 'verify') {
134
+ throw new Error('Usage: okclaw migration <export|restore|verify> --task-id <id> --shrimp-id <id> --source-host-id <id> --target-host-id <id>');
135
+ }
136
+ const flags = parseFlags(args.slice(1));
137
+ const parsed = {
138
+ action,
139
+ taskId: requireFlag(flags, 'task-id'),
140
+ shrimpId: requireFlag(flags, 'shrimp-id'),
141
+ sourceHostId: requireFlag(flags, 'source-host-id'),
142
+ targetHostId: requireFlag(flags, 'target-host-id'),
143
+ out: flags.get('out'),
144
+ archive: flags.get('archive'),
145
+ keyFile: flags.get('key-file'),
146
+ manifest: flags.get('manifest'),
147
+ };
148
+ if (action === 'export' && (!parsed.out || !parsed.keyFile)) {
149
+ throw new Error('Usage: okclaw migration export --task-id <id> --shrimp-id <id> --source-host-id <id> --target-host-id <id> --out <archive> --key-file <key>');
150
+ }
151
+ if (action === 'restore' && (!parsed.archive || !parsed.keyFile)) {
152
+ throw new Error('Usage: okclaw migration restore --task-id <id> --shrimp-id <id> --source-host-id <id> --target-host-id <id> --archive <archive> --key-file <key>');
153
+ }
154
+ if (action === 'verify' && !parsed.manifest) {
155
+ throw new Error('Usage: okclaw migration verify --task-id <id> --shrimp-id <id> --source-host-id <id> --target-host-id <id> --manifest <manifest>');
156
+ }
157
+ return parsed;
158
+ }
159
+ function parseFlags(args) {
160
+ const flags = new Map();
161
+ for (let i = 0; i < args.length; i++) {
162
+ const arg = args[i];
163
+ if (!arg.startsWith('--'))
164
+ throw new Error(`Unexpected argument: ${arg}`);
165
+ const withoutPrefix = arg.slice(2);
166
+ const eq = withoutPrefix.indexOf('=');
167
+ if (eq >= 0) {
168
+ flags.set(withoutPrefix.slice(0, eq), withoutPrefix.slice(eq + 1));
169
+ continue;
170
+ }
171
+ const value = args[++i];
172
+ if (!value || value.startsWith('--'))
173
+ throw new Error(`Missing value for --${withoutPrefix}`);
174
+ flags.set(withoutPrefix, value);
175
+ }
176
+ return flags;
177
+ }
178
+ function requireFlag(flags, name) {
179
+ const value = flags.get(name);
180
+ if (!value)
181
+ throw new Error(`--${name} is required`);
182
+ return value;
183
+ }
184
+ function identityFromArgs(args) {
185
+ return {
186
+ taskId: args.taskId,
187
+ shrimpId: args.shrimpId,
188
+ sourceHostId: args.sourceHostId,
189
+ targetHostId: args.targetHostId,
190
+ };
191
+ }
192
+ async function assertRequiredTools(commands) {
193
+ for (const command of commands) {
194
+ if (!await commandExists(command)) {
195
+ throw new Error(`Missing required command: ${command}`);
196
+ }
197
+ }
198
+ }
199
+ function migrationFields(phase, message, data = {}) {
200
+ return { phase, message, data };
201
+ }
202
+ function sha256File(path) {
203
+ return createHash('sha256').update(readFileSync(path)).digest('hex');
204
+ }
205
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/commands/migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { restoreOpenclawUserDataArchive } from '../openclaw-user-data.js';
2
+ type RestoreEvent = {
3
+ ok: boolean;
4
+ code: string;
5
+ message: string;
6
+ stagingDir?: string;
7
+ archivePath?: string;
8
+ restoredFiles?: string[];
9
+ error?: string;
10
+ };
11
+ export type RestoreCommandDeps = {
12
+ restoreArchive?: typeof restoreOpenclawUserDataArchive;
13
+ emit?: (event: RestoreEvent) => void;
14
+ };
15
+ export declare function restoreCommand(args: string[], deps?: RestoreCommandDeps): Promise<void>;
16
+ export {};
@@ -0,0 +1,75 @@
1
+ import { error, info } from '../utils/logger.js';
2
+ import { restoreOpenclawUserDataArchive } from '../openclaw-user-data.js';
3
+ export async function restoreCommand(args, deps = {}) {
4
+ const parsed = parseRestoreArgs(args);
5
+ const emit = deps.emit ?? defaultEmit;
6
+ const restoreArchive = deps.restoreArchive ?? restoreOpenclawUserDataArchive;
7
+ if (parsed.target !== 'openclaw-user-data' || !parsed.archivePath) {
8
+ error('Usage: okclaw restore openclaw-user-data --archive <path> [--include-workspace-extra] [--output=ndjson]');
9
+ process.exit(1);
10
+ }
11
+ try {
12
+ const result = await restoreArchive({
13
+ archivePath: parsed.archivePath,
14
+ includeWorkspaceExtra: parsed.includeWorkspaceExtra,
15
+ });
16
+ emit({
17
+ ok: true,
18
+ code: 'OK',
19
+ message: 'openclaw user data restored',
20
+ stagingDir: result.stagingDir,
21
+ archivePath: result.archivePath,
22
+ restoredFiles: result.restoredFiles,
23
+ });
24
+ if (!parsed.ndjson) {
25
+ info(`Restored openclaw user data from ${result.archivePath}`);
26
+ }
27
+ }
28
+ catch (e) {
29
+ const err = e;
30
+ emit({
31
+ ok: false,
32
+ code: 'E_RESTORE_FAILED',
33
+ message: 'openclaw user data restore failed',
34
+ stagingDir: err.stagingDir,
35
+ archivePath: err.archivePath ?? parsed.archivePath,
36
+ error: err.message,
37
+ });
38
+ throw e;
39
+ }
40
+ }
41
+ function parseRestoreArgs(args) {
42
+ let target;
43
+ let archivePath;
44
+ let includeWorkspaceExtra = false;
45
+ let ndjson = false;
46
+ for (let i = 0; i < args.length; i++) {
47
+ const arg = args[i];
48
+ if (!target && !arg.startsWith('--')) {
49
+ target = arg;
50
+ continue;
51
+ }
52
+ if (arg === '--archive' && args[i + 1]) {
53
+ archivePath = args[++i];
54
+ continue;
55
+ }
56
+ if (arg.startsWith('--archive=')) {
57
+ archivePath = arg.slice('--archive='.length);
58
+ continue;
59
+ }
60
+ if (arg === '--include-workspace-extra') {
61
+ includeWorkspaceExtra = true;
62
+ continue;
63
+ }
64
+ if (arg === '--output=ndjson' || (arg === '--output' && args[i + 1] === 'ndjson')) {
65
+ ndjson = true;
66
+ if (arg === '--output')
67
+ i += 1;
68
+ }
69
+ }
70
+ return { target, archivePath, includeWorkspaceExtra, ndjson };
71
+ }
72
+ function defaultEmit(event) {
73
+ process.stdout.write(JSON.stringify(event) + '\n');
74
+ }
75
+ //# sourceMappingURL=restore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restore.js","sourceRoot":"","sources":["../../src/commands/restore.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,66 @@
1
- import { shell, shellCapture } from '../utils/shell.js';
2
1
  import { info, success } from '../utils/logger.js';
3
- import { OPENVIKING_ENV } from '../utils/constants.js';
2
+ import { NdjsonEmitter, registerExitHandlers } from '../output/ndjson.js';
3
+ import { isNdjson } from '../output/mode.js';
4
+ import { OPENCLAW_GATEWAY_PORT } from '../utils/constants.js';
5
+ import { startGateway, stopGateway, restartGateway, probeGatewayState } from '../utils/openclaw-daemon.js';
6
+ async function runSimpleOp(op, step, humanVerb, action) {
7
+ const emitter = new NdjsonEmitter(op);
8
+ registerExitHandlers(emitter);
9
+ emitter.start(`${humanVerb} gateway`);
10
+ info(`${humanVerb} openclaw gateway...`);
11
+ try {
12
+ emitter.stepStart(step, `${humanVerb} gateway`);
13
+ await action();
14
+ emitter.stepDone(step, 'done');
15
+ success(`Gateway ${step}ed.`);
16
+ emitter.end(true, 0);
17
+ }
18
+ catch (e) {
19
+ const msg = e instanceof Error ? e.message : String(e);
20
+ emitter.end(false, 1, `E_${op.toUpperCase()}_FAILED`, { error: msg });
21
+ throw e;
22
+ }
23
+ }
4
24
  export async function startCommand() {
5
- info('Starting openclaw gateway...');
6
- await shell(`source ${OPENVIKING_ENV} 2>/dev/null || true; openclaw gateway start`);
7
- success('Gateway started.');
25
+ await runSimpleOp('start', 'start', 'Starting', startGateway);
8
26
  }
9
27
  export async function stopCommand() {
10
- info('Stopping openclaw gateway...');
11
- await shell('openclaw gateway stop 2>/dev/null || true');
12
- success('Gateway stopped.');
28
+ await runSimpleOp('stop', 'stop', 'Stopping', stopGateway);
13
29
  }
14
30
  export async function restartCommand() {
15
- info('Restarting openclaw gateway...');
16
- await shell(`source ${OPENVIKING_ENV} 2>/dev/null || true; openclaw gateway restart`);
17
- success('Gateway restarted.');
31
+ await runSimpleOp('restart', 'restart', 'Restarting', restartGateway);
18
32
  }
19
33
  export async function statusCommand() {
20
- const result = await shellCapture('openclaw gateway status 2>&1 || true');
21
- console.log(result.stdout || result.stderr || 'No output');
34
+ const emitter = new NdjsonEmitter('status');
35
+ registerExitHandlers(emitter);
36
+ emitter.start('querying gateway status');
37
+ emitter.stepStart('status', 'checking openclaw gateway process');
38
+ try {
39
+ // 健康判定以 18789 端口监听为准 —— systemd 服务 active ≠ 端口已对外服务。
40
+ // probeGatewayState 内含启动窗口的 bounded wait。
41
+ const state = await probeGatewayState();
42
+ const running = state === 'listening';
43
+ const output = state === 'listening'
44
+ ? `Gateway listening on port ${OPENCLAW_GATEWAY_PORT}`
45
+ : state === 'starting'
46
+ ? `Gateway service active but not listening on port ${OPENCLAW_GATEWAY_PORT} (starting/degraded)`
47
+ : `No gateway process found on port ${OPENCLAW_GATEWAY_PORT}`;
48
+ if (!isNdjson()) {
49
+ console.log(output);
50
+ }
51
+ emitter.stepDone('status', 'status query done');
52
+ emitter.end(running, running ? 0 : 1, running ? undefined : state === 'starting' ? 'E_STATUS_DEGRADED' : 'E_STATUS_NOT_RUNNING', { running, state, rawOutput: output });
53
+ // gateway 没真正对外监听时进程退出码也必须非 0 —— os-api 的 bootstrap
54
+ // 「Step 6」和迁移「target:status」都靠 shell 退出码做校验门
55
+ // (`okclaw status || 失败`),只写 ndjson、进程仍 exit 0 会让校验形同虚设。
56
+ if (!running) {
57
+ process.exit(1);
58
+ }
59
+ }
60
+ catch (e) {
61
+ const msg = e instanceof Error ? e.message : String(e);
62
+ emitter.end(false, 1, 'E_STATUS_FAILED', { error: msg });
63
+ throw e;
64
+ }
22
65
  }
23
66
  //# sourceMappingURL=service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/commands/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACrC,MAAM,KAAK,CAAC,UAAU,cAAc,8CAA8C,CAAC,CAAC;IACpF,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACrC,MAAM,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IACvC,MAAM,KAAK,CAAC,UAAU,cAAc,gDAAgD,CAAC,CAAC;IACtF,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,sCAAsC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC;AAC7D,CAAC"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/commands/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE3G,KAAK,UAAU,WAAW,CACxB,EAAU,EACV,IAAY,EACZ,SAAiB,EACjB,MAA2B;IAE3B,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,EAAE,CAAC,CAAC;IACtC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,SAAS,sBAAsB,CAAC,CAAC;IACzC,IAAI,CAAC;QACH,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,SAAS,UAAU,CAAC,CAAC;QAChD,MAAM,MAAM,EAAE,CAAC;QACf,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACtE,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC5C,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACzC,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,mCAAmC,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,qDAAqD;QACrD,0CAA0C;QAC1C,MAAM,KAAK,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,KAAK,KAAK,WAAW,CAAC;QACtC,MAAM,MAAM,GACV,KAAK,KAAK,WAAW;YACnB,CAAC,CAAC,6BAA6B,qBAAqB,EAAE;YACtD,CAAC,CAAC,KAAK,KAAK,UAAU;gBACpB,CAAC,CAAC,oDAAoD,qBAAqB,sBAAsB;gBACjG,CAAC,CAAC,oCAAoC,qBAAqB,EAAE,CAAC;QACpE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CACT,OAAO,EACP,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACf,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,sBAAsB,EACzF,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CACtC,CAAC;QACF,oDAAoD;QACpD,6CAA6C;QAC7C,yDAAyD;QACzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,iBAAiB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * okclaw show <target...>
3
+ *
4
+ * 把 target 对应的文件内容原样输出到 stdout(text 模式);
5
+ * 在 ndjson 模式下,文件内容放到 end 事件的 fields.content(plan 决策 #16)。
6
+ *
7
+ * - 文件存在 → 输出文件内容,exit 0
8
+ * - 文件不存在 → 输出空内容,exit 0(视为尚未创建)
9
+ * - target 非法 → stderr 提示,exit 1
10
+ *
11
+ * `targets` 参数用于测试注入;生产调用不传第二个参数,使用 edit.ts 导出的 TARGETS。
12
+ */
13
+ export declare function showCommand(args: string[], targets?: Record<string, string>): Promise<void>;
@@ -0,0 +1,70 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { error } from '../utils/logger.js';
3
+ import { TARGETS as DEFAULT_TARGETS } from './edit.js';
4
+ import { NdjsonEmitter, registerExitHandlers } from '../output/ndjson.js';
5
+ import { isNdjson } from '../output/mode.js';
6
+ /**
7
+ * okclaw show <target...>
8
+ *
9
+ * 把 target 对应的文件内容原样输出到 stdout(text 模式);
10
+ * 在 ndjson 模式下,文件内容放到 end 事件的 fields.content(plan 决策 #16)。
11
+ *
12
+ * - 文件存在 → 输出文件内容,exit 0
13
+ * - 文件不存在 → 输出空内容,exit 0(视为尚未创建)
14
+ * - target 非法 → stderr 提示,exit 1
15
+ *
16
+ * `targets` 参数用于测试注入;生产调用不传第二个参数,使用 edit.ts 导出的 TARGETS。
17
+ */
18
+ export async function showCommand(args, targets = DEFAULT_TARGETS) {
19
+ const emitter = new NdjsonEmitter('file_read');
20
+ registerExitHandlers(emitter);
21
+ const requestedTargets = args.filter((arg) => !arg.startsWith('--'));
22
+ if (requestedTargets.length === 0 || requestedTargets.some((target) => !targets[target])) {
23
+ error(`Usage: okclaw show <${Object.keys(targets).join('|')}>`);
24
+ emitter.end(false, 1, 'E_USAGE');
25
+ process.exit(1);
26
+ }
27
+ if (!isNdjson() && requestedTargets.length > 1) {
28
+ error('Multiple targets are only supported with --output=ndjson');
29
+ emitter.end(false, 1, 'E_USAGE');
30
+ process.exit(1);
31
+ }
32
+ emitter.start(`reading ${requestedTargets.join(',')}`, { targets: requestedTargets });
33
+ try {
34
+ const files = [];
35
+ for (const target of requestedTargets) {
36
+ const path = targets[target];
37
+ emitter.stepStart(`read:${target}`, `reading ${path}`, { target, path });
38
+ const exists = existsSync(path);
39
+ const content = exists ? readFileSync(path, 'utf8') : '';
40
+ files.push({ fileKey: target, path, exists, content });
41
+ emitter.stepDone(`read:${target}`, exists ? 'read ok' : 'file not found, returning empty');
42
+ }
43
+ if (!isNdjson()) {
44
+ const { exists, content } = files[0];
45
+ if (exists) {
46
+ process.stdout.write(content);
47
+ }
48
+ }
49
+ // 单文件保持 content 兼容;批量读取用 files 数组承载返回值。
50
+ if (requestedTargets.length === 1) {
51
+ const file = files[0];
52
+ emitter.end(true, 0, undefined, {
53
+ target: file.fileKey,
54
+ path: file.path,
55
+ exists: file.exists,
56
+ content: file.content,
57
+ });
58
+ }
59
+ else {
60
+ emitter.end(true, 0, undefined, { files });
61
+ }
62
+ }
63
+ catch (e) {
64
+ const msg = e instanceof Error ? e.message : String(e);
65
+ error(msg);
66
+ emitter.end(false, 1, 'E_READ_FAILED', { error: msg });
67
+ process.exit(1);
68
+ }
69
+ }
70
+ //# sourceMappingURL=show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../../src/commands/show.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function skillCommand(args: string[]): Promise<void>;
@@ -0,0 +1,137 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { SkillInstaller } from '../installers/skill.js';
3
+ import { configureMirrors } from '../utils/mirror.js';
4
+ import { info, error, success } from '../utils/logger.js';
5
+ import { NdjsonEmitter, registerExitHandlers } from '../output/ndjson.js';
6
+ import { assertSafeInstallName, assertSafePackageVersion, parsePackageSource, } from '../utils/install-safety.js';
7
+ export async function skillCommand(args) {
8
+ const subCommand = args[0];
9
+ const skillName = args[1];
10
+ if (!subCommand || !['install', 'uninstall'].includes(subCommand)) {
11
+ const emitter = new NdjsonEmitter('skill_install');
12
+ registerExitHandlers(emitter);
13
+ error('Usage: okclaw skill <install|uninstall> <name> [options]');
14
+ emitter.end(false, 1, 'E_USAGE');
15
+ process.exit(1);
16
+ }
17
+ const op = subCommand === 'install' ? 'skill_install' : 'skill_uninstall';
18
+ const emitter = new NdjsonEmitter(op);
19
+ registerExitHandlers(emitter);
20
+ if (!skillName) {
21
+ error(`Usage: okclaw skill ${subCommand} <name>${subCommand === 'install' ? ' --version <ver> [--package-url <url>]' : ''}`);
22
+ emitter.end(false, 1, 'E_USAGE');
23
+ process.exit(1);
24
+ }
25
+ let safeSkillName;
26
+ try {
27
+ safeSkillName = assertSafeInstallName('skill', skillName);
28
+ }
29
+ catch (e) {
30
+ const msg = e instanceof Error ? e.message : String(e);
31
+ error(msg);
32
+ emitter.end(false, 1, 'E_INVALID_ARGS', { error: msg });
33
+ process.exit(1);
34
+ }
35
+ const installer = new SkillInstaller(safeSkillName);
36
+ if (subCommand === 'uninstall') {
37
+ emitter.start(`uninstalling skill ${safeSkillName}`, { skillName: safeSkillName });
38
+ info(`Uninstalling skill ${safeSkillName}...`);
39
+ try {
40
+ emitter.stepStart('validate', `validating skill name ${safeSkillName}`);
41
+ // installer 内部校验名称,SkillInstaller.uninstall 会在目标不存在时快速返回
42
+ emitter.stepDone('validate', 'skill name ok');
43
+ emitter.stepStart('uninstall', `removing ${safeSkillName}`);
44
+ await installer.uninstall();
45
+ emitter.stepDone('uninstall', 'skill removed');
46
+ success(`Skill ${safeSkillName} uninstalled.`);
47
+ emitter.end(true, 0, undefined, { skillName: safeSkillName });
48
+ }
49
+ catch (e) {
50
+ const msg = e instanceof Error ? e.message : String(e);
51
+ error(msg);
52
+ emitter.end(false, 1, 'E_SKILL_UNINSTALL_FAILED', { error: msg });
53
+ process.exit(1);
54
+ }
55
+ return;
56
+ }
57
+ // install
58
+ let version = '';
59
+ let config;
60
+ let packageUrl;
61
+ for (let i = 2; i < args.length; i++) {
62
+ const arg = args[i];
63
+ if ((arg === '--version' || arg.startsWith('--version=')) && !version) {
64
+ version = arg.includes('=') ? arg.split('=')[1] : args[++i];
65
+ continue;
66
+ }
67
+ if (arg === '--config' && args[i + 1]) {
68
+ try {
69
+ config = JSON.parse(args[++i]);
70
+ }
71
+ catch {
72
+ error('Invalid --config JSON');
73
+ emitter.end(false, 1, 'E_CONFIG_JSON');
74
+ process.exit(1);
75
+ }
76
+ continue;
77
+ }
78
+ if ((arg === '--config-file' || arg.startsWith('--config-file=')) && !config) {
79
+ const filePath = arg.includes('=') ? arg.split('=')[1] : args[++i];
80
+ try {
81
+ config = JSON.parse(readFileSync(filePath, 'utf8'));
82
+ }
83
+ catch (e) {
84
+ error(`Failed to read config file: ${e}`);
85
+ emitter.end(false, 1, 'E_CONFIG_FILE');
86
+ process.exit(1);
87
+ }
88
+ continue;
89
+ }
90
+ if ((arg === '--package-url' || arg.startsWith('--package-url=')) && !packageUrl) {
91
+ packageUrl = arg.includes('=') ? arg.split('=')[1] : args[++i];
92
+ continue;
93
+ }
94
+ }
95
+ if (!version) {
96
+ error('--version is required for install');
97
+ emitter.end(false, 1, 'E_VERSION_REQUIRED');
98
+ process.exit(1);
99
+ }
100
+ let safeVersion;
101
+ let packageSource;
102
+ try {
103
+ safeVersion = assertSafePackageVersion(version);
104
+ packageSource = packageUrl ? parsePackageSource(packageUrl) : undefined;
105
+ }
106
+ catch (e) {
107
+ const msg = e instanceof Error ? e.message : String(e);
108
+ error(msg);
109
+ emitter.end(false, 1, 'E_INVALID_ARGS', { error: msg });
110
+ process.exit(1);
111
+ }
112
+ emitter.start(`installing skill ${safeSkillName}@${safeVersion}`, { skillName: safeSkillName, version: safeVersion });
113
+ info(`Installing skill ${safeSkillName}@${safeVersion}...`);
114
+ try {
115
+ emitter.stepStart('validate', 'validating install args');
116
+ await installer.checkDeps();
117
+ emitter.stepDone('validate', 'args ok, deps ready');
118
+ emitter.stepStart('download', `downloading skill ${safeSkillName}@${safeVersion}`);
119
+ await configureMirrors();
120
+ await installer.install(safeVersion, packageSource);
121
+ emitter.stepDone('download', 'skill downloaded');
122
+ emitter.stepStart('install', `applying skill ${safeSkillName}`);
123
+ if (config) {
124
+ await installer.configure(config);
125
+ }
126
+ emitter.stepDone('install', 'skill installed');
127
+ success(`Skill ${safeSkillName}@${safeVersion} installed.`);
128
+ emitter.end(true, 0, undefined, { skillName: safeSkillName, version: safeVersion });
129
+ }
130
+ catch (e) {
131
+ const msg = e instanceof Error ? e.message : String(e);
132
+ error(msg);
133
+ emitter.end(false, 1, 'E_SKILL_INSTALL_FAILED', { error: msg });
134
+ process.exit(1);
135
+ }
136
+ }
137
+ //# sourceMappingURL=skill.js.map