akm-cli 0.9.17-alpha.2 → 0.9.17-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +756 -0
- package/dist/akm +94 -196
- package/dist/cli/shared.js +6 -2
- package/dist/cli.js +22 -9
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +2 -2
- package/dist/commands/health/checks.js +30 -75
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +0 -38
- package/dist/commands/health/improve-metrics.js +123 -562
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +11 -106
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -73
- package/dist/commands/health.js +122 -143
- package/dist/commands/improve/consolidate/chunking.js +25 -100
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +538 -1075
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1075
- package/dist/commands/improve/eligibility.js +126 -400
- package/dist/commands/improve/execution.js +3 -5
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +29 -166
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +12 -7
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +443 -1063
- package/dist/commands/improve/ledger.js +114 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +459 -1172
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +14 -118
- package/dist/commands/improve/memory/memory-improve.js +4 -3
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -10
- package/dist/commands/improve/preparation.js +851 -2339
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +621 -1367
- package/dist/commands/improve/salience.js +46 -232
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +323 -0
- package/dist/commands/proposal/drain.js +251 -644
- package/dist/commands/proposal/proposal-cli.js +3 -18
- package/dist/commands/proposal/proposal-types.js +20 -41
- package/dist/commands/proposal/proposal.js +1 -2
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +502 -1487
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +13 -89
- package/dist/commands/read/curate.js +63 -413
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +2 -13
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +7 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +2 -11
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/stash-cli.js +1 -1
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +9 -8
- package/dist/commands/tasks/tasks.js +326 -930
- package/dist/commands/tasks/validate.js +42 -21
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +0 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +11 -12
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +291 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +1 -33
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +163 -68
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +21 -95
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-lock.js +76 -173
- package/dist/core/logs-db.js +2 -2
- package/dist/core/paths.js +0 -27
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +108 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +293 -1012
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/graph-db.js +106 -46
- package/dist/indexer/ensure-index.js +44 -85
- package/dist/indexer/graph/graph-extraction.js +340 -562
- package/dist/indexer/graph/graph-related.js +130 -0
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +139 -151
- package/dist/indexer/indexer.js +524 -846
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +81 -90
- package/dist/indexer/passes/metadata.js +132 -200
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +1 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +181 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +2 -7
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +10 -15
- package/dist/llm/graph-extract.js +3 -12
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/metadata-enhance.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +2 -34
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +60 -23
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +1 -2
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +43937 -93313
- package/dist/scripts/akm-migrate.js +43697 -93071
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +0 -17
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +168 -0
- package/dist/storage/repositories/index-connection.js +34 -70
- package/dist/storage/repositories/index-entries-repository.js +69 -111
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +83 -269
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +192 -220
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +35 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +34 -27
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +129 -277
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +125 -745
- package/dist/tasks/backends/schtasks.js +101 -620
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/scheduler-binding.js +18 -238
- package/dist/tasks/scheduler-invocation.js +52 -52
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +363 -679
- package/dist/tasks/source/parse-task-source.js +160 -10
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +2 -2
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +41 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
- package/docs/reference/cli.md +182 -125
- package/docs/reference/configuration.md +49 -56
- package/docs/reference/data-and-telemetry.md +19 -20
- package/docs/reference/tasks.md +86 -38
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +87 -406
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -146
- package/dist/commands/improve/distill/promote-memory.js +0 -329
- package/dist/commands/improve/distill/quality-gate.js +0 -500
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -21
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/config/retired-experimental-keys-shim.js +0 -62
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -78
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -9,18 +9,23 @@
|
|
|
9
9
|
* a bundle/adapter/concept id at all — it reads exactly the path it was
|
|
10
10
|
* given and classifies it.
|
|
11
11
|
*
|
|
12
|
-
* Reuses the exact
|
|
13
|
-
* (`src/tasks/source/parse-task-source.ts`)
|
|
14
|
-
* reader
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* Reuses the exact version-routing shim `parseTaskSource`
|
|
13
|
+
* (`src/tasks/source/parse-task-source.ts`) already applies for every other
|
|
14
|
+
* task-source reader (`akm task sync`'s `compileTaskSources` included) —
|
|
15
|
+
* this module never forks a second parser or a second v2/v3 migration
|
|
16
|
+
* planner. `readBoundedTaskSourceYaml` / `peekTaskSourceVersion` / `own` are
|
|
17
|
+
* the SAME front-end helpers that shim itself calls first; they are used
|
|
18
|
+
* here only to recover the file's ORIGINALLY DECLARED schema version for
|
|
19
|
+
* the report, because `parseTaskSource`'s own `ParsedTaskSource.version` is
|
|
20
|
+
* always `4` post-shim — it cannot answer "was this a v2/v3/v4 file?" on
|
|
21
|
+
* its own once a v2/v3 source has been converted in memory.
|
|
17
22
|
*
|
|
18
23
|
* Beyond parsing, this module also runs the SAME two per-source gates
|
|
19
24
|
* `akm task sync`'s `compileTaskSources` runs before it ever installs a
|
|
20
25
|
* schedule — `assertTaskScheduleInputsSatisfyContract` and
|
|
21
26
|
* `assertTaskScheduleCronValid` (both extracted from `scheduler-sync.ts` for
|
|
22
27
|
* exactly this reuse) — so a file `sync` would reject can never
|
|
23
|
-
* be reported `valid` here. Cron dialect is checked against
|
|
28
|
+
* be reported `valid`/`converts` here. Cron dialect is checked against
|
|
24
29
|
* `backendNameForPlatform()`, the same platform default `sync` falls back
|
|
25
30
|
* to whenever it has no injected/native-inspected backend to hand (see
|
|
26
31
|
* `akmTasksAdd`, `src/commands/tasks/tasks.ts`); a bare file was never
|
|
@@ -43,12 +48,23 @@
|
|
|
43
48
|
* table in its header, extended for the two gates above):
|
|
44
49
|
* - `valid` — parses as task source v4 directly (declared `version: 4`)
|
|
45
50
|
* and passes both sync gates.
|
|
46
|
-
* - `
|
|
47
|
-
*
|
|
51
|
+
* - `converts` — declared `version: 2` or `3`; the deterministic
|
|
52
|
+
* in-memory migrator produced a valid v4 document that
|
|
53
|
+
* passes both sync gates. A declared `version: 4`
|
|
54
|
+
* document whose only defect is a retired
|
|
55
|
+
* `schedule[].enabled` key also reports `converts`
|
|
56
|
+
* (`sourceVersion` is still `4`) — it read through the
|
|
57
|
+
* same in-memory shim, not the direct v4 parse path.
|
|
58
|
+
* - `blocked` — declared `version: 2` or `3`; the migrator itself
|
|
59
|
+
* could not convert it (an ambiguous/unmigratable
|
|
60
|
+
* shape) — the ONLY way `parseTaskSource` ever throws
|
|
61
|
+
* for those two version numbers, so no message-text
|
|
62
|
+
* sniffing is needed to tell this apart from `invalid`.
|
|
48
63
|
* - `invalid` — the document declares SOME version (`4`, or anything
|
|
49
64
|
* other than 2/3/4) but fails to parse/validate, OR it
|
|
50
|
-
* parsed
|
|
51
|
-
*
|
|
65
|
+
* parsed (directly or via a SUCCESSFUL v2/v3
|
|
66
|
+
* conversion) but fails one of the two sync gates
|
|
67
|
+
* above, OR the YAML itself does not parse at all
|
|
52
68
|
* (a genuine syntax error, not merely a non-task
|
|
53
69
|
* shape) — reported with the parser's own reason.
|
|
54
70
|
* - `not-a-task` — the document parses as YAML but never declares a
|
|
@@ -62,7 +78,7 @@ import { UsageError } from "../../core/errors.js";
|
|
|
62
78
|
import { backendNameForPlatform } from "../../tasks/backends/index.js";
|
|
63
79
|
import { assertTaskScheduleCronValid, assertTaskScheduleInputsSatisfyContract } from "../../tasks/scheduler-sync.js";
|
|
64
80
|
import { own, readBoundedTaskSourceYaml } from "../../tasks/source/bounded-document.js";
|
|
65
|
-
import { parseTaskSource, peekTaskSourceVersion } from "../../tasks/source/parse-task-source.js";
|
|
81
|
+
import { parseTaskSource, peekTaskSourceVersion, v4ScheduleHasRetiredEnabledKey, } from "../../tasks/source/parse-task-source.js";
|
|
66
82
|
/** True when `root` is a YAML mapping that itself declares a `version:` key, regardless of that key's type/value. */
|
|
67
83
|
function declaresVersionKey(root) {
|
|
68
84
|
return root !== null && typeof root === "object" && !Array.isArray(root) && own(root, "version");
|
|
@@ -126,14 +142,11 @@ export async function akmTaskValidate(filePath) {
|
|
|
126
142
|
if (!(cause instanceof UsageError))
|
|
127
143
|
throw cause;
|
|
128
144
|
const reason = cause.message;
|
|
145
|
+
// `parseTaskSource` only ever throws for a declared version 2/3 via the
|
|
146
|
+
// unmigratable-conversion branch (see this file's header) — no separate
|
|
147
|
+
// message check needed to recognize "blocked" here.
|
|
129
148
|
if (declaredVersion === 2 || declaredVersion === 3) {
|
|
130
|
-
return {
|
|
131
|
-
ok: false,
|
|
132
|
-
path: resolvedPath,
|
|
133
|
-
sourceVersion: declaredVersion,
|
|
134
|
-
outcome: "blocked",
|
|
135
|
-
reason: `${reason} Run \`akm migrate apply --dry-run\`, review the plan, then run \`akm migrate apply\`.`,
|
|
136
|
-
};
|
|
149
|
+
return { ok: false, path: resolvedPath, sourceVersion: declaredVersion, outcome: "blocked", reason };
|
|
137
150
|
}
|
|
138
151
|
if (peekFailed) {
|
|
139
152
|
return { ok: false, path: resolvedPath, outcome: "invalid", reason };
|
|
@@ -152,8 +165,11 @@ export async function akmTaskValidate(filePath) {
|
|
|
152
165
|
// Success is unreachable from any path that leaves `declaredVersion`
|
|
153
166
|
// undefined — the router requires a numeric 2/3/4 version to reach here.
|
|
154
167
|
const sourceVersion = declaredVersion ?? 4;
|
|
155
|
-
// The
|
|
156
|
-
//
|
|
168
|
+
// The document itself parsed (directly, or via a successful v2/v3
|
|
169
|
+
// conversion) — now the two gates `compileTaskSources` runs before
|
|
170
|
+
// accepting it. A violation here is `invalid`, never `blocked`: the
|
|
171
|
+
// migrator already succeeded, so this is the same kind of defect a
|
|
172
|
+
// native v4 document with the identical schedule would have.
|
|
157
173
|
try {
|
|
158
174
|
assertTaskScheduleInputsSatisfyContract(parsed.v4, resolvedPath);
|
|
159
175
|
assertTaskScheduleCronValid(parsed.v4, backend);
|
|
@@ -163,12 +179,17 @@ export async function akmTaskValidate(filePath) {
|
|
|
163
179
|
throw cause;
|
|
164
180
|
return { ok: false, path: resolvedPath, sourceVersion, outcome: "invalid", reason: cause.message };
|
|
165
181
|
}
|
|
182
|
+
// A declared `version: 4` document with a retired `schedule[].enabled`
|
|
183
|
+
// key parsed through `parseTaskSource`'s in-memory shim, not the direct
|
|
184
|
+
// v4 path, even though `sourceVersion` reads `4` — report it the same
|
|
185
|
+
// way a converted v2/v3 document is reported.
|
|
186
|
+
const convertedFromRetiredScheduleEnabled = sourceVersion === 4 && !peekFailed && v4ScheduleHasRetiredEnabledKey(root);
|
|
166
187
|
const id = path.parse(resolvedPath).name;
|
|
167
188
|
return {
|
|
168
189
|
ok: true,
|
|
169
190
|
path: resolvedPath,
|
|
170
191
|
sourceVersion,
|
|
171
|
-
outcome: "valid",
|
|
192
|
+
outcome: sourceVersion === 2 || sourceVersion === 3 || convertedFromRetiredScheduleEnabled ? "converts" : "valid",
|
|
172
193
|
resolved: buildResolved(id, parsed.v4),
|
|
173
194
|
};
|
|
174
195
|
}
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
|
-
* `akm workflow plan <ref>` — compile + freeze WITHOUT publishing
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* never `publishWorkflowRunV4`, `startWorkflowRun`, `warn()`, `appendEvent`,
|
|
11
|
-
* or `akmIndex`.
|
|
5
|
+
* `akm workflow plan <ref>` — compile + freeze WITHOUT publishing. Zero
|
|
6
|
+
* durable writes, zero usage/event rows: this module calls exactly the same
|
|
7
|
+
* two functions `startWorkflowRun` does to reach a frozen plan
|
|
8
|
+
* (`loadWorkflowAsset`, `freezeWorkflow`) and NOTHING else — never
|
|
9
|
+
* `publishWorkflowRunV4`, `startWorkflowRun`, `appendEvent`, or `akmIndex`.
|
|
12
10
|
*
|
|
13
11
|
* SECRET-FREE, by construction (§4.6's closed print list): a resolved
|
|
14
12
|
* reference VALUE is never printed (references resolve at pre-attempt, not
|
|
@@ -20,9 +18,8 @@
|
|
|
20
18
|
*/
|
|
21
19
|
import path from "node:path";
|
|
22
20
|
import { loadConfig } from "../../core/config/config.js";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import { compileResolveFreezeWorkflowV4 } from "../../workflows/ir/freeze-v4.js";
|
|
21
|
+
import { buildExecutionFromWire } from "../../integrations/agent/execution.js";
|
|
22
|
+
import { freezeWorkflow } from "../../workflows/freeze/freeze.js";
|
|
26
23
|
import { computePlanHash } from "../../workflows/ir/plan-hash.js";
|
|
27
24
|
import { loadWorkflowAsset } from "../../workflows/runtime/workflow-asset-loader.js";
|
|
28
25
|
/** The step's dispatch unit — the map template for a fan-out, else the root unit. Undefined for a route step. */
|
|
@@ -49,7 +46,7 @@ function childExportedOutputNames(frozenPlan) {
|
|
|
49
46
|
}
|
|
50
47
|
/**
|
|
51
48
|
* A `child-workflow` target's `expansion`. Recurses into the embedded
|
|
52
|
-
* plan's own steps in the identical shape
|
|
49
|
+
* plan's own steps in the identical shape — `usesById` is
|
|
53
50
|
* omitted for the recursive call because a nested child's own authored
|
|
54
51
|
* source is not available here (only its already-frozen plan is), so a
|
|
55
52
|
* task-wrapped step nested inside a child conservatively reports `via:
|
|
@@ -67,15 +64,15 @@ function childExpansion(target) {
|
|
|
67
64
|
};
|
|
68
65
|
}
|
|
69
66
|
/** The task/child expansion boundary for one step (§4.6). */
|
|
70
|
-
function stepExpansion(step, frozenTarget,
|
|
67
|
+
function stepExpansion(step, frozenTarget, usesById) {
|
|
71
68
|
if (frozenTarget?.kind === "child-workflow")
|
|
72
69
|
return childExpansion(frozenTarget);
|
|
73
|
-
const uses =
|
|
70
|
+
const uses = usesById?.get(step.stepId);
|
|
74
71
|
if (uses?.startsWith("tasks/"))
|
|
75
72
|
return { via: "task", taskRef: uses };
|
|
76
73
|
return { via: "direct" };
|
|
77
74
|
}
|
|
78
|
-
function projectStep(step, sequenceIndex,
|
|
75
|
+
function projectStep(step, sequenceIndex, usesById) {
|
|
79
76
|
const unit = stepUnit(step);
|
|
80
77
|
const frozenTarget = unit?.frozenTarget;
|
|
81
78
|
const kind = step.route ? "route" : step.root?.kind === "map" ? "map" : "unit";
|
|
@@ -95,7 +92,7 @@ function projectStep(step, sequenceIndex, sourceStepsById) {
|
|
|
95
92
|
judgeEngine: step.gate.frozenJudge ? step.gate.frozenJudge.request.engine.name : null,
|
|
96
93
|
},
|
|
97
94
|
...(step.outputSchema !== undefined ? { outputSchema: step.outputSchema } : {}),
|
|
98
|
-
expansion: stepExpansion(step, frozenTarget,
|
|
95
|
+
expansion: stepExpansion(step, frozenTarget, usesById),
|
|
99
96
|
};
|
|
100
97
|
}
|
|
101
98
|
/**
|
|
@@ -103,30 +100,27 @@ function projectStep(step, sequenceIndex, sourceStepsById) {
|
|
|
103
100
|
* from its own already-frozen `request` (the identical computation
|
|
104
101
|
* `freeze/targets/command.ts`'s `commandResult` already performs at freeze
|
|
105
102
|
* time and discards) — walked over the whole plan, including gate judges and
|
|
106
|
-
* recursively into every embedded child plan. Read-only: `
|
|
107
|
-
*
|
|
103
|
+
* recursively into every embedded child plan. Read-only: `buildExecutionFromWire`
|
|
104
|
+
* reads no config and dispatches nothing.
|
|
108
105
|
*/
|
|
109
106
|
function collectLoweringNotices(plan, config) {
|
|
110
107
|
const notices = [];
|
|
111
|
-
const lower = (
|
|
112
|
-
notices.push(...
|
|
108
|
+
const lower = (target) => {
|
|
109
|
+
notices.push(...buildExecutionFromWire(target).notices);
|
|
113
110
|
};
|
|
114
111
|
for (const step of plan.steps) {
|
|
115
112
|
const unit = stepUnit(step);
|
|
116
113
|
if (unit) {
|
|
117
114
|
if (unit.frozenTarget.kind === "command")
|
|
118
|
-
lower(unit.frozenTarget
|
|
115
|
+
lower(unit.frozenTarget);
|
|
119
116
|
else if (unit.frozenTarget.kind === "child-workflow")
|
|
120
117
|
notices.push(...collectLoweringNotices(unit.frozenTarget.frozenPlan, config));
|
|
121
118
|
}
|
|
122
119
|
if (step.gate.frozenJudge)
|
|
123
|
-
lower(step.gate.frozenJudge
|
|
120
|
+
lower(step.gate.frozenJudge);
|
|
124
121
|
}
|
|
125
122
|
return notices;
|
|
126
123
|
}
|
|
127
|
-
function relativeSourceReadSet(plan) {
|
|
128
|
-
return plan.sourceReadSet.map((snapshot) => snapshot.identity.file);
|
|
129
|
-
}
|
|
130
124
|
/**
|
|
131
125
|
* Compile + freeze `ref` and project the frozen plan into the read-only
|
|
132
126
|
* `akm workflow plan` envelope. Never publishes, never writes, never warns.
|
|
@@ -134,9 +128,9 @@ function relativeSourceReadSet(plan) {
|
|
|
134
128
|
export async function akmWorkflowPlan(ref) {
|
|
135
129
|
const asset = await loadWorkflowAsset(ref);
|
|
136
130
|
const config = loadConfig();
|
|
137
|
-
const frozen = await
|
|
131
|
+
const frozen = await freezeWorkflow(asset, config);
|
|
138
132
|
const plan = frozen.plan;
|
|
139
|
-
const
|
|
133
|
+
const usesById = new Map(asset.plan.steps.map((step) => [step.stepId, step.spec?.uses]));
|
|
140
134
|
const sourceFormat = path.extname(asset.path).toLowerCase() === ".md" ? "markdown" : "github-yaml";
|
|
141
135
|
return {
|
|
142
136
|
ok: true,
|
|
@@ -151,9 +145,8 @@ export async function akmWorkflowPlan(ref) {
|
|
|
151
145
|
...(plan.budget ? { budget: plan.budget } : {}),
|
|
152
146
|
...(plan.params ? { params: plan.params } : {}),
|
|
153
147
|
...(plan.outputs ? { outputs: plan.outputs } : {}),
|
|
154
|
-
steps: plan.steps.map((step, index) => projectStep(step, index,
|
|
155
|
-
sourceReadSet: relativeSourceReadSet(plan),
|
|
148
|
+
steps: plan.steps.map((step, index) => projectStep(step, index, usesById)),
|
|
156
149
|
notices: collectLoweringNotices(plan, config),
|
|
157
|
-
warnings:
|
|
150
|
+
warnings: frozen.warnings.map((warning) => warning.message),
|
|
158
151
|
};
|
|
159
152
|
}
|
|
@@ -15,7 +15,7 @@ import { NotFoundError, TransientError, UsageError } from "../core/errors.js";
|
|
|
15
15
|
import { warn } from "../core/warn.js";
|
|
16
16
|
import { akmIndex } from "../indexer/indexer.js";
|
|
17
17
|
import { assertWorkflowMarkdownName, createWorkflowAsset, getWorkflowTemplate } from "../workflows/authoring/authoring.js";
|
|
18
|
-
import { WORKFLOW_MAX_TIMEOUT_MS } from "../workflows/
|
|
18
|
+
import { WORKFLOW_MAX_TIMEOUT_MS } from "../workflows/resource-limits.js";
|
|
19
19
|
import { abandonWorkflowRun, getWorkflowStatus, listWorkflowRuns, resolveWorkflowRunTarget, resumeWorkflowRun, } from "../workflows/runtime/runs.js";
|
|
20
20
|
import { akmWorkflowPlan } from "./workflow/plan.js";
|
|
21
21
|
const workflowStatusCommand = defineJsonCommand({
|
|
@@ -174,8 +174,8 @@ const workflowCreateCommand = defineJsonCommand({
|
|
|
174
174
|
* `--skip-if-locked` (#948) eligibility: only these two named, retryable
|
|
175
175
|
* `TransientError` codes (#948 addendum — moved off UsageError, exit 75) turn
|
|
176
176
|
* a `workflow run` failure into a graceful skip — `RUN_LEASE_HELD` (another
|
|
177
|
-
*
|
|
178
|
-
*
|
|
177
|
+
* live akm process holds THIS run's lock file, `exec/run-workflow.ts`) and
|
|
178
|
+
* `STATE_DB_CONTENDED` (an unrelated akm process is
|
|
179
179
|
* writing state.db right now, `core/state-db.ts`'s BEGIN IMMEDIATE retry
|
|
180
180
|
* exhaustion). Every other error — a bad flag, an unresolvable target —
|
|
181
181
|
* still fails loudly.
|
|
@@ -202,7 +202,7 @@ const workflowRunCommand = defineJsonCommand({
|
|
|
202
202
|
},
|
|
203
203
|
"skip-if-locked": {
|
|
204
204
|
type: "boolean",
|
|
205
|
-
description: "If another akm process already
|
|
205
|
+
description: "If another akm process is already driving this run, or state.db is busy with another " +
|
|
206
206
|
"writer, skip gracefully (exit 0) instead of failing (exit 75). Use for high-frequency scheduled runs " +
|
|
207
207
|
"so they don't pile up failures while a longer-running invocation is in progress.",
|
|
208
208
|
default: false,
|
|
@@ -192,7 +192,6 @@ const DOCUMENT_JSON_CARRIED_FIELDS = [
|
|
|
192
192
|
"cwd",
|
|
193
193
|
"wikiRole",
|
|
194
194
|
"sources",
|
|
195
|
-
"generation",
|
|
196
195
|
"evidenceSources",
|
|
197
196
|
// D2 (#730): the OKF v0.2 provenance `promoteProposal` stamps onto AKM-native
|
|
198
197
|
// writes (generated/verified/sources, namespaced — see `types.ts`'s
|
|
@@ -54,8 +54,7 @@ import path from "node:path";
|
|
|
54
54
|
import { isDangerousEnvKey } from "../../../commands/lint/env-key-rules.js";
|
|
55
55
|
import { parseTaskSource } from "../../../tasks/source/parse-task-source.js";
|
|
56
56
|
import { taskSourceErrorDetail } from "../../../tasks/source-v3.js";
|
|
57
|
-
import {
|
|
58
|
-
import { compileWorkflowSource } from "../../../workflows/source-ir/compile.js";
|
|
57
|
+
import { checkWorkflowPlan, compileWorkflowSource } from "../../../workflows/compile.js";
|
|
59
58
|
import { conceptIdForStashFile } from "../../asset/resolve-ref.js";
|
|
60
59
|
import { isAkmRegistryCachePath, scanEnvKeyNames } from "../../common.js";
|
|
61
60
|
/** Recommended `category` values for facts — `commands/lint/fact-linter.ts:9`. */
|
|
@@ -370,7 +369,7 @@ export function workflowFrontendDiagnostics(relPath, raw, parsePath) {
|
|
|
370
369
|
}
|
|
371
370
|
return { errors, warnings };
|
|
372
371
|
}
|
|
373
|
-
const compiled =
|
|
372
|
+
const compiled = checkWorkflowPlan(result.plan);
|
|
374
373
|
if (!compiled.ok) {
|
|
375
374
|
for (const err of compiled.errors) {
|
|
376
375
|
errors.push({
|
|
@@ -56,8 +56,7 @@
|
|
|
56
56
|
*/
|
|
57
57
|
import { scanEnvKeyNames } from "../../../commands/env/env.js";
|
|
58
58
|
import { parseTaskSource } from "../../../tasks/source/parse-task-source.js";
|
|
59
|
-
import { compileWorkflowSource } from "../../../workflows/
|
|
60
|
-
import { sourceStepInstructions } from "../../../workflows/source-ir/program.js";
|
|
59
|
+
import { compileWorkflowSource, workflowStepInstructions } from "../../../workflows/compile.js";
|
|
61
60
|
import { parseFrontmatter } from "../../asset/frontmatter.js";
|
|
62
61
|
import { parseMarkdownToc } from "../../asset/markdown.js";
|
|
63
62
|
import { nonEmptyString } from "./shared.js";
|
|
@@ -320,19 +319,19 @@ export function foldRecognizedMetadata(rendererName, file) {
|
|
|
320
319
|
const result = compileWorkflowSource(file.content(), { path: file.relPath, workspaceRoot: file.stashRoot });
|
|
321
320
|
if (!result.ok)
|
|
322
321
|
return out;
|
|
323
|
-
const
|
|
322
|
+
const plan = result.plan;
|
|
324
323
|
const hints = new Set();
|
|
325
|
-
if (
|
|
326
|
-
hints.add(
|
|
327
|
-
for (const step of
|
|
328
|
-
hints.add(step.
|
|
329
|
-
hints.add(
|
|
330
|
-
if (step.gate
|
|
331
|
-
hints.add(step.gate.
|
|
324
|
+
if (plan.preamble)
|
|
325
|
+
hints.add(plan.preamble);
|
|
326
|
+
for (const step of plan.steps) {
|
|
327
|
+
hints.add(step.stepId);
|
|
328
|
+
hints.add(workflowStepInstructions(step));
|
|
329
|
+
if (step.gate.criteria[0])
|
|
330
|
+
hints.add(step.gate.criteria[0]);
|
|
332
331
|
}
|
|
333
332
|
out.searchHints = Array.from(hints).filter(Boolean);
|
|
334
|
-
if (
|
|
335
|
-
const parameters = Object.entries(
|
|
333
|
+
if (plan.paramSchemas) {
|
|
334
|
+
const parameters = Object.entries(plan.paramSchemas).map(([name, schema]) => {
|
|
336
335
|
const description = schema.description;
|
|
337
336
|
return { name, ...(typeof description === "string" && description ? { description } : {}) };
|
|
338
337
|
});
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import fs from "node:fs";
|
|
23
23
|
import path from "node:path";
|
|
24
|
-
import { looksLikeGithubWorkflowSource } from "../../../workflows/
|
|
24
|
+
import { looksLikeGithubWorkflowSource } from "../../../workflows/compile.js";
|
|
25
25
|
import { parseFrontmatter } from "../../asset/frontmatter.js";
|
|
26
26
|
import { toPosix } from "../../common.js";
|
|
27
27
|
import { perTypeValidateChecks, workflowYamlSourceDiagnostics } from "./akm-lint.js";
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { isMap, isScalar, parseDocument, visit } from "yaml";
|
|
6
6
|
import { cloneExecutionJson, cloneExecutionJsonObject, } from "../../execution/json.js";
|
|
7
|
-
import {
|
|
7
|
+
import { snapshotStrictRecord } from "../../execution/record.js";
|
|
8
8
|
import { cloneToolSelection, createAdapterRenderedExecutionSource, } from "../../execution/source.js";
|
|
9
9
|
import { UsageError } from "../errors.js";
|
|
10
10
|
import { warnOnce } from "../warn.js";
|
|
@@ -137,20 +137,16 @@ function nullableTimeout(value, path) {
|
|
|
137
137
|
/** Adapter helper for the common frontmatter fields fixed by the 0.9.2 design. */
|
|
138
138
|
export function executionDefaultsFromFrontmatter(data, options) {
|
|
139
139
|
const frontmatter = snapshotStrictRecord(data, "frontmatter");
|
|
140
|
-
const
|
|
141
|
-
assertSnapshotKeys(optionRecord, ["kind", "allowTopLevelEngine", "toolsKeys"], "execution frontmatter projection options");
|
|
142
|
-
const kind = optionRecord.kind;
|
|
140
|
+
const kind = options.kind;
|
|
143
141
|
if (kind !== "command" && kind !== "persona") {
|
|
144
142
|
throw new TypeError("execution frontmatter projection options.kind is invalid");
|
|
145
143
|
}
|
|
146
|
-
const allowTopLevelEngine = Object.hasOwn(
|
|
147
|
-
? optionRecord.allowTopLevelEngine
|
|
148
|
-
: false;
|
|
144
|
+
const allowTopLevelEngine = Object.hasOwn(options, "allowTopLevelEngine") ? options.allowTopLevelEngine : false;
|
|
149
145
|
if (typeof allowTopLevelEngine !== "boolean") {
|
|
150
146
|
throw new TypeError("execution frontmatter projection options.allowTopLevelEngine must be a boolean");
|
|
151
147
|
}
|
|
152
|
-
const configuredToolsKeys = Object.hasOwn(
|
|
153
|
-
? cloneExecutionJson(
|
|
148
|
+
const configuredToolsKeys = Object.hasOwn(options, "toolsKeys")
|
|
149
|
+
? cloneExecutionJson(options.toolsKeys, "execution frontmatter projection options.toolsKeys")
|
|
154
150
|
: ["tools"];
|
|
155
151
|
if (!Array.isArray(configuredToolsKeys) || configuredToolsKeys.some((key) => typeof key !== "string" || !key)) {
|
|
156
152
|
throw new TypeError("execution frontmatter projection options.toolsKeys must be an array of non-empty strings");
|
|
@@ -272,43 +268,35 @@ export function executionDefaultsFromFrontmatter(data, options) {
|
|
|
272
268
|
}
|
|
273
269
|
return out;
|
|
274
270
|
}
|
|
275
|
-
function snapshotRendererInput(input) {
|
|
276
|
-
const inputSnapshot = snapshotStrictRecord(input, "adapter execution source");
|
|
277
|
-
assertSnapshotKeys(inputSnapshot, ["kind", "raw", "identity", "defaults", "extensions"], "adapter execution source");
|
|
278
|
-
const identity = snapshotStrictRecord(inputSnapshot.identity, "adapter execution source identity");
|
|
279
|
-
assertSnapshotKeys(identity, ["ref", "bundle", "adapter", "file"], "adapter execution source identity");
|
|
280
|
-
return { input: inputSnapshot, identity };
|
|
281
|
-
}
|
|
282
271
|
export function renderMarkdownExecutionSource(input) {
|
|
283
|
-
const
|
|
284
|
-
const raw = snapshots.input.raw;
|
|
272
|
+
const raw = input.raw;
|
|
285
273
|
if (typeof raw !== "string")
|
|
286
274
|
throw new TypeError("adapter execution source.raw must be a string");
|
|
287
|
-
const kind =
|
|
275
|
+
const kind = input.kind;
|
|
288
276
|
if (kind !== "command" && kind !== "persona")
|
|
289
277
|
throw new TypeError("adapter execution source.kind is invalid");
|
|
290
|
-
const
|
|
291
|
-
const parsed = parseExecutionMarkdown(raw,
|
|
292
|
-
const hasDefaults = Object.hasOwn(
|
|
293
|
-
const defaultsProjection =
|
|
278
|
+
const identity = input.identity;
|
|
279
|
+
const parsed = parseExecutionMarkdown(raw, identity.file);
|
|
280
|
+
const hasDefaults = Object.hasOwn(input, "defaults");
|
|
281
|
+
const defaultsProjection = input.defaults;
|
|
294
282
|
const defaults = typeof defaultsProjection === "function" ? defaultsProjection(parsed.data) : defaultsProjection;
|
|
295
283
|
if (hasDefaults && defaults === undefined) {
|
|
296
284
|
throw new TypeError("adapter execution source defaults must be omitted or resolve to an object");
|
|
297
285
|
}
|
|
298
|
-
const extensionsProjection =
|
|
286
|
+
const extensionsProjection = input.extensions;
|
|
299
287
|
const extensionsAreProjected = typeof extensionsProjection === "function";
|
|
300
288
|
const extensions = extensionsAreProjected ? extensionsProjection(parsed.data) : extensionsProjection;
|
|
301
|
-
if (Object.hasOwn(
|
|
289
|
+
if (Object.hasOwn(input, "extensions") && !extensionsAreProjected && extensions === undefined) {
|
|
302
290
|
throw new TypeError("adapter execution source extensions must be omitted or be an adapter-owned extension object");
|
|
303
291
|
}
|
|
304
292
|
return createAdapterRenderedExecutionSource({
|
|
305
293
|
kind,
|
|
306
294
|
content: parsed.content,
|
|
307
295
|
identity: {
|
|
308
|
-
ref:
|
|
309
|
-
bundle:
|
|
310
|
-
adapter:
|
|
311
|
-
file:
|
|
296
|
+
ref: identity.ref,
|
|
297
|
+
bundle: identity.bundle,
|
|
298
|
+
adapter: identity.adapter,
|
|
299
|
+
file: identity.file,
|
|
312
300
|
hash: createHash("sha256").update(raw, "utf8").digest("hex"),
|
|
313
301
|
},
|
|
314
302
|
...(hasDefaults ? { defaults } : {}),
|
|
@@ -89,7 +89,7 @@ function notFound(conceptId, triedForms, ctx) {
|
|
|
89
89
|
*
|
|
90
90
|
* Exported (Chunk-8 WI-8.5c) as the ONE conceptId derivation the improve
|
|
91
91
|
* correlation sites (`eligibility.ts` candidate refs, `salience.ts`
|
|
92
|
-
* last-use lookup
|
|
92
|
+
* last-use lookup) share with the
|
|
93
93
|
* display rule — the permanent successor to the retired transient
|
|
94
94
|
* `legacyConceptId`.
|
|
95
95
|
*/
|
package/dist/core/bundle-id.js
CHANGED
|
@@ -4,18 +4,55 @@
|
|
|
4
4
|
import crypto from "node:crypto";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { isBundleSlug } from "./asset/asset-ref.js";
|
|
7
|
+
import { UsageError } from "./errors.js";
|
|
7
8
|
/** Deterministic, filesystem-safe bundle slug from a source path. */
|
|
8
9
|
export function slugForPath(sourcePath) {
|
|
9
10
|
const resolved = path.resolve(sourcePath);
|
|
10
|
-
const base = path
|
|
11
|
-
.basename(resolved)
|
|
12
|
-
.toLowerCase()
|
|
13
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
14
|
-
.replace(/^-+|-+$/g, "");
|
|
11
|
+
const base = slugify(path.basename(resolved));
|
|
15
12
|
if (base.length > 0)
|
|
16
13
|
return base;
|
|
17
14
|
return `bundle-${shortHash(resolved)}`;
|
|
18
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Bundle slug from the package/repo name a registry install id names
|
|
18
|
+
* (`npm:@scope/pkg` → `pkg`, `github:owner/repo` → `repo`,
|
|
19
|
+
* `git:https://host/owner/repo` → `repo`); empty when it names none.
|
|
20
|
+
*/
|
|
21
|
+
export function slugForRegistryId(registryId) {
|
|
22
|
+
const locator = registryId.slice(registryId.indexOf(":") + 1);
|
|
23
|
+
return slugify(locator.split(/[/:]/).filter(Boolean).pop() ?? "");
|
|
24
|
+
}
|
|
25
|
+
function slugify(name) {
|
|
26
|
+
return name
|
|
27
|
+
.toLowerCase()
|
|
28
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
29
|
+
.replace(/^-+|-+$/g, "");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Enforce the `--name` contract on every add path (D6): an explicit name is
|
|
33
|
+
* not a silent hint that may fall back to a derived id — it is a request
|
|
34
|
+
* that either succeeds exactly or fails loudly, before anything is written.
|
|
35
|
+
*
|
|
36
|
+
* `existingKeyForThisInstall` is the bundle key this exact source (path/URL/
|
|
37
|
+
* registry id) is already configured under, if any. Re-adding that same
|
|
38
|
+
* source under a *different* explicit name is rejected in favor of
|
|
39
|
+
* `akm bundle rename`, which is the one command allowed to change a bundle's
|
|
40
|
+
* key. A caller with no existing install for this source (the common case)
|
|
41
|
+
* omits it.
|
|
42
|
+
*/
|
|
43
|
+
export function validateExplicitBundleName(bundles, name, existingKeyForThisInstall) {
|
|
44
|
+
if (!isBundleSlug(name)) {
|
|
45
|
+
throw new UsageError(`"${name}" is not a legal bundle name: it must not contain whitespace or the characters ":" "." "#" "/".`, "INVALID_FLAG_VALUE");
|
|
46
|
+
}
|
|
47
|
+
if (existingKeyForThisInstall !== undefined && name !== existingKeyForThisInstall) {
|
|
48
|
+
throw new UsageError(`This source is already installed as bundle "${existingKeyForThisInstall}". Re-adding it under a ` +
|
|
49
|
+
`different name is not supported — run \`akm bundle rename ${existingKeyForThisInstall} ${name}\` instead.`, "INVALID_FLAG_VALUE");
|
|
50
|
+
}
|
|
51
|
+
if (Object.hasOwn(bundles, name) && name !== existingKeyForThisInstall) {
|
|
52
|
+
throw new UsageError(`Bundle name "${name}" already exists. Choose another name, or run ` +
|
|
53
|
+
`\`akm bundle rename ${name} <new-name>\` first.`, "INVALID_FLAG_VALUE");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
19
56
|
/** Derive one batch-unique bundle id. */
|
|
20
57
|
export function deriveBundleId(registryId, sourcePath, usedIds) {
|
|
21
58
|
const preferred = registryId && registryId.length > 0 && isBundleSlug(registryId) ? registryId : slugForPath(sourcePath);
|