akm-cli 0.9.8-beta.1 → 0.9.8-beta.3

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.
@@ -112,6 +112,12 @@ function base(input) {
112
112
  ...(input.containmentRoot ? { containmentRoot: input.containmentRoot } : {}),
113
113
  };
114
114
  }
115
+ /**
116
+ * #902: the one blocker with an unambiguous remedy. The sibling shell-safety
117
+ * reasons need a case-by-case judgement and stay reason-only.
118
+ */
119
+ const ARGV_ARRAY_BLOCK_DETAIL = "Manual conversion required: an array `command:` has no safe v3 `run:` string. Rewrite it by hand as " +
120
+ "`run:` (string) plus `shell:` — see docs/migration/v0.9.1-to-v0.9.2.md for the full v2 to v4 field mapping.";
115
121
  function blocked(input, reason, detail) {
116
122
  return Object.freeze({ status: "blocked", ...base(input), reason, ...(detail ? { detail } : {}) });
117
123
  }
@@ -389,8 +395,10 @@ export function planLegacyTaskDataToV3(input, data) {
389
395
  catch (cause) {
390
396
  return blocked(input, "invalid-v2-task", cause instanceof Error ? cause.message : String(cause));
391
397
  }
392
- if (isReason(migrated))
393
- return blocked(input, migrated);
398
+ if (isReason(migrated)) {
399
+ const detail = migrated === "argv-array-has-no-portable-shell-string" ? ARGV_ARRAY_BLOCK_DETAIL : undefined;
400
+ return blocked(input, migrated, detail);
401
+ }
394
402
  const after = Buffer.from(stringifyYaml(migrated), "utf8");
395
403
  try {
396
404
  parseTaskV3Yaml({
@@ -212,10 +212,24 @@ command: [node, scripts/release.js, "--exact value"]
212
212
 
213
213
  Shell-sensitive strings — assignments, shell builtins, reserved words, and
214
214
  similar constructs — are also blocked when translating them would invent
215
- shell semantics. The original bytes remain untouched. Author a v3 `run`
216
- string or a script/command asset deliberately, validate it, and rerun the
217
- preview. (This step still produces v3 output, which the second generation
218
- then carries the rest of the way to v4 in the same `akm migrate apply` run.)
215
+ shell semantics. The original bytes remain untouched, and `akm migrate
216
+ status`/`apply` names the block as `argv-array-has-no-portable-shell-string`
217
+ (or a sibling shell-safety reason) rather than guessing: this is manual
218
+ conversion, not a case the migrator can be re-run to fix. Rewrite the file
219
+ by hand using this field mapping:
220
+
221
+ | v2 | v4 |
222
+ |---|---|
223
+ | `command:` (array, argv style) | `run:` (string) plus `shell:` |
224
+ | `timeoutMs:` | `timeout:` |
225
+ | `enabled:` (document level) | removed — use `schedule:` as a list of `{cron, enabled}` entries |
226
+ | `schedule:` (cron string) | still accepted as a bare string, or as the list form above |
227
+
228
+ validate it, and rerun the preview. You can either write the replacement
229
+ directly as `version: 4` (generation 1 then reports it `already-v4` and
230
+ leaves it alone) or as a `version: 3` `run:` string, letting the second
231
+ generation carry it the rest of the way to v4 in the same `akm migrate
232
+ apply` run.
219
233
 
220
234
  ### Migrating task v3 to task source v4
221
235
 
@@ -582,7 +582,7 @@ Subcommands:
582
582
  | `list` | List workflow runs (optionally filtered by `--ref`; `--active` shows only `status=active` runs, excluding `blocked`/`failed`/`completed`). Child workflow runs are excluded unless `--children` is passed |
583
583
  | `resume <run-id>` | Flip a `blocked` or `failed` run back to `active`. Completed runs cannot be resumed |
584
584
  | `abandon <run-id>` | Mark a run failed so it stops counting as active (`resume` can reopen it) |
585
- | `plan <ref>` | **Evolving.** Compile and freeze a workflow WITHOUT publishing a run: the canonical step graph, per-step frozen target kinds, task/child expansion, input bindings, source read set, and lowering notices — zero durable writes. Defaults to a human-readable summary; pass `--format json` for the full envelope |
585
+ | `plan <ref>` | **Evolving.** Compile and freeze a workflow WITHOUT publishing a run: the canonical step graph, per-step frozen target kinds, task/child expansion, input bindings, source read set, and lowering notices — zero durable writes. Returns the full JSON envelope by default, like every other command; pass `--format text` for a human-readable summary |
586
586
 
587
587
  The public `workflow start`, `next`, and `complete` lifecycle was removed in
588
588
  0.9, along with the experimental `brief`/`report` external-driver protocol.
@@ -60,6 +60,7 @@ Override: set `AKM_CONFIG_DIR` or `XDG_CONFIG_HOME`.
60
60
  | `state.db` | Events, local usage telemetry, proposals, task history, improve run results, and workflow run state/history (the former `workflow.db` was folded in during the 0.9.0 cutover) | **No** — deletes event/usage logs, proposal queue, improve history, and workflow run history |
61
61
  | `logs.db` | Structured, high-volume task/run log lines (`{ts, task_id, run_id, stream, level, line}`), joined to `state.db`'s `task_history` rows by `task_id@started_at`. Kept separate from `state.db` because log lines are append-only and freely purgeable, unlike durable state | Yes — log lines are regenerable per run; deleting loses historical run output only |
62
62
  | `akm.lock` | Inter-process write lock | Yes — recreated automatically |
63
+ | `backups/task-v3/`, `backups/task-v4/` | Copies of task files taken by `akm migrate apply` before it rewrites them, one timestamped directory per run; the five most recent per generation are kept (#897) | Yes — once the migrated tasks are verified |
63
64
  | `akm.lock.lck` | Lock write sentinel | Yes — recreated automatically |
64
65
 
65
66
  Override: set `AKM_DATA_DIR` or `XDG_DATA_HOME`.
@@ -325,6 +325,17 @@ for both generations combined. Resolve every blocked file manually, then
325
325
  preview again. Apply validates a complete replacement before writing and
326
326
  backs up each original immediately before replacement.
327
327
 
328
+ Common v2 → v3 blocked reasons and what to do about each — these need a
329
+ hand-authored replacement, not a re-run; see [the 0.9.1 to 0.9.2 migration
330
+ guide](../migration/v0.9.1-to-v0.9.2.md#v2--v3-blocked-cases) for the full v2
331
+ to v4 field mapping (`command:` array → `run:` + `shell:`, `timeoutMs:` →
332
+ `timeout:`, document-level `enabled:` → per-`schedule:`-entry `enabled`):
333
+
334
+ | Reason | Meaning | Fix |
335
+ |---|---|---|
336
+ | `argv-array-has-no-portable-shell-string` | The task's `command:` is an argv array; no single shell string is provably equivalent. | Rewrite the file by hand — a `run:` string plus `shell:` — using the field mapping above. |
337
+ | `shell-quoting-changes-v2-whitespace-split-semantics`, `shell-operators-change-v2-literal-argv-semantics`, `shell-command-resolution-changes-v2-literal-argv-semantics` | The `command:` string contains quoting, shell operators, or a bare executable name whose v2 argv-exec behavior a v3 `run:` (host-shell) invocation cannot reproduce unambiguously. | Review the command's intended shell semantics and author the v3/v4 `run:`/`shell:` fields by hand. |
338
+
328
339
  Common v3 → v4 blocked reasons and what to do about each:
329
340
 
330
341
  | Reason | Meaning | Fix |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akm-cli",
3
- "version": "0.9.8-beta.1",
3
+ "version": "0.9.8-beta.3",
4
4
  "type": "module",
5
5
  "description": "akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cursor.",
6
6
  "keywords": [
@@ -77,14 +77,10 @@
77
77
  "test:integration": "bash scripts/test-integration.sh",
78
78
  "test:node-smoke": "bun scripts/node-smoke.ts",
79
79
  "test:node-compat": "AKM_NODE_COMPAT_TESTS=1 bun test --timeout=120000 tests/integration/node-compat.test.ts",
80
- "lint:isolation": "bun scripts/lint-tests-isolation.ts",
81
80
  "lint:doc-examples": "bun scripts/lint-doc-examples.ts",
82
- "lint:active-docs-terminology": "bun scripts/lint-active-docs-terminology.ts",
83
81
  "publish:devto": "npx -y @sinedied/devto-cli push \"docs/posts/**/*.md\" --token \"$DEVTO_TOKEN\" --repo \"$GITHUB_REPOSITORY\" --branch \"${GITHUB_REF_NAME:-main}\" --reconcile",
84
82
  "release:check": "./tests/release-check.sh",
85
83
  "lint": "bunx biome check src/ tests/ scripts/ && bun scripts/lint-secret-resolver-boundary.ts && bun scripts/lint-shipped-assets.ts && bun scripts/lint-doc-examples.ts",
86
- "lint:runtime-boundary": "bun scripts/lint-runtime-boundary.ts",
87
- "lint:tests-isolation": "bun scripts/lint-tests-isolation.ts",
88
84
  "lint:fix": "bunx biome check --write src/ tests/ scripts/",
89
85
  "format": "bunx biome format --write src/ tests/ scripts/",
90
86
  "prepublishOnly": "cp .github/README.npm.md README.md && bun run build",