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
|
@@ -8,23 +8,24 @@
|
|
|
8
8
|
import * as p from "../../cli/clack.js";
|
|
9
9
|
import { detectAgentCliProfiles, pickDefaultAgentProfile } from "../../integrations/agent/index.js";
|
|
10
10
|
import { detectAgentPlatforms } from "../detect.js";
|
|
11
|
-
import {
|
|
11
|
+
import { readAgentEngineSelection } from "../engine-config.js";
|
|
12
12
|
import { prompt } from "../prompt.js";
|
|
13
|
+
// The just-computed source list is threaded through the private setup draft.
|
|
13
14
|
export async function stepAgentPlatforms(current) {
|
|
14
15
|
const platforms = detectAgentPlatforms();
|
|
15
16
|
if (platforms.length === 0) {
|
|
16
17
|
p.log.info("No agent platform configurations detected.");
|
|
17
18
|
return [];
|
|
18
19
|
}
|
|
19
|
-
const existingPaths = new Set((current.
|
|
20
|
+
const existingPaths = new Set((current.additionalSources ?? []).map((s) => s.path));
|
|
20
21
|
// Filter out platforms already configured
|
|
21
22
|
const newPlatforms = platforms.filter((pl) => !existingPaths.has(pl.path));
|
|
22
23
|
if (newPlatforms.length === 0) {
|
|
23
|
-
p.log.info(`Detected ${platforms.length} agent platform(s), all already configured as
|
|
24
|
+
p.log.info(`Detected ${platforms.length} agent platform(s), all already configured as bundle sources.`);
|
|
24
25
|
return [];
|
|
25
26
|
}
|
|
26
27
|
const selected = await prompt(() => p.multiselect({
|
|
27
|
-
message: "Found agent platform configurations. Add as
|
|
28
|
+
message: "Found agent platform configurations. Add as bundle sources?",
|
|
28
29
|
options: newPlatforms.map((pl) => ({
|
|
29
30
|
value: pl.path,
|
|
30
31
|
label: pl.name,
|
|
@@ -50,23 +51,23 @@ export async function stepAgentPlatforms(current) {
|
|
|
50
51
|
*/
|
|
51
52
|
export function printCapabilitySummary(smallModelSkipped, agentConfigured) {
|
|
52
53
|
const lines = ["Setup complete. Here's what's enabled:", ""];
|
|
53
|
-
lines.push(" ✓ akm search, akm curate, akm show — always available");
|
|
54
|
+
lines.push(" ✓ akm search, akm curate, akm show, akm index, akm remember — always available");
|
|
54
55
|
if (!smallModelSkipped) {
|
|
55
|
-
lines.push(" ✓
|
|
56
|
+
lines.push(" ✓ index metadata enhancement, akm improve, akm remember --enrich — small model configured");
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
58
|
-
lines.push(" ✗
|
|
59
|
+
lines.push(" ✗ index metadata enhancement, akm improve, akm remember --enrich — run `akm setup` to enable");
|
|
59
60
|
}
|
|
60
61
|
if (agentConfigured) {
|
|
61
|
-
lines.push(" ✓ akm
|
|
62
|
+
lines.push(" ✓ akm proposal new, akm improve, akm task — agent configured");
|
|
62
63
|
}
|
|
63
64
|
else {
|
|
64
|
-
lines.push(" ✗ akm
|
|
65
|
+
lines.push(" ✗ akm proposal new, akm improve, akm task — run `akm setup` to enable");
|
|
65
66
|
}
|
|
66
67
|
p.note(lines.join("\n"), "Feature Summary");
|
|
67
68
|
}
|
|
68
69
|
export async function stepAgentSelection(current, detections) {
|
|
69
|
-
const currentAgentBlock =
|
|
70
|
+
const currentAgentBlock = readAgentEngineSelection(current);
|
|
70
71
|
const available = detections.filter((d) => d.available);
|
|
71
72
|
if (available.length === 0) {
|
|
72
73
|
return currentAgentBlock;
|
|
@@ -85,7 +86,7 @@ export async function stepAgentSelection(current, detections) {
|
|
|
85
86
|
initialValue,
|
|
86
87
|
}));
|
|
87
88
|
if (selectedDefault === "disabled") {
|
|
88
|
-
if (!currentAgentBlock?.
|
|
89
|
+
if (!currentAgentBlock?.engines) {
|
|
89
90
|
return undefined;
|
|
90
91
|
}
|
|
91
92
|
return {
|
|
@@ -110,7 +111,7 @@ export async function stepAgentSelection(current, detections) {
|
|
|
110
111
|
*/
|
|
111
112
|
export function stepAgentCliDetection(current, detectFn = detectAgentCliProfiles) {
|
|
112
113
|
const detections = detectFn(current);
|
|
113
|
-
const currentAgentBlock =
|
|
114
|
+
const currentAgentBlock = readAgentEngineSelection(current);
|
|
114
115
|
const defaultName = pickDefaultAgentProfile(detections, currentAgentBlock?.default);
|
|
115
116
|
// No installed agents found and no existing config → leave block absent.
|
|
116
117
|
if (!defaultName && !currentAgentBlock) {
|
|
@@ -8,15 +8,27 @@
|
|
|
8
8
|
import * as p from "../../cli/clack.js";
|
|
9
9
|
import { prompt } from "../prompt.js";
|
|
10
10
|
import { describeSemanticSearchAssets, isRemoteEmbeddingConfig } from "../semantic-assets.js";
|
|
11
|
-
export async function stepSemanticSearch(
|
|
11
|
+
export async function stepSemanticSearch(
|
|
12
|
+
// Owner ruling 9 (R-039): the runtime default is "off" (a bare/headless
|
|
13
|
+
// install must never silently pull the ~130 MB model), but the interactive
|
|
14
|
+
// wizard pre-selects semantic search ON — a human is present to read the
|
|
15
|
+
// warning below and decide. `_current` is intentionally unused for the
|
|
16
|
+
// enable/disable pre-selection below: it must NOT track
|
|
17
|
+
// `semanticSearchMode`, or this pre-selection would silently flip to off
|
|
18
|
+
// along with the runtime default. Kept in the signature for call-site
|
|
19
|
+
// stability (callers pass the in-progress setup config positionally).
|
|
20
|
+
_current, embedding) {
|
|
21
|
+
// Show the warning (asset sizes; "no local model download" when a remote
|
|
22
|
+
// embedding endpoint is configured) BEFORE the prompt so the pre-checked
|
|
23
|
+
// default is an informed choice, not a surprise.
|
|
24
|
+
p.note(describeSemanticSearchAssets(embedding).join("\n"), "Semantic Search Assets");
|
|
12
25
|
const enabled = await prompt(() => p.confirm({
|
|
13
26
|
message: "Enable semantic search?",
|
|
14
|
-
initialValue:
|
|
27
|
+
initialValue: true,
|
|
15
28
|
}));
|
|
16
29
|
if (!enabled) {
|
|
17
30
|
return { mode: "off", prepareAssets: false };
|
|
18
31
|
}
|
|
19
|
-
p.note(describeSemanticSearchAssets(embedding).join("\n"), "Semantic Search Assets");
|
|
20
32
|
const prepareAssets = await prompt(() => p.confirm({
|
|
21
33
|
message: isRemoteEmbeddingConfig(embedding)
|
|
22
34
|
? "Check the embedding endpoint and verify semantic search now?"
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* built-in registries.
|
|
8
8
|
*/
|
|
9
9
|
import * as p from "../../cli/clack.js";
|
|
10
|
-
import { DEFAULT_CONFIG, getEffectiveRegistries } from "../../core/config/config.js";
|
|
10
|
+
import { DEFAULT_CONFIG, getEffectiveRegistries, getSources } from "../../core/config/config.js";
|
|
11
|
+
import { readLockfile } from "../../integrations/lockfile.js";
|
|
11
12
|
import { prompt, promptOrBack } from "../prompt.js";
|
|
12
13
|
import { loadSetupStashes } from "../registry-stash-loader.js";
|
|
13
14
|
function configuredSourceKey(source) {
|
|
@@ -30,15 +31,15 @@ function renderConfiguredSourceList(sources) {
|
|
|
30
31
|
})
|
|
31
32
|
.join("\n");
|
|
32
33
|
}
|
|
33
|
-
function renderInstalledSourceList(
|
|
34
|
-
return
|
|
34
|
+
function renderInstalledSourceList(managed) {
|
|
35
|
+
return managed.map((entry) => `- ${entry.name ?? entry.url ?? entry.path ?? "unknown"} (${entry.type})`).join("\n");
|
|
35
36
|
}
|
|
36
37
|
export async function stepAdditionalSources(currentSources) {
|
|
37
38
|
const sources = [...currentSources];
|
|
38
39
|
let addMore = true;
|
|
39
40
|
while (addMore) {
|
|
40
41
|
const action = await prompt(() => p.select({
|
|
41
|
-
message: "Add another
|
|
42
|
+
message: "Add another bundle source?",
|
|
42
43
|
options: [
|
|
43
44
|
{ value: "done", label: "Done — no more sources" },
|
|
44
45
|
{ value: "github-repo", label: "GitHub repository", hint: "custom URL" },
|
|
@@ -62,7 +63,7 @@ export async function stepAdditionalSources(currentSources) {
|
|
|
62
63
|
if (url === null)
|
|
63
64
|
continue;
|
|
64
65
|
const name = await promptOrBack(() => p.text({
|
|
65
|
-
message: "Give this
|
|
66
|
+
message: "Give this bundle a name (optional):",
|
|
66
67
|
placeholder: "my-repo",
|
|
67
68
|
}));
|
|
68
69
|
if (name === null)
|
|
@@ -80,7 +81,7 @@ export async function stepAdditionalSources(currentSources) {
|
|
|
80
81
|
if (action === "filesystem") {
|
|
81
82
|
const fsPath = await promptOrBack(() => p.text({
|
|
82
83
|
message: "Enter the directory path:",
|
|
83
|
-
placeholder: "/path/to/
|
|
84
|
+
placeholder: "/path/to/bundle",
|
|
84
85
|
validate: (v) => {
|
|
85
86
|
if (!v?.trim())
|
|
86
87
|
return "Path cannot be empty";
|
|
@@ -90,8 +91,8 @@ export async function stepAdditionalSources(currentSources) {
|
|
|
90
91
|
continue;
|
|
91
92
|
const resolved = fsPath.trim();
|
|
92
93
|
const name = await promptOrBack(() => p.text({
|
|
93
|
-
message: "Give this
|
|
94
|
-
placeholder: "my-
|
|
94
|
+
message: "Give this bundle a name (optional):",
|
|
95
|
+
placeholder: "my-bundle",
|
|
95
96
|
}));
|
|
96
97
|
if (name === null)
|
|
97
98
|
continue;
|
|
@@ -150,13 +151,18 @@ export async function stepRegistries(current) {
|
|
|
150
151
|
* @internal Exported for testing only.
|
|
151
152
|
*/
|
|
152
153
|
export async function stepAddSources(current, options) {
|
|
153
|
-
|
|
154
|
+
// The wizard toggles plain additional bundles, not the default bundle or
|
|
155
|
+
// lock-backed registry installs, which are preserved untouched.
|
|
156
|
+
const lockIds = new Set(readLockfile().map((entry) => entry.id));
|
|
157
|
+
const allSources = getSources(current);
|
|
158
|
+
const existingSources = allSources.filter((source) => !source.primary && !(source.name && lockIds.has(source.name)));
|
|
159
|
+
const managedSources = allSources.filter((source) => source.name != null && lockIds.has(source.name));
|
|
154
160
|
const sources = [];
|
|
155
161
|
if (existingSources.length > 0) {
|
|
156
|
-
p.note(renderConfiguredSourceList(existingSources), "Configured
|
|
162
|
+
p.note(renderConfiguredSourceList(existingSources), "Configured bundle sources");
|
|
157
163
|
const options = existingSources.map(describeConfiguredSource);
|
|
158
164
|
const selected = await prompt(() => p.multiselect({
|
|
159
|
-
message: "Configured
|
|
165
|
+
message: "Configured bundle sources — uncheck any you want to disable:",
|
|
160
166
|
options,
|
|
161
167
|
initialValues: options.map((option) => option.value),
|
|
162
168
|
required: false,
|
|
@@ -167,8 +173,8 @@ export async function stepAddSources(current, options) {
|
|
|
167
173
|
}
|
|
168
174
|
}
|
|
169
175
|
}
|
|
170
|
-
if (
|
|
171
|
-
p.note(renderInstalledSourceList(
|
|
176
|
+
if (managedSources.length > 0) {
|
|
177
|
+
p.note(renderInstalledSourceList(managedSources), "Installed managed bundles (preserved)");
|
|
172
178
|
}
|
|
173
179
|
// ── Registry-driven stash recommendations ─────────────────────────────
|
|
174
180
|
// Fetch available stashes from the official registry (cached, stale-ok).
|
|
@@ -189,8 +195,8 @@ export async function stepAddSources(current, options) {
|
|
|
189
195
|
: availableStashes.filter((s) => s.defaultSelected).map((s) => s.url);
|
|
190
196
|
const selectedUrls = await prompt(() => p.multiselect({
|
|
191
197
|
message: availableStashes[0]?.source === "registry"
|
|
192
|
-
? "Available
|
|
193
|
-
: "Recommended
|
|
198
|
+
? "Available bundles from the AKM registry — toggle to add or remove:"
|
|
199
|
+
: "Recommended bundle sources — toggle to add or remove:",
|
|
194
200
|
options: stashOptions,
|
|
195
201
|
initialValues,
|
|
196
202
|
required: false,
|
|
@@ -6,24 +6,26 @@
|
|
|
6
6
|
* and other assets).
|
|
7
7
|
*/
|
|
8
8
|
import * as p from "../../cli/clack.js";
|
|
9
|
+
import { primaryBundlePath } from "../../core/config/config.js";
|
|
9
10
|
import { assertSafeStashDir, getDefaultStashDir } from "../../core/paths.js";
|
|
10
11
|
import { prompt } from "../prompt.js";
|
|
11
12
|
export async function stepStashDir(current, options) {
|
|
12
|
-
const
|
|
13
|
+
const currentPrimary = primaryBundlePath(current);
|
|
14
|
+
const defaultDir = options?.preferredDir ?? currentPrimary ?? getDefaultStashDir();
|
|
13
15
|
if (options?.nonInteractive) {
|
|
14
16
|
return defaultDir;
|
|
15
17
|
}
|
|
16
18
|
const choice = await prompt(() => p.select({
|
|
17
19
|
message: "Where should akm store skills, commands, and other assets?",
|
|
18
20
|
options: [
|
|
19
|
-
{ value: "default", label: defaultDir, hint:
|
|
21
|
+
{ value: "default", label: defaultDir, hint: currentPrimary ? "current" : "default" },
|
|
20
22
|
{ value: "custom", label: "Enter a custom path..." },
|
|
21
23
|
],
|
|
22
24
|
}));
|
|
23
25
|
if (choice === "default")
|
|
24
26
|
return defaultDir;
|
|
25
27
|
const customPath = await prompt(() => p.text({
|
|
26
|
-
message: "Enter the
|
|
28
|
+
message: "Enter the bundle directory path:",
|
|
27
29
|
placeholder: defaultDir,
|
|
28
30
|
validate: (v) => {
|
|
29
31
|
if (!v?.trim())
|
|
@@ -34,7 +36,7 @@ export async function stepStashDir(current, options) {
|
|
|
34
36
|
catch (err) {
|
|
35
37
|
if (err instanceof Error)
|
|
36
38
|
return err.message;
|
|
37
|
-
return "Refused: unsafe
|
|
39
|
+
return "Refused: unsafe bundle directory";
|
|
38
40
|
}
|
|
39
41
|
},
|
|
40
42
|
}));
|
|
@@ -1,152 +1,269 @@
|
|
|
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
|
-
|
|
4
|
+
/** Setup wizard step for reviewing task definitions and activating schedules. */
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { parse as yamlParse, stringify as yamlStringify } from "yaml";
|
|
8
9
|
import * as p from "../../cli/clack.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { akmTasksSync, setEnabledInYaml } from "../../commands/tasks/tasks.js";
|
|
11
|
+
import { loadConfig } from "../../core/config/config.js";
|
|
12
|
+
import { UsageError } from "../../core/errors.js";
|
|
13
|
+
import { commitWriteTargetBoundary, deleteAssetFromSource, prepareWriteTargetForMutation, resolveWriteTarget, writeAssetToSource, } from "../../core/write-source.js";
|
|
12
14
|
import { backendNameForPlatform } from "../../tasks/backends/index.js";
|
|
13
15
|
import { listEmbeddedTasks } from "../../tasks/embedded.js";
|
|
16
|
+
import { parseTaskDocument } from "../../tasks/parser.js";
|
|
14
17
|
import { parseSchedule } from "../../tasks/schedule.js";
|
|
15
18
|
import { prompt } from "../prompt.js";
|
|
16
19
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
+
* A scheduled server-only nightly full sweep exists among the embedded
|
|
21
|
+
* improve-schedule templates (folded in from the retired
|
|
22
|
+
* `registerDefaultTasks`/`akm tasks init` path in 0.9, S6). This id is
|
|
23
|
+
* preselected in the review multiselect on a detected server install — the
|
|
24
|
+
* "battery heuristic" {@link detectServerDefault} preserved from that path.
|
|
20
25
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
const SERVER_SUGGESTED_TASK_ID = "akm-improve-nightly";
|
|
27
|
+
let scheduledTasksEnvOverrides;
|
|
28
|
+
/** TEST-ONLY. Swap the CI/server-detection probes; pass undefined to restore. */
|
|
29
|
+
export function _setScheduledTasksEnvForTests(fakes) {
|
|
30
|
+
scheduledTasksEnvOverrides = fakes;
|
|
23
31
|
}
|
|
24
32
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* {@link registerDefaultTasks}, which is CI-aware and never duplicates an
|
|
29
|
-
* existing task. Skipped entirely under CI (the registration helper short-
|
|
30
|
-
* circuits, and we never even prompt).
|
|
31
|
-
*
|
|
32
|
-
* Exported for testing.
|
|
33
|
+
* Decide whether `akm setup` is running in a CI environment, where it must
|
|
34
|
+
* register NO scheduled tasks. Mirrors the common `CI=true` convention used by
|
|
35
|
+
* GitHub Actions, GitLab CI, CircleCI, etc.
|
|
33
36
|
*/
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
export function isCiEnvironment(env = process.env) {
|
|
38
|
+
if (scheduledTasksEnvOverrides?.isCiEnvironment)
|
|
39
|
+
return scheduledTasksEnvOverrides.isCiEnvironment(env);
|
|
40
|
+
const ci = env.CI;
|
|
41
|
+
if (ci === undefined || ci === null)
|
|
42
|
+
return false;
|
|
43
|
+
const v = String(ci).trim().toLowerCase();
|
|
44
|
+
return v !== "" && v !== "0" && v !== "false";
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Platform-appropriate default for "Is this a server install?":
|
|
48
|
+
* - Linux without a battery → `true` (server).
|
|
49
|
+
* - macOS / any host with a battery (laptop) → `false`.
|
|
50
|
+
* Used to preselect {@link SERVER_SUGGESTED_TASK_ID} in the task-review
|
|
51
|
+
* multiselect.
|
|
52
|
+
*/
|
|
53
|
+
export function detectServerDefault() {
|
|
54
|
+
if (scheduledTasksEnvOverrides?.detectServerDefault)
|
|
55
|
+
return scheduledTasksEnvOverrides.detectServerDefault();
|
|
56
|
+
if (os.platform() !== "linux")
|
|
57
|
+
return false;
|
|
58
|
+
// A laptop exposes a battery under /sys/class/power_supply/BAT*. Absence of
|
|
59
|
+
// any battery is our heuristic for "server / desktop".
|
|
60
|
+
try {
|
|
61
|
+
const entries = fs.readdirSync("/sys/class/power_supply");
|
|
62
|
+
const hasBattery = entries.some((e) => /^BAT/i.test(e));
|
|
63
|
+
return !hasBattery;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// If we cannot read power-supply info, prefer the safe server default on
|
|
67
|
+
// Linux (the nightly sweep is low-impact and re-runnable).
|
|
68
|
+
return true;
|
|
39
69
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
70
|
+
}
|
|
71
|
+
function normaliseTaskIdForMatch(raw) {
|
|
72
|
+
return raw.trim().replace(/\.(yml|md)$/, "");
|
|
73
|
+
}
|
|
74
|
+
export function listSetupTaskDefinitions() {
|
|
75
|
+
const config = loadConfig();
|
|
76
|
+
const target = resolveWriteTarget(config, config.defaultBundle, { requireWritable: false });
|
|
77
|
+
const taskDir = path.join(target.source.path, "tasks");
|
|
78
|
+
if (!fs.existsSync(taskDir))
|
|
79
|
+
return [];
|
|
80
|
+
const tasks = [];
|
|
81
|
+
for (const file of fs.readdirSync(taskDir)) {
|
|
82
|
+
if (!file.endsWith(".yml"))
|
|
83
|
+
continue;
|
|
84
|
+
const id = file.slice(0, -4);
|
|
85
|
+
const filePath = path.join(taskDir, file);
|
|
86
|
+
try {
|
|
87
|
+
const task = parseTaskDocument({ yaml: fs.readFileSync(filePath, "utf8"), filePath, id });
|
|
88
|
+
tasks.push({ id: task.id, schedule: task.schedule, enabled: task.enabled, description: task.description });
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new UsageError(`Cannot review task definition ${filePath}: ${error instanceof Error ? error.message : String(error)} ` +
|
|
92
|
+
"Fix or remove the invalid task, then rerun `akm setup`. No task files or scheduler state were changed.", "INVALID_FLAG_VALUE", "Fix or remove the invalid task definition, then rerun `akm setup`.");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return tasks.sort((a, b) => a.id.localeCompare(b.id));
|
|
96
|
+
}
|
|
97
|
+
export async function prepareSetupTaskDefinitions(tasks, deps = {}) {
|
|
98
|
+
const config = loadConfig();
|
|
99
|
+
const target = prepareWriteTargetForMutation(resolveWriteTarget(config, config.defaultBundle, { requireWritable: true }));
|
|
100
|
+
const taskDir = path.join(target.source.path, "tasks");
|
|
101
|
+
const writeAsset = deps.writeAsset ?? writeAssetToSource;
|
|
102
|
+
const deleteAsset = deps.deleteAsset ?? deleteAssetFromSource;
|
|
103
|
+
const commitBoundary = deps.commitBoundary ?? commitWriteTargetBoundary;
|
|
104
|
+
const prepared = tasks.map((plan) => {
|
|
105
|
+
const filePath = path.join(taskDir, `${plan.task.id}.yml`);
|
|
106
|
+
const original = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : undefined;
|
|
107
|
+
let yaml;
|
|
108
|
+
if (original !== undefined) {
|
|
109
|
+
yaml = setEnabledInYaml(original, plan.enabled);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const document = yamlParse(plan.task.yaml);
|
|
113
|
+
document.schedule = plan.schedule;
|
|
114
|
+
document.enabled = plan.enabled;
|
|
115
|
+
yaml = yamlStringify(document);
|
|
116
|
+
}
|
|
117
|
+
parseTaskDocument({ yaml, filePath, id: plan.task.id });
|
|
118
|
+
parseSchedule(plan.schedule, backendNameForPlatform());
|
|
119
|
+
return { filePath, original, yaml, ref: { type: "task", name: plan.task.id } };
|
|
120
|
+
});
|
|
121
|
+
const changed = prepared.filter((entry) => entry.original !== entry.yaml);
|
|
122
|
+
if (changed.length === 0)
|
|
123
|
+
return 0;
|
|
124
|
+
const attempted = [];
|
|
125
|
+
try {
|
|
126
|
+
for (const entry of changed) {
|
|
127
|
+
attempted.push(entry);
|
|
128
|
+
await writeAsset(target.source, target.config, entry.ref, entry.yaml);
|
|
129
|
+
}
|
|
130
|
+
commitBoundary(target, "Prepare scheduled tasks");
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
const rollbackErrors = [];
|
|
134
|
+
for (const entry of [...attempted].reverse()) {
|
|
135
|
+
try {
|
|
136
|
+
if (entry.original === undefined) {
|
|
137
|
+
if (fs.existsSync(entry.filePath))
|
|
138
|
+
await deleteAsset(target.source, target.config, entry.ref);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
await writeAsset(target.source, target.config, entry.ref, entry.original);
|
|
142
|
+
fs.writeFileSync(entry.filePath, entry.original, "utf8");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (rollbackError) {
|
|
146
|
+
rollbackErrors.push(rollbackError);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
commitBoundary(target, "Restore scheduled tasks after failed setup");
|
|
151
|
+
}
|
|
152
|
+
catch (rollbackError) {
|
|
153
|
+
rollbackErrors.push(rollbackError);
|
|
154
|
+
}
|
|
155
|
+
if (rollbackErrors.length > 0) {
|
|
156
|
+
throw new AggregateError([error, ...rollbackErrors], `Task definition preparation failed and rollback was incomplete: ${error instanceof Error ? error.message : String(error)}`);
|
|
157
|
+
}
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
return changed.length;
|
|
50
161
|
}
|
|
51
162
|
const DEFAULT_SCHEDULED_TASKS_DEPS = {
|
|
52
|
-
list:
|
|
53
|
-
|
|
54
|
-
setEnabled: akmTasksSetEnabled,
|
|
163
|
+
list: listSetupTaskDefinitions,
|
|
164
|
+
prepare: prepareSetupTaskDefinitions,
|
|
55
165
|
sync: akmTasksSync,
|
|
56
|
-
gitSync: saveGitStash,
|
|
57
166
|
};
|
|
58
|
-
export async function stepScheduledTasks(deps = DEFAULT_SCHEDULED_TASKS_DEPS) {
|
|
167
|
+
export async function stepScheduledTasks(deps = DEFAULT_SCHEDULED_TASKS_DEPS, options = {}) {
|
|
168
|
+
if (options.nonInteractive || isCiEnvironment()) {
|
|
169
|
+
p.log.info("Non-interactive setup leaves task files and scheduler state unchanged. Run `akm setup` interactively to review tasks.");
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
// ALL templates are offered, including ships-disabled ones (e.g. the
|
|
173
|
+
// manual-recovery catchup task): an unselected template is still PREPARED
|
|
174
|
+
// with `enabled: false`, so its YAML exists for `akm task run <id>` while
|
|
175
|
+
// nothing lands in the scheduler uncommented. Filtering on `task.enabled`
|
|
176
|
+
// here would make ships-disabled templates invisible and unpreparable.
|
|
59
177
|
const embedded = listEmbeddedTasks();
|
|
60
178
|
if (embedded.length === 0)
|
|
61
179
|
return;
|
|
62
|
-
|
|
63
|
-
let installed = [];
|
|
64
|
-
try {
|
|
65
|
-
installed = (await deps.list()).tasks;
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
// A missing/empty tasks dir is fine — treat as nothing installed.
|
|
69
|
-
installed = [];
|
|
70
|
-
}
|
|
180
|
+
const installed = await deps.list();
|
|
71
181
|
const byId = new Map();
|
|
72
|
-
for (const
|
|
73
|
-
byId.set(normaliseTaskIdForMatch(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
182
|
+
for (const task of installed)
|
|
183
|
+
byId.set(normaliseTaskIdForMatch(task.id), task);
|
|
184
|
+
const preChecked = embedded.filter((task) => byId.get(task.id)?.enabled === true).map((task) => task.id);
|
|
185
|
+
// Battery heuristic preserved from the retired `registerDefaultTasks` path
|
|
186
|
+
// (S6): suggest the nightly full sweep on a detected server install, same
|
|
187
|
+
// as every other embedded template, still gated behind the confirmation
|
|
188
|
+
// below.
|
|
189
|
+
if (!byId.has(SERVER_SUGGESTED_TASK_ID) &&
|
|
190
|
+
!preChecked.includes(SERVER_SUGGESTED_TASK_ID) &&
|
|
191
|
+
embedded.some((task) => task.id === SERVER_SUGGESTED_TASK_ID) &&
|
|
192
|
+
detectServerDefault()) {
|
|
193
|
+
preChecked.push(SERVER_SUGGESTED_TASK_ID);
|
|
194
|
+
}
|
|
82
195
|
const selected = await prompt(() => p.multiselect({
|
|
83
|
-
message: "
|
|
196
|
+
message: "Which task definitions should be enabled? (scheduler activation is confirmed separately)",
|
|
84
197
|
required: false,
|
|
85
198
|
initialValues: preChecked,
|
|
86
|
-
options: embedded.map((
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
199
|
+
options: embedded.map((task) => {
|
|
200
|
+
const current = byId.get(task.id);
|
|
201
|
+
const schedule = current?.schedule ?? task.schedule;
|
|
202
|
+
const state = current ? (current.enabled ? "enabled" : "disabled") : "not prepared";
|
|
203
|
+
return {
|
|
204
|
+
value: task.id,
|
|
205
|
+
label: task.label,
|
|
206
|
+
hint: `${task.description} - ${schedule} [${state}]`,
|
|
207
|
+
};
|
|
208
|
+
}),
|
|
91
209
|
}));
|
|
92
210
|
const selectedSet = new Set(selected);
|
|
93
|
-
// Resolve per-task schedule edits for newly-checked, not-yet-installed tasks.
|
|
94
211
|
const scheduleFor = new Map();
|
|
95
|
-
for (const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
scheduleFor.set(e.id, sched);
|
|
114
|
-
}
|
|
212
|
+
for (const task of embedded) {
|
|
213
|
+
if (!selectedSet.has(task.id) || byId.has(task.id))
|
|
214
|
+
continue;
|
|
215
|
+
const edited = await prompt(() => p.text({
|
|
216
|
+
message: `Schedule for ${task.label}?`,
|
|
217
|
+
initialValue: task.schedule,
|
|
218
|
+
validate(value) {
|
|
219
|
+
const candidate = (value ?? "").trim() || task.schedule;
|
|
220
|
+
try {
|
|
221
|
+
parseSchedule(candidate, backendNameForPlatform());
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
return error instanceof Error ? error.message : "Invalid schedule.";
|
|
225
|
+
}
|
|
226
|
+
return undefined;
|
|
227
|
+
},
|
|
228
|
+
}));
|
|
229
|
+
scheduleFor.set(task.id, (edited ?? "").trim() || task.schedule);
|
|
115
230
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
// No state change → no action.
|
|
231
|
+
const plans = embedded.map((task) => {
|
|
232
|
+
const current = byId.get(task.id);
|
|
233
|
+
return {
|
|
234
|
+
task,
|
|
235
|
+
schedule: current?.schedule ?? scheduleFor.get(task.id) ?? task.schedule,
|
|
236
|
+
enabled: selectedSet.has(task.id),
|
|
237
|
+
installed: current !== undefined,
|
|
238
|
+
};
|
|
239
|
+
});
|
|
240
|
+
const embeddedIds = new Set(embedded.map((task) => task.id));
|
|
241
|
+
const custom = installed.filter((task) => !embeddedIds.has(normaliseTaskIdForMatch(task.id)));
|
|
242
|
+
p.note([
|
|
243
|
+
...plans.map((plan) => `${plan.task.label}: ${plan.enabled ? "enabled" : "disabled"} | ${plan.schedule} | ${plan.task.description}`),
|
|
244
|
+
...custom.map((task) => `${task.id}: ${task.enabled ? "enabled" : "disabled"} | ${task.schedule}${task.description ? ` | ${task.description}` : ""}`),
|
|
245
|
+
].join("\n"), "Task Schedule Review");
|
|
246
|
+
const activate = await prompt(() => p.confirm({
|
|
247
|
+
message: `Activate these schedules now? This will update task files and sync them to the ${backendNameForPlatform()} scheduler.`,
|
|
248
|
+
initialValue: false,
|
|
249
|
+
}));
|
|
250
|
+
if (!activate) {
|
|
251
|
+
p.log.info("Task definitions and scheduler state were not changed.");
|
|
252
|
+
return;
|
|
140
253
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
catch {
|
|
149
|
-
// Non-fatal — the task is installed regardless of git sync outcome.
|
|
254
|
+
const changed = await deps.prepare(plans);
|
|
255
|
+
if (changed > 0)
|
|
256
|
+
p.log.success(`Prepared ${changed} task definition${changed === 1 ? "" : "s"}.`);
|
|
257
|
+
const syncResult = await deps.sync();
|
|
258
|
+
if (syncResult.skipped.length > 0) {
|
|
259
|
+
for (const skipped of syncResult.skipped) {
|
|
260
|
+
p.log.warn(`Task "${skipped.id}" was not activated: ${skipped.reason}`);
|
|
150
261
|
}
|
|
262
|
+
const activeCount = syncResult.installed.length + syncResult.updated.length + syncResult.unchanged.length;
|
|
263
|
+
p.log.warn(`${activeCount === 0 ? "No task schedules were activated." : "Task schedule activation was incomplete."} ` +
|
|
264
|
+
"If you are running AKM from source, run the installed `akm setup`. " +
|
|
265
|
+
"To migrate or repair existing scheduler bindings explicitly, run `akm task sync --rebind`.");
|
|
266
|
+
return;
|
|
151
267
|
}
|
|
268
|
+
p.log.success("Task schedules activated. Verify them with `akm task doctor`.");
|
|
152
269
|
}
|