akm-cli 0.9.0-rc.1 → 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 +1190 -52
- 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/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 +13 -9
- package/dist/commands/env/env-cli.js +76 -159
- 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/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 +75 -228
- 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 -855
- 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/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 -73
- 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 -58
- 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 +8 -3
- package/dist/integrations/agent/profiles.js +6 -99
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +78 -13
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +48 -279
- package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
- package/dist/integrations/harnesses/aider/index.js +2 -12
- package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
- package/dist/integrations/harnesses/amazonq/index.js +3 -17
- package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +1 -14
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
- package/dist/integrations/harnesses/codex/index.js +2 -13
- package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
- package/dist/integrations/harnesses/copilot/index.js +1 -13
- package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
- package/dist/integrations/harnesses/gemini/index.js +1 -13
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +31 -33
- 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 +1 -18
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
- package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
- package/dist/integrations/harnesses/openhands/index.js +2 -12
- package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
- package/dist/integrations/harnesses/pi/index.js +3 -16
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +38 -34
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +24 -40
- 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 +15 -281
- 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 +8 -40
- 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 -1375
- 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 +1 -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 +68 -35
- 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/workflows/authoring/authoring.js +96 -148
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -20
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +25 -59
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +157 -94
- package/dist/workflows/exec/report.js +365 -200
- package/dist/workflows/exec/run-workflow.js +46 -40
- package/dist/workflows/exec/scheduler.js +12 -41
- package/dist/workflows/exec/step-work.js +239 -205
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/ir/compile.js +141 -283
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/plan-hash.js +40 -5
- package/dist/workflows/ir/schema.js +537 -1
- package/dist/workflows/parser.js +878 -306
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +99 -121
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +200 -113
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +4 -26
- 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/{dist/schemas → schemas}/akm-workflow.json +127 -82
- 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 -316
- 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 -1414
- 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 -25
- 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/schemas/akm-config.json +0 -14225
- package/dist/scripts/migrate-storage.js +0 -13169
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
- 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/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/db.js +0 -350
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -760
- package/dist/workflows/program/project.js +0 -105
- package/docs/data-and-telemetry.md +0 -227
- package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -11,23 +11,36 @@
|
|
|
11
11
|
*
|
|
12
12
|
* `akm secret` manages whole-file secrets under each stash's secrets/ directory.
|
|
13
13
|
* Unlike env files (.env key/value), the ENTIRE file is the secret value. The bytes
|
|
14
|
-
* are NEVER written to stdout or structured output.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* are NEVER written to stdout or structured output. The only value-use path is
|
|
15
|
+
* `akm secret run` (injected into a child env var).
|
|
16
|
+
*
|
|
17
|
+
* `secret path` and `secret remove` were REMOVED in 0.9.0 (R-027 / D-49): an
|
|
18
|
+
* audit found `path` resolved the ref through the read-side, all-sources
|
|
19
|
+
* resolver while `remove` resolved it through the write-target resolver, so
|
|
20
|
+
* `akm secret path <ref>` and `akm secret remove <ref>` could silently name
|
|
21
|
+
* two DIFFERENT files when a ref existed in more than one stash — inspect one,
|
|
22
|
+
* delete the other. The owner's ruling was to drop both subcommands rather
|
|
23
|
+
* than reconcile the resolvers. A ref's file lives at `<bundle>/secrets/<name>`
|
|
24
|
+
* (matching the ref exactly, e.g. `secrets/deploy-key` -> `secrets/deploy-key`
|
|
25
|
+
* under a bundle root — `akm bundle list` prints each configured bundle's root
|
|
26
|
+
* path); locate or delete it directly, or consume its value without touching
|
|
27
|
+
* disk via `akm secret run <ref> <VAR> -- <command>`.
|
|
17
28
|
*/
|
|
18
29
|
import { spawnSync } from "node:child_process";
|
|
19
30
|
import fs from "node:fs";
|
|
20
31
|
import path from "node:path";
|
|
32
|
+
import { getParsedInvocation } from "../../cli/invocation.js";
|
|
21
33
|
import { getStringArg } from "../../cli/parse-args.js";
|
|
22
34
|
import { defineGroupCommand, defineJsonCommand, output } from "../../cli/shared.js";
|
|
23
|
-
import { deriveCanonicalAssetName } from "../../core/asset/asset-
|
|
35
|
+
import { deriveCanonicalAssetName } from "../../core/asset/asset-placement.js";
|
|
24
36
|
import { loadConfig } from "../../core/config/config.js";
|
|
25
|
-
import { makeSecretRef, resolveSecretPath } from "../../core/env-secret-ref.js";
|
|
37
|
+
import { makeSecretRef, resolveSecretPath, resolveSecretWriteTarget, withEnvSecretWrite, } from "../../core/env-secret-ref.js";
|
|
26
38
|
import { ConfigError, NotFoundError, UsageError } from "../../core/errors.js";
|
|
27
39
|
import { appendEvent } from "../../core/events.js";
|
|
28
40
|
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
29
41
|
import { readStdin } from "../../runtime.js";
|
|
30
42
|
import { buildChildEnv } from "./child-env.js";
|
|
43
|
+
import { sensitiveMarkerPath } from "./marker-path.js";
|
|
31
44
|
function parseKeyListFlag(raw) {
|
|
32
45
|
if (raw === undefined)
|
|
33
46
|
return undefined;
|
|
@@ -56,7 +69,7 @@ function listSecretsRecursive() {
|
|
|
56
69
|
if (entry.name.endsWith(".lock") || entry.name.endsWith(".sensitive"))
|
|
57
70
|
continue;
|
|
58
71
|
// A sibling `<name>.sensitive` marker suppresses listing.
|
|
59
|
-
if (fs.existsSync(
|
|
72
|
+
if (fs.existsSync(sensitiveMarkerPath(full, "secret")))
|
|
60
73
|
continue;
|
|
61
74
|
const canonical = deriveCanonicalAssetName("secret", secretsDir, full);
|
|
62
75
|
if (!canonical)
|
|
@@ -71,7 +84,7 @@ function listSecretsRecursive() {
|
|
|
71
84
|
const secretListCommand = defineJsonCommand({
|
|
72
85
|
meta: {
|
|
73
86
|
name: "list",
|
|
74
|
-
description: "List all secrets across all
|
|
87
|
+
description: "List all secrets across all bundles by name (the file contents are never shown)",
|
|
75
88
|
},
|
|
76
89
|
async run() {
|
|
77
90
|
output("secret-list", { secrets: listSecretsRecursive() });
|
|
@@ -85,7 +98,7 @@ const secretSetCommand = defineJsonCommand({
|
|
|
85
98
|
args: {
|
|
86
99
|
ref: {
|
|
87
100
|
type: "positional",
|
|
88
|
-
description: "Secret ref (flat name, e.g.
|
|
101
|
+
description: "Secret ref (flat name, e.g. secrets/deploy-key or just deploy-key; use --path for a subdirectory)",
|
|
89
102
|
required: true,
|
|
90
103
|
},
|
|
91
104
|
path: {
|
|
@@ -94,10 +107,16 @@ const secretSetCommand = defineJsonCommand({
|
|
|
94
107
|
},
|
|
95
108
|
"from-file": { type: "string", description: "Read the value from this file (stored byte-exact)" },
|
|
96
109
|
"from-env": { type: "string", description: "Read the value from the named environment variable" },
|
|
110
|
+
target: {
|
|
111
|
+
type: "string",
|
|
112
|
+
description: "Override the write destination. Accepts a source name from your config; falls back to defaultWriteTarget then the working bundle.",
|
|
113
|
+
},
|
|
97
114
|
},
|
|
98
115
|
async run({ args }) {
|
|
99
116
|
const { setSecret } = await import("./secret.js");
|
|
100
|
-
const { name, absPath,
|
|
117
|
+
const { name, absPath, target, ref } = resolveSecretWriteTarget(args.ref, args.target, {
|
|
118
|
+
subPath: getStringArg(args, "path"),
|
|
119
|
+
});
|
|
101
120
|
const fromEnv = args["from-env"];
|
|
102
121
|
const fromFile = args["from-file"];
|
|
103
122
|
if (fromEnv !== undefined && fromFile !== undefined) {
|
|
@@ -131,24 +150,8 @@ const secretSetCommand = defineJsonCommand({
|
|
|
131
150
|
// byte-exact storage of multi-line material (PEM keys, certs).
|
|
132
151
|
value = Buffer.from(stdinBuf.toString("utf8").replace(/\n$/, ""), "utf8");
|
|
133
152
|
}
|
|
134
|
-
setSecret(absPath, value);
|
|
135
|
-
output("secret-set", { ref
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
const secretPathCommand = defineJsonCommand({
|
|
139
|
-
meta: {
|
|
140
|
-
name: "path",
|
|
141
|
-
description: "Print the absolute secret file path for the Docker `_FILE` convention, e.g. `MY_SECRET_FILE=$(akm secret path secret:deploy-key)`.",
|
|
142
|
-
},
|
|
143
|
-
args: {
|
|
144
|
-
ref: { type: "positional", description: "Secret ref", required: true },
|
|
145
|
-
},
|
|
146
|
-
async run({ args }) {
|
|
147
|
-
const { name, absPath, source } = resolveSecretPath(args.ref);
|
|
148
|
-
if (!fs.existsSync(absPath)) {
|
|
149
|
-
throw new NotFoundError(`Secret not found: ${makeSecretRef(name, source)}`);
|
|
150
|
-
}
|
|
151
|
-
process.stdout.write(`${absPath}\n`);
|
|
153
|
+
withEnvSecretWrite(target, { type: "secret", name }, "Update", [absPath], () => setSecret(absPath, value));
|
|
154
|
+
output("secret-set", { ref });
|
|
152
155
|
},
|
|
153
156
|
});
|
|
154
157
|
const secretRunCommand = defineJsonCommand({
|
|
@@ -181,11 +184,10 @@ const secretRunCommand = defineJsonCommand({
|
|
|
181
184
|
if (isDangerousEnvKey(varName)) {
|
|
182
185
|
throw new UsageError(`Refusing to inject a secret into "${varName}": it is a known process-hijacking variable (e.g. LD_PRELOAD, PATH).`, "INVALID_FLAG_VALUE");
|
|
183
186
|
}
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
187
|
+
const command = getParsedInvocation().passthroughArgs();
|
|
188
|
+
if (command.length === 0) {
|
|
186
189
|
throw new UsageError("Missing command. Usage: akm secret run <ref> <VAR> -- <command>");
|
|
187
190
|
}
|
|
188
|
-
const command = process.argv.slice(dashIndex + 1);
|
|
189
191
|
const { name, absPath, source } = resolveSecretPath(args.ref);
|
|
190
192
|
if (!fs.existsSync(absPath)) {
|
|
191
193
|
throw new NotFoundError(`Secret not found: ${makeSecretRef(name, source)}`);
|
|
@@ -216,46 +218,28 @@ const secretRunCommand = defineJsonCommand({
|
|
|
216
218
|
}
|
|
217
219
|
throw err;
|
|
218
220
|
}
|
|
219
|
-
process.exit(result.status ?? 0)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
},
|
|
228
|
-
async run({ args }) {
|
|
229
|
-
const { name, absPath, source } = resolveSecretPath(args.ref);
|
|
230
|
-
const { confirmDestructive } = await import("../../cli/confirm.js");
|
|
231
|
-
const confirmed = await confirmDestructive(`Remove secret "${args.ref}"? This cannot be undone.`, {
|
|
232
|
-
yes: args.yes === true,
|
|
233
|
-
});
|
|
234
|
-
if (!confirmed) {
|
|
235
|
-
process.stderr.write("Aborted.\n");
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
const { removeSecret } = await import("./secret.js");
|
|
239
|
-
if (!fs.existsSync(absPath)) {
|
|
240
|
-
throw new NotFoundError(`Secret not found: ${makeSecretRef(name, source)}`);
|
|
241
|
-
}
|
|
242
|
-
const removed = removeSecret(absPath);
|
|
243
|
-
output("secret-remove", { ref: makeSecretRef(name, source), removed });
|
|
221
|
+
// R-067: was `process.exit(result.status ?? 0)`, unconditional even on
|
|
222
|
+
// the success path — it skipped the `finally { await
|
|
223
|
+
// disposeDispatchResources(); }` cleanup in src/cli.ts's `runCommand`.
|
|
224
|
+
// Setting `process.exitCode` and returning still exits with the child's
|
|
225
|
+
// exact status once the event loop drains, but lets cleanup run first —
|
|
226
|
+
// same pattern `emitJsonError` (src/cli/shared.ts) already established.
|
|
227
|
+
process.exitCode = result.status ?? 0;
|
|
228
|
+
return;
|
|
244
229
|
},
|
|
245
230
|
});
|
|
246
231
|
export const secretCommand = defineGroupCommand({
|
|
247
232
|
meta: {
|
|
248
233
|
name: "secret",
|
|
249
|
-
description: "Manage secrets —
|
|
234
|
+
description: "Manage secrets — one standalone sensitive value per file (an API token, a PEM private key, a TLS cert).\n\n" +
|
|
235
|
+
"Names are visible; the file contents are the value and never appear in structured output. For a group of related configuration loaded together, use `akm env`. A secret's file lives at `<bundle>/secrets/<name>` (`akm bundle list` shows bundle roots) — read or delete it there directly, or consume its value without writing it anywhere via `akm secret run <ref> <VAR> -- <command>`.",
|
|
250
236
|
},
|
|
251
237
|
subCommands: {
|
|
252
238
|
list: secretListCommand,
|
|
253
|
-
path: secretPathCommand,
|
|
254
239
|
run: secretRunCommand,
|
|
255
240
|
set: secretSetCommand,
|
|
256
|
-
remove: secretRemoveCommand,
|
|
257
|
-
},
|
|
258
|
-
defaultRun() {
|
|
259
|
-
output("secret-list", { secrets: listSecretsRecursive() });
|
|
260
241
|
},
|
|
242
|
+
// No `defaultRun`: bare `akm secret` is a usage error (exit 2), the canonical
|
|
243
|
+
// bare-group behavior — owner ruling 12. Run `akm secret list` for what the
|
|
244
|
+
// bare form used to print.
|
|
261
245
|
});
|
|
@@ -14,20 +14,26 @@
|
|
|
14
14
|
*
|
|
15
15
|
* Invariant: a secret's bytes must never be written to stdout, returned
|
|
16
16
|
* through the indexer / `akm show` renderer, or any structured output channel.
|
|
17
|
-
* The supported value-use
|
|
17
|
+
* The supported value-use path is:
|
|
18
18
|
*
|
|
19
19
|
* - `akm secret run <ref> <VAR> -- <cmd>` — value injected into the child
|
|
20
20
|
* process env as `VAR=<value>` (see `readValue`).
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
*
|
|
22
|
+
* `akm secret path <ref>` (print the file path for the Docker `/run/secrets` +
|
|
23
|
+
* `_FILE` convention) was removed in 0.9.0 alongside `akm secret remove` — an
|
|
24
|
+
* audit found the two resolved a ref through different stash-selection logic
|
|
25
|
+
* and could silently target different files. A ref's file still lives at
|
|
26
|
+
* `<stash>/secrets/<name>`; locate or delete it there directly.
|
|
23
27
|
*
|
|
24
28
|
* Values are stored as raw bytes (no quoting, multi-line allowed) so they
|
|
25
29
|
* round-trip byte-exact, unlike env values which forbid literal newlines.
|
|
26
30
|
*/
|
|
31
|
+
import { createHash } from "node:crypto";
|
|
27
32
|
import fs from "node:fs";
|
|
28
33
|
import path from "node:path";
|
|
29
|
-
import { writeFileAtomic } from "../../core/common.js";
|
|
30
|
-
import { probeLock, releaseLock, tryAcquireLockSync } from "../../core/file-lock.js";
|
|
34
|
+
import { safeRealpath, writeFileAtomic } from "../../core/common.js";
|
|
35
|
+
import { createLockPayload, probeLock, reclaimStaleLock, releaseLock, tryAcquireLockSync, } from "../../core/file-lock.js";
|
|
36
|
+
import { getDataDir } from "../../core/paths.js";
|
|
31
37
|
import { sleepSync } from "../../runtime.js";
|
|
32
38
|
// ── Write-lock helper ─────────────────────────────────────────────────────────
|
|
33
39
|
/**
|
|
@@ -37,19 +43,22 @@ import { sleepSync } from "../../runtime.js";
|
|
|
37
43
|
* throw rather than silently proceeding.
|
|
38
44
|
*/
|
|
39
45
|
export function withSecretLock(secretPath, fn) {
|
|
40
|
-
const lockPath =
|
|
46
|
+
const lockPath = secretLockPath(secretPath);
|
|
47
|
+
const lockDir = path.dirname(lockPath);
|
|
48
|
+
fs.mkdirSync(lockDir, { recursive: true, mode: 0o700 });
|
|
41
49
|
const deadline = Date.now() + 5000;
|
|
42
|
-
|
|
50
|
+
let ownership;
|
|
51
|
+
while (!ownership) {
|
|
52
|
+
ownership = tryAcquireLockSync(lockPath, createLockPayload());
|
|
53
|
+
if (ownership)
|
|
54
|
+
break;
|
|
43
55
|
const probe = probeLock(lockPath);
|
|
44
|
-
if (probe.state === "stale") {
|
|
45
|
-
releaseLock(lockPath);
|
|
56
|
+
if (probe.state === "stale" && reclaimStaleLock(lockPath, probe)) {
|
|
46
57
|
continue;
|
|
47
58
|
}
|
|
48
59
|
if (Date.now() > deadline) {
|
|
49
|
-
const holderHint = probe.state === "held"
|
|
50
|
-
|
|
51
|
-
: ` Lock file ${lockPath} could not be inspected.`;
|
|
52
|
-
throw new Error(`Could not acquire secret lock for ${secretPath} after 5s.${holderHint} Retry once any other akm secret operation finishes, or remove the stale lock file.`);
|
|
60
|
+
const holderHint = probe.state === "held" ? ` It is held by live PID ${probe.holderPid}.` : "";
|
|
61
|
+
throw new Error(`Could not acquire the secret write lock after 5s.${holderHint} Retry once any other akm secret operation finishes.`);
|
|
53
62
|
}
|
|
54
63
|
sleepSync(10);
|
|
55
64
|
}
|
|
@@ -57,9 +66,15 @@ export function withSecretLock(secretPath, fn) {
|
|
|
57
66
|
return fn();
|
|
58
67
|
}
|
|
59
68
|
finally {
|
|
60
|
-
releaseLock(
|
|
69
|
+
releaseLock(ownership);
|
|
61
70
|
}
|
|
62
71
|
}
|
|
72
|
+
export function secretLockPath(secretPath, platform = process.platform) {
|
|
73
|
+
const canonical = safeRealpath(secretPath);
|
|
74
|
+
const identity = platform === "win32" ? canonical.toLowerCase() : canonical;
|
|
75
|
+
const key = createHash("sha256").update(identity).digest("hex");
|
|
76
|
+
return path.join(getDataDir(), "secret-locks", `${key}.lock`);
|
|
77
|
+
}
|
|
63
78
|
// ── Atomic byte write ──────────────────────────────────────────────────────────
|
|
64
79
|
function ensureParentDir(filePath) {
|
|
65
80
|
const dir = path.dirname(filePath);
|
|
@@ -68,38 +83,8 @@ function ensureParentDir(filePath) {
|
|
|
68
83
|
}
|
|
69
84
|
// ── Public API ──────────────────────────────────────────────────────────────
|
|
70
85
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* secrets with a sibling `<name>.sensitive` marker are excluded. The file
|
|
74
|
-
* bodies are NEVER read.
|
|
75
|
-
*/
|
|
76
|
-
export function listNames(secretsRoot) {
|
|
77
|
-
if (!fs.existsSync(secretsRoot))
|
|
78
|
-
return [];
|
|
79
|
-
const names = [];
|
|
80
|
-
const walk = (dir) => {
|
|
81
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
82
|
-
const full = path.join(dir, entry.name);
|
|
83
|
-
if (entry.isDirectory()) {
|
|
84
|
-
walk(full);
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
if (!entry.isFile())
|
|
88
|
-
continue;
|
|
89
|
-
if (entry.name.endsWith(".lock") || entry.name.endsWith(".sensitive"))
|
|
90
|
-
continue;
|
|
91
|
-
// A sibling `<name>.sensitive` marker suppresses listing.
|
|
92
|
-
if (fs.existsSync(`${full}.sensitive`))
|
|
93
|
-
continue;
|
|
94
|
-
names.push(path.relative(secretsRoot, full).split(path.sep).join("/"));
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
walk(secretsRoot);
|
|
98
|
-
return names.sort();
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Read a secret's raw bytes. Internal use only (for `secret run` / `secret
|
|
102
|
-
* path`). Callers MUST NOT write the returned value to stdout or any log.
|
|
86
|
+
* Read a secret's raw bytes. Internal use only (for `secret run`). Callers
|
|
87
|
+
* MUST NOT write the returned value to stdout or any log.
|
|
103
88
|
*/
|
|
104
89
|
export function readValue(secretPath) {
|
|
105
90
|
return fs.readFileSync(secretPath);
|
|
@@ -109,24 +94,9 @@ export function readValue(secretPath) {
|
|
|
109
94
|
* mode 0600 under a write-lock. No quoting; multi-line / binary allowed.
|
|
110
95
|
*/
|
|
111
96
|
export function setSecret(secretPath, value) {
|
|
112
|
-
ensureParentDir(secretPath);
|
|
113
97
|
withSecretLock(secretPath, () => {
|
|
98
|
+
ensureParentDir(secretPath);
|
|
114
99
|
// Mode 0600: secrets must never be world-readable, even transiently.
|
|
115
100
|
writeFileAtomic(secretPath, value, 0o600);
|
|
116
101
|
});
|
|
117
102
|
}
|
|
118
|
-
/**
|
|
119
|
-
* Remove a secret file (and its `.sensitive` marker, if present). Returns true
|
|
120
|
-
* if the secret existed.
|
|
121
|
-
*/
|
|
122
|
-
export function removeSecret(secretPath) {
|
|
123
|
-
return withSecretLock(secretPath, () => {
|
|
124
|
-
if (!fs.existsSync(secretPath))
|
|
125
|
-
return false;
|
|
126
|
-
fs.rmSync(secretPath);
|
|
127
|
-
const marker = `${secretPath}.sensitive`;
|
|
128
|
-
if (fs.existsSync(marker))
|
|
129
|
-
fs.rmSync(marker);
|
|
130
|
-
return true;
|
|
131
|
-
});
|
|
132
|
-
}
|