akm-cli 0.9.0-rc.8 → 0.9.0
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 +1063 -44
- package/README.md +51 -25
- package/SECURITY.md +14 -1
- package/STABILITY.md +497 -0
- package/dist/akm +148 -35
- package/dist/{akm-migrate-storage → akm-migrate} +6 -9
- package/dist/assets/hints/cli-hints-full.md +223 -95
- package/dist/assets/hints/cli-hints-short.md +85 -22
- package/dist/assets/improve-strategies/default.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/stash-skeleton/README.md +6 -5
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
- package/dist/assets/tasks/core/extract.yml +1 -1
- package/dist/assets/tasks/core/version-check.yml +1 -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 +1 -3
- package/dist/assets/workflows/workflow-template.md +32 -15
- package/dist/cli/invocation.js +40 -15
- package/dist/cli/parse-args.js +0 -22
- package/dist/cli/retired-commands.js +121 -0
- package/dist/cli/shared.js +154 -22
- package/dist/cli/unknown-flags.js +236 -0
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +696 -258
- package/dist/commands/agent/agent-dispatch.js +14 -3
- package/dist/commands/agent/contribute-cli.js +73 -88
- package/dist/commands/completions.js +79 -22
- package/dist/commands/config-cli.js +17 -150
- package/dist/commands/env/env-cli.js +59 -143
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +36 -66
- package/dist/commands/env/secret.js +24 -57
- package/dist/commands/feedback-cli.js +141 -87
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +3 -4
- package/dist/commands/health/checks.js +85 -23
- package/dist/commands/health/html-report.js +7 -10
- package/dist/commands/health/improve-metrics.js +25 -83
- package/dist/commands/health/md-report.js +5 -9
- package/dist/commands/health/metrics.js +62 -20
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +4 -5
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +3 -48
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/commands/health/types-improve.js +7 -0
- package/dist/commands/health.js +99 -28
- package/dist/commands/improve/anti-collapse.js +2 -2
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +41 -40
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +140 -1000
- package/dist/commands/improve/distill/promote-memory.js +12 -12
- package/dist/commands/improve/distill/quality-gate.js +6 -6
- package/dist/commands/improve/distill.js +58 -69
- package/dist/commands/improve/eligibility.js +105 -57
- package/dist/commands/improve/extract-cli.js +14 -133
- package/dist/commands/improve/improve-cli.js +98 -114
- package/dist/commands/improve/improve-result-file.js +1 -28
- package/dist/commands/improve/improve-strategies.js +8 -5
- package/dist/commands/improve/improve.js +128 -91
- package/dist/commands/improve/loop-stages.js +182 -20
- package/dist/commands/improve/memory/derived-ref.js +45 -43
- package/dist/commands/improve/memory/memory-belief.js +1 -1
- package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
- package/dist/commands/improve/memory/memory-improve.js +6 -5
- package/dist/commands/improve/outcome-loop.js +22 -65
- package/dist/commands/improve/preparation.js +114 -123
- package/dist/commands/improve/proactive-maintenance.js +2 -5
- package/dist/commands/improve/reflect.js +56 -160
- package/dist/commands/improve/salience.js +11 -122
- package/dist/commands/improve/source-identity.js +10 -38
- package/dist/commands/lint/base-linter.js +20 -124
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +249 -43
- package/dist/commands/{events.js → log.js} +33 -38
- package/dist/commands/migrate-cli.js +92 -12
- package/dist/commands/migration-tool.js +46 -0
- package/dist/commands/observability-cli.js +70 -209
- package/dist/commands/proposal/drain.js +101 -29
- package/dist/commands/proposal/proposal-cli.js +76 -48
- package/dist/commands/proposal/proposal.js +54 -18
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +23 -15
- package/dist/commands/proposal/repository.js +701 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
- package/dist/commands/proposal/validators/proposal-validators.js +55 -7
- package/dist/commands/proposal/validators/proposals.js +4 -7
- package/dist/commands/read/curate.js +34 -53
- package/dist/commands/read/knowledge.js +150 -95
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +42 -15
- package/dist/commands/read/search-cli.js +180 -78
- package/dist/commands/read/search.js +58 -43
- package/dist/commands/read/show.js +197 -141
- package/dist/commands/registry-cli.js +12 -51
- package/dist/commands/remember.js +14 -57
- package/dist/commands/sources/add-cli.js +100 -31
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +7 -2
- package/dist/commands/sources/info.js +18 -5
- package/dist/commands/sources/init.js +12 -12
- package/dist/commands/sources/installed-stashes.js +382 -98
- package/dist/commands/sources/schema-repair.js +3 -2
- package/dist/commands/sources/self-update.js +131 -38
- package/dist/commands/sources/source-add.js +72 -17
- package/dist/commands/sources/source-clone.js +129 -45
- package/dist/commands/sources/source-manage.js +43 -23
- package/dist/commands/sources/sources-cli.js +57 -208
- package/dist/commands/sources/stash-cli.js +46 -53
- package/dist/commands/tasks/tasks-cli.js +91 -97
- package/dist/commands/tasks/tasks.js +276 -421
- package/dist/commands/workflow-cli.js +175 -450
- package/dist/core/adapter/adapters/akm-adapter.js +47 -28
- package/dist/core/adapter/adapters/akm-lint.js +42 -27
- package/dist/core/adapter/adapters/akm-metadata.js +15 -44
- package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
- package/dist/core/adapter/adapters/index.js +6 -6
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
- package/dist/core/adapter/adapters/okf-adapter.js +187 -19
- package/dist/core/adapter/adapters/shared.js +3 -19
- package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +6 -4
- package/dist/core/adapter/validate-context.js +214 -0
- package/dist/core/asset/akm-markdown.js +63 -0
- package/dist/core/asset/asset-placement.js +20 -6
- package/dist/core/asset/asset-ref.js +11 -9
- package/dist/core/asset/frontmatter-lint.js +30 -0
- package/dist/core/asset/frontmatter.js +37 -9
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +89 -18
- package/dist/core/asset/stash-meta.js +1 -1
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +152 -38
- package/dist/core/config/config-io.js +12 -1
- package/dist/core/config/config-schema.js +35 -8
- package/dist/core/config/config-sources.js +55 -11
- package/dist/core/config/config-walker.js +25 -9
- package/dist/core/config/config.js +9 -48
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +5 -1
- package/dist/core/config/schema/experimental.js +30 -0
- package/dist/core/config/schema/improve-processes.js +0 -6
- package/dist/core/config/schema/improve.js +21 -3
- package/dist/core/config/schema/index-config.js +8 -15
- package/dist/core/config/schema/output.js +4 -1
- package/dist/core/config/schema/setup.js +9 -18
- package/dist/core/config/schema/sources-bundles.js +49 -33
- package/dist/core/config/schema/workflow.js +3 -3
- package/dist/core/env-secret-ref.js +76 -46
- package/dist/core/errors.js +18 -12
- package/dist/core/events.js +46 -128
- package/dist/core/file-change.js +6 -5
- package/dist/core/fs-txn.js +83 -7
- package/dist/core/git-message.js +2 -2
- package/dist/core/improve-result.js +1 -100
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +2 -1
- package/dist/core/migration-operation.js +16 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/parse.js +4 -1
- package/dist/core/paths.js +17 -20
- package/dist/core/recognition-util.js +12 -14
- package/dist/core/redaction.js +34 -0
- package/dist/core/standards/resolve-standards-context.js +2 -14
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +2 -2
- package/dist/core/state/migrations.js +41 -18
- package/dist/core/state-db.js +5 -14
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +6 -4
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/type-presentation.js +3 -3
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +771 -95
- package/dist/indexer/bundle-identity-guard.js +3 -2
- package/dist/indexer/db/graph-db.js +0 -24
- package/dist/indexer/ensure-index.js +1 -0
- package/dist/indexer/graph/graph-boost.js +9 -34
- package/dist/indexer/graph/graph-extraction.js +8 -5
- package/dist/indexer/index-writer-lock.js +53 -17
- package/dist/indexer/index-written-assets.js +16 -22
- package/dist/indexer/indexer.js +497 -239
- package/dist/indexer/installations.js +14 -96
- package/dist/indexer/passes/dir-staleness.js +16 -9
- package/dist/indexer/passes/memory-inference.js +11 -9
- package/dist/indexer/passes/metadata.js +113 -47
- package/dist/indexer/scan/doc-to-entry.js +38 -1
- package/dist/indexer/scan/drain-dir.js +13 -23
- package/dist/indexer/search/db-search.js +99 -54
- package/dist/indexer/search/fts-query.js +47 -24
- package/dist/indexer/search/ranking-contributors.js +42 -20
- package/dist/indexer/search/ranking.js +18 -99
- package/dist/indexer/search/search-fields.js +7 -2
- package/dist/indexer/search/search-source.js +82 -93
- package/dist/indexer/usage/usage-events.js +0 -89
- package/dist/indexer/walk/file-context.js +2 -1
- package/dist/indexer/walk/matchers.js +30 -43
- package/dist/indexer/walk/path-resolver.js +7 -2
- package/dist/indexer/walk/walker.js +38 -12
- package/dist/integrations/agent/builders.js +0 -6
- package/dist/integrations/agent/config.js +2 -2
- package/dist/integrations/agent/detect.js +49 -19
- package/dist/integrations/agent/engine-fallback.js +76 -0
- package/dist/integrations/agent/profiles.js +14 -0
- package/dist/integrations/agent/prompts.js +12 -8
- package/dist/integrations/agent/runner-dispatch.js +4 -2
- package/dist/integrations/agent/runner.js +0 -1
- package/dist/integrations/agent/spawn.js +5 -6
- package/dist/integrations/github.js +1 -1
- package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
- package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
- package/dist/integrations/harnesses/claude/session-log.js +0 -10
- package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
- package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
- package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
- package/dist/integrations/harnesses/index.js +3 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
- package/dist/integrations/harnesses/opencode/session-log.js +0 -15
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
- package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
- package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
- package/dist/integrations/lockfile.js +101 -6
- package/dist/integrations/session-logs/index.js +3 -28
- package/dist/llm/client.js +136 -100
- package/dist/llm/embedders/remote.js +13 -5
- package/dist/llm/feature-gate.js +4 -12
- package/dist/llm/graph-extract.js +5 -11
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +5 -7
- package/dist/llm/structured-call.js +1 -1
- package/dist/llm/usage-persist.js +26 -5
- package/dist/llm/usage-telemetry.js +25 -2
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +259 -0
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -36
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +56 -83
- package/dist/output/shapes/migrate.js +8 -0
- package/dist/output/shapes/passthrough.js +7 -41
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes.js +2 -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 +164 -96
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/health-format.js +103 -0
- package/dist/output/text/health.js +7 -0
- package/dist/output/text/helpers.js +10 -8
- package/dist/output/text/lint-format.js +43 -0
- package/dist/output/text/{save.js → lint.js} +2 -2
- package/dist/output/text/migrate.js +88 -0
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +44 -72
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +15 -7
- package/dist/output/text/status-list.js +32 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +24 -203
- package/dist/output/text/workflow.js +1 -7
- package/dist/output/text.js +16 -17
- 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 +13 -23
- package/dist/registry/resolve.js +42 -7
- package/dist/registry/semver.js +34 -84
- package/dist/runtime.js +2 -23
- package/dist/scripts/akm-migrate-node.js +60290 -0
- package/dist/scripts/akm-migrate.js +59628 -0
- package/dist/setup/detect.js +42 -15
- package/dist/setup/registry-stash-loader.js +2 -2
- package/dist/setup/setup.js +236 -136
- package/dist/setup/steps/connection.js +7 -9
- package/dist/setup/steps/platforms.js +9 -9
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +12 -13
- package/dist/setup/steps/stashdir.js +2 -3
- package/dist/setup/steps/tasks.js +237 -120
- package/dist/sources/freshness.js +1 -1
- 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 +25 -23
- package/dist/sources/providers/git-stash.js +395 -106
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +7 -4
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +6 -1
- package/dist/sources/resolve.js +6 -5
- package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
- package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
- package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
- package/dist/sources/snapshot-fetchers/github.js +100 -0
- package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
- package/dist/sources/snapshot-fetchers/registry.js +17 -1
- package/dist/sources/snapshot-fetchers/robots.js +348 -0
- package/dist/sources/snapshot-fetchers/rss.js +282 -0
- package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
- package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
- package/dist/sources/snapshot-fetchers/x.js +910 -0
- package/dist/storage/database.js +7 -0
- package/dist/storage/engines/sqlite-migrations.js +23 -111
- package/dist/storage/managed-db.js +2 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +27 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -12
- package/dist/storage/repositories/index-connection.js +17 -6
- package/dist/storage/repositories/index-entries-repository.js +151 -240
- package/dist/storage/repositories/index-entry-mapper.js +15 -11
- package/dist/storage/repositories/index-fts-repository.js +5 -2
- package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
- package/dist/storage/repositories/index-meta-repository.js +2 -3
- package/dist/storage/repositories/index-schema.js +10 -25
- package/dist/storage/repositories/index-utility-repository.js +15 -28
- package/dist/storage/repositories/index-vec-repository.js +6 -1
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +296 -59
- package/dist/storage/repositories/registry-cache.js +19 -0
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +15 -13
- package/dist/storage/repositories/workflow-runs-repository.js +52 -40
- package/dist/tasks/backends/cron.js +105 -15
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +85 -38
- package/dist/tasks/backends/schtasks.js +135 -15
- package/dist/tasks/embedded.js +56 -40
- package/dist/tasks/parser.js +7 -157
- package/dist/tasks/resolve-akm-bin.js +137 -59
- package/dist/tasks/runner.js +79 -42
- package/dist/tasks/scheduler-invocation.js +220 -10
- package/dist/tasks/schema.js +24 -1
- package/dist/tasks/task-id.js +1 -3
- package/dist/tasks/validator.js +20 -6
- package/dist/workflows/authoring/authoring.js +94 -143
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/exec/frozen-judge.js +28 -2
- package/dist/workflows/exec/native-executor.js +77 -57
- package/dist/workflows/exec/param-secrets.js +9 -9
- package/dist/workflows/exec/run-workflow.js +133 -79
- package/dist/workflows/exec/step-work.js +219 -346
- package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
- package/dist/workflows/ir/compile.js +141 -270
- package/dist/workflows/ir/freeze.js +40 -30
- package/dist/workflows/ir/params.js +135 -11
- package/dist/workflows/ir/plan-hash.js +1 -1
- package/dist/workflows/ir/schema.js +25 -26
- package/dist/workflows/parser.js +872 -307
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +95 -68
- package/dist/workflows/resource-limits.js +2 -0
- package/dist/workflows/runtime/checkin.js +3 -3
- package/dist/workflows/runtime/plan-classifier.js +16 -75
- package/dist/workflows/runtime/runs.js +186 -127
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +2 -2
- package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +30 -36
- package/dist/workflows/validator.js +21 -62
- package/docs/README.md +68 -0
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.7.0.md +11 -11
- package/docs/migration/release-notes/0.9.0.md +208 -27
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +564 -208
- package/docs/migration/v0.9.0-troubleshooting.md +561 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/cli.md +2253 -0
- package/docs/reference/configuration.md +358 -0
- package/docs/reference/data-and-telemetry.md +105 -42
- package/docs/reference/workflows.md +647 -0
- package/package.json +22 -11
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +81 -128
- package/schemas/akm-workflow.json +74 -73
- package/dist/assets/tasks/core/backup.yml +0 -5
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/cli/config-migrate.js +0 -1806
- package/dist/cli/config-validate.js +0 -41
- package/dist/commands/backup-cli.js +0 -56
- package/dist/commands/bundle/bundle-cli.js +0 -68
- package/dist/commands/bundle/bundle.js +0 -219
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -489
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/mv-cli.js +0 -1221
- package/dist/commands/sources/history.js +0 -201
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/core/migration-backup.js +0 -1234
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/migrate/legacy/config-source-migration.js +0 -223
- package/dist/migrate/legacy/content-migration.js +0 -305
- package/dist/migrate/legacy/legacy-layout.js +0 -779
- package/dist/migrate/legacy/legacy-paths.js +0 -25
- package/dist/migrate/legacy/legacy-stash-json.js +0 -72
- package/dist/migrate/legacy/proposal-fs-import.js +0 -168
- package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
- package/dist/migrate/legacy/three-db-cutover.js +0 -841
- package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
- package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
- package/dist/migrate/legacy-ref-grammar.js +0 -214
- 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/registry/build-index.js +0 -382
- package/dist/schemas/akm-config.json +0 -4704
- package/dist/schemas/akm-task.json +0 -87
- package/dist/schemas/akm-workflow.json +0 -372
- package/dist/scripts/migrate-storage.js +0 -3816
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/cli.js +0 -53
- package/dist/workflows/exec/brief.js +0 -481
- package/dist/workflows/exec/report.js +0 -1460
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -813
- package/dist/workflows/program/project.js +0 -104
|
@@ -261,9 +261,8 @@ export async function stepSmallModelConnection(current) {
|
|
|
261
261
|
p.note([
|
|
262
262
|
"This connection is used for background processing:",
|
|
263
263
|
" • akm index (metadata enhancement)",
|
|
264
|
-
" • akm
|
|
264
|
+
" • akm improve (lesson distillation)",
|
|
265
265
|
" • akm remember --enrich (memory compression)",
|
|
266
|
-
" • akm curate --rerank (search reranking)",
|
|
267
266
|
].join("\n"));
|
|
268
267
|
// Probe for Ollama and LM Studio in the background while showing the note.
|
|
269
268
|
const spin = p.spinner();
|
|
@@ -303,9 +302,8 @@ export async function stepSmallModelConnection(current) {
|
|
|
303
302
|
p.note([
|
|
304
303
|
"Enrichment features disabled:",
|
|
305
304
|
" • akm index — metadata enhancement disabled",
|
|
306
|
-
" • akm
|
|
305
|
+
" • akm improve — lesson generation",
|
|
307
306
|
" • akm remember --enrich",
|
|
308
|
-
" • akm curate --rerank",
|
|
309
307
|
"",
|
|
310
308
|
"You can configure this later with `akm setup`.",
|
|
311
309
|
].join("\n"), "Warning");
|
|
@@ -384,9 +382,9 @@ export async function stepAgentConnection(current, smallModel) {
|
|
|
384
382
|
p.log.step("Step 2/2: Configure your agent connection");
|
|
385
383
|
p.note([
|
|
386
384
|
"This connection is used for agentic commands:",
|
|
387
|
-
" • akm
|
|
388
|
-
" • akm improve
|
|
389
|
-
" • akm
|
|
385
|
+
" • akm proposal new (generate improvement proposals)",
|
|
386
|
+
" • akm improve (run the reflect/distill/consolidate self-improvement pipeline)",
|
|
387
|
+
" • akm task run (run automated task prompts)",
|
|
390
388
|
].join("\n"));
|
|
391
389
|
// Detect available CLI agents.
|
|
392
390
|
const detections = detectAgentCliProfiles(current);
|
|
@@ -437,9 +435,9 @@ export async function stepAgentConnection(current, smallModel) {
|
|
|
437
435
|
if (agentChoice === "none") {
|
|
438
436
|
p.note([
|
|
439
437
|
"Agentic features disabled:",
|
|
440
|
-
' • akm
|
|
438
|
+
' • akm proposal new — will show "no agent configured" error',
|
|
441
439
|
' • akm improve — will show "no agent configured" error',
|
|
442
|
-
' • akm
|
|
440
|
+
' • akm task run — will show "no agent configured" error',
|
|
443
441
|
"",
|
|
444
442
|
"You can configure this later with `akm setup`.",
|
|
445
443
|
].join("\n"), "Warning");
|
|
@@ -10,22 +10,22 @@ import { detectAgentCliProfiles, pickDefaultAgentProfile } from "../../integrati
|
|
|
10
10
|
import { detectAgentPlatforms } from "../detect.js";
|
|
11
11
|
import { readAgentEngineSelection } from "../engine-config.js";
|
|
12
12
|
import { prompt } from "../prompt.js";
|
|
13
|
-
// The just-computed source list is threaded
|
|
13
|
+
// The just-computed source list is threaded through the private setup draft.
|
|
14
14
|
export async function stepAgentPlatforms(current) {
|
|
15
15
|
const platforms = detectAgentPlatforms();
|
|
16
16
|
if (platforms.length === 0) {
|
|
17
17
|
p.log.info("No agent platform configurations detected.");
|
|
18
18
|
return [];
|
|
19
19
|
}
|
|
20
|
-
const existingPaths = new Set((current.
|
|
20
|
+
const existingPaths = new Set((current.additionalSources ?? []).map((s) => s.path));
|
|
21
21
|
// Filter out platforms already configured
|
|
22
22
|
const newPlatforms = platforms.filter((pl) => !existingPaths.has(pl.path));
|
|
23
23
|
if (newPlatforms.length === 0) {
|
|
24
|
-
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.`);
|
|
25
25
|
return [];
|
|
26
26
|
}
|
|
27
27
|
const selected = await prompt(() => p.multiselect({
|
|
28
|
-
message: "Found agent platform configurations. Add as
|
|
28
|
+
message: "Found agent platform configurations. Add as bundle sources?",
|
|
29
29
|
options: newPlatforms.map((pl) => ({
|
|
30
30
|
value: pl.path,
|
|
31
31
|
label: pl.name,
|
|
@@ -51,18 +51,18 @@ export async function stepAgentPlatforms(current) {
|
|
|
51
51
|
*/
|
|
52
52
|
export function printCapabilitySummary(smallModelSkipped, agentConfigured) {
|
|
53
53
|
const lines = ["Setup complete. Here's what's enabled:", ""];
|
|
54
|
-
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");
|
|
55
55
|
if (!smallModelSkipped) {
|
|
56
|
-
lines.push(" ✓
|
|
56
|
+
lines.push(" ✓ index metadata enhancement, akm improve, akm remember --enrich — small model configured");
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
|
-
lines.push(" ✗
|
|
59
|
+
lines.push(" ✗ index metadata enhancement, akm improve, akm remember --enrich — run `akm setup` to enable");
|
|
60
60
|
}
|
|
61
61
|
if (agentConfigured) {
|
|
62
|
-
lines.push(" ✓ akm
|
|
62
|
+
lines.push(" ✓ akm proposal new, akm improve, akm task — agent configured");
|
|
63
63
|
}
|
|
64
64
|
else {
|
|
65
|
-
lines.push(" ✗ akm
|
|
65
|
+
lines.push(" ✗ akm proposal new, akm improve, akm task — run `akm setup` to enable");
|
|
66
66
|
}
|
|
67
67
|
p.note(lines.join("\n"), "Feature Summary");
|
|
68
68
|
}
|
|
@@ -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?"
|
|
@@ -39,7 +39,7 @@ export async function stepAdditionalSources(currentSources) {
|
|
|
39
39
|
let addMore = true;
|
|
40
40
|
while (addMore) {
|
|
41
41
|
const action = await prompt(() => p.select({
|
|
42
|
-
message: "Add another
|
|
42
|
+
message: "Add another bundle source?",
|
|
43
43
|
options: [
|
|
44
44
|
{ value: "done", label: "Done — no more sources" },
|
|
45
45
|
{ value: "github-repo", label: "GitHub repository", hint: "custom URL" },
|
|
@@ -63,7 +63,7 @@ export async function stepAdditionalSources(currentSources) {
|
|
|
63
63
|
if (url === null)
|
|
64
64
|
continue;
|
|
65
65
|
const name = await promptOrBack(() => p.text({
|
|
66
|
-
message: "Give this
|
|
66
|
+
message: "Give this bundle a name (optional):",
|
|
67
67
|
placeholder: "my-repo",
|
|
68
68
|
}));
|
|
69
69
|
if (name === null)
|
|
@@ -81,7 +81,7 @@ export async function stepAdditionalSources(currentSources) {
|
|
|
81
81
|
if (action === "filesystem") {
|
|
82
82
|
const fsPath = await promptOrBack(() => p.text({
|
|
83
83
|
message: "Enter the directory path:",
|
|
84
|
-
placeholder: "/path/to/
|
|
84
|
+
placeholder: "/path/to/bundle",
|
|
85
85
|
validate: (v) => {
|
|
86
86
|
if (!v?.trim())
|
|
87
87
|
return "Path cannot be empty";
|
|
@@ -91,8 +91,8 @@ export async function stepAdditionalSources(currentSources) {
|
|
|
91
91
|
continue;
|
|
92
92
|
const resolved = fsPath.trim();
|
|
93
93
|
const name = await promptOrBack(() => p.text({
|
|
94
|
-
message: "Give this
|
|
95
|
-
placeholder: "my-
|
|
94
|
+
message: "Give this bundle a name (optional):",
|
|
95
|
+
placeholder: "my-bundle",
|
|
96
96
|
}));
|
|
97
97
|
if (name === null)
|
|
98
98
|
continue;
|
|
@@ -151,19 +151,18 @@ export async function stepRegistries(current) {
|
|
|
151
151
|
* @internal Exported for testing only.
|
|
152
152
|
*/
|
|
153
153
|
export async function stepAddSources(current, options) {
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
// lock-backed registry installs, which are preserved untouched).
|
|
154
|
+
// The wizard toggles plain additional bundles, not the default bundle or
|
|
155
|
+
// lock-backed registry installs, which are preserved untouched.
|
|
157
156
|
const lockIds = new Set(readLockfile().map((entry) => entry.id));
|
|
158
157
|
const allSources = getSources(current);
|
|
159
158
|
const existingSources = allSources.filter((source) => !source.primary && !(source.name && lockIds.has(source.name)));
|
|
160
159
|
const managedSources = allSources.filter((source) => source.name != null && lockIds.has(source.name));
|
|
161
160
|
const sources = [];
|
|
162
161
|
if (existingSources.length > 0) {
|
|
163
|
-
p.note(renderConfiguredSourceList(existingSources), "Configured
|
|
162
|
+
p.note(renderConfiguredSourceList(existingSources), "Configured bundle sources");
|
|
164
163
|
const options = existingSources.map(describeConfiguredSource);
|
|
165
164
|
const selected = await prompt(() => p.multiselect({
|
|
166
|
-
message: "Configured
|
|
165
|
+
message: "Configured bundle sources — uncheck any you want to disable:",
|
|
167
166
|
options,
|
|
168
167
|
initialValues: options.map((option) => option.value),
|
|
169
168
|
required: false,
|
|
@@ -175,7 +174,7 @@ export async function stepAddSources(current, options) {
|
|
|
175
174
|
}
|
|
176
175
|
}
|
|
177
176
|
if (managedSources.length > 0) {
|
|
178
|
-
p.note(renderInstalledSourceList(managedSources), "Installed managed
|
|
177
|
+
p.note(renderInstalledSourceList(managedSources), "Installed managed bundles (preserved)");
|
|
179
178
|
}
|
|
180
179
|
// ── Registry-driven stash recommendations ─────────────────────────────
|
|
181
180
|
// Fetch available stashes from the official registry (cached, stale-ok).
|
|
@@ -196,8 +195,8 @@ export async function stepAddSources(current, options) {
|
|
|
196
195
|
: availableStashes.filter((s) => s.defaultSelected).map((s) => s.url);
|
|
197
196
|
const selectedUrls = await prompt(() => p.multiselect({
|
|
198
197
|
message: availableStashes[0]?.source === "registry"
|
|
199
|
-
? "Available
|
|
200
|
-
: "Recommended
|
|
198
|
+
? "Available bundles from the AKM registry — toggle to add or remove:"
|
|
199
|
+
: "Recommended bundle sources — toggle to add or remove:",
|
|
201
200
|
options: stashOptions,
|
|
202
201
|
initialValues,
|
|
203
202
|
required: false,
|
|
@@ -10,7 +10,6 @@ import { primaryBundlePath } from "../../core/config/config.js";
|
|
|
10
10
|
import { assertSafeStashDir, getDefaultStashDir } from "../../core/paths.js";
|
|
11
11
|
import { prompt } from "../prompt.js";
|
|
12
12
|
export async function stepStashDir(current, options) {
|
|
13
|
-
// 0.9.0 (spec §10.1): the current primary stash is the defaultBundle's path.
|
|
14
13
|
const currentPrimary = primaryBundlePath(current);
|
|
15
14
|
const defaultDir = options?.preferredDir ?? currentPrimary ?? getDefaultStashDir();
|
|
16
15
|
if (options?.nonInteractive) {
|
|
@@ -26,7 +25,7 @@ export async function stepStashDir(current, options) {
|
|
|
26
25
|
if (choice === "default")
|
|
27
26
|
return defaultDir;
|
|
28
27
|
const customPath = await prompt(() => p.text({
|
|
29
|
-
message: "Enter the
|
|
28
|
+
message: "Enter the bundle directory path:",
|
|
30
29
|
placeholder: defaultDir,
|
|
31
30
|
validate: (v) => {
|
|
32
31
|
if (!v?.trim())
|
|
@@ -37,7 +36,7 @@ export async function stepStashDir(current, options) {
|
|
|
37
36
|
catch (err) {
|
|
38
37
|
if (err instanceof Error)
|
|
39
38
|
return err.message;
|
|
40
|
-
return "Refused: unsafe
|
|
39
|
+
return "Refused: unsafe bundle directory";
|
|
41
40
|
}
|
|
42
41
|
},
|
|
43
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) {
|
|
59
|
-
|
|
60
|
-
|
|
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.");
|
|
61
170
|
return;
|
|
62
|
-
// Snapshot current state so we can diff against the user's selection.
|
|
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
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.
|
|
177
|
+
const embedded = listEmbeddedTasks();
|
|
178
|
+
if (embedded.length === 0)
|
|
179
|
+
return;
|
|
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
|
}
|
|
@@ -31,7 +31,7 @@ export async function withFreshnessCache(options) {
|
|
|
31
31
|
await options.refresh();
|
|
32
32
|
}
|
|
33
33
|
catch (err) {
|
|
34
|
-
if (mtime && !isExpired(mtime, options.staleMs) && usable()) {
|
|
34
|
+
if (options.allowStaleOnRefreshFailure !== false && mtime && !isExpired(mtime, options.staleMs) && usable()) {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
throw err;
|