akm-cli 0.9.0-rc.0 → 0.9.0-rc.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1283 -22
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +2 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +99 -0
- package/dist/commands/env/env-cli.js +84 -224
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +232 -121
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -834
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/json-schema.js +142 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -34
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -56
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +36 -62
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +93 -4
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +88 -196
- package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
- package/dist/integrations/harnesses/aider/index.js +48 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
- package/dist/integrations/harnesses/amazonq/index.js +45 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +24 -35
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
- package/dist/integrations/harnesses/codex/index.js +52 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +48 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
- package/dist/integrations/harnesses/gemini/index.js +48 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +54 -34
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +14 -32
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
- package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
- package/dist/integrations/harnesses/openhands/index.js +48 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
- package/dist/integrations/harnesses/pi/index.js +45 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +43 -32
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +36 -39
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -279
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +11 -39
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1164
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +3 -2
- package/dist/output/text.js +10 -19
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +240 -19
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/text-import-hook.mjs +1 -1
- package/dist/workflows/authoring/authoring.js +104 -43
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -16
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +450 -0
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +1038 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1460 -0
- package/dist/workflows/exec/run-workflow.js +602 -0
- package/dist/workflows/exec/scheduler.js +71 -0
- package/dist/workflows/exec/step-work.js +1190 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +246 -0
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +68 -0
- package/dist/workflows/ir/schema.js +540 -0
- package/dist/workflows/parser.js +878 -304
- package/dist/workflows/program/expressions.js +181 -0
- package/dist/workflows/program/schema.js +51 -0
- package/dist/workflows/renderer.js +100 -45
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +376 -119
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +2 -3
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +373 -0
- package/dist/akm-migrate-storage +0 -38
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -259
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1413
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/scripts/migrate-storage.js +0 -19108
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1012
- package/dist/workflows/db.js +0 -215
- package/docs/data-and-telemetry.md +0 -226
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { resolveStashDir } from "../../core/common.js";
|
|
15
15
|
import { loadConfig } from "../../core/config/config.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
16
|
+
import { resolveWriteTarget } from "../../core/write-source.js";
|
|
17
|
+
import { withAssetMutationLease } from "../../indexer/index-writer-lock.js";
|
|
18
|
+
import { createProposal, diffProposal, isProposalSkipped, listProposals, promoteProposal, proposalContent, recoverProposalTransactionsForStash, rejectProposalDurably, resolveProposalId, resolveProposalIdForReject, revertProposal, } from "./repository.js";
|
|
19
19
|
import { validateProposal } from "./validators/proposals.js";
|
|
20
20
|
// ── Shared helpers ──────────────────────────────────────────────────────────
|
|
21
21
|
function resolveStash(stashDir) {
|
|
@@ -23,6 +23,14 @@ function resolveStash(stashDir) {
|
|
|
23
23
|
return stashDir;
|
|
24
24
|
return resolveStashDir();
|
|
25
25
|
}
|
|
26
|
+
function resolveProposalQueue(stashDir, queue, config) {
|
|
27
|
+
if (stashDir)
|
|
28
|
+
return { stashDir };
|
|
29
|
+
if (!queue)
|
|
30
|
+
return { stashDir: resolveStash() };
|
|
31
|
+
const target = resolveWriteTarget(config ?? loadConfig(), queue);
|
|
32
|
+
return { stashDir: target.source.path, target };
|
|
33
|
+
}
|
|
26
34
|
/**
|
|
27
35
|
* Thin in-process read of the pending proposal queue, used by the health HTML
|
|
28
36
|
* report builder (#582) so it never shells out to `akm proposal list`.
|
|
@@ -35,7 +43,7 @@ export function listPendingProposals(stashDir) {
|
|
|
35
43
|
return listProposals(resolveStash(stashDir), { status: "pending" });
|
|
36
44
|
}
|
|
37
45
|
export function akmProposalList(options = {}) {
|
|
38
|
-
const stash =
|
|
46
|
+
const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, options.config);
|
|
39
47
|
// `--status accepted|rejected|reverted` implies archive-inclusion since the
|
|
40
48
|
// live queue only ever contains pending entries.
|
|
41
49
|
const includeArchive = options.includeArchive === true ||
|
|
@@ -51,8 +59,8 @@ export function akmProposalList(options = {}) {
|
|
|
51
59
|
return { schemaVersion: 1, totalCount: proposals.length, proposals };
|
|
52
60
|
}
|
|
53
61
|
export function akmProposalShow(options) {
|
|
54
|
-
const stash =
|
|
55
|
-
const proposal =
|
|
62
|
+
const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, options.config);
|
|
63
|
+
const proposal = resolveProposalId(stash, options.id);
|
|
56
64
|
return {
|
|
57
65
|
schemaVersion: 1,
|
|
58
66
|
proposal,
|
|
@@ -60,29 +68,11 @@ export function akmProposalShow(options) {
|
|
|
60
68
|
};
|
|
61
69
|
}
|
|
62
70
|
export async function akmProposalAccept(options) {
|
|
63
|
-
const stash = resolveStash(options.stashDir);
|
|
64
71
|
const config = options.config ?? loadConfig();
|
|
72
|
+
const queue = resolveProposalQueue(options.stashDir, options.queue, config);
|
|
73
|
+
const stash = queue.stashDir;
|
|
65
74
|
const resolvedId = resolveProposalId(stash, options.id).id;
|
|
66
|
-
const result = await promoteProposal(stash, config, resolvedId, { target: options.target }, options.ctx);
|
|
67
|
-
// Emit `promoted` to the events stream so observers (audit, dashboards,
|
|
68
|
-
// sync) see the accept happen. Only emit on the happy path — promotion
|
|
69
|
-
// throws on validation failure, so reaching this point means the asset
|
|
70
|
-
// is committed.
|
|
71
|
-
appendEvent({
|
|
72
|
-
eventType: "promoted",
|
|
73
|
-
ref: result.ref,
|
|
74
|
-
metadata: {
|
|
75
|
-
proposalId: result.proposal.id,
|
|
76
|
-
source: result.proposal.source,
|
|
77
|
-
...(result.proposal.sourceRun !== undefined ? { sourceRun: result.proposal.sourceRun } : {}),
|
|
78
|
-
assetPath: result.assetPath,
|
|
79
|
-
// Attribution tagging: carry the eligibility lane from the proposal record
|
|
80
|
-
// onto the promoted event so accept outcomes can be sliced by lane.
|
|
81
|
-
...(result.proposal.eligibilitySource !== undefined
|
|
82
|
-
? { eligibilitySource: result.proposal.eligibilitySource }
|
|
83
|
-
: {}),
|
|
84
|
-
},
|
|
85
|
-
});
|
|
75
|
+
const result = await promoteProposal(stash, config, resolvedId, { target: options.target, queueTarget: queue.target, gateDecision: options.gateDecision }, options.ctx);
|
|
86
76
|
return {
|
|
87
77
|
schemaVersion: 1,
|
|
88
78
|
ok: true,
|
|
@@ -92,37 +82,32 @@ export async function akmProposalAccept(options) {
|
|
|
92
82
|
proposal: result.proposal,
|
|
93
83
|
};
|
|
94
84
|
}
|
|
95
|
-
export function akmProposalReject(options) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
85
|
+
export async function akmProposalReject(options) {
|
|
86
|
+
return withAssetMutationLease("proposal-reject", async () => {
|
|
87
|
+
const config = options.config ?? loadConfig();
|
|
88
|
+
const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, config);
|
|
89
|
+
// resolveProposalIdForReject tolerates a legacy row whose metadata fails
|
|
90
|
+
// strict decoding — resolveProposalId's exact-UUID match would otherwise
|
|
91
|
+
// throw here, before the terminal-status machinery even runs.
|
|
92
|
+
const proposalId = resolveProposalIdForReject(stash, options.id, options.ctx);
|
|
93
|
+
await recoverProposalTransactionsForStash(stash, config, options.ctx, proposalId);
|
|
94
|
+
const updated = rejectProposalDurably(stash, proposalId, options.reason, options.ctx, options.gateDecision);
|
|
95
|
+
return {
|
|
96
|
+
schemaVersion: 1,
|
|
97
|
+
ok: true,
|
|
98
|
+
id: updated.id,
|
|
99
|
+
ref: updated.ref,
|
|
109
100
|
...(options.reason !== undefined ? { reason: options.reason } : {}),
|
|
110
|
-
|
|
101
|
+
proposal: updated,
|
|
102
|
+
};
|
|
111
103
|
});
|
|
112
|
-
return {
|
|
113
|
-
schemaVersion: 1,
|
|
114
|
-
ok: true,
|
|
115
|
-
id: updated.id,
|
|
116
|
-
ref: updated.ref,
|
|
117
|
-
...(options.reason !== undefined ? { reason: options.reason } : {}),
|
|
118
|
-
proposal: updated,
|
|
119
|
-
};
|
|
120
104
|
}
|
|
121
105
|
export function akmProposalDiff(options) {
|
|
122
|
-
const stash = resolveStash(options.stashDir);
|
|
123
106
|
const config = options.config ?? loadConfig();
|
|
107
|
+
const queue = resolveProposalQueue(options.stashDir, options.queue, config);
|
|
108
|
+
const stash = queue.stashDir;
|
|
124
109
|
const proposal = resolveProposalId(stash, options.id);
|
|
125
|
-
const diff = diffProposal(stash, config, proposal.id, { target: options.target });
|
|
110
|
+
const diff = diffProposal(stash, config, proposal.id, { target: options.target, queueTarget: queue.target });
|
|
126
111
|
return {
|
|
127
112
|
schemaVersion: 1,
|
|
128
113
|
id: proposal.id,
|
|
@@ -133,12 +118,15 @@ export function akmProposalDiff(options) {
|
|
|
133
118
|
};
|
|
134
119
|
}
|
|
135
120
|
export function akmProposalCreate(options) {
|
|
136
|
-
const
|
|
121
|
+
const queue = resolveProposalQueue(options.stashDir, options.queue, options.config);
|
|
122
|
+
const stash = queue.stashDir;
|
|
123
|
+
const target = options.target ?? (queue.target ? { source: queue.target.source.name, root: queue.target.source.path } : undefined);
|
|
137
124
|
// Manual proposal creation (via `akm proposal create`) always bypasses
|
|
138
125
|
// dedup/cooldown guards — the operator is explicitly requesting a proposal.
|
|
139
126
|
const result = createProposal(stash, {
|
|
140
127
|
ref: options.ref,
|
|
141
128
|
source: options.source,
|
|
129
|
+
...(target !== undefined ? { target } : {}),
|
|
142
130
|
...(options.sourceRun !== undefined ? { sourceRun: options.sourceRun } : {}),
|
|
143
131
|
payload: options.payload,
|
|
144
132
|
force: true,
|
|
@@ -166,20 +154,11 @@ export function akmProposalCreate(options) {
|
|
|
166
154
|
* `rejected`.
|
|
167
155
|
*/
|
|
168
156
|
export async function akmProposalRevert(options) {
|
|
169
|
-
const stash = resolveStash(options.stashDir);
|
|
170
157
|
const config = options.config ?? loadConfig();
|
|
158
|
+
const queue = resolveProposalQueue(options.stashDir, options.queue, config);
|
|
159
|
+
const stash = queue.stashDir;
|
|
171
160
|
const resolvedId = resolveProposalId(stash, options.id).id;
|
|
172
|
-
const result = await revertProposal(stash, config, resolvedId, { target: options.target }, options.ctx);
|
|
173
|
-
appendEvent({
|
|
174
|
-
eventType: "proposal_reverted",
|
|
175
|
-
ref: result.ref,
|
|
176
|
-
metadata: {
|
|
177
|
-
proposalId: result.proposal.id,
|
|
178
|
-
source: result.proposal.source,
|
|
179
|
-
...(result.proposal.sourceRun !== undefined ? { sourceRun: result.proposal.sourceRun } : {}),
|
|
180
|
-
assetPath: result.assetPath,
|
|
181
|
-
},
|
|
182
|
-
});
|
|
161
|
+
const result = await revertProposal(stash, config, resolvedId, { target: options.target, queueTarget: queue.target }, options.ctx);
|
|
183
162
|
return {
|
|
184
163
|
schemaVersion: 1,
|
|
185
164
|
ok: true,
|
|
@@ -189,3 +168,42 @@ export async function akmProposalRevert(options) {
|
|
|
189
168
|
proposal: result.proposal,
|
|
190
169
|
};
|
|
191
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Bulk accept/reject every pending proposal from one generator, applying the
|
|
173
|
+
* shared `--max-diff-lines` / `--older-than` filters. Consolidates the two
|
|
174
|
+
* near-identical loops that lived in `proposal-cli.ts` (Chunk 6 WI-6.6);
|
|
175
|
+
* behavior is verbatim — same filter order, same per-item envelopes, same
|
|
176
|
+
* dry-run record shape. The destructive-confirmation prompt stays CLI-side.
|
|
177
|
+
*/
|
|
178
|
+
export async function bulkAdjudicateProposals(options) {
|
|
179
|
+
const config = options.config ?? loadConfig();
|
|
180
|
+
const { stashDir } = resolveProposalQueue(options.stashDir, options.queue, config);
|
|
181
|
+
const pending = listProposals(stashDir, { status: "pending" }).filter((p) => {
|
|
182
|
+
if (p.source !== options.generator)
|
|
183
|
+
return false;
|
|
184
|
+
if (options.maxDiffLines !== undefined) {
|
|
185
|
+
const lines = proposalContent(p).split("\n").length;
|
|
186
|
+
if (lines > options.maxDiffLines)
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
if (options.olderThanMs !== undefined) {
|
|
190
|
+
const age = Date.now() - new Date(p.createdAt).getTime();
|
|
191
|
+
if (age < options.olderThanMs)
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
});
|
|
196
|
+
const results = [];
|
|
197
|
+
for (const proposal of pending) {
|
|
198
|
+
if (options.dryRun) {
|
|
199
|
+
results.push({ id: proposal.id, ref: proposal.ref, source: proposal.source, dryRun: true });
|
|
200
|
+
}
|
|
201
|
+
else if (options.action === "accept") {
|
|
202
|
+
results.push(await akmProposalAccept({ stashDir, id: proposal.id, queue: options.queue, target: options.target, config }));
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
results.push(await akmProposalReject({ stashDir, id: proposal.id, queue: options.queue, reason: options.reason, config }));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return { count: results.length, results };
|
|
209
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* `akm proposal new` — the asset-authoring entry point (formerly the
|
|
6
|
+
* top-level `akm propose`, moved under the `proposal` group per the 0.9 CLI
|
|
7
|
+
* overhaul, S8). Shares no private helper with the proposal MANAGEMENT
|
|
8
|
+
* family (list/show/accept/reject/…, `./proposal-cli.ts`) — its path/name
|
|
9
|
+
* helpers come from the shared src/core/asset/asset-create.ts module.
|
|
10
|
+
*
|
|
11
|
+
* Keeps the inline `runWithJsonErrors` form (branches on the result and sets
|
|
12
|
+
* `process.exitCode` conditionally on a failed proposal) rather than
|
|
13
|
+
* migrating to `defineJsonCommand`, matching the original contribute-cli.ts
|
|
14
|
+
* rationale: `process.exitCode` (not `process.exit()`) so the process still
|
|
15
|
+
* exits via natural event-loop drain rather than skipping pending cleanup.
|
|
16
|
+
*/
|
|
17
|
+
import fs from "node:fs";
|
|
18
|
+
import path from "node:path";
|
|
19
|
+
import { defineCommand } from "citty";
|
|
20
|
+
import { getStringArg, parsePositiveIntFlag } from "../../cli/parse-args.js";
|
|
21
|
+
import { EXIT_CODES, GLOBAL_OUTPUT_ARGS, output, runWithJsonErrors } from "../../cli/shared.js";
|
|
22
|
+
import { assertFlatAssetName, combineCreatePath, normalizeCreateSubPath } from "../../core/asset/asset-create.js";
|
|
23
|
+
import { UsageError } from "../../core/errors.js";
|
|
24
|
+
import { akmPropose } from "./propose.js";
|
|
25
|
+
const EXIT_GENERAL = EXIT_CODES.GENERAL;
|
|
26
|
+
export const proposeCommand = defineCommand({
|
|
27
|
+
meta: {
|
|
28
|
+
name: "new",
|
|
29
|
+
description: "Ask the configured agent CLI to author a brand-new asset and queue it as a proposal",
|
|
30
|
+
},
|
|
31
|
+
// Raw defineCommand: declare the global output flags so their space-separated
|
|
32
|
+
// values are consumed rather than shifting the `type` / `name` positionals.
|
|
33
|
+
args: {
|
|
34
|
+
...GLOBAL_OUTPUT_ARGS,
|
|
35
|
+
// Optional in citty so run() is invoked when omitted; we re-validate
|
|
36
|
+
// below to surface a structured UsageError (exit 2) instead of citty's
|
|
37
|
+
// default help-banner exit-0.
|
|
38
|
+
type: { type: "positional", description: "Asset type (skill, command, knowledge, lesson, ...)", required: false },
|
|
39
|
+
name: {
|
|
40
|
+
type: "positional",
|
|
41
|
+
description: "Asset name (flat, no '/'; use --path for a subdirectory)",
|
|
42
|
+
required: false,
|
|
43
|
+
},
|
|
44
|
+
path: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "Relative subdirectory under the type dir to place the proposed asset in (e.g. 'release'). The filename comes from the name.",
|
|
47
|
+
},
|
|
48
|
+
task: { type: "string", description: "Task description for the agent (what should the asset do?)" },
|
|
49
|
+
file: { type: "string", description: "Read the task or prompt text from a UTF-8 file" },
|
|
50
|
+
engine: { type: "string", description: "Engine to use (defaults to defaults.engine)" },
|
|
51
|
+
"timeout-ms": { type: "string", description: "Override the agent CLI timeout in milliseconds" },
|
|
52
|
+
},
|
|
53
|
+
async run({ args }) {
|
|
54
|
+
await runWithJsonErrors(async () => {
|
|
55
|
+
// citty silently shows help and exits 0 when required positionals are
|
|
56
|
+
// omitted. Re-validate explicitly so the exit code is 2 (USAGE) and a
|
|
57
|
+
// structured JSON error reaches scripted callers.
|
|
58
|
+
const taskFromFlag = typeof args.task === "string" ? args.task : undefined;
|
|
59
|
+
const fileFromFlag = typeof args.file === "string" ? args.file : undefined;
|
|
60
|
+
if (!args.type || !args.name || (!taskFromFlag && !fileFromFlag)) {
|
|
61
|
+
throw new UsageError("Usage: akm proposal new <type> <name> (--task '<task>' | --file <path>).", "MISSING_REQUIRED_ARGUMENT", "Provide the asset type, name, and exactly one of --task or --file.");
|
|
62
|
+
}
|
|
63
|
+
if (taskFromFlag && fileFromFlag) {
|
|
64
|
+
throw new UsageError("Pass exactly one of --task or --file.", "INVALID_FLAG_VALUE");
|
|
65
|
+
}
|
|
66
|
+
// `name` is flat; subdirectory placement is `--path`'s job.
|
|
67
|
+
assertFlatAssetName(String(args.name));
|
|
68
|
+
const proposedName = combineCreatePath(normalizeCreateSubPath(getStringArg(args, "path")), String(args.name));
|
|
69
|
+
const taskText = fileFromFlag ? fs.readFileSync(path.resolve(fileFromFlag), "utf8") : (taskFromFlag ?? "");
|
|
70
|
+
const timeoutMs = parsePositiveIntFlag(args["timeout-ms"], "--timeout-ms");
|
|
71
|
+
const result = await akmPropose({
|
|
72
|
+
type: String(args.type),
|
|
73
|
+
name: proposedName,
|
|
74
|
+
task: taskText,
|
|
75
|
+
engine: getStringArg(args, "engine"),
|
|
76
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
77
|
+
});
|
|
78
|
+
output("proposal-new", result);
|
|
79
|
+
if (result.ok === false) {
|
|
80
|
+
// Same reasoning as agentCommand in contribute-cli.ts: output() already
|
|
81
|
+
// ran, this is the last statement in the handler, so process.exitCode +
|
|
82
|
+
// return is equivalent without skipping any pending cleanup.
|
|
83
|
+
process.exitCode = EXIT_GENERAL;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
});
|
|
@@ -13,25 +13,57 @@
|
|
|
13
13
|
* `akm reflect`. `propose_invoked` is emitted at command entry.
|
|
14
14
|
*/
|
|
15
15
|
import fs from "node:fs";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { placementTypes, stashDirFor } from "../../core/asset/asset-placement.js";
|
|
17
|
+
import { parseRefInput } from "../../core/asset/resolve-ref.js";
|
|
18
18
|
import { resolveStashDir } from "../../core/common.js";
|
|
19
19
|
import { ConfigError, UsageError } from "../../core/errors.js";
|
|
20
20
|
import { appendEvent } from "../../core/events.js";
|
|
21
|
+
import { redactSensitiveText } from "../../core/redaction.js";
|
|
21
22
|
import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
23
|
+
import { deriveEntryProvenance } from "../../indexer/installations.js";
|
|
24
|
+
import { resolveEngine } from "../../integrations/agent/engine-resolution.js";
|
|
24
25
|
import { buildProposePrompt, parseAgentProposalPayload } from "../../integrations/agent/prompts.js";
|
|
25
|
-
import {
|
|
26
|
-
import { baseFailureFields, enoentHintMessage, isEnoentFailure
|
|
27
|
-
import { createProposal, isProposalSkipped, } from "./repository.js";
|
|
28
|
-
function failureEnvelope(result, type, name, fallbackReason = "non_zero_exit") {
|
|
26
|
+
import { collectDispatchSensitiveValues, executeRunner } from "../../integrations/agent/runner-dispatch.js";
|
|
27
|
+
import { baseFailureFields, enoentHintMessage, isEnoentFailure } from "../agent/agent-support.js";
|
|
28
|
+
import { createProposal, isProposalSkipped, resolveProposalQueueTarget, } from "./repository.js";
|
|
29
|
+
function failureEnvelope(result, type, name, engine, fallbackReason = "non_zero_exit") {
|
|
29
30
|
return {
|
|
30
31
|
...baseFailureFields(result, fallbackReason),
|
|
32
|
+
schemaVersion: 2,
|
|
31
33
|
type,
|
|
32
34
|
name,
|
|
35
|
+
engine,
|
|
33
36
|
};
|
|
34
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* WI-8.5a — the fully-qualified `bundle//conceptId` item_ref for a proposal
|
|
40
|
+
* target in `stashDir`. The conceptId is BUILT from the D-R2 static table
|
|
41
|
+
* (`deriveEntryProvenance`), never looked up, so a propose target that does not
|
|
42
|
+
* yet exist on disk still keys onto its final spelling; the bundle is the
|
|
43
|
+
* write-target stash's installation id (same derivation the index write path
|
|
44
|
+
* uses). Matches `createProposal`'s durable `proposals.ref` mint, so the entry
|
|
45
|
+
* event, the fallback ref, and the stored proposal all carry one spelling.
|
|
46
|
+
*/
|
|
47
|
+
function proposeItemRef(bundleId, type, name) {
|
|
48
|
+
return deriveEntryProvenance({ bundleId, componentId: bundleId, adapterId: "akm" }, type, name).itemRef;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The command-entry `propose_invoked` event. WI-8.5b: the ref carries the same
|
|
52
|
+
* fully-qualified item_ref the durable proposal is minted under
|
|
53
|
+
* (`proposeItemRef`), so the entry event and the stored proposal agree.
|
|
54
|
+
*/
|
|
55
|
+
function emitProposeInvoked(bundleId, options) {
|
|
56
|
+
appendEvent({
|
|
57
|
+
eventType: "propose_invoked",
|
|
58
|
+
ref: proposeItemRef(bundleId, options.type, options.name),
|
|
59
|
+
metadata: {
|
|
60
|
+
type: options.type,
|
|
61
|
+
name: options.name,
|
|
62
|
+
task: options.task,
|
|
63
|
+
...(options.engine ? { engine: options.engine } : {}),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
35
67
|
export async function akmPropose(options) {
|
|
36
68
|
if (!options.type?.trim()) {
|
|
37
69
|
throw new UsageError("propose: <type> is required.", "MISSING_REQUIRED_ARGUMENT");
|
|
@@ -42,53 +74,20 @@ export async function akmPropose(options) {
|
|
|
42
74
|
if (!options.task?.trim()) {
|
|
43
75
|
throw new UsageError("propose: --task is required.", "MISSING_REQUIRED_ARGUMENT");
|
|
44
76
|
}
|
|
45
|
-
if (!
|
|
46
|
-
throw new UsageError(`propose: unknown asset type "${options.type}". Known types: ${
|
|
77
|
+
if (!stashDirFor(options.type)) {
|
|
78
|
+
throw new UsageError(`propose: unknown asset type "${options.type}". Known types: ${[...placementTypes()].sort().join(", ")}.`, "INVALID_FLAG_VALUE");
|
|
47
79
|
}
|
|
48
80
|
const stash = options.stashDir ?? resolveStashDir();
|
|
49
|
-
// 1.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
});
|
|
60
|
-
// 2. Resolve profile.
|
|
61
|
-
// When an explicit --profile flag is given, honour it directly (existing
|
|
62
|
-
// behaviour). Otherwise use resolveProcessAgentProfile so that per-process
|
|
63
|
-
// agent config (agent.processes["propose"]) is picked up automatically.
|
|
64
|
-
let profile;
|
|
65
|
-
let resolvedTimeoutMs = options.timeoutMs;
|
|
66
|
-
try {
|
|
67
|
-
if (options.agentProfile) {
|
|
68
|
-
// Test seam: injected profile bypasses all config.
|
|
69
|
-
profile = options.agentProfile;
|
|
70
|
-
}
|
|
71
|
-
else if (options.profile) {
|
|
72
|
-
// Explicit --profile flag wins over process config.
|
|
73
|
-
profile = resolveAgentProfile(options);
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
// Use per-process config resolution (falls back to agent.default).
|
|
77
|
-
const agent = options.agentConfig ?? loadAgentConfigFromDisk();
|
|
78
|
-
const processName = options.agentProcess ?? "propose";
|
|
79
|
-
const resolved = resolveProcessAgentProfile(processName, agent);
|
|
80
|
-
profile = resolved.profile;
|
|
81
|
-
// Only apply process-resolved timeoutMs when caller didn't supply one.
|
|
82
|
-
if (resolvedTimeoutMs === undefined) {
|
|
83
|
-
resolvedTimeoutMs = resolved.timeoutMs;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
catch (err) {
|
|
88
|
-
if (err instanceof ConfigError || err instanceof UsageError)
|
|
89
|
-
throw err;
|
|
90
|
-
throw err;
|
|
91
|
-
}
|
|
81
|
+
// 1. Resolve the selected engine and write target exactly once.
|
|
82
|
+
// the LLM arm uses the caller-specific plain-chat handler below.
|
|
83
|
+
const config = options.agentConfig ?? (await import("../../core/config/config.js")).loadConfig();
|
|
84
|
+
const target = resolveProposalQueueTarget(stash, config);
|
|
85
|
+
emitProposeInvoked(target.source, options);
|
|
86
|
+
const engineName = options.engine ?? config.defaults?.engine;
|
|
87
|
+
if (!engineName)
|
|
88
|
+
throw new ConfigError("propose requires --engine or defaults.engine.", "INVALID_CONFIG_FILE");
|
|
89
|
+
const runner = resolveEngine(engineName, config);
|
|
90
|
+
const profile = runner.kind === "llm" ? undefined : runner.profile;
|
|
92
91
|
// 3. Build prompt.
|
|
93
92
|
// Synthesize a temp draft path so opencode can write the asset content
|
|
94
93
|
// directly using its file tools rather than returning JSON via stdout.
|
|
@@ -104,39 +103,51 @@ export async function akmPropose(options) {
|
|
|
104
103
|
...(standardsContext.trim() ? { standardsContext } : {}),
|
|
105
104
|
draftFilePath: resolvedDraftPath,
|
|
106
105
|
});
|
|
107
|
-
// 4.
|
|
106
|
+
// 4. Dispatch the selected engine.
|
|
108
107
|
// Real agent runs use interactive mode so file tools can write the draft.
|
|
109
108
|
// Injected/custom spawns still need captured stdout for JSON payload tests.
|
|
110
|
-
//
|
|
109
|
+
// All kinds cross the unified RunnerSpec dispatch boundary.
|
|
111
110
|
const useCustomSpawn = Boolean(options.runAgentOptions?.spawn);
|
|
112
111
|
let result;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
112
|
+
const runOptions = {
|
|
113
|
+
stdio: useCustomSpawn ? "captured" : "interactive",
|
|
114
|
+
parseOutput: "text",
|
|
115
|
+
...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
|
|
116
|
+
...(options.runAgentOptions ?? {}),
|
|
117
|
+
};
|
|
118
|
+
const sensitiveValues = collectDispatchSensitiveValues(runner, runOptions);
|
|
119
|
+
result = await executeRunner(runner, prompt, runOptions, {
|
|
120
|
+
llm: async (spec, llmPrompt, opts) => {
|
|
121
|
+
const { chatCompletion } = await import("../../llm/client.js");
|
|
122
|
+
const started = Date.now();
|
|
123
|
+
try {
|
|
124
|
+
const stdout = await chatCompletion(spec.connection, [{ role: "user", content: llmPrompt }], {
|
|
125
|
+
...(Object.hasOwn(opts, "timeoutMs") ? { timeoutMs: opts.timeoutMs } : {}),
|
|
126
|
+
});
|
|
127
|
+
return { ok: true, exitCode: 0, stdout, stderr: "", durationMs: Date.now() - started };
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
exitCode: null,
|
|
133
|
+
stdout: "",
|
|
134
|
+
stderr: "",
|
|
135
|
+
durationMs: Date.now() - started,
|
|
136
|
+
error: String(error),
|
|
137
|
+
reason: "spawn_failed",
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
});
|
|
134
142
|
if (!result.ok) {
|
|
135
143
|
// B3: ENOENT / not-found gives an actionable hint.
|
|
136
144
|
if (isEnoentFailure(result)) {
|
|
137
|
-
return {
|
|
145
|
+
return {
|
|
146
|
+
...failureEnvelope(result, options.type, options.name, engineName),
|
|
147
|
+
error: enoentHintMessage(profile?.bin ?? engineName),
|
|
148
|
+
};
|
|
138
149
|
}
|
|
139
|
-
return failureEnvelope(result, options.type, options.name);
|
|
150
|
+
return failureEnvelope(result, options.type, options.name, engineName);
|
|
140
151
|
}
|
|
141
152
|
// 5. Resolve the proposal content.
|
|
142
153
|
// Path A: opencode wrote the draft file — read it directly (no stdout parse).
|
|
@@ -146,7 +157,7 @@ export async function akmPropose(options) {
|
|
|
146
157
|
const draftContent = fs.readFileSync(resolvedDraftPath, "utf8");
|
|
147
158
|
fs.unlinkSync(resolvedDraftPath);
|
|
148
159
|
payload = {
|
|
149
|
-
ref:
|
|
160
|
+
ref: proposeItemRef(target.source, options.type, options.name),
|
|
150
161
|
content: draftContent,
|
|
151
162
|
};
|
|
152
163
|
}
|
|
@@ -156,12 +167,13 @@ export async function akmPropose(options) {
|
|
|
156
167
|
const stdioWasInteractive = !useCustomSpawn;
|
|
157
168
|
if (stdioWasInteractive && (result.stdout ?? "") === "") {
|
|
158
169
|
return {
|
|
159
|
-
schemaVersion:
|
|
170
|
+
schemaVersion: 2,
|
|
160
171
|
ok: false,
|
|
161
172
|
reason: "parse_error",
|
|
162
173
|
error: "Agent did not write draft file and stdout was not captured (interactive mode). Check that the agent CLI understood the file-write instruction, or configure a headless profile with stdio: 'captured'.",
|
|
163
174
|
type: options.type,
|
|
164
175
|
name: options.name,
|
|
176
|
+
engine: engineName,
|
|
165
177
|
exitCode: result.exitCode,
|
|
166
178
|
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
167
179
|
};
|
|
@@ -171,36 +183,39 @@ export async function akmPropose(options) {
|
|
|
171
183
|
}
|
|
172
184
|
catch (err) {
|
|
173
185
|
return {
|
|
174
|
-
schemaVersion:
|
|
186
|
+
schemaVersion: 2,
|
|
175
187
|
ok: false,
|
|
176
188
|
reason: "parse_error",
|
|
177
189
|
error: err instanceof Error ? err.message : String(err),
|
|
178
190
|
type: options.type,
|
|
179
191
|
name: options.name,
|
|
192
|
+
engine: engineName,
|
|
180
193
|
exitCode: result.exitCode,
|
|
181
194
|
stdout: result.stdout,
|
|
182
195
|
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
183
196
|
};
|
|
184
197
|
}
|
|
185
198
|
}
|
|
199
|
+
payload = { ...payload, content: redactSensitiveText(payload.content, sensitiveValues) };
|
|
186
200
|
// 6. Insert the proposal. Note: we allow the agent's `ref` to normalise the
|
|
187
201
|
// asset name (e.g. path-cleanup), but only after validating that the ref is
|
|
188
202
|
// well-formed and the type still matches the requested type.
|
|
189
|
-
const expectedRef =
|
|
203
|
+
const expectedRef = proposeItemRef(target.source, options.type, options.name);
|
|
190
204
|
let ref = expectedRef;
|
|
191
205
|
if (payload.ref) {
|
|
192
206
|
let parsedRef;
|
|
193
207
|
try {
|
|
194
|
-
parsedRef =
|
|
208
|
+
parsedRef = parseRefInput(payload.ref);
|
|
195
209
|
}
|
|
196
210
|
catch (err) {
|
|
197
211
|
return {
|
|
198
|
-
schemaVersion:
|
|
212
|
+
schemaVersion: 2,
|
|
199
213
|
ok: false,
|
|
200
214
|
reason: "parse_error",
|
|
201
215
|
error: err instanceof Error ? err.message : String(err),
|
|
202
216
|
type: options.type,
|
|
203
217
|
name: options.name,
|
|
218
|
+
engine: engineName,
|
|
204
219
|
exitCode: result.exitCode,
|
|
205
220
|
stdout: result.stdout,
|
|
206
221
|
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
@@ -208,23 +223,25 @@ export async function akmPropose(options) {
|
|
|
208
223
|
}
|
|
209
224
|
if (parsedRef.type !== options.type) {
|
|
210
225
|
return {
|
|
211
|
-
schemaVersion:
|
|
226
|
+
schemaVersion: 2,
|
|
212
227
|
ok: false,
|
|
213
228
|
reason: "parse_error",
|
|
214
229
|
error: `Agent returned ref type ${parsedRef.type} but expected ${options.type}`,
|
|
215
230
|
type: options.type,
|
|
216
231
|
name: options.name,
|
|
232
|
+
engine: engineName,
|
|
217
233
|
exitCode: result.exitCode,
|
|
218
234
|
stdout: result.stdout,
|
|
219
235
|
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
220
236
|
};
|
|
221
237
|
}
|
|
222
|
-
ref =
|
|
238
|
+
ref = proposeItemRef(target.source, parsedRef.type, parsedRef.name);
|
|
223
239
|
}
|
|
224
240
|
const createInput = {
|
|
225
241
|
ref,
|
|
226
242
|
source: "propose",
|
|
227
243
|
sourceRun: `propose-${Date.now()}`,
|
|
244
|
+
target,
|
|
228
245
|
// User-initiated proposals always bypass dedup/cooldown guards — the
|
|
229
246
|
// operator is explicitly asking for a new proposal.
|
|
230
247
|
force: true,
|
|
@@ -241,11 +258,11 @@ export async function akmPropose(options) {
|
|
|
241
258
|
}
|
|
242
259
|
const proposal = proposalResult;
|
|
243
260
|
return {
|
|
244
|
-
schemaVersion:
|
|
261
|
+
schemaVersion: 2,
|
|
245
262
|
ok: true,
|
|
246
263
|
proposal,
|
|
247
264
|
ref: proposal.ref,
|
|
248
|
-
|
|
265
|
+
engine: engineName,
|
|
249
266
|
durationMs: result.durationMs,
|
|
250
267
|
};
|
|
251
268
|
}
|