akm-cli 0.9.16 → 0.9.17-alpha.10
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 +2101 -0
- package/STABILITY.md +11 -10
- package/dist/akm +124 -193
- package/dist/akm-migrate +38 -19
- package/dist/assets/hints/cli-hints-full.md +6 -7
- package/dist/assets/improve-strategies/catchup.json +0 -3
- package/dist/assets/improve-strategies/consolidate.json +0 -1
- package/dist/assets/improve-strategies/default.json +1 -2
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
- package/dist/assets/improve-strategies/quick.json +1 -2
- package/dist/assets/improve-strategies/reflect-distill.json +1 -2
- package/dist/assets/improve-strategies/thorough.json +0 -3
- package/dist/assets/prompts/consolidate-pair.md +20 -0
- package/dist/assets/prompts/consolidate-system.md +4 -11
- package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
- package/dist/assets/templates/html/health.html +3 -5
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +6 -2
- package/dist/cli/unknown-flags.js +24 -1
- package/dist/cli.js +68 -10
- 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 +6 -0
- package/dist/commands/health/archive-usage.js +92 -0
- package/dist/commands/health/checks.js +83 -74
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/data-dir-usage.js +25 -13
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +1 -42
- package/dist/commands/health/improve-metrics.js +136 -591
- package/dist/commands/health/md-report.js +1 -6
- 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 +14 -120
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -74
- package/dist/commands/health.js +145 -143
- package/dist/commands/improve/consolidate/chunking.js +26 -117
- package/dist/commands/improve/consolidate/continuity-check.js +137 -0
- package/dist/commands/improve/consolidate/pair-pass.js +791 -0
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +589 -1127
- 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 -1041
- package/dist/commands/improve/eligibility.js +126 -390
- package/dist/commands/improve/execution.js +8 -10
- package/dist/commands/improve/extract-prompt.js +1 -2
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +75 -169
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +52 -4
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +480 -1074
- package/dist/commands/improve/ledger.js +119 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +415 -1073
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +16 -118
- package/dist/commands/improve/memory/memory-improve.js +266 -14
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -15
- package/dist/commands/improve/preparation.js +779 -2319
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +642 -1353
- package/dist/commands/improve/retrieval-gate.js +127 -0
- package/dist/commands/improve/retrieval-scope.js +92 -0
- package/dist/commands/improve/salience.js +41 -240
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +322 -0
- package/dist/commands/lint/base-linter.js +37 -15
- package/dist/commands/proposal/drain.js +261 -578
- package/dist/commands/proposal/proposal-cli.js +19 -20
- package/dist/commands/proposal/proposal-types.js +31 -24
- package/dist/commands/proposal/proposal.js +38 -8
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +1097 -1394
- 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 +22 -89
- package/dist/commands/read/curate.js +105 -462
- package/dist/commands/read/knowledge.js +3 -2
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +57 -108
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +4 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +127 -29
- 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/source-manage.js +9 -2
- package/dist/commands/sources/stash-cli.js +24 -4
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +12 -13
- package/dist/commands/tasks/tasks.js +350 -936
- package/dist/commands/tasks/validate.js +26 -24
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +2 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +42 -12
- package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/asset-placement.js +4 -13
- package/dist/core/asset/frontmatter.js +106 -1
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +285 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +9 -34
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +184 -111
- package/dist/core/config/engine-semantics.js +0 -2
- 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 +54 -125
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/index-config.js +9 -48
- 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-change.js +13 -5
- package/dist/core/file-lock.js +76 -173
- package/dist/core/improve-result.js +35 -7
- package/dist/core/improve-types.js +0 -1
- package/dist/core/logs-db.js +2 -2
- package/dist/core/loopback.js +7 -12
- package/dist/core/non-task-input.js +20 -0
- package/dist/core/parse.js +13 -16
- package/dist/core/paths.js +0 -24
- 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 +123 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/time.js +0 -20
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +294 -1005
- 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/llm-cache.js +2 -2
- package/dist/indexer/ensure-index.js +77 -73
- 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 +141 -154
- package/dist/indexer/indexer.js +400 -1124
- package/dist/indexer/links/declared-links.js +90 -0
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +96 -90
- package/dist/indexer/passes/metadata.js +132 -219
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +2 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +190 -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 +36 -7
- package/dist/indexer/walk/walker.js +3 -4
- 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/client.js +18 -6
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +11 -17
- package/dist/llm/feature-gate.js +0 -8
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.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 +25 -38
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +69 -31
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +48 -3
- package/dist/output/text/show-format.js +13 -17
- 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 +42948 -92369
- package/dist/scripts/akm-migrate.js +42935 -92354
- 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/connection.js +5 -6
- package/dist/setup/steps/platforms.js +2 -2
- 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 +83 -21
- 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 +209 -0
- package/dist/storage/repositories/index-connection.js +39 -72
- package/dist/storage/repositories/index-entries-repository.js +131 -129
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +101 -268
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-links-repository.js +143 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +257 -325
- 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 +104 -1
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/salience-repository.js +1 -19
- 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 +130 -0
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +191 -302
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +141 -748
- package/dist/tasks/backends/schtasks.js +119 -623
- 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/run/load-task.js +1 -1
- package/dist/tasks/scheduler-binding.js +20 -238
- package/dist/tasks/scheduler-invocation.js +136 -244
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +368 -679
- package/dist/tasks/source/parse-task-source.js +55 -9
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +464 -88
- 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 +43 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
- package/docs/reference/cli.md +232 -135
- package/docs/reference/configuration.md +71 -57
- package/docs/reference/data-and-telemetry.md +20 -21
- package/docs/reference/tasks.md +105 -39
- 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 +115 -738
- package/schemas/akm-workflow.json +1 -0
- package/dist/assets/improve-strategies/graph-refresh.json +0 -15
- package/dist/assets/prompts/contradiction-judge.md +0 -33
- package/dist/assets/prompts/graph-extract-system.md +0 -1
- package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
- package/dist/assets/prompts/metadata-enhance-system.md +0 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
- 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 -149
- package/dist/commands/improve/distill/promote-memory.js +0 -291
- package/dist/commands/improve/distill/quality-gate.js +0 -337
- package/dist/commands/improve/eval-cases.js +0 -52
- 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 -31
- 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/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/db/graph-db.js +0 -444
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/graph/graph-extraction.js +0 -1108
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/search/ranking-types.js +0 -4
- 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/llm/graph-extract.js +0 -728
- package/dist/llm/metadata-enhance.js +0 -96
- 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/tasks/source/task-to-v3.js +0 -507
- 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 -77
- 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
|
@@ -1,80 +1,34 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// 1. Code-fence leakage: the entire merged asset is wrapped in
|
|
10
|
-
// ```markdown … ``` (or ```yaml … ```) despite the prompt forbidding
|
|
11
|
-
// fences. The post-processor used to pass this through verbatim, so the
|
|
12
|
-
// first character of the asset content became a backtick rather than
|
|
13
|
-
// `---`, defeating the frontmatter parser.
|
|
14
|
-
// 2. YAML quote-escaping bugs: descriptions like `'"Specialty intro...:`
|
|
15
|
-
// with unbalanced quotes that break the YAML reader. The post-processor
|
|
16
|
-
// historically passed the LLM's raw scalar straight into a manually
|
|
17
|
-
// assembled `description: <raw>` line.
|
|
18
|
-
// 3. Truncated descriptions hitting token cutoffs — the model's max_tokens
|
|
19
|
-
// runs out mid-sentence, leaving things like
|
|
20
|
-
// `description: "Tables in narrow column containers need max-width:100% +"`
|
|
21
|
-
// with no closing context.
|
|
22
|
-
//
|
|
23
|
-
// `sanitizeMergedContent` and `validateProposalFrontmatter` defend against
|
|
24
|
-
// all three at the point where LLM output is consumed.
|
|
4
|
+
/**
|
|
5
|
+
* Consolidate's defence against three recurring LLM output defects: the whole
|
|
6
|
+
* asset wrapped in a code fence, frontmatter with broken YAML quoting, and a
|
|
7
|
+
* missing closing `---`.
|
|
8
|
+
*/
|
|
25
9
|
import { parse as yamlParse } from "yaml";
|
|
26
10
|
import { assembleAssetFromString, serializeFrontmatter } from "../../../core/asset/asset-serialize.js";
|
|
27
11
|
import { parseFrontmatter } from "../../../core/asset/frontmatter.js";
|
|
12
|
+
const FRONTMATTER_BLOCK = /^---\r?\n([\s\S]*?)\r?\n---(?:\r\n|\r|\n|$)([\s\S]*)$/;
|
|
28
13
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* line that cannot be a YAML scalar (i.e. not a key-value, indented
|
|
33
|
-
* continuation, comment, or list item). Injects `---` before that line so
|
|
34
|
-
* the normal parser can proceed.
|
|
35
|
-
*
|
|
36
|
-
* Returns the patched string on success, or `null` if the structure is too
|
|
37
|
-
* ambiguous to recover safely (e.g. no opening `---`, or no body content
|
|
38
|
-
* found after the frontmatter key-value lines).
|
|
14
|
+
* Insert the missing closing `---` before the first blank line or the first
|
|
15
|
+
* line that cannot be YAML (key, indented continuation, comment, list item);
|
|
16
|
+
* `null` when there is no such line.
|
|
39
17
|
*/
|
|
40
18
|
function recoverMalformedFrontmatter(raw) {
|
|
41
19
|
if (!raw.startsWith("---"))
|
|
42
20
|
return null;
|
|
43
21
|
const lines = raw.split(/\r?\n/);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const line = lines[i];
|
|
48
|
-
// A blank line marks the end of the frontmatter block in many YAML variants.
|
|
49
|
-
if (line.trim() === "") {
|
|
50
|
-
insertAt = i;
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
// A line that is clearly body content: doesn't look like a YAML key, an
|
|
54
|
-
// indented continuation, a comment, or a sequence item.
|
|
55
|
-
const isYaml = /^\w[\w-]*\s*:/.test(line) || // key: value
|
|
56
|
-
/^\s+\S/.test(line) || // indented continuation / nested
|
|
57
|
-
/^\s*#/.test(line) || // YAML comment
|
|
58
|
-
/^\s*-\s/.test(line); // sequence item
|
|
59
|
-
if (!isYaml) {
|
|
60
|
-
insertAt = i;
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
22
|
+
const insertAt = lines.findIndex((line, i) => i > 0 &&
|
|
23
|
+
(line.trim() === "" ||
|
|
24
|
+
!(/^\w[\w-]*\s*:/.test(line) || /^\s+\S/.test(line) || /^\s*#/.test(line) || /^\s*-\s/.test(line))));
|
|
64
25
|
if (insertAt < 0)
|
|
65
26
|
return null;
|
|
66
|
-
|
|
67
|
-
return result;
|
|
27
|
+
return [...lines.slice(0, insertAt), "---", ...lines.slice(insertAt)].join("\n");
|
|
68
28
|
}
|
|
69
29
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* variant additionally recognises `yaml` and bare-language fences and refuses
|
|
73
|
-
* to strip an unbalanced fence — i.e. a leading ``` with no trailing ``` is
|
|
74
|
-
* treated as a malformed response, not partially sanitized.
|
|
75
|
-
*
|
|
76
|
-
* Returns `null` when only one half of a fence pair is present (caller
|
|
77
|
-
* should reject the response entirely).
|
|
30
|
+
* Strip a markdown/yaml/bare code fence wrapping the whole response; `null`
|
|
31
|
+
* when only one half of the pair is present.
|
|
78
32
|
*/
|
|
79
33
|
export function stripOuterCodeFence(raw) {
|
|
80
34
|
const trimmed = raw.trim();
|
|
@@ -83,91 +37,63 @@ export function stripOuterCodeFence(raw) {
|
|
|
83
37
|
if (!leading && !trailing)
|
|
84
38
|
return { content: trimmed, stripped: false };
|
|
85
39
|
if (!leading || !trailing)
|
|
86
|
-
return null;
|
|
87
|
-
|
|
88
|
-
return { content: inner, stripped: true };
|
|
40
|
+
return null;
|
|
41
|
+
return { content: trimmed.slice(leading[0].length, trimmed.length - trailing[0].length).trim(), stripped: true };
|
|
89
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Model output as an asset: fence stripped, `<think>` removed, frontmatter
|
|
45
|
+
* re-serialized through the YAML library (the lenient parser recovers what the
|
|
46
|
+
* strict one rejects), or a reason it is unusable.
|
|
47
|
+
*/
|
|
90
48
|
export function sanitizeMergedContent(raw) {
|
|
91
|
-
// Step 1: Strip outer code fence.
|
|
92
|
-
// Recovery path: if only the leading fence is present, strip it and continue
|
|
93
|
-
// provided the inner content starts with `---`. Trailing-only fences are NOT
|
|
94
|
-
// recovered — a trailing ``` is more likely a body code block than a forgotten
|
|
95
|
-
// wrapper, so recovering would silently corrupt the body.
|
|
96
49
|
let body;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
50
|
+
const fenceResult = stripOuterCodeFence(raw);
|
|
51
|
+
if (fenceResult) {
|
|
52
|
+
body = fenceResult.content;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// A leading fence alone is recovered when frontmatter follows; a trailing
|
|
56
|
+
// one alone is more likely a body code block, so it is not.
|
|
57
|
+
const inner = raw
|
|
58
|
+
.trim()
|
|
59
|
+
.match(/^```(?:markdown|md|yaml|yml)?\s*\r?\n([\s\S]*)$/i)?.[1]
|
|
60
|
+
?.trim();
|
|
61
|
+
if (!inner?.startsWith("---"))
|
|
62
|
+
return { ok: false, reason: "UNBALANCED_CODE_FENCE" };
|
|
63
|
+
body = inner;
|
|
111
64
|
}
|
|
112
|
-
// Strip <think> blocks (some local models still emit them despite system prompts).
|
|
113
65
|
body = body.replace(/<think>[\s\S]*?<\/think>/gi, "").trim();
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
// merged content:") before the `---`. Accept if `---` appears within 300 chars.
|
|
117
|
-
// Beyond that it's more likely a body section divider, not a frontmatter start.
|
|
66
|
+
// A line or two of preamble before the frontmatter is tolerated; a `---`
|
|
67
|
+
// further in is more likely a section divider.
|
|
118
68
|
if (!body.startsWith("---")) {
|
|
119
69
|
const nlIdx = body.indexOf("\n---");
|
|
120
|
-
if (nlIdx
|
|
121
|
-
body = body.slice(nlIdx + 1);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
70
|
+
if (nlIdx < 0 || nlIdx >= 300)
|
|
124
71
|
return { ok: false, reason: "MISSING_FRONTMATTER_SENTINEL" };
|
|
125
|
-
|
|
72
|
+
body = body.slice(nlIdx + 1);
|
|
126
73
|
}
|
|
127
|
-
|
|
128
|
-
// Recovery path: LLM sometimes omits the closing `---` delimiter. Detect this
|
|
129
|
-
// by scanning lines after the opening `---` for the first blank line or the
|
|
130
|
-
// first line that isn't a YAML key-value pair, then inject `---` there.
|
|
131
|
-
let match = body.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r\n|\r|\n|$)([\s\S]*)$/);
|
|
74
|
+
let match = body.match(FRONTMATTER_BLOCK);
|
|
132
75
|
if (!match) {
|
|
133
76
|
const recovered = recoverMalformedFrontmatter(body);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
if (!match) {
|
|
77
|
+
match = recovered ? recovered.match(FRONTMATTER_BLOCK) : null;
|
|
78
|
+
if (!match)
|
|
138
79
|
return { ok: false, reason: "MALFORMED_FRONTMATTER_BLOCK" };
|
|
139
|
-
}
|
|
140
80
|
}
|
|
141
|
-
// Re-parse via the yaml library so any quote-escaping mistakes either get
|
|
142
|
-
// normalised or surface as a parse error we can reject.
|
|
143
|
-
// Recovery: if the strict yaml library fails, fall back to the lenient
|
|
144
|
-
// hand-rolled parseFrontmatter parser, which tolerates common LLM YAML
|
|
145
|
-
// quirks (unescaped special chars, bare scalars, etc.). If it recovers
|
|
146
|
-
// at least one key, proceed — serializeFrontmatter below will re-serialize
|
|
147
|
-
// cleanly. Only reject if both parsers fail to extract any data.
|
|
148
81
|
let parsedFm;
|
|
149
82
|
try {
|
|
150
83
|
parsedFm = yamlParse(match[1]);
|
|
151
84
|
}
|
|
152
85
|
catch (e) {
|
|
153
86
|
const fallback = parseFrontmatter(`---\n${match[1]}\n---\n${match[2]}`);
|
|
154
|
-
if (fallback.frontmatter
|
|
155
|
-
parsedFm = fallback.data;
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
87
|
+
if (fallback.frontmatter === null || Object.keys(fallback.data).length === 0) {
|
|
158
88
|
return { ok: false, reason: `INVALID_YAML: ${e instanceof Error ? e.message : String(e)}` };
|
|
159
89
|
}
|
|
90
|
+
parsedFm = fallback.data;
|
|
160
91
|
}
|
|
161
92
|
if (parsedFm === null || typeof parsedFm !== "object" || Array.isArray(parsedFm)) {
|
|
162
93
|
return { ok: false, reason: "FRONTMATTER_NOT_OBJECT" };
|
|
163
94
|
}
|
|
164
95
|
const fm = parsedFm;
|
|
165
|
-
// Normalise placeholder leaks like `updated: today`, `updated: {today: null}`,
|
|
166
|
-
// `updated: now`, etc. The consolidate prompt instructs the LLM not to emit
|
|
167
|
-
// these, but small models still do. Replace any such leak with today's ISO
|
|
168
|
-
// date OR drop the field if we can't safely normalise it.
|
|
169
96
|
normalizeUpdatedField(fm);
|
|
170
|
-
// Re-serialise via yaml.stringify to fix any quoting quirks.
|
|
171
97
|
let serialized;
|
|
172
98
|
try {
|
|
173
99
|
serialized = serializeFrontmatter(fm);
|
|
@@ -175,57 +101,36 @@ export function sanitizeMergedContent(raw) {
|
|
|
175
101
|
catch (e) {
|
|
176
102
|
return { ok: false, reason: `YAML_STRINGIFY_FAILED: ${e instanceof Error ? e.message : String(e)}` };
|
|
177
103
|
}
|
|
178
|
-
|
|
179
|
-
return { ok: true, result: { content: cleaned, frontmatter: fm } };
|
|
104
|
+
return { ok: true, result: { content: assembleAssetFromString(serialized, match[2]), frontmatter: fm } };
|
|
180
105
|
}
|
|
181
106
|
/**
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
* Rules:
|
|
187
|
-
* - A real ISO-style date string (YYYY-MM-DD, optionally with time) stays as-is.
|
|
188
|
-
* - A Date object (some YAML parsers materialise dates) is converted to its
|
|
189
|
-
* ISO yyyy-mm-dd form.
|
|
190
|
-
* - A placeholder string ("today", "now", "{today}", "${today}", template
|
|
191
|
-
* variables) is replaced with today's ISO date.
|
|
192
|
-
* - A map/object (e.g. `{today: null}`) is replaced with today's ISO date.
|
|
193
|
-
* - `null`, empty string, missing → left alone (no field added; reviewers
|
|
194
|
-
* should not silently gain metadata they didn't write).
|
|
195
|
-
*
|
|
196
|
-
* Exported for unit testing.
|
|
107
|
+
* Normalize a leaked `updated` placeholder in place: a Date becomes
|
|
108
|
+
* `YYYY-MM-DD`; `today`/`now`/`{today}`-style templates and maps like
|
|
109
|
+
* `{today: null}` become today's date; real dates, unknown strings and empty
|
|
110
|
+
* values are left alone (visible in the diff, never invented).
|
|
197
111
|
*/
|
|
198
112
|
export function normalizeUpdatedField(fm) {
|
|
199
|
-
if (!("updated" in fm))
|
|
200
|
-
return;
|
|
201
113
|
const v = fm.updated;
|
|
202
114
|
if (v === null || v === undefined || v === "")
|
|
203
115
|
return;
|
|
204
116
|
const todayIso = new Date().toISOString().slice(0, 10);
|
|
205
117
|
if (v instanceof Date) {
|
|
206
118
|
fm.updated = v.toISOString().slice(0, 10);
|
|
207
|
-
return;
|
|
208
119
|
}
|
|
209
|
-
if (typeof v === "string") {
|
|
120
|
+
else if (typeof v === "string") {
|
|
210
121
|
const trimmed = v.trim().toLowerCase();
|
|
211
122
|
if (/^\d{4}-\d{2}-\d{2}/.test(v.trim()))
|
|
212
|
-
return;
|
|
123
|
+
return;
|
|
213
124
|
if (trimmed === "today" ||
|
|
214
125
|
trimmed === "now" ||
|
|
215
|
-
|
|
216
|
-
// biome-ignore lint/suspicious/noTemplateCurlyInString: matches the literal user-typed placeholder text "${today}" so we can normalize it to today's ISO date
|
|
126
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: the literal "${today}" placeholder a model emits
|
|
217
127
|
trimmed === "${today}" ||
|
|
218
128
|
trimmed === "{{today}}" ||
|
|
219
129
|
/^\{?\s*today\s*\}?$/.test(trimmed)) {
|
|
220
130
|
fm.updated = todayIso;
|
|
221
|
-
return;
|
|
222
131
|
}
|
|
223
|
-
// Unknown string format — leave alone so it's visible in the diff.
|
|
224
|
-
return;
|
|
225
132
|
}
|
|
226
|
-
if (typeof v === "object") {
|
|
227
|
-
// Maps like `{today: null}`, `{now: null}` — clearly a template leak.
|
|
133
|
+
else if (typeof v === "object") {
|
|
228
134
|
fm.updated = todayIso;
|
|
229
|
-
return;
|
|
230
135
|
}
|
|
231
136
|
}
|