akm-cli 0.9.0-rc.0 → 0.9.0-rc.13
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 +1283 -22
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +2 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +99 -0
- package/dist/commands/env/env-cli.js +84 -224
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +232 -121
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -834
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/json-schema.js +142 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -34
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -56
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +36 -62
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +93 -4
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +88 -196
- package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
- package/dist/integrations/harnesses/aider/index.js +48 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
- package/dist/integrations/harnesses/amazonq/index.js +45 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +24 -35
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
- package/dist/integrations/harnesses/codex/index.js +52 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +48 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
- package/dist/integrations/harnesses/gemini/index.js +48 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +54 -34
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +14 -32
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
- package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
- package/dist/integrations/harnesses/openhands/index.js +48 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
- package/dist/integrations/harnesses/pi/index.js +45 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +43 -32
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +36 -39
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -279
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +11 -39
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1164
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +3 -2
- package/dist/output/text.js +10 -19
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +240 -19
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/text-import-hook.mjs +1 -1
- package/dist/workflows/authoring/authoring.js +104 -43
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -16
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +450 -0
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +1038 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1460 -0
- package/dist/workflows/exec/run-workflow.js +602 -0
- package/dist/workflows/exec/scheduler.js +71 -0
- package/dist/workflows/exec/step-work.js +1190 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +246 -0
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +68 -0
- package/dist/workflows/ir/schema.js +540 -0
- package/dist/workflows/parser.js +878 -304
- package/dist/workflows/program/expressions.js +181 -0
- package/dist/workflows/program/schema.js +51 -0
- package/dist/workflows/renderer.js +100 -45
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +376 -119
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +2 -3
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +373 -0
- package/dist/akm-migrate-storage +0 -38
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -259
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1413
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/scripts/migrate-storage.js +0 -19108
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1012
- package/dist/workflows/db.js +0 -215
- package/docs/data-and-telemetry.md +0 -226
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
package/dist/output/context.js
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* calls read from this in-memory singleton instead of re-scanning argv and
|
|
10
10
|
* re-loading config on every call.
|
|
11
11
|
*
|
|
12
|
-
* Initialized from `cli.ts` before `
|
|
12
|
+
* Initialized from `cli.ts` before `runCli` dispatches the command (`cli.ts`
|
|
13
|
+
* drives citty's `runCommand` directly rather than `runMain` — see the
|
|
14
|
+
* top-level driver comment there).
|
|
13
15
|
*/
|
|
14
16
|
import { UsageError } from "../core/errors.js";
|
|
15
17
|
const OUTPUT_FORMATS = ["json", "yaml", "text", "jsonl", "md", "html"];
|
|
@@ -39,6 +41,8 @@ function parseShapeMode(value) {
|
|
|
39
41
|
export function parseFlagValue(argv, flag) {
|
|
40
42
|
for (let i = 0; i < argv.length; i++) {
|
|
41
43
|
const arg = argv[i];
|
|
44
|
+
if (arg === "--")
|
|
45
|
+
break;
|
|
42
46
|
if (arg === flag)
|
|
43
47
|
return argv[i + 1];
|
|
44
48
|
if (arg.startsWith(`${flag}=`))
|
|
@@ -47,15 +51,26 @@ export function parseFlagValue(argv, flag) {
|
|
|
47
51
|
return undefined;
|
|
48
52
|
}
|
|
49
53
|
export function hasBooleanFlag(argv, flag) {
|
|
50
|
-
|
|
54
|
+
for (const arg of argv) {
|
|
55
|
+
if (arg === "--")
|
|
56
|
+
return false;
|
|
57
|
+
if (arg === flag || arg === `${flag}=true`)
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
51
61
|
}
|
|
52
62
|
/**
|
|
53
63
|
* Read a hyphenated arg out of citty's parsed `args` object.
|
|
54
64
|
*
|
|
55
|
-
* citty
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
65
|
+
* Verified live: citty DOES auto-camelise a DECLARED hyphenated arg — for
|
|
66
|
+
* `"max-pages": { type: "string" }` in a command's `args`, citty's parsed
|
|
67
|
+
* object answers both `args["max-pages"]` and `args.maxPages` (a `Proxy`
|
|
68
|
+
* falls back through `camelCase`/`kebabCase`, and `--no-<flag>` negation is
|
|
69
|
+
* handled the same way for booleans). What citty's own TS types do NOT give
|
|
70
|
+
* callers is a statically-typed handle on that mapping, and command handlers
|
|
71
|
+
* here type `args` as `unknown` at the boundary — so every read site still
|
|
72
|
+
* needs a cast. This helper encapsulates that cast; it exists for typing
|
|
73
|
+
* convenience, not to work around a citty parsing limitation.
|
|
59
74
|
*/
|
|
60
75
|
export function getHyphenatedArg(args, key) {
|
|
61
76
|
if (typeof args !== "object" || args === null)
|
|
@@ -81,7 +96,7 @@ export function resolveOutputMode(argv, defaults = {}) {
|
|
|
81
96
|
const detail = parseDetailLevel(rawDetail) ?? defaults?.detail ?? "brief";
|
|
82
97
|
const shape = parseShapeMode(rawShape) ?? "human";
|
|
83
98
|
const outputPath = parseFlagValue(argv, "--output");
|
|
84
|
-
return { format, detail, shape,
|
|
99
|
+
return { format, detail, shape, ...(outputPath ? { outputPath } : {}) };
|
|
85
100
|
}
|
|
86
101
|
let _mode;
|
|
87
102
|
/**
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Commands whose output is not an envelope, and therefore not formattable (D7).
|
|
6
|
+
*
|
|
7
|
+
* D7 makes all six `--format` values work on every command that renders through
|
|
8
|
+
* `output()`. A small set does not render an envelope at all: they emit a shell
|
|
9
|
+
* script, drive an interactive prompt, hand stdout to a child process, or print
|
|
10
|
+
* a document that IS the payload. Passing `--format` to one of those cannot do
|
|
11
|
+
* anything useful.
|
|
12
|
+
*
|
|
13
|
+
* The point of declaring the set here is that the exemption stops being
|
|
14
|
+
* implicit. Before D7 you discovered it by getting JSON when you asked for
|
|
15
|
+
* Markdown, or an exit 2 when you asked for HTML. Now the list is one grep away,
|
|
16
|
+
* it is documented in `STABILITY.md`, and asking for a format on an exempt
|
|
17
|
+
* command warns instead of silently doing something else.
|
|
18
|
+
*
|
|
19
|
+
* Names are canonical command paths resolved from the Citty tree.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Top-level command tokens whose entire surface is format-exempt.
|
|
23
|
+
*/
|
|
24
|
+
const EXEMPT_COMMANDS = new Set([
|
|
25
|
+
// Emits shell completion script source for eval.
|
|
26
|
+
"completions",
|
|
27
|
+
// Both subcommands (`status`, `apply`) are also a child-process passthrough:
|
|
28
|
+
// `runMigrationTool` (src/commands/migration-tool.ts) spawns the standalone
|
|
29
|
+
// `scripts/akm-migrate.ts` tool and writes its stdout/stderr verbatim — the
|
|
30
|
+
// spawned script always emits its own fixed JSON shape and never consults
|
|
31
|
+
// `--format`. Found while verifying F1 (D7 B1): the finding's repro list
|
|
32
|
+
// named `akm migrate status --format text` alongside `secret list` as the
|
|
33
|
+
// SAME defect (missing text renderer inside `output()`), but `migrate
|
|
34
|
+
// status`/`apply` never reach `output()` at all, so that fix cannot and
|
|
35
|
+
// does not change their behavior — this is the `env run`/`secret run`
|
|
36
|
+
// passthrough pattern, not the generic-text-fallback one.
|
|
37
|
+
"migrate",
|
|
38
|
+
// Document payload group: bare `help` prints the sectioned overview,
|
|
39
|
+
// `help migrate <version>` prints release notes, and `help agents` prints
|
|
40
|
+
// the embedded CLI-reference guide (`src/output/cli-hints.ts`) — none of
|
|
41
|
+
// the three render a result envelope.
|
|
42
|
+
"help",
|
|
43
|
+
// Embedded agent guide document.
|
|
44
|
+
"hints",
|
|
45
|
+
]);
|
|
46
|
+
/**
|
|
47
|
+
* `<command> <subcommand>` pairs that are exempt while the rest of the group
|
|
48
|
+
* formats normally.
|
|
49
|
+
*/
|
|
50
|
+
const EXEMPT_SUBCOMMANDS = new Set([
|
|
51
|
+
// Child-process passthrough (the env/secret groups otherwise format fine).
|
|
52
|
+
"env run",
|
|
53
|
+
"secret run",
|
|
54
|
+
// B3/B4 (W1-F): a bare absolute filesystem path IS the payload — the
|
|
55
|
+
// documented shell-substitution primitive (`$(akm env path <ref>)`,
|
|
56
|
+
// Docker `_FILE` / `--env-file`) — not a field worth wrapping in an
|
|
57
|
+
// envelope. Wrapping it broke every existing substitution silently: the
|
|
58
|
+
// CLI's default format is `json`, so an un-flagged `akm env path <ref>`
|
|
59
|
+
// (exactly how the substitution is always written) started emitting
|
|
60
|
+
// `{"path":"..."}` instead of the raw path. Unlike `config path`, this
|
|
61
|
+
// command has no `--all`-style multi-field variant, so the whole surface
|
|
62
|
+
// can be exempt without wrongly warning on a real envelope case.
|
|
63
|
+
"env path",
|
|
64
|
+
]);
|
|
65
|
+
/**
|
|
66
|
+
* True when `--format` cannot meaningfully apply to this invocation.
|
|
67
|
+
*
|
|
68
|
+
* `commandPath` contains canonical Citty command names from the top-level
|
|
69
|
+
* command through the deepest resolved subcommand.
|
|
70
|
+
*/
|
|
71
|
+
export function isFormatExemptCommand(commandPath) {
|
|
72
|
+
const command = commandPath[0];
|
|
73
|
+
if (command === undefined)
|
|
74
|
+
return false;
|
|
75
|
+
return EXEMPT_COMMANDS.has(command) || EXEMPT_SUBCOMMANDS.has(commandPath.join(" "));
|
|
76
|
+
}
|
|
77
|
+
/** The declared exempt set, for docs generation and tests. */
|
|
78
|
+
export function formatExemptSurfaces() {
|
|
79
|
+
return { commands: [...EXEMPT_COMMANDS], subcommands: [...EXEMPT_SUBCOMMANDS] };
|
|
80
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* True when `value` is a non-empty array of plain objects — the shape worth
|
|
6
|
+
* rendering as a table rather than as a nested list. Uniformity is judged on
|
|
7
|
+
* the union of keys, not on strict equality, so one row carrying an extra
|
|
8
|
+
* optional field still tabulates (its column is simply blank elsewhere).
|
|
9
|
+
*/
|
|
10
|
+
function isTabular(value) {
|
|
11
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
12
|
+
return false;
|
|
13
|
+
return value.every((row) => row !== null && typeof row === "object" && !Array.isArray(row));
|
|
14
|
+
}
|
|
15
|
+
/** Column order for a table: first appearance across all rows, order-stable. */
|
|
16
|
+
function tableColumns(rows) {
|
|
17
|
+
const columns = [];
|
|
18
|
+
for (const row of rows) {
|
|
19
|
+
for (const key of Object.keys(row)) {
|
|
20
|
+
if (!columns.includes(key))
|
|
21
|
+
columns.push(key);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return columns;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Render a leaf value for display. Objects and arrays that reach a cell are
|
|
28
|
+
* JSON-encoded rather than expanded — a table cell is not a place to nest.
|
|
29
|
+
*/
|
|
30
|
+
function displayScalar(value) {
|
|
31
|
+
if (value === null || value === undefined)
|
|
32
|
+
return "";
|
|
33
|
+
if (typeof value === "string")
|
|
34
|
+
return value;
|
|
35
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
36
|
+
return String(value);
|
|
37
|
+
return JSON.stringify(value);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Root-level envelope metadata the shape registry stamps on top of a
|
|
41
|
+
* command's actual result: `shape` (the discriminator) and `schemaVersion`
|
|
42
|
+
* (the envelope's own version), both added by the passthrough stamp in
|
|
43
|
+
* `src/output/shapes/passthrough.ts` and equivalent per-command shapers
|
|
44
|
+
* elsewhere. Transport bookkeeping, not a result anyone asked for — a `##
|
|
45
|
+
* shape` / `## schemaVersion` section (`renderGenericMarkdown`), an
|
|
46
|
+
* `<h2>shape</h2>` block (`renderGenericHtml`), or a `shape=…` line
|
|
47
|
+
* (`renderGenericText`) is noise in every command's output, so every generic
|
|
48
|
+
* renderer drops both. ONLY at the root, though: some shapes reuse
|
|
49
|
+
* `schemaVersion` as genuine per-entry content one level down (each event in
|
|
50
|
+
* `log list`'s `events[]` carries its own `schemaVersion`, see
|
|
51
|
+
* `shapeEventEntry` in `src/output/shapes/helpers.ts`), and that must
|
|
52
|
+
* survive untouched — every renderer below applies this filter only to the
|
|
53
|
+
* top-level `Object.entries` loop over the envelope, never recursively.
|
|
54
|
+
*/
|
|
55
|
+
const ENVELOPE_META_KEYS = new Set(["shape", "schemaVersion"]);
|
|
56
|
+
// ── Markdown ─────────────────────────────────────────────────────────────────
|
|
57
|
+
/** Escape the one character that can break a Markdown table row. */
|
|
58
|
+
function escapeCell(text) {
|
|
59
|
+
return text.replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
60
|
+
}
|
|
61
|
+
function markdownTable(rows) {
|
|
62
|
+
const columns = tableColumns(rows);
|
|
63
|
+
if (columns.length === 0)
|
|
64
|
+
return [];
|
|
65
|
+
const lines = [
|
|
66
|
+
`| ${columns.join(" | ")} |`,
|
|
67
|
+
`| ${columns.map(() => "---").join(" | ")} |`,
|
|
68
|
+
...rows.map((row) => `| ${columns.map((c) => escapeCell(displayScalar(row[c]))).join(" | ")} |`),
|
|
69
|
+
];
|
|
70
|
+
return lines;
|
|
71
|
+
}
|
|
72
|
+
function markdownValue(value, depth) {
|
|
73
|
+
if (isTabular(value))
|
|
74
|
+
return markdownTable(value);
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
if (value.length === 0)
|
|
77
|
+
return ["_(none)_"];
|
|
78
|
+
return value.map((item) => `- ${escapeCell(displayScalar(item))}`);
|
|
79
|
+
}
|
|
80
|
+
if (value !== null && typeof value === "object") {
|
|
81
|
+
const lines = [];
|
|
82
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
83
|
+
// Headings stop at h6; deeper nesting continues as bolded labels.
|
|
84
|
+
const heading = "#".repeat(Math.min(depth, 6));
|
|
85
|
+
lines.push(depth <= 6 ? `${heading} ${key}` : `**${key}**`, "", ...markdownValue(nested, depth + 1), "");
|
|
86
|
+
}
|
|
87
|
+
return lines;
|
|
88
|
+
}
|
|
89
|
+
return [displayScalar(value) === "" ? "_(empty)_" : displayScalar(value)];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Render a shaped envelope as Markdown. `command` titles the document so a
|
|
93
|
+
* rendered file identifies itself once detached from the invocation.
|
|
94
|
+
*/
|
|
95
|
+
export function renderGenericMarkdown(command, value) {
|
|
96
|
+
const body = value !== null && typeof value === "object" && !Array.isArray(value)
|
|
97
|
+
? Object.entries(value)
|
|
98
|
+
.filter(([key]) => !ENVELOPE_META_KEYS.has(key)) // transport metadata, not a result
|
|
99
|
+
.flatMap(([key, nested]) => [`## ${key}`, "", ...markdownValue(nested, 3), ""])
|
|
100
|
+
: markdownValue(value, 2);
|
|
101
|
+
const lines = [`# ${command}`, "", ...body];
|
|
102
|
+
const rendered = lines
|
|
103
|
+
.join("\n")
|
|
104
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
105
|
+
.trimEnd();
|
|
106
|
+
return `${rendered}\n`;
|
|
107
|
+
}
|
|
108
|
+
// ── HTML ─────────────────────────────────────────────────────────────────────
|
|
109
|
+
const HTML_ESCAPES = {
|
|
110
|
+
"&": "&",
|
|
111
|
+
"<": "<",
|
|
112
|
+
">": ">",
|
|
113
|
+
'"': """,
|
|
114
|
+
"'": "'",
|
|
115
|
+
};
|
|
116
|
+
/** Escape every value that reaches the document — this is untrusted content. */
|
|
117
|
+
function escapeHtml(text) {
|
|
118
|
+
return text.replace(/[&<>"']/g, (char) => HTML_ESCAPES[char] ?? char);
|
|
119
|
+
}
|
|
120
|
+
function htmlTable(rows) {
|
|
121
|
+
const columns = tableColumns(rows);
|
|
122
|
+
if (columns.length === 0)
|
|
123
|
+
return "";
|
|
124
|
+
const head = `<tr>${columns.map((c) => `<th scope="col">${escapeHtml(c)}</th>`).join("")}</tr>`;
|
|
125
|
+
const body = rows
|
|
126
|
+
.map((row) => `<tr>${columns.map((c) => `<td>${escapeHtml(displayScalar(row[c]))}</td>`).join("")}</tr>`)
|
|
127
|
+
.join("");
|
|
128
|
+
return `<table><thead>${head}</thead><tbody>${body}</tbody></table>`;
|
|
129
|
+
}
|
|
130
|
+
function htmlValue(value, depth) {
|
|
131
|
+
if (isTabular(value))
|
|
132
|
+
return htmlTable(value);
|
|
133
|
+
if (Array.isArray(value)) {
|
|
134
|
+
if (value.length === 0)
|
|
135
|
+
return "<p><em>(none)</em></p>";
|
|
136
|
+
return `<ul>${value.map((item) => `<li>${escapeHtml(displayScalar(item))}</li>`).join("")}</ul>`;
|
|
137
|
+
}
|
|
138
|
+
if (value !== null && typeof value === "object") {
|
|
139
|
+
const level = Math.min(depth, 6);
|
|
140
|
+
return Object.entries(value)
|
|
141
|
+
.map(([key, nested]) => `<h${level}>${escapeHtml(key)}</h${level}>${htmlValue(nested, depth + 1)}`)
|
|
142
|
+
.join("");
|
|
143
|
+
}
|
|
144
|
+
const scalar = displayScalar(value);
|
|
145
|
+
return scalar === "" ? "<p><em>(empty)</em></p>" : `<p>${escapeHtml(scalar)}</p>`;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Render a shaped envelope as a self-contained HTML document.
|
|
149
|
+
*
|
|
150
|
+
* Self-contained matters: the output is routinely redirected to a file and
|
|
151
|
+
* opened directly, so it carries its own minimal styling and references
|
|
152
|
+
* nothing external.
|
|
153
|
+
*/
|
|
154
|
+
export function renderGenericHtml(command, value) {
|
|
155
|
+
const body = value !== null && typeof value === "object" && !Array.isArray(value)
|
|
156
|
+
? Object.entries(value)
|
|
157
|
+
.filter(([key]) => !ENVELOPE_META_KEYS.has(key)) // transport metadata, not a result
|
|
158
|
+
.map(([key, nested]) => `<h2>${escapeHtml(key)}</h2>${htmlValue(nested, 3)}`)
|
|
159
|
+
.join("")
|
|
160
|
+
: htmlValue(value, 2);
|
|
161
|
+
return [
|
|
162
|
+
"<!doctype html>",
|
|
163
|
+
'<html lang="en">',
|
|
164
|
+
"<head>",
|
|
165
|
+
'<meta charset="utf-8">',
|
|
166
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1">',
|
|
167
|
+
`<title>akm ${escapeHtml(command)}</title>`,
|
|
168
|
+
"<style>",
|
|
169
|
+
"body{font:16px/1.5 system-ui,sans-serif;margin:2rem auto;max-width:60rem;padding:0 1rem}",
|
|
170
|
+
"table{border-collapse:collapse;width:100%;margin:0 0 1rem}",
|
|
171
|
+
"th,td{border:1px solid #8884;padding:.35rem .6rem;text-align:left}",
|
|
172
|
+
"th{background:#8881}",
|
|
173
|
+
"h1{margin-bottom:1.5rem}",
|
|
174
|
+
"@media(prefers-color-scheme:dark){body{background:#111;color:#eee}}",
|
|
175
|
+
"</style>",
|
|
176
|
+
"</head>",
|
|
177
|
+
"<body>",
|
|
178
|
+
`<h1>akm ${escapeHtml(command)}</h1>`,
|
|
179
|
+
body === "" ? "<p><em>(no output)</em></p>" : body,
|
|
180
|
+
"</body>",
|
|
181
|
+
"</html>",
|
|
182
|
+
"",
|
|
183
|
+
].join("\n");
|
|
184
|
+
}
|
|
185
|
+
// ── Text ─────────────────────────────────────────────────────────────────────
|
|
186
|
+
/**
|
|
187
|
+
* Flatten `value` onto `lines` as `dotted.path=value` entries — the exact
|
|
188
|
+
* algorithm `formatConfigPlain` (`src/output/text/command-format.ts`)
|
|
189
|
+
* already established as this CLI's real plain-text house style for `akm
|
|
190
|
+
* config list`. Arrays serialize as one compact-JSON line rather than
|
|
191
|
+
* index-per-line (`items.0.name=…`), matching that same precedent instead of
|
|
192
|
+
* inventing a second convention: the arrays that reach this generic
|
|
193
|
+
* fallback are typically short id/tag lists, where one JSON-array line reads
|
|
194
|
+
* better than N extra `path.0=`, `path.1=`, … lines.
|
|
195
|
+
*/
|
|
196
|
+
function flattenForText(value, path, lines) {
|
|
197
|
+
if (value === null || value === undefined) {
|
|
198
|
+
lines.push(`${path}=`);
|
|
199
|
+
}
|
|
200
|
+
else if (Array.isArray(value)) {
|
|
201
|
+
lines.push(`${path}=${JSON.stringify(value)}`);
|
|
202
|
+
}
|
|
203
|
+
else if (typeof value === "object") {
|
|
204
|
+
const entries = Object.entries(value);
|
|
205
|
+
if (entries.length === 0) {
|
|
206
|
+
lines.push(`${path}={}`);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
for (const [key, nested] of entries) {
|
|
210
|
+
flattenForText(nested, `${path}.${key}`, lines);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
lines.push(`${path}=${String(value)}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Render a shaped envelope as flat `key=value` text — no markup characters.
|
|
219
|
+
*
|
|
220
|
+
* This is a DISTINCT function from `renderGenericMarkdown`, not a reuse of
|
|
221
|
+
* it, and that is a deliberate reversal of this fallback's first cut, which
|
|
222
|
+
* called `renderGenericMarkdown` directly for `text` on the reasoning that
|
|
223
|
+
* it emits no HTML and is therefore "plain-text-safe." That reasoning was
|
|
224
|
+
* wrong: `#` heading markers, `_..._` emphasis, and `| ... |` table syntax
|
|
225
|
+
* ARE markup — a terminal happens to print them as literal characters
|
|
226
|
+
* instead of throwing, but a user piping `--format text` into `grep` or a
|
|
227
|
+
* line-oriented script still sees literal `#`/`_`/`|` noise that plain JSON
|
|
228
|
+
* at least didn't have. That is the exact "one format wearing another
|
|
229
|
+
* format's flag" defect this whole fallback exists to close, with Markdown
|
|
230
|
+
* substituted for JSON instead of JSON itself.
|
|
231
|
+
*
|
|
232
|
+
* `akm config list --format text` and `akm info --format text` already
|
|
233
|
+
* establish this CLI's real plain-text convention — flat `dotted.path=value`
|
|
234
|
+
* lines, no markup — so the generic fallback now matches its registered
|
|
235
|
+
* siblings (what a command looks like once someone writes it a bespoke
|
|
236
|
+
* formatter) instead of matching `md`'s.
|
|
237
|
+
*/
|
|
238
|
+
export function renderGenericText(command, value) {
|
|
239
|
+
const lines = [];
|
|
240
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
241
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
242
|
+
if (ENVELOPE_META_KEYS.has(key))
|
|
243
|
+
continue; // transport metadata, not a result
|
|
244
|
+
flattenForText(nested, key, lines);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
flattenForText(value, command, lines);
|
|
249
|
+
}
|
|
250
|
+
return lines.length === 0 ? `${command}: (empty)\n` : `${lines.join("\n")}\n`;
|
|
251
|
+
}
|
|
@@ -5,30 +5,25 @@
|
|
|
5
5
|
* `--format html` rendering primitives (#582).
|
|
6
6
|
*
|
|
7
7
|
* Templates live in `src/assets/templates/html/` (mirrored to
|
|
8
|
-
* `dist/assets/templates/html/` by `scripts/copy-assets.ts`).
|
|
9
|
-
*
|
|
10
|
-
* `
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* `dist/assets/templates/html/` by `scripts/copy-assets.ts`). `--format html`
|
|
9
|
+
* is health-only (chunk-9 WI-9.4c / Decision 4): `akm health` ships the sole
|
|
10
|
+
* bespoke `<command>.html` template; every other command rejects `--format
|
|
11
|
+
* html` with a `UsageError` before reaching this module (see
|
|
12
|
+
* `src/cli/shared.ts`'s `output()`). Substitution is plain `%%TOKEN%%` string
|
|
13
|
+
* replacement — no template engine, by design.
|
|
13
14
|
*/
|
|
14
15
|
import fs from "node:fs";
|
|
15
16
|
import path from "node:path";
|
|
16
17
|
import { getDirname } from "../runtime.js";
|
|
17
18
|
const TEMPLATES_DIR = path.join(getDirname(import.meta.url), "../assets/templates/html");
|
|
18
|
-
/** Template used by every command without a bespoke `<command>.html`. */
|
|
19
|
-
export const DEFAULT_TEMPLATE = "default";
|
|
20
19
|
/**
|
|
21
|
-
* Resolve the on-disk template path for a command
|
|
22
|
-
* command
|
|
23
|
-
*
|
|
24
|
-
* command string can never escape the templates directory.
|
|
20
|
+
* Resolve the on-disk template path for a command's bespoke `<command>.html`.
|
|
21
|
+
* The command name is sanitized to a bare basename so a hostile command
|
|
22
|
+
* string can never escape the templates directory.
|
|
25
23
|
*/
|
|
26
24
|
export function resolveTemplatePath(command) {
|
|
27
25
|
const name = path.basename(command.trim());
|
|
28
|
-
|
|
29
|
-
if (name !== DEFAULT_TEMPLATE && fs.existsSync(candidate))
|
|
30
|
-
return candidate;
|
|
31
|
-
return path.join(TEMPLATES_DIR, `${DEFAULT_TEMPLATE}.html`);
|
|
26
|
+
return path.join(TEMPLATES_DIR, `${name}.html`);
|
|
32
27
|
}
|
|
33
28
|
/** Matches a `%%TOKEN%%` placeholder (uppercase + underscore key). */
|
|
34
29
|
const TOKEN_RE = /%%[A-Z_]+%%/g;
|
|
@@ -43,7 +38,7 @@ const TOKEN_RE = /%%[A-Z_]+%%/g;
|
|
|
43
38
|
*/
|
|
44
39
|
export function renderHtml(templatePath, replacements) {
|
|
45
40
|
const html = fs.readFileSync(templatePath, "utf8");
|
|
46
|
-
return html.replace(TOKEN_RE, (token) =>
|
|
41
|
+
return html.replace(TOKEN_RE, (token) => replacements[token] ?? token);
|
|
47
42
|
}
|
|
48
43
|
/**
|
|
49
44
|
* Minimal HTML entity escaping for text interpolated into templates. Escapes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Per-command `md` / `html` renderer registries (D7).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors `src/output/text/registry.ts`: a command may register a bespoke
|
|
8
|
+
* renderer for a document format, and anything unregistered falls back to the
|
|
9
|
+
* generic rendering of its shaped envelope (`./generic-render`). The fallback
|
|
10
|
+
* is what makes all six `--format` values universal; the registry is what lets
|
|
11
|
+
* a command that has something better to say — `akm health` and its report
|
|
12
|
+
* templates — say it without the output pipeline knowing that command exists.
|
|
13
|
+
*
|
|
14
|
+
* Kept separate from the module that dispatches through it so per-command
|
|
15
|
+
* renderer modules can import `registerMdRenderer` / `registerHtmlRenderer`
|
|
16
|
+
* without a cycle back into the pipeline, exactly as the text registry does.
|
|
17
|
+
*
|
|
18
|
+
* Returning `null` from a handler means "I have nothing special for this
|
|
19
|
+
* payload" and falls through to the generic renderer — `akm health` uses that
|
|
20
|
+
* to keep its bespoke tables for the shapes that have them while still
|
|
21
|
+
* rendering everything else.
|
|
22
|
+
*/
|
|
23
|
+
import { createCommandRegistry } from "./command-registry.js";
|
|
24
|
+
const MD_RENDERER_REGISTRY = createCommandRegistry();
|
|
25
|
+
const HTML_RENDERER_REGISTRY = createCommandRegistry();
|
|
26
|
+
/** Register a Markdown renderer for a command name. */
|
|
27
|
+
export function registerMdRenderer(command, handler) {
|
|
28
|
+
MD_RENDERER_REGISTRY.register(command, handler);
|
|
29
|
+
}
|
|
30
|
+
/** Register a batch of Markdown renderers in iteration order. */
|
|
31
|
+
export function registerMdRenderers(entries) {
|
|
32
|
+
MD_RENDERER_REGISTRY.registerAll(entries);
|
|
33
|
+
}
|
|
34
|
+
/** Look up a registered Markdown renderer, or `undefined` when unregistered. */
|
|
35
|
+
export function getMdRendererHandler(command) {
|
|
36
|
+
return MD_RENDERER_REGISTRY.get(command);
|
|
37
|
+
}
|
|
38
|
+
/** Remove a previously-registered Markdown renderer. Test-only utility. */
|
|
39
|
+
export function deregisterMdRenderer(command) {
|
|
40
|
+
MD_RENDERER_REGISTRY.deregister(command);
|
|
41
|
+
}
|
|
42
|
+
/** Register an HTML renderer for a command name. */
|
|
43
|
+
export function registerHtmlRenderer(command, handler) {
|
|
44
|
+
HTML_RENDERER_REGISTRY.register(command, handler);
|
|
45
|
+
}
|
|
46
|
+
/** Register a batch of HTML renderers in iteration order. */
|
|
47
|
+
export function registerHtmlRenderers(entries) {
|
|
48
|
+
HTML_RENDERER_REGISTRY.registerAll(entries);
|
|
49
|
+
}
|
|
50
|
+
/** Look up a registered HTML renderer, or `undefined` when unregistered. */
|
|
51
|
+
export function getHtmlRendererHandler(command) {
|
|
52
|
+
return HTML_RENDERER_REGISTRY.get(command);
|
|
53
|
+
}
|
|
54
|
+
/** Remove a previously-registered HTML renderer. Test-only utility. */
|
|
55
|
+
export function deregisterHtmlRenderer(command) {
|
|
56
|
+
HTML_RENDERER_REGISTRY.deregister(command);
|
|
57
|
+
}
|