@cogineai/clawpacker 0.1.0

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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +373 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +22 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/export.d.ts +11 -0
  7. package/dist/commands/export.js +48 -0
  8. package/dist/commands/export.js.map +1 -0
  9. package/dist/commands/import.d.ts +10 -0
  10. package/dist/commands/import.js +51 -0
  11. package/dist/commands/import.js.map +1 -0
  12. package/dist/commands/inspect.d.ts +10 -0
  13. package/dist/commands/inspect.js +80 -0
  14. package/dist/commands/inspect.js.map +1 -0
  15. package/dist/commands/validate.d.ts +9 -0
  16. package/dist/commands/validate.js +29 -0
  17. package/dist/commands/validate.js.map +1 -0
  18. package/dist/core/agent-extract.d.ts +5 -0
  19. package/dist/core/agent-extract.js +51 -0
  20. package/dist/core/agent-extract.js.map +1 -0
  21. package/dist/core/checksums.d.ts +2 -0
  22. package/dist/core/checksums.js +14 -0
  23. package/dist/core/checksums.js.map +1 -0
  24. package/dist/core/constants.d.ts +9 -0
  25. package/dist/core/constants.js +27 -0
  26. package/dist/core/constants.js.map +1 -0
  27. package/dist/core/import-exec.d.ts +5 -0
  28. package/dist/core/import-exec.js +56 -0
  29. package/dist/core/import-exec.js.map +1 -0
  30. package/dist/core/import-plan.d.ts +8 -0
  31. package/dist/core/import-plan.js +91 -0
  32. package/dist/core/import-plan.js.map +1 -0
  33. package/dist/core/manifest.d.ts +24 -0
  34. package/dist/core/manifest.js +59 -0
  35. package/dist/core/manifest.js.map +1 -0
  36. package/dist/core/openclaw-config.d.ts +46 -0
  37. package/dist/core/openclaw-config.js +127 -0
  38. package/dist/core/openclaw-config.js.map +1 -0
  39. package/dist/core/package-read.d.ts +2 -0
  40. package/dist/core/package-read.js +64 -0
  41. package/dist/core/package-read.js.map +1 -0
  42. package/dist/core/package-write.d.ts +8 -0
  43. package/dist/core/package-write.js +59 -0
  44. package/dist/core/package-write.js.map +1 -0
  45. package/dist/core/skills-detect.d.ts +2 -0
  46. package/dist/core/skills-detect.js +43 -0
  47. package/dist/core/skills-detect.js.map +1 -0
  48. package/dist/core/types.d.ts +151 -0
  49. package/dist/core/types.js +3 -0
  50. package/dist/core/types.js.map +1 -0
  51. package/dist/core/validate.d.ts +6 -0
  52. package/dist/core/validate.js +89 -0
  53. package/dist/core/validate.js.map +1 -0
  54. package/dist/core/workspace-scan.d.ts +2 -0
  55. package/dist/core/workspace-scan.js +57 -0
  56. package/dist/core/workspace-scan.js.map +1 -0
  57. package/dist/utils/json.d.ts +2 -0
  58. package/dist/utils/json.js +12 -0
  59. package/dist/utils/json.js.map +1 -0
  60. package/package.json +33 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cogine AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,373 @@
1
+ # Clawpacker
2
+
3
+ > Portable OpenClaw agent/workspace templates for sharing, cloning, and rehydrating on another instance.
4
+
5
+ Clawpacker is a small TypeScript CLI for exporting the portable parts of an OpenClaw agent workspace into a declarative package, then importing that package into another OpenClaw setup.
6
+
7
+ ## Why this exists
8
+
9
+ OpenClaw agents often live inside a workspace with persona files, conventions, and a bit of agent config glue. Recreating that setup by hand is annoying, error-prone, and easy to drift.
10
+
11
+ Clawpacker focuses on the reusable part of that problem:
12
+
13
+ - capture the workspace files that define an agent's behavior
14
+ - extract a portable slice of agent config
15
+ - restore that template somewhere else
16
+ - clearly tell you what still needs manual setup
17
+
18
+ This is **template portability**, not full-instance backup.
19
+
20
+ ## Status
21
+
22
+ **Internal alpha.** The current CLI is usable for v1-style experiments, but the package format and UX should still be treated as early-stage.
23
+
24
+ Use it when you want to:
25
+
26
+ - package an existing OpenClaw workspace as a reusable template
27
+ - move a persona/operator setup between instances with minimal manual work
28
+ - validate what was imported
29
+
30
+ Do **not** treat it as a production-grade backup, archival, or disaster-recovery tool yet.
31
+
32
+ ## What Clawpacker does in v1
33
+
34
+ ### Included
35
+
36
+ By default, Clawpacker exports the portable workspace files:
37
+
38
+ - `AGENTS.md`
39
+ - `SOUL.md`
40
+ - `IDENTITY.md`
41
+ - `USER.md`
42
+ - `TOOLS.md`
43
+ - `MEMORY.md`
44
+ - `HEARTBEAT.md` if present
45
+
46
+ It also writes package metadata:
47
+
48
+ - `manifest.json`
49
+ - `config/agent.json`
50
+ - `config/import-hints.json`
51
+ - `config/skills-manifest.json`
52
+ - `meta/checksums.json`
53
+ - `meta/export-report.json`
54
+
55
+ ### Excluded
56
+
57
+ Clawpacker intentionally excludes or avoids restoring:
58
+
59
+ - `memory/*.md` daily logs
60
+ - secrets, auth state, cookies, API keys, credentials
61
+ - session/runtime state
62
+ - channel bindings / routing state
63
+ - globally installed skills or extensions
64
+ - machine-specific absolute-path behavior that is not portable
65
+
66
+ ### Skills model in v1
67
+
68
+ Skills are **manifest-only** right now.
69
+
70
+ That means Clawpacker records detected skill references, but it does not bundle or install skill implementations for you.
71
+
72
+ ## Install
73
+
74
+ ### Published package
75
+
76
+ ```bash
77
+ npm install -g clawpacker
78
+ clawpacker --help
79
+ ```
80
+
81
+ ### From source
82
+
83
+ ```bash
84
+ npm install
85
+ npm run build
86
+ ```
87
+
88
+ Run the built CLI:
89
+
90
+ ```bash
91
+ node dist/cli.js --help
92
+ ```
93
+
94
+ ### Node requirement
95
+
96
+ - Node.js `>= 20`
97
+
98
+ ## Command overview
99
+
100
+ After building, the CLI exposes four commands:
101
+
102
+ - `inspect` — analyze a workspace before packaging
103
+ - `export` — write a `.ocpkg/` directory package
104
+ - `import` — restore a package into a target workspace
105
+ - `validate` — verify an imported workspace target
106
+
107
+ If you install the published package, the CLI command is:
108
+
109
+ ```bash
110
+ clawpacker
111
+ ```
112
+
113
+ For local source usage, you can still run:
114
+
115
+ ```bash
116
+ node dist/cli.js
117
+ ```
118
+
119
+ ## Usage
120
+
121
+ ### 1) Inspect a source workspace
122
+
123
+ Human-readable report:
124
+
125
+ ```bash
126
+ node dist/cli.js inspect \
127
+ --workspace ./tests/fixtures/source-workspace
128
+ ```
129
+
130
+ Machine-readable JSON report:
131
+
132
+ ```bash
133
+ node dist/cli.js inspect \
134
+ --workspace ./tests/fixtures/source-workspace \
135
+ --config ./tests/fixtures/openclaw-config/source-config.jsonc \
136
+ --json
137
+ ```
138
+
139
+ What `inspect` tells you:
140
+
141
+ - which workspace files are included
142
+ - which files are excluded or ignored
143
+ - whether a portable agent definition could be derived
144
+ - which fields are portable vs import-time inputs
145
+ - which skills were detected
146
+ - v1 warnings you should expect on export/import
147
+
148
+ ### 2) Export a package
149
+
150
+ ```bash
151
+ node dist/cli.js export \
152
+ --workspace ./tests/fixtures/source-workspace \
153
+ --config ./tests/fixtures/openclaw-config/source-config.jsonc \
154
+ --out ./tests/tmp/example-supercoder.ocpkg \
155
+ --name supercoder-template
156
+ ```
157
+
158
+ Current output is JSON, for example:
159
+
160
+ ```json
161
+ {
162
+ "status": "ok",
163
+ "packageRoot": ".../example-supercoder.ocpkg",
164
+ "manifestPath": ".../example-supercoder.ocpkg/manifest.json",
165
+ "fileCount": 12
166
+ }
167
+ ```
168
+
169
+ ### 3) Import a package
170
+
171
+ ```bash
172
+ node dist/cli.js import \
173
+ ./tests/tmp/example-supercoder.ocpkg \
174
+ --target-workspace ./tests/tmp/workspace-supercoder-imported \
175
+ --agent-id supercoder-imported \
176
+ --config ./tests/tmp/target-openclaw-config.json
177
+ ```
178
+
179
+ Notes:
180
+
181
+ - `--target-workspace` is required
182
+ - `--agent-id` is strongly recommended and becomes required in practice for collision-safe import planning
183
+ - if the target workspace or target agent already exists, import blocks unless you pass `--force`
184
+ - if no config is found, import can still restore workspace files, but config registration becomes limited
185
+
186
+ ### 4) Validate the imported result
187
+
188
+ ```bash
189
+ node dist/cli.js validate \
190
+ --target-workspace ./tests/tmp/workspace-supercoder-imported \
191
+ --agent-id supercoder-imported \
192
+ --config ./tests/tmp/target-openclaw-config.json
193
+ ```
194
+
195
+ Current output is a JSON validation report with:
196
+
197
+ - `passed`
198
+ - `warnings`
199
+ - `failed`
200
+ - `nextSteps`
201
+
202
+ ## OpenClaw config awareness
203
+
204
+ Clawpacker is OpenClaw-aware, but intentionally narrow.
205
+
206
+ When you provide `--config`, or when import can discover a nearby OpenClaw config, Clawpacker can:
207
+
208
+ - derive a portable agent definition from an existing config entry
209
+ - classify config fields as portable, excluded, or requiring import-time input
210
+ - upsert the imported agent into the target OpenClaw config
211
+ - validate that the imported workspace path matches the target config entry
212
+
213
+ ### Config discovery behavior
214
+
215
+ If you do not pass `--config`, Clawpacker looks for a config in these places:
216
+
217
+ - `./openclaw-config.json`
218
+ - `./openclaw-config.jsonc`
219
+ - `~/.openclaw/config.json`
220
+ - `~/.openclaw/config.jsonc`
221
+
222
+ ### Portable config philosophy
223
+
224
+ Clawpacker does **not** export raw OpenClaw config wholesale.
225
+
226
+ Instead, it extracts a minimal, portable slice, such as:
227
+
228
+ - suggested agent id
229
+ - suggested display name
230
+ - workspace basename suggestion
231
+ - identity name
232
+ - default model, when present
233
+
234
+ And it explicitly excludes things like:
235
+
236
+ - channel bindings
237
+ - secrets
238
+ - provider/account-specific runtime state
239
+
240
+ ## Safety model
241
+
242
+ Clawpacker is designed to be conservative.
243
+
244
+ ### Export safety
245
+
246
+ - only known portable workspace files are copied
247
+ - daily memory logs are excluded by default
248
+ - package contents are declared in a manifest instead of hidden in opaque state
249
+ - checksums are generated for integrity verification
250
+
251
+ ### Import safety
252
+
253
+ - import is planned before it executes
254
+ - existing workspace collisions block by default
255
+ - existing config agent collisions block by default
256
+ - `--force` is required to overwrite existing targets
257
+ - import writes local metadata so validation can confirm what happened later
258
+
259
+ ### Post-import safety expectations
260
+
261
+ Even after a successful import, you should still:
262
+
263
+ - review `USER.md`, `TOOLS.md`, and `MEMORY.md`
264
+ - reinstall any required skills manually
265
+ - recreate channel bindings manually
266
+ - verify model/provider availability on the target instance
267
+
268
+ ## Package structure
269
+
270
+ A typical v1 package looks like this:
271
+
272
+ ```text
273
+ supercoder-template.ocpkg/
274
+ manifest.json
275
+ workspace/
276
+ AGENTS.md
277
+ SOUL.md
278
+ IDENTITY.md
279
+ USER.md
280
+ TOOLS.md
281
+ MEMORY.md
282
+ HEARTBEAT.md
283
+ config/
284
+ agent.json
285
+ import-hints.json
286
+ skills-manifest.json
287
+ meta/
288
+ checksums.json
289
+ export-report.json
290
+ ```
291
+
292
+ ## What is intentionally out of scope in v1
293
+
294
+ - full OpenClaw instance backup
295
+ - secret migration
296
+ - auth/session migration
297
+ - channel binding export/import
298
+ - packaging globally installed skill implementations
299
+ - archive transport formats beyond the current directory package flow
300
+ - zero-touch import across mismatched environments
301
+
302
+ ## Roadmap / known limitations
303
+
304
+ Near-term likely improvements:
305
+
306
+ - publishable npm package + stable binary release
307
+ - friendlier non-JSON output for `export`, `import`, and `validate`
308
+ - optional archive packaging for transport
309
+ - richer import guidance when models or skills are missing
310
+ - optional packaging for workspace-local skill folders
311
+ - better package compatibility/version negotiation
312
+
313
+ Current limitations to be aware of:
314
+
315
+ - package format should still be treated as alpha
316
+ - skills are detected, but not bundled
317
+ - import assumes conservative file-level replacement semantics via `--force`
318
+ - OpenClaw config support is minimal by design
319
+ - examples currently assume local source usage, not a published global install
320
+
321
+ ## Development
322
+
323
+ Install dependencies:
324
+
325
+ ```bash
326
+ npm install
327
+ ```
328
+
329
+ Build:
330
+
331
+ ```bash
332
+ npm run build
333
+ ```
334
+
335
+ Run tests:
336
+
337
+ ```bash
338
+ npm test
339
+ ```
340
+
341
+ Run the CLI directly in dev:
342
+
343
+ ```bash
344
+ npm run dev -- --help
345
+ ```
346
+
347
+ ## Verifying the examples locally
348
+
349
+ A practical smoke path is:
350
+
351
+ ```bash
352
+ npm run build
353
+ node dist/cli.js inspect --workspace ./tests/fixtures/source-workspace --json
354
+ node dist/cli.js export --workspace ./tests/fixtures/source-workspace --out ./tests/tmp/readme-demo.ocpkg
355
+ node dist/cli.js import ./tests/tmp/readme-demo.ocpkg --target-workspace ./tests/tmp/readme-demo-target --agent-id readme-demo
356
+ node dist/cli.js validate --target-workspace ./tests/tmp/readme-demo-target --agent-id readme-demo
357
+ npm test
358
+ ```
359
+
360
+ ## Naming
361
+
362
+ The npm package name is **`clawpacker`** while the GitHub repository remains **`cogine-ai/clawpack`**.
363
+
364
+ Why this naming split:
365
+
366
+ - short and memorable
367
+ - feels native to the OpenClaw ecosystem
368
+ - communicates portability/transport clearly
369
+ - keeps the repository path stable while making the published package name explicit
370
+
371
+ ---
372
+
373
+ If you are evaluating this repo for internal alpha use: treat it as a practical portability prototype with a conservative safety model, not as a finished backup product.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const export_1 = require("./commands/export");
6
+ const import_1 = require("./commands/import");
7
+ const inspect_1 = require("./commands/inspect");
8
+ const validate_1 = require("./commands/validate");
9
+ const program = new commander_1.Command();
10
+ program
11
+ .name('clawpacker')
12
+ .description('Export, import, and validate portable OpenClaw agent/workspace templates.')
13
+ .version('0.1.0');
14
+ (0, inspect_1.registerInspectCommand)(program.command('inspect'));
15
+ (0, export_1.registerExportCommand)(program.command('export'));
16
+ (0, import_1.registerImportCommand)(program.command('import'));
17
+ (0, validate_1.registerValidateCommand)(program.command('validate'));
18
+ program.parseAsync(process.argv).catch((error) => {
19
+ console.error(error);
20
+ process.exitCode = 1;
21
+ });
22
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,8CAA0D;AAC1D,8CAA0D;AAC1D,gDAA4D;AAC5D,kDAA8D;AAE9D,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,2EAA2E,CAAC;KACxF,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,IAAA,gCAAsB,EAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;AACnD,IAAA,8BAAqB,EAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjD,IAAA,8BAAqB,EAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjD,IAAA,kCAAuB,EAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;AAErD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IACxD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Command } from 'commander';
2
+ interface ExportOptions {
3
+ workspace: string;
4
+ out: string;
5
+ name?: string;
6
+ config?: string;
7
+ agentId?: string;
8
+ }
9
+ export declare function runExport(options: ExportOptions): Promise<void>;
10
+ export declare function registerExportCommand(command: Command): void;
11
+ export {};
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runExport = runExport;
7
+ exports.registerExportCommand = registerExportCommand;
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const agent_extract_1 = require("../core/agent-extract");
10
+ const package_write_1 = require("../core/package-write");
11
+ const skills_detect_1 = require("../core/skills-detect");
12
+ const workspace_scan_1 = require("../core/workspace-scan");
13
+ async function runExport(options) {
14
+ if (!options.workspace || !options.out) {
15
+ throw new Error('export requires --workspace <path> and --out <path>');
16
+ }
17
+ const scan = await (0, workspace_scan_1.scanWorkspace)(node_path_1.default.resolve(options.workspace));
18
+ const skills = await (0, skills_detect_1.detectSkills)(scan);
19
+ const agentDefinition = await (0, agent_extract_1.extractAgentDefinition)(scan.workspacePath, {
20
+ configPath: options.config,
21
+ agentId: options.agentId,
22
+ });
23
+ const packageName = options.name ?? node_path_1.default.basename(options.out).replace(/\.ocpkg$/, '');
24
+ const result = await (0, package_write_1.writePackageDirectory)({
25
+ outputPath: node_path_1.default.resolve(options.out),
26
+ packageName,
27
+ scan,
28
+ skills,
29
+ agentDefinition,
30
+ });
31
+ console.log(JSON.stringify({
32
+ status: 'ok',
33
+ packageRoot: result.packageRoot,
34
+ manifestPath: result.manifestPath,
35
+ fileCount: result.fileCount,
36
+ }, null, 2));
37
+ }
38
+ function registerExportCommand(command) {
39
+ command
40
+ .description('Export a portable .ocpkg directory from a workspace.')
41
+ .requiredOption('--workspace <path>', 'Source workspace path')
42
+ .requiredOption('--out <path>', 'Output package directory path')
43
+ .option('--name <package-name>', 'Package name override')
44
+ .option('--config <path>', 'OpenClaw config path')
45
+ .option('--agent-id <id>', 'Source agent id override')
46
+ .action(runExport);
47
+ }
48
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":";;;;;AAeA,8BAiCC;AAED,sDASC;AA3DD,0DAA6B;AAE7B,yDAA+D;AAC/D,yDAA8D;AAC9D,yDAAqD;AACrD,2DAAuD;AAUhD,KAAK,UAAU,SAAS,CAAC,OAAsB;IACpD,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,IAAA,8BAAa,EAAC,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAY,EAAC,IAAI,CAAC,CAAC;IACxC,MAAM,eAAe,GAAG,MAAM,IAAA,sCAAsB,EAAC,IAAI,CAAC,aAAa,EAAE;QACvE,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAEvF,MAAM,MAAM,GAAG,MAAM,IAAA,qCAAqB,EAAC;QACzC,UAAU,EAAE,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;QACrC,WAAW;QACX,IAAI;QACJ,MAAM;QACN,eAAe;KAChB,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;QACE,MAAM,EAAE,IAAI;QACZ,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;AACJ,CAAC;AAED,SAAgB,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,WAAW,CAAC,sDAAsD,CAAC;SACnE,cAAc,CAAC,oBAAoB,EAAE,uBAAuB,CAAC;SAC7D,cAAc,CAAC,cAAc,EAAE,+BAA+B,CAAC;SAC/D,MAAM,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;SACxD,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;SACjD,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACrD,MAAM,CAAC,SAAS,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Command } from 'commander';
2
+ interface ImportOptions {
3
+ targetWorkspace: string;
4
+ agentId?: string;
5
+ config?: string;
6
+ force?: boolean;
7
+ }
8
+ export declare function runImport(packagePath: string, options: ImportOptions): Promise<void>;
9
+ export declare function registerImportCommand(command: Command): void;
10
+ export {};
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runImport = runImport;
7
+ exports.registerImportCommand = registerImportCommand;
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const import_exec_1 = require("../core/import-exec");
10
+ const openclaw_config_1 = require("../core/openclaw-config");
11
+ const import_plan_1 = require("../core/import-plan");
12
+ const package_read_1 = require("../core/package-read");
13
+ async function runImport(packagePath, options) {
14
+ if (!packagePath || !options.targetWorkspace) {
15
+ throw new Error('import requires <package-path> and --target-workspace <path>');
16
+ }
17
+ const pkg = await (0, package_read_1.readPackageDirectory)(node_path_1.default.resolve(packagePath));
18
+ const configPath = options.config
19
+ ? node_path_1.default.resolve(options.config)
20
+ : (await (0, openclaw_config_1.discoverOpenClawConfig)({ cwd: node_path_1.default.resolve(options.targetWorkspace) }).catch(() => undefined))?.configPath;
21
+ const plan = await (0, import_plan_1.planImport)({
22
+ pkg,
23
+ targetWorkspacePath: node_path_1.default.resolve(options.targetWorkspace),
24
+ targetAgentId: options.agentId,
25
+ targetConfigPath: configPath,
26
+ force: options.force,
27
+ });
28
+ if (!plan.canProceed) {
29
+ throw new Error(JSON.stringify({
30
+ status: 'blocked',
31
+ failed: plan.failed,
32
+ requiredInputs: plan.requiredInputs,
33
+ warnings: plan.warnings,
34
+ nextSteps: plan.nextSteps,
35
+ writePlan: plan.writePlan,
36
+ }, null, 2));
37
+ }
38
+ const result = await (0, import_exec_1.executeImport)({ pkg, plan });
39
+ console.log(JSON.stringify(result, null, 2));
40
+ }
41
+ function registerImportCommand(command) {
42
+ command
43
+ .description('Import a portable .ocpkg directory into a target workspace.')
44
+ .argument('<package-path>', 'Portable package directory path')
45
+ .requiredOption('--target-workspace <path>', 'Target workspace path')
46
+ .option('--agent-id <id>', 'Target agent id override')
47
+ .option('--config <path>', 'Target OpenClaw config path')
48
+ .option('--force', 'Overwrite an existing target workspace')
49
+ .action(runImport);
50
+ }
51
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":";;;;;AAcA,8BA+BC;AAED,sDASC;AAxDD,0DAA6B;AAE7B,qDAAoD;AACpD,6DAAiE;AACjE,qDAAiD;AACjD,uDAA4D;AASrD,KAAK,UAAU,SAAS,CAAC,WAAmB,EAAE,OAAsB;IACzE,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,IAAA,mCAAoB,EAAC,mBAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IAClE,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM;QAC/B,CAAC,CAAC,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9B,CAAC,CAAC,CAAC,MAAM,IAAA,wCAAsB,EAAC,EAAE,GAAG,EAAE,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC;IAEtH,MAAM,IAAI,GAAG,MAAM,IAAA,wBAAU,EAAC;QAC5B,GAAG;QACH,mBAAmB,EAAE,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC;QAC1D,aAAa,EAAE,OAAO,CAAC,OAAO;QAC9B,gBAAgB,EAAE,UAAU;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC7B,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,IAAA,2BAAa,EAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAgB,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,WAAW,CAAC,6DAA6D,CAAC;SAC1E,QAAQ,CAAC,gBAAgB,EAAE,iCAAiC,CAAC;SAC7D,cAAc,CAAC,2BAA2B,EAAE,uBAAuB,CAAC;SACpE,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACrD,MAAM,CAAC,iBAAiB,EAAE,6BAA6B,CAAC;SACxD,MAAM,CAAC,SAAS,EAAE,wCAAwC,CAAC;SAC3D,MAAM,CAAC,SAAS,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Command } from 'commander';
2
+ interface InspectOptions {
3
+ workspace: string;
4
+ config?: string;
5
+ agentId?: string;
6
+ json?: boolean;
7
+ }
8
+ export declare function runInspect(options: InspectOptions): Promise<void>;
9
+ export declare function registerInspectCommand(command: Command): void;
10
+ export {};
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runInspect = runInspect;
7
+ exports.registerInspectCommand = registerInspectCommand;
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const agent_extract_1 = require("../core/agent-extract");
10
+ const skills_detect_1 = require("../core/skills-detect");
11
+ const workspace_scan_1 = require("../core/workspace-scan");
12
+ async function runInspect(options) {
13
+ if (!options.workspace) {
14
+ throw new Error('inspect requires --workspace <path>');
15
+ }
16
+ const workspacePath = node_path_1.default.resolve(options.workspace);
17
+ const scan = await (0, workspace_scan_1.scanWorkspace)(workspacePath);
18
+ const skills = await (0, skills_detect_1.detectSkills)(scan);
19
+ const agentDefinition = await (0, agent_extract_1.extractAgentDefinition)(workspacePath, {
20
+ configPath: options.config,
21
+ agentId: options.agentId,
22
+ });
23
+ const warnings = [
24
+ 'Channel bindings are not included in v1 packages.',
25
+ 'Skills are manifest-only and may require manual installation.',
26
+ ];
27
+ const report = {
28
+ workspacePath,
29
+ includedFiles: scan.includedFiles.map((file) => file.relativePath),
30
+ excludedFiles: scan.excludedFiles,
31
+ ignoredFiles: scan.ignoredFiles,
32
+ missingOptionalFiles: scan.missingOptionalFiles,
33
+ portableConfig: {
34
+ found: !agentDefinition.notes.some((note) => note.includes('placeholder')),
35
+ agent: agentDefinition.agent,
36
+ fieldClassification: agentDefinition.fieldClassification,
37
+ notes: agentDefinition.notes,
38
+ },
39
+ skills,
40
+ warnings,
41
+ errors: [],
42
+ };
43
+ if (options.json) {
44
+ console.log(JSON.stringify(report, null, 2));
45
+ return;
46
+ }
47
+ const lines = [
48
+ `Workspace: ${report.workspacePath}`,
49
+ `Included files (${report.includedFiles.length}): ${report.includedFiles.join(', ') || 'none'}`,
50
+ `Excluded files (${report.excludedFiles.length}): ${report.excludedFiles.map((entry) => `${entry.relativePath} [${entry.reason}]`).join(', ') || 'none'}`,
51
+ `Ignored files (${report.ignoredFiles.length}): ${report.ignoredFiles.join(', ') || 'none'}`,
52
+ `Missing optional files (${report.missingOptionalFiles.length}): ${report.missingOptionalFiles.join(', ') || 'none'}`,
53
+ 'Portable agent definition:',
54
+ ` found: ${report.portableConfig.found ? 'yes' : 'no'}`,
55
+ ` suggested id: ${report.portableConfig.agent.suggestedId}`,
56
+ ` suggested name: ${report.portableConfig.agent.suggestedName}`,
57
+ ` workspace basename: ${report.portableConfig.agent.workspace.suggestedBasename}`,
58
+ ` identity name: ${report.portableConfig.agent.identity.name}`,
59
+ ` default model: ${report.portableConfig.agent.model?.default ?? 'not set'}`,
60
+ ` portable fields: ${Object.entries(report.portableConfig.fieldClassification).map(([key, value]) => `${key}=${value}`).join(', ')}`,
61
+ `Skills (workspace): ${skills.workspaceSkills.join(', ') || 'none'}`,
62
+ `Skills (referenced): ${skills.referencedSkills.join(', ') || 'none'}`,
63
+ `Skill notes: ${skills.notes.join(' | ') || 'none'}`,
64
+ `Warnings: ${warnings.join(' | ') || 'none'}`,
65
+ ];
66
+ if (report.portableConfig.notes.length > 0) {
67
+ lines.push(`Portable config notes: ${report.portableConfig.notes.join(' | ')}`);
68
+ }
69
+ console.log(lines.join('\n'));
70
+ }
71
+ function registerInspectCommand(command) {
72
+ command
73
+ .description('Inspect a workspace and report what is portable in v1.')
74
+ .requiredOption('--workspace <path>', 'Source workspace path')
75
+ .option('--config <path>', 'OpenClaw config path')
76
+ .option('--agent-id <id>', 'Source agent id override')
77
+ .option('--json', 'Emit the full machine-readable JSON report')
78
+ .action(runInspect);
79
+ }
80
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Command } from 'commander';
2
+ interface ValidateOptions {
3
+ targetWorkspace: string;
4
+ agentId?: string;
5
+ config?: string;
6
+ }
7
+ export declare function runValidate(options: ValidateOptions): Promise<void>;
8
+ export declare function registerValidateCommand(command: Command): void;
9
+ export {};