@cogineai/clawpacker 0.1.0 → 0.3.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 (71) hide show
  1. package/README.md +235 -53
  2. package/dist/cli.js +12 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/export.d.ts +3 -0
  5. package/dist/commands/export.js +57 -7
  6. package/dist/commands/export.js.map +1 -1
  7. package/dist/commands/import.d.ts +3 -0
  8. package/dist/commands/import.js +153 -26
  9. package/dist/commands/import.js.map +1 -1
  10. package/dist/commands/inspect.d.ts +1 -0
  11. package/dist/commands/inspect.js +49 -7
  12. package/dist/commands/inspect.js.map +1 -1
  13. package/dist/commands/validate.d.ts +2 -0
  14. package/dist/commands/validate.js +15 -2
  15. package/dist/commands/validate.js.map +1 -1
  16. package/dist/core/agent-extract.js.map +1 -1
  17. package/dist/core/archive.d.ts +5 -0
  18. package/dist/core/archive.js +83 -0
  19. package/dist/core/archive.js.map +1 -0
  20. package/dist/core/constants.d.ts +14 -4
  21. package/dist/core/constants.js +56 -8
  22. package/dist/core/constants.js.map +1 -1
  23. package/dist/core/import-exec.d.ts +2 -2
  24. package/dist/core/import-exec.js +33 -3
  25. package/dist/core/import-exec.js.map +1 -1
  26. package/dist/core/import-plan.d.ts +1 -0
  27. package/dist/core/import-plan.js +203 -14
  28. package/dist/core/import-plan.js.map +1 -1
  29. package/dist/core/manifest.d.ts +13 -1
  30. package/dist/core/manifest.js +31 -4
  31. package/dist/core/manifest.js.map +1 -1
  32. package/dist/core/models-sanitize.d.ts +4 -0
  33. package/dist/core/models-sanitize.js +120 -0
  34. package/dist/core/models-sanitize.js.map +1 -0
  35. package/dist/core/openclaw-config.d.ts +41 -10
  36. package/dist/core/openclaw-config.js +168 -33
  37. package/dist/core/openclaw-config.js.map +1 -1
  38. package/dist/core/package-read.d.ts +5 -0
  39. package/dist/core/package-read.js +69 -3
  40. package/dist/core/package-read.js.map +1 -1
  41. package/dist/core/package-write.d.ts +16 -1
  42. package/dist/core/package-write.js +101 -4
  43. package/dist/core/package-write.js.map +1 -1
  44. package/dist/core/path-rewrite.d.ts +18 -0
  45. package/dist/core/path-rewrite.js +79 -0
  46. package/dist/core/path-rewrite.js.map +1 -0
  47. package/dist/core/runtime-mode.d.ts +2 -0
  48. package/dist/core/runtime-mode.js +19 -0
  49. package/dist/core/runtime-mode.js.map +1 -0
  50. package/dist/core/runtime-scan.d.ts +6 -0
  51. package/dist/core/runtime-scan.js +180 -0
  52. package/dist/core/runtime-scan.js.map +1 -0
  53. package/dist/core/settings-analysis.d.ts +5 -0
  54. package/dist/core/settings-analysis.js +85 -0
  55. package/dist/core/settings-analysis.js.map +1 -0
  56. package/dist/core/types.d.ts +150 -9
  57. package/dist/core/validate.d.ts +1 -0
  58. package/dist/core/validate.js +121 -14
  59. package/dist/core/validate.js.map +1 -1
  60. package/dist/core/workspace-scan.js +46 -37
  61. package/dist/core/workspace-scan.js.map +1 -1
  62. package/dist/renderable-cli-error.d.ts +6 -0
  63. package/dist/renderable-cli-error.js +14 -0
  64. package/dist/renderable-cli-error.js.map +1 -0
  65. package/dist/utils/fs.d.ts +1 -0
  66. package/dist/utils/fs.js +14 -0
  67. package/dist/utils/fs.js.map +1 -0
  68. package/dist/utils/output.d.ts +5 -0
  69. package/dist/utils/output.js +14 -0
  70. package/dist/utils/output.js.map +1 -0
  71. package/package.json +16 -4
package/README.md CHANGED
@@ -19,7 +19,7 @@ This is **template portability**, not full-instance backup.
19
19
 
20
20
  ## Status
21
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.
22
+ **Internal alpha.** The current CLI is usable for early experiments (package format v2), but the format and UX should still be treated as early-stage.
23
23
 
24
24
  Use it when you want to:
25
25
 
@@ -29,21 +29,19 @@ Use it when you want to:
29
29
 
30
30
  Do **not** treat it as a production-grade backup, archival, or disaster-recovery tool yet.
31
31
 
32
- ## What Clawpacker does in v1
32
+ ## What Clawpacker does
33
33
 
34
34
  ### Included
35
35
 
36
- By default, Clawpacker exports the portable workspace files:
36
+ Clawpacker uses a **blacklist model** — it includes all files in the workspace (including subdirectories) except those matching explicit exclusion rules.
37
37
 
38
- - `AGENTS.md`
39
- - `SOUL.md`
40
- - `IDENTITY.md`
41
- - `USER.md`
42
- - `TOOLS.md`
43
- - `MEMORY.md`
44
- - `HEARTBEAT.md` if present
38
+ The following files are recognized as **bootstrap files** and flagged in the manifest:
45
39
 
46
- It also writes package metadata:
40
+ `AGENTS.md`, `SOUL.md`, `IDENTITY.md`, `USER.md`, `TOOLS.md`, `MEMORY.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`
41
+
42
+ All other workspace files are included as well, preserving directory structure.
43
+
44
+ The package also contains metadata:
47
45
 
48
46
  - `manifest.json`
49
47
  - `config/agent.json`
@@ -54,27 +52,109 @@ It also writes package metadata:
54
52
 
55
53
  ### Excluded
56
54
 
57
- Clawpacker intentionally excludes or avoids restoring:
55
+ Clawpacker excludes the following subdirectories if they appear inside the workspace:
56
+
57
+ - `.git`
58
+ - `.openclaw`
59
+ - `node_modules`
60
+
61
+ And these file patterns:
58
62
 
59
63
  - `memory/*.md` daily logs
64
+
65
+ These rules only apply to contents **within** the scanned workspace directory. The parent `~/.openclaw/` installation and its config files are not part of the workspace scan — OpenClaw config is read separately via `--config` or config discovery.
66
+
67
+ Beyond file-level exclusions, Clawpacker never exports or restores:
68
+
60
69
  - secrets, auth state, cookies, API keys, credentials
61
70
  - session/runtime state
62
71
  - channel bindings / routing state
63
72
  - globally installed skills or extensions
64
73
  - machine-specific absolute-path behavior that is not portable
65
74
 
66
- ### Skills model in v1
75
+ ### Skills model
67
76
 
68
77
  Skills are **manifest-only** right now.
69
78
 
70
- That means Clawpacker records detected skill references, but it does not bundle or install skill implementations for you.
79
+ That means Clawpacker records detected skill references (using backtick-quoted references like `` `skill-name` ``), but it does not bundle or install skill implementations for you.
80
+
81
+ ### Runtime layer (optional)
82
+
83
+ In addition to workspace files, OpenClaw agents often have runtime configuration stored in a separate **agentDir** — things like `settings.json`, prompt templates, themes, and model definitions. Clawpacker can optionally package a portable slice of this runtime layer alongside the workspace.
84
+
85
+ This is an **optional portability convenience**, not a full backup of the agent runtime directory.
86
+
87
+ #### The three modes
88
+
89
+ | Mode | What gets packaged | When to use |
90
+ |------|-------------------|-------------|
91
+ | `none` | Nothing from agentDir | You only need workspace files |
92
+ | `default` | `AGENTS.md`, `settings.json`, `prompts/**`, `themes/**`, `models.json` | Most agent transfers (recommended) |
93
+ | `full` | Everything in `default`, plus `skills/**` and `extensions/**` | When the target instance needs locally installed skills or extensions |
94
+
95
+ Use `--runtime-mode <mode>` on `inspect` and `export`. When omitted, `inspect` defaults to `default`; `export` skips the runtime layer unless the flag is explicitly provided.
96
+
97
+ #### What is always excluded
98
+
99
+ Regardless of mode, Clawpacker never packages these from agentDir:
100
+
101
+ - `auth.json`, `auth-profiles.json` — authentication state
102
+ - `sessions/**` — session data
103
+ - `.git/**`, `node_modules/**`, `npm/**`, `bin/**` — toolchain artifacts
104
+ - `tools/**`, `caches/**`, `logs/**` — ephemeral runtime state
105
+ - Files with extensions `.log`, `.lock`, `.tmp`, `.bak`, `.swp`, `.pid`
106
+
107
+ These exclusions exist because auth and session state is inherently non-portable and should be established fresh on the target instance.
108
+
109
+ #### models.json sanitization
110
+
111
+ When `models.json` is included, Clawpacker **sanitizes** it before packaging:
112
+
113
+ - API keys, secrets, and `$secretRef` objects are stripped
114
+ - Secret-bearing HTTP headers are removed
115
+ - Non-sensitive fields (model id, provider, max tokens, temperature) are preserved
116
+
117
+ If sanitization removes everything useful, the file is excluded entirely and a warning is emitted.
118
+
119
+ #### settings.json path analysis
120
+
121
+ Clawpacker analyzes path-like values in `settings.json` and classifies them:
122
+
123
+ | Classification | Meaning | On import |
124
+ |---------------|---------|-----------|
125
+ | `package-internal-workspace` | Points inside the source workspace | Rewritten to target workspace path |
126
+ | `package-internal-agentDir` | Points inside the source agentDir | Rewritten to target agentDir path |
127
+ | `relative` | Relative path (e.g. `./data`) | Preserved as-is |
128
+ | `external-absolute` | Absolute path outside workspace/agentDir | Preserved (may need manual update) |
129
+ | `host-bound` | Platform-specific path (e.g. `C:\...`, `/proc/...`) | Preserved (warning emitted) |
130
+
131
+ #### Runtime import behavior
132
+
133
+ When importing a package that includes a runtime layer:
134
+
135
+ - **`--target-agent-dir`** specifies where runtime files should be written. If omitted, Clawpacker attempts to resolve it from the target OpenClaw config.
136
+ - If no target agentDir can be resolved, import **blocks** and tells you what is needed.
137
+ - If runtime files already exist at the target agentDir, import **blocks** unless `--force` is passed. Only allowlisted runtime files are overwritten — auth and session files are never written.
138
+ - If a target OpenClaw config is provided, the agent entry is upserted with the agentDir path.
139
+ - `settings.json` paths referencing the source workspace or agentDir are automatically rewritten to the target paths.
140
+
141
+ Use `--dry-run` to preview the full import plan (including runtime file list, path rewrites, and collision detection) before committing.
142
+
143
+ #### agentDir resolution
144
+
145
+ The agentDir is resolved from the OpenClaw config by matching the agent entry that owns the source workspace. This requires:
146
+
147
+ 1. A readable OpenClaw config (via `--config`, `OPENCLAW_CONFIG_PATH`, or `~/.openclaw/openclaw.json`)
148
+ 2. An agent entry with an `agentDir` field
149
+
150
+ If the config is missing or the agent entry has no `agentDir`, the runtime layer is skipped on inspect, and export errors out with a clear message.
71
151
 
72
152
  ## Install
73
153
 
74
154
  ### Published package
75
155
 
76
156
  ```bash
77
- npm install -g clawpacker
157
+ npm install -g @cogineai/clawpacker
78
158
  clawpacker --help
79
159
  ```
80
160
 
@@ -100,7 +180,7 @@ node dist/cli.js --help
100
180
  After building, the CLI exposes four commands:
101
181
 
102
182
  - `inspect` — analyze a workspace before packaging
103
- - `export` — write a `.ocpkg/` directory package
183
+ - `export` — write a `.ocpkg/` directory or `.ocpkg.tar.gz` archive
104
184
  - `import` — restore a package into a target workspace
105
185
  - `validate` — verify an imported workspace target
106
186
 
@@ -127,12 +207,22 @@ node dist/cli.js inspect \
127
207
  --workspace ./tests/fixtures/source-workspace
128
208
  ```
129
209
 
210
+ With runtime layer inspection:
211
+
212
+ ```bash
213
+ node dist/cli.js inspect \
214
+ --workspace ./tests/fixtures/source-workspace \
215
+ --config ./tests/fixtures/openclaw-config/source-config.jsonc \
216
+ --runtime-mode default
217
+ ```
218
+
130
219
  Machine-readable JSON report:
131
220
 
132
221
  ```bash
133
222
  node dist/cli.js inspect \
134
223
  --workspace ./tests/fixtures/source-workspace \
135
224
  --config ./tests/fixtures/openclaw-config/source-config.jsonc \
225
+ --runtime-mode default \
136
226
  --json
137
227
  ```
138
228
 
@@ -143,45 +233,101 @@ What `inspect` tells you:
143
233
  - whether a portable agent definition could be derived
144
234
  - which fields are portable vs import-time inputs
145
235
  - which skills were detected
146
- - v1 warnings you should expect on export/import
236
+ - runtime layer contents (when `--runtime-mode` is `default` or `full`)
237
+ - warnings you should expect on export/import
147
238
 
148
239
  ### 2) Export a package
149
240
 
241
+ Directory package (workspace only):
242
+
243
+ ```bash
244
+ node dist/cli.js export \
245
+ --workspace ./tests/fixtures/source-workspace \
246
+ --out ./tests/tmp/example-supercoder.ocpkg \
247
+ --name supercoder-template \
248
+ --runtime-mode none
249
+ ```
250
+
251
+ Directory package with runtime layer:
252
+
253
+ ```bash
254
+ node dist/cli.js export \
255
+ --workspace ./tests/fixtures/source-workspace \
256
+ --config ./tests/fixtures/openclaw-config/source-config.jsonc \
257
+ --out ./tests/tmp/example-supercoder.ocpkg \
258
+ --name supercoder-template \
259
+ --runtime-mode default
260
+ ```
261
+
262
+ Single-file archive:
263
+
150
264
  ```bash
151
265
  node dist/cli.js export \
152
266
  --workspace ./tests/fixtures/source-workspace \
153
267
  --config ./tests/fixtures/openclaw-config/source-config.jsonc \
154
268
  --out ./tests/tmp/example-supercoder.ocpkg \
155
- --name supercoder-template
269
+ --name supercoder-template \
270
+ --runtime-mode default \
271
+ --archive
156
272
  ```
157
273
 
158
- Current output is JSON, for example:
274
+ The `--archive` flag produces a `.ocpkg.tar.gz` file for easier transport.
275
+
276
+ Output defaults to human-readable text. Add `--json` for machine-readable output:
159
277
 
160
278
  ```json
161
279
  {
162
280
  "status": "ok",
163
281
  "packageRoot": ".../example-supercoder.ocpkg",
164
282
  "manifestPath": ".../example-supercoder.ocpkg/manifest.json",
165
- "fileCount": 12
283
+ "fileCount": 12,
284
+ "runtimeMode": "default",
285
+ "runtimeFiles": ["AGENTS.md", "settings.json", "prompts/system.md"]
166
286
  }
167
287
  ```
168
288
 
169
289
  ### 3) Import a package
170
290
 
291
+ Accepts both `.ocpkg/` directories and `.ocpkg.tar.gz` archives:
292
+
293
+ ```bash
294
+ node dist/cli.js import \
295
+ ./tests/tmp/example-supercoder.ocpkg \
296
+ --target-workspace ./tests/tmp/workspace-supercoder-imported \
297
+ --agent-id supercoder-imported \
298
+ --config ./tests/tmp/target-openclaw-config.json
299
+ ```
300
+
301
+ Import with runtime layer targeting a specific agentDir:
302
+
171
303
  ```bash
172
304
  node dist/cli.js import \
173
305
  ./tests/tmp/example-supercoder.ocpkg \
174
306
  --target-workspace ./tests/tmp/workspace-supercoder-imported \
175
307
  --agent-id supercoder-imported \
308
+ --target-agent-dir ~/.openclaw/agents/supercoder-imported \
176
309
  --config ./tests/tmp/target-openclaw-config.json
177
310
  ```
178
311
 
312
+ Preview the import plan without writing anything:
313
+
314
+ ```bash
315
+ node dist/cli.js import \
316
+ ./tests/tmp/example-supercoder.ocpkg \
317
+ --target-workspace ./tests/tmp/workspace-supercoder-imported \
318
+ --agent-id supercoder-imported \
319
+ --dry-run
320
+ ```
321
+
179
322
  Notes:
180
323
 
181
324
  - `--target-workspace` is required
182
325
  - `--agent-id` is strongly recommended and becomes required in practice for collision-safe import planning
326
+ - `--target-agent-dir` is required when the package includes a runtime layer and no agentDir is discoverable from the target config
327
+ - `--dry-run` prints the import plan (including runtime details, path rewrites, and collision info) and exits without writing files
183
328
  - 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
329
+ - if runtime files already exist at the target agentDir, import blocks unless `--force` is passed; auth and session files are never written even with `--force`
330
+ - if no config is found, import can still restore workspace files, but config registration and runtime import become limited
185
331
 
186
332
  ### 4) Validate the imported result
187
333
 
@@ -192,12 +338,24 @@ node dist/cli.js validate \
192
338
  --config ./tests/tmp/target-openclaw-config.json
193
339
  ```
194
340
 
195
- Current output is a JSON validation report with:
341
+ When a runtime layer was imported, validate also checks runtime file integrity:
196
342
 
197
- - `passed`
198
- - `warnings`
199
- - `failed`
200
- - `nextSteps`
343
+ ```bash
344
+ node dist/cli.js validate \
345
+ --target-workspace ./tests/tmp/workspace-supercoder-imported \
346
+ --agent-id supercoder-imported \
347
+ --target-agent-dir ~/.openclaw/agents/supercoder-imported \
348
+ --config ./tests/tmp/target-openclaw-config.json
349
+ ```
350
+
351
+ The `--target-agent-dir` flag can be omitted — validate auto-infers it from import metadata when available.
352
+
353
+ Output defaults to human-readable text. Add `--json` for a structured report with:
354
+
355
+ - `passed` — checks that succeeded (including runtime file presence and agentDir consistency)
356
+ - `warnings` — non-blocking observations (e.g. auth files found at agentDir)
357
+ - `failed` — checks that failed (e.g. missing runtime files, agentDir mismatch)
358
+ - `nextSteps` — recommended actions
201
359
 
202
360
  ## OpenClaw config awareness
203
361
 
@@ -212,24 +370,23 @@ When you provide `--config`, or when import can discover a nearby OpenClaw confi
212
370
 
213
371
  ### Config discovery behavior
214
372
 
215
- If you do not pass `--config`, Clawpacker looks for a config in these places:
373
+ Config is resolved in this order:
216
374
 
217
- - `./openclaw-config.json`
218
- - `./openclaw-config.jsonc`
219
- - `~/.openclaw/config.json`
220
- - `~/.openclaw/config.jsonc`
375
+ 1. explicit `--config` flag
376
+ 2. `OPENCLAW_CONFIG_PATH` environment variable
377
+ 3. `~/.openclaw/openclaw.json` (default)
221
378
 
222
379
  ### Portable config philosophy
223
380
 
224
381
  Clawpacker does **not** export raw OpenClaw config wholesale.
225
382
 
226
- Instead, it extracts a minimal, portable slice, such as:
383
+ Instead, it extracts a portable slice of agent config, including:
227
384
 
228
- - suggested agent id
229
- - suggested display name
385
+ - agent id and display name
230
386
  - workspace basename suggestion
231
387
  - identity name
232
388
  - default model, when present
389
+ - tools, skills, heartbeat, sandbox, and runtime settings
233
390
 
234
391
  And it explicitly excludes things like:
235
392
 
@@ -243,17 +400,23 @@ Clawpacker is designed to be conservative.
243
400
 
244
401
  ### Export safety
245
402
 
246
- - only known portable workspace files are copied
247
- - daily memory logs are excluded by default
403
+ - all workspace files are included except explicitly excluded directories and patterns
404
+ - daily memory logs (`memory/*.md`) are excluded by default
248
405
  - package contents are declared in a manifest instead of hidden in opaque state
249
406
  - checksums are generated for integrity verification
407
+ - runtime layer is opt-in via `--runtime-mode`
408
+ - `models.json` is sanitized before packaging — API keys, secrets, and `$secretRef` objects are removed
409
+ - auth and session files are never included in the runtime layer regardless of mode
250
410
 
251
411
  ### Import safety
252
412
 
253
413
  - import is planned before it executes
254
414
  - existing workspace collisions block by default
255
415
  - existing config agent collisions block by default
256
- - `--force` is required to overwrite existing targets
416
+ - existing runtime file collisions block by default
417
+ - `--force` is required to overwrite existing targets (workspace and runtime files)
418
+ - `--force` never writes auth or session files — these are always excluded
419
+ - `settings.json` paths referencing the source workspace or agentDir are automatically rewritten to the target paths
257
420
  - import writes local metadata so validation can confirm what happened later
258
421
 
259
422
  ### Post-import safety expectations
@@ -267,7 +430,7 @@ Even after a successful import, you should still:
267
430
 
268
431
  ## Package structure
269
432
 
270
- A typical v1 package looks like this:
433
+ A typical package looks like this:
271
434
 
272
435
  ```text
273
436
  supercoder-template.ocpkg/
@@ -280,6 +443,9 @@ supercoder-template.ocpkg/
280
443
  TOOLS.md
281
444
  MEMORY.md
282
445
  HEARTBEAT.md
446
+ custom-prompts/
447
+ review.md
448
+ ... # any other workspace files
283
449
  config/
284
450
  agent.json
285
451
  import-hints.json
@@ -287,36 +453,52 @@ supercoder-template.ocpkg/
287
453
  meta/
288
454
  checksums.json
289
455
  export-report.json
456
+ runtime/ # present when --runtime-mode is default or full
457
+ manifest.json
458
+ checksums.json
459
+ path-rewrites.json
460
+ settings-analysis.json # present when settings.json was included
461
+ files/
462
+ AGENTS.md
463
+ settings.json
464
+ models.json # sanitized — no API keys or secrets
465
+ prompts/
466
+ system.md
467
+ themes/
468
+ dark.json
469
+ skills/ # present only in full mode
470
+ my-skill/
471
+ SKILL.md
290
472
  ```
291
473
 
292
- ## What is intentionally out of scope in v1
474
+ The `workspace/` directory mirrors the source workspace structure. All non-excluded files are included, so the contents vary depending on what lives in the source workspace.
475
+
476
+ The `runtime/` subtree is only present when `--runtime-mode default` or `--runtime-mode full` is used on export. Its `manifest.json` records the mode, source agentDir, and which files were included or excluded. The `files/` subdirectory contains the actual runtime files.
477
+
478
+ Packages can also be distributed as single-file `.ocpkg.tar.gz` archives.
479
+
480
+ ## What is intentionally out of scope
293
481
 
294
- - full OpenClaw instance backup
295
- - secret migration
296
- - auth/session migration
482
+ - full OpenClaw instance backup (the runtime layer is a portable slice, not a full agentDir copy)
483
+ - secret migration (API keys and auth tokens are stripped on export)
484
+ - auth/session migration (auth files are always excluded)
297
485
  - channel binding export/import
298
- - packaging globally installed skill implementations
299
- - archive transport formats beyond the current directory package flow
300
486
  - zero-touch import across mismatched environments
301
487
 
302
488
  ## Roadmap / known limitations
303
489
 
304
490
  Near-term likely improvements:
305
491
 
306
- - publishable npm package + stable binary release
307
- - friendlier non-JSON output for `export`, `import`, and `validate`
308
- - optional archive packaging for transport
309
492
  - richer import guidance when models or skills are missing
310
- - optional packaging for workspace-local skill folders
311
493
  - better package compatibility/version negotiation
312
494
 
313
495
  Current limitations to be aware of:
314
496
 
315
- - package format should still be treated as alpha
316
- - skills are detected, but not bundled
497
+ - package format should still be treated as early-stage (currently v2)
498
+ - skills are detected and optionally bundled via `--runtime-mode full`, but not auto-installed on import
317
499
  - import assumes conservative file-level replacement semantics via `--force`
318
500
  - OpenClaw config support is minimal by design
319
- - examples currently assume local source usage, not a published global install
501
+ - runtime layer path rewriting only handles `settings.json` other config files with embedded paths require manual update
320
502
 
321
503
  ## Development
322
504
 
@@ -351,7 +533,7 @@ A practical smoke path is:
351
533
  ```bash
352
534
  npm run build
353
535
  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
536
+ node dist/cli.js export --workspace ./tests/fixtures/source-workspace --out ./tests/tmp/readme-demo.ocpkg --runtime-mode none
355
537
  node dist/cli.js import ./tests/tmp/readme-demo.ocpkg --target-workspace ./tests/tmp/readme-demo-target --agent-id readme-demo
356
538
  node dist/cli.js validate --target-workspace ./tests/tmp/readme-demo-target --agent-id readme-demo
357
539
  npm test
@@ -359,7 +541,7 @@ npm test
359
541
 
360
542
  ## Naming
361
543
 
362
- The npm package name is **`clawpacker`** while the GitHub repository remains **`cogine-ai/clawpack`**.
544
+ The npm package name is **`@cogineai/clawpacker`** while the GitHub repository remains **`cogine-ai/clawpack`**.
363
545
 
364
546
  Why this naming split:
365
547
 
package/dist/cli.js CHANGED
@@ -6,17 +6,26 @@ const export_1 = require("./commands/export");
6
6
  const import_1 = require("./commands/import");
7
7
  const inspect_1 = require("./commands/inspect");
8
8
  const validate_1 = require("./commands/validate");
9
+ const renderable_cli_error_1 = require("./renderable-cli-error");
9
10
  const program = new commander_1.Command();
10
11
  program
11
12
  .name('clawpacker')
12
- .description('Export, import, and validate portable OpenClaw agent/workspace templates.')
13
- .version('0.1.0');
13
+ .description('Export, import, and validate portable OpenClaw agent/workspace templates.\n\nSupports an optional runtime layer (--runtime-mode) that packages agent-level\nconfig from the OpenClaw agentDir alongside workspace files.')
14
+ .version('0.3.0');
14
15
  (0, inspect_1.registerInspectCommand)(program.command('inspect'));
15
16
  (0, export_1.registerExportCommand)(program.command('export'));
16
17
  (0, import_1.registerImportCommand)(program.command('import'));
17
18
  (0, validate_1.registerValidateCommand)(program.command('validate'));
18
19
  program.parseAsync(process.argv).catch((error) => {
19
- console.error(error);
20
+ if ((0, renderable_cli_error_1.isRenderableCliError)(error)) {
21
+ console.error(error.render());
22
+ }
23
+ else if (error instanceof Error) {
24
+ console.error(error.message);
25
+ }
26
+ else {
27
+ console.error(String(error));
28
+ }
20
29
  process.exitCode = 1;
21
30
  });
22
31
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,8CAA0D;AAC1D,8CAA0D;AAC1D,gDAA4D;AAC5D,kDAA8D;AAC9D,iEAA8D;AAE9D,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,0NAA0N,CAAC;KACvO,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,IAAI,IAAA,2CAAoB,EAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAChC,CAAC;SAAM,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -5,6 +5,9 @@ interface ExportOptions {
5
5
  name?: string;
6
6
  config?: string;
7
7
  agentId?: string;
8
+ archive?: boolean;
9
+ json?: boolean;
10
+ runtimeMode?: string;
8
11
  }
9
12
  export declare function runExport(options: ExportOptions): Promise<void>;
10
13
  export declare function registerExportCommand(command: Command): void;
@@ -7,42 +7,92 @@ exports.runExport = runExport;
7
7
  exports.registerExportCommand = registerExportCommand;
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const agent_extract_1 = require("../core/agent-extract");
10
+ const openclaw_config_1 = require("../core/openclaw-config");
10
11
  const package_write_1 = require("../core/package-write");
12
+ const runtime_mode_1 = require("../core/runtime-mode");
13
+ const runtime_scan_1 = require("../core/runtime-scan");
11
14
  const skills_detect_1 = require("../core/skills-detect");
12
15
  const workspace_scan_1 = require("../core/workspace-scan");
13
16
  async function runExport(options) {
14
17
  if (!options.workspace || !options.out) {
15
18
  throw new Error('export requires --workspace <path> and --out <path>');
16
19
  }
20
+ const runtimeMode = (0, runtime_mode_1.normalizeRuntimeMode)(options.runtimeMode);
17
21
  const scan = await (0, workspace_scan_1.scanWorkspace)(node_path_1.default.resolve(options.workspace));
18
22
  const skills = await (0, skills_detect_1.detectSkills)(scan);
19
23
  const agentDefinition = await (0, agent_extract_1.extractAgentDefinition)(scan.workspacePath, {
20
24
  configPath: options.config,
21
25
  agentId: options.agentId,
22
26
  });
23
- const packageName = options.name ?? node_path_1.default.basename(options.out).replace(/\.ocpkg$/, '');
24
- const result = await (0, package_write_1.writePackageDirectory)({
27
+ const openclawVersion = await (0, openclaw_config_1.detectOpenClawVersion)({
28
+ configPath: options.config,
29
+ cwd: scan.workspacePath,
30
+ });
31
+ const packageName = options.name ?? node_path_1.default.basename(options.out).replace(/\.ocpkg(\.tar\.gz)?$/, '');
32
+ let runtimeScan;
33
+ if (runtimeMode && runtimeMode !== 'none') {
34
+ const agentDir = await (0, openclaw_config_1.resolveAgentDir)({
35
+ configPath: options.config,
36
+ workspacePath: scan.workspacePath,
37
+ agentId: options.agentId,
38
+ });
39
+ if (!agentDir) {
40
+ throw new Error('Cannot export runtime layer: agentDir could not be resolved from OpenClaw config. ' +
41
+ 'Ensure the agent entry includes an agentDir field, or use --runtime-mode none.');
42
+ }
43
+ runtimeScan = await (0, runtime_scan_1.scanRuntime)({
44
+ mode: runtimeMode,
45
+ agentDir,
46
+ workspacePath: scan.workspacePath,
47
+ });
48
+ }
49
+ const writeParams = {
25
50
  outputPath: node_path_1.default.resolve(options.out),
26
51
  packageName,
27
52
  scan,
28
53
  skills,
29
54
  agentDefinition,
30
- });
31
- console.log(JSON.stringify({
55
+ openclawVersion,
56
+ runtimeScan,
57
+ };
58
+ const result = options.archive
59
+ ? await (0, package_write_1.writePackageArchive)(writeParams)
60
+ : await (0, package_write_1.writePackageDirectory)(writeParams);
61
+ const report = {
32
62
  status: 'ok',
33
63
  packageRoot: result.packageRoot,
34
64
  manifestPath: result.manifestPath,
35
65
  fileCount: result.fileCount,
36
- }, null, 2));
66
+ runtimeMode: runtimeScan?.mode,
67
+ runtimeFiles: runtimeScan?.includedFiles.map(f => f.relativePath),
68
+ };
69
+ if (options.json) {
70
+ console.log(JSON.stringify(report, null, 2));
71
+ return;
72
+ }
73
+ const lines = [
74
+ 'Export complete',
75
+ ` Package: ${report.packageRoot}`,
76
+ ` Manifest: ${report.manifestPath}`,
77
+ ` Files: ${report.fileCount}`,
78
+ ];
79
+ if (runtimeScan && runtimeScan.mode !== 'none') {
80
+ lines.push(` Runtime mode: ${runtimeScan.mode}`);
81
+ lines.push(` Runtime files: ${runtimeScan.includedFiles.length}`);
82
+ }
83
+ console.log(lines.join('\n'));
37
84
  }
38
85
  function registerExportCommand(command) {
39
86
  command
40
- .description('Export a portable .ocpkg directory from a workspace.')
87
+ .description('Export a portable .ocpkg directory or .ocpkg.tar.gz archive from a workspace.')
41
88
  .requiredOption('--workspace <path>', 'Source workspace path')
42
- .requiredOption('--out <path>', 'Output package directory path')
89
+ .requiredOption('--out <path>', 'Output package path')
43
90
  .option('--name <package-name>', 'Package name override')
44
91
  .option('--config <path>', 'OpenClaw config path')
45
92
  .option('--agent-id <id>', 'Source agent id override')
93
+ .option('--runtime-mode <mode>', 'Runtime layer mode: none (skip), default (settings, prompts, themes, models), or full (adds skills, extensions). Requires a resolvable agentDir in OpenClaw config. Auth and session files are always excluded.')
94
+ .option('--archive', 'Produce a .ocpkg.tar.gz single-file archive')
95
+ .option('--json', 'Emit the full machine-readable JSON report')
46
96
  .action(runExport);
47
97
  }
48
98
  //# sourceMappingURL=export.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":";;;;;AAsBA,8BAgFC;AAED,sDAeC;AAvHD,0DAA6B;AAE7B,yDAA+D;AAC/D,6DAAiF;AACjF,yDAAmF;AACnF,uDAA4D;AAC5D,uDAAmD;AACnD,yDAAqD;AAErD,2DAAuD;AAahD,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,WAAW,GAAG,IAAA,mCAAoB,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,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,eAAe,GAAG,MAAM,IAAA,uCAAqB,EAAC;QAClD,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,GAAG,EAAE,IAAI,CAAC,aAAa;KACxB,CAAC,CAAC;IACH,MAAM,WAAW,GACf,OAAO,CAAC,IAAI,IAAI,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IAEjF,IAAI,WAA0C,CAAC;IAC/C,IAAI,WAAW,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACb,oFAAoF;gBACpF,gFAAgF,CACjF,CAAC;QACJ,CAAC;QAED,WAAW,GAAG,MAAM,IAAA,0BAAW,EAAC;YAC9B,IAAI,EAAE,WAAW;YACjB,QAAQ;YACR,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,WAAW,GAAG;QAClB,UAAU,EAAE,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;QACrC,WAAW;QACX,IAAI;QACJ,MAAM;QACN,eAAe;QACf,eAAe;QACf,WAAW;KACZ,CAAC;IAEF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO;QAC5B,CAAC,CAAC,MAAM,IAAA,mCAAmB,EAAC,WAAW,CAAC;QACxC,CAAC,CAAC,MAAM,IAAA,qCAAqB,EAAC,WAAW,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAG;QACb,MAAM,EAAE,IAAa;QACrB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,WAAW,EAAE,IAAI;QAC9B,YAAY,EAAE,WAAW,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;KAClE,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG;QACZ,iBAAiB;QACjB,cAAc,MAAM,CAAC,WAAW,EAAE;QAClC,eAAe,MAAM,CAAC,YAAY,EAAE;QACpC,YAAY,MAAM,CAAC,SAAS,EAAE;KAC/B,CAAC;IACF,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,mBAAmB,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,oBAAoB,WAAW,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAgB,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,WAAW,CAAC,+EAA+E,CAAC;SAC5F,cAAc,CAAC,oBAAoB,EAAE,uBAAuB,CAAC;SAC7D,cAAc,CAAC,cAAc,EAAE,qBAAqB,CAAC;SACrD,MAAM,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;SACxD,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;SACjD,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACrD,MAAM,CACL,uBAAuB,EACvB,iNAAiN,CAClN;SACA,MAAM,CAAC,WAAW,EAAE,6CAA6C,CAAC;SAClE,MAAM,CAAC,QAAQ,EAAE,4CAA4C,CAAC;SAC9D,MAAM,CAAC,SAAS,CAAC,CAAC;AACvB,CAAC"}
@@ -2,8 +2,11 @@ import type { Command } from 'commander';
2
2
  interface ImportOptions {
3
3
  targetWorkspace: string;
4
4
  agentId?: string;
5
+ targetAgentDir?: string;
5
6
  config?: string;
6
7
  force?: boolean;
8
+ json?: boolean;
9
+ dryRun?: boolean;
7
10
  }
8
11
  export declare function runImport(packagePath: string, options: ImportOptions): Promise<void>;
9
12
  export declare function registerImportCommand(command: Command): void;