akm-cli 0.10.261012-beta → 0.10.261014-beta
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 +710 -3
- package/README.md +15 -0
- package/SECURITY.md +11 -10
- package/STABILITY.md +47 -51
- package/dist/assets/hints/cli-hints-full.md +21 -19
- package/dist/assets/hints/cli-hints-short.md +3 -4
- package/dist/assets/opencode/akm-plugin.js +177 -0
- package/dist/assets/stash-skeleton/README.md +1 -1
- package/dist/assets/tasks/core/improve.yml +1 -1
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
- package/dist/assets/ui/config.js +27 -10
- package/dist/assets/workflows/workflow-template.md +2 -2
- package/dist/cli/clack.js +3 -1
- package/dist/cli/selection.js +33 -0
- package/dist/cli/shared.js +14 -1
- package/dist/cli/unknown-flags.js +6 -37
- package/dist/cli.js +69 -48
- package/dist/commands/agent/agent-dispatch.js +17 -25
- package/dist/commands/agent/contribute-cli.js +9 -8
- package/dist/commands/command/command-cli.js +4 -8
- package/dist/commands/command/command-execution.js +25 -39
- package/dist/commands/command/execution-source-loader.js +10 -14
- package/dist/commands/completions.js +1 -1
- package/dist/commands/config-cli.js +14 -5
- package/dist/commands/env/child-env.js +12 -14
- package/dist/commands/env/env-binding.js +47 -58
- package/dist/commands/env/env-cli.js +22 -24
- package/dist/commands/env/env.js +10 -58
- package/dist/commands/env/secret-cli.js +11 -29
- package/dist/commands/env/secret.js +3 -10
- package/dist/commands/health/checks.js +10 -849
- package/dist/commands/health/connections-and-harnesses-check.js +109 -0
- package/dist/commands/health/egress.js +3 -3
- package/dist/commands/health/html-report.js +9 -10
- package/dist/commands/health/plugin-staleness.js +18 -11
- package/dist/commands/health/report-view-model.js +16 -12
- package/dist/commands/health/scheduler-binary.js +1 -1
- package/dist/commands/health/semantic-search-check.js +85 -0
- package/dist/commands/health/type-directory-check.js +0 -3
- package/dist/commands/health.js +30 -42
- package/dist/commands/improve/consolidate/pair-pass.js +10 -25
- package/dist/commands/improve/consolidate.js +10 -15
- package/dist/commands/improve/distill.js +5 -17
- package/dist/commands/improve/eligibility.js +1 -3
- package/dist/commands/improve/execution.js +37 -40
- package/dist/commands/improve/extract-cli.js +6 -11
- package/dist/commands/improve/extract-prompt.js +2 -2
- package/dist/commands/improve/extract.js +67 -97
- package/dist/commands/improve/improve-cli.js +22 -128
- package/dist/commands/improve/improve-report.js +1 -1
- package/dist/commands/improve/improve-strategies.js +25 -108
- package/dist/commands/improve/improve.js +10 -14
- package/dist/commands/improve/loop-stages.js +3 -0
- package/dist/commands/improve/memory/memory-improve.js +1 -1
- package/dist/commands/improve/preparation.js +8 -13
- package/dist/commands/improve/reflect.js +203 -332
- package/dist/commands/improve/retrieval-scope.js +1 -1
- package/dist/commands/improve/session-asset.js +3 -2
- package/dist/commands/improve/stage.js +87 -115
- package/dist/commands/lint/base-linter.js +3 -3
- package/dist/commands/lint/env-key-rules.js +7 -6
- package/dist/commands/lint/index.js +3 -3
- package/dist/commands/models-cli.js +103 -63
- package/dist/commands/proposal/drain.js +26 -39
- package/dist/commands/proposal/proposal-cli.js +14 -18
- package/dist/commands/proposal/propose-cli.js +4 -2
- package/dist/commands/proposal/propose.js +37 -64
- package/dist/commands/proposal/repository.js +17 -17
- package/dist/commands/proposal/validators/proposal-validators.js +3 -6
- package/dist/commands/read/curate.js +10 -6
- package/dist/commands/read/registry-search.js +2 -48
- package/dist/commands/read/search-cli.js +1 -8
- package/dist/commands/read/search.js +5 -6
- package/dist/commands/read/show.js +6 -29
- package/dist/commands/remember.js +25 -40
- package/dist/commands/sources/add-cli.js +8 -63
- package/dist/commands/sources/bundle-cli.js +8 -9
- package/dist/commands/sources/bundle-config-ops.js +2 -2
- package/dist/commands/sources/info.js +12 -1
- package/dist/commands/sources/init.js +1 -1
- package/dist/commands/sources/installed-stashes.js +119 -63
- package/dist/commands/sources/migration-help.js +1 -1
- package/dist/commands/sources/plugin-upgrade.js +8 -15
- package/dist/commands/sources/schema-repair.js +4 -10
- package/dist/commands/sources/source-add.js +2 -2
- package/dist/commands/sources/source-clone.js +31 -7
- package/dist/commands/sources/source-manage.js +4 -4
- package/dist/commands/targets.js +175 -0
- package/dist/commands/tasks/explain.js +104 -69
- package/dist/commands/tasks/tasks-cli.js +9 -11
- package/dist/commands/tasks/tasks.js +75 -97
- package/dist/commands/ui/api.js +11 -3
- package/dist/commands/ui/redact.js +5 -31
- package/dist/commands/ui/workspace-actions.js +1 -1
- package/dist/commands/workflow/plan.js +48 -9
- package/dist/commands/workflow-cli.js +40 -45
- package/dist/core/adapter/adapters/agent-skills-adapter.js +10 -11
- package/dist/core/adapter/adapters/akm-adapter.js +36 -41
- package/dist/core/adapter/adapters/akm-lint.js +10 -12
- package/dist/core/adapter/adapters/akm-metadata.js +2 -2
- package/dist/core/adapter/adapters/akm-task-adapter.js +8 -9
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +5 -5
- package/dist/core/adapter/adapters/claude-adapter.js +1 -1
- package/dist/core/adapter/adapters/dotenv-adapter.js +7 -6
- package/dist/core/adapter/adapters/generic-files-adapter.js +5 -5
- package/dist/core/adapter/adapters/index.js +3 -4
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +12 -14
- package/dist/core/adapter/adapters/okf-adapter.js +8 -10
- package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
- package/dist/core/adapter/adapters/shared.js +3 -3
- package/dist/core/adapter/adapters/tool-dir-shared.js +7 -25
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +3 -3
- package/dist/core/adapter/detect-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +13 -35
- package/dist/core/adapter/registry.js +1 -1
- package/dist/core/adapter/validate-context.js +2 -4
- package/dist/core/asset/asset-placement.js +1 -1
- package/dist/core/asset/asset-ref.js +3 -3
- package/dist/core/asset/resolve-ref.js +5 -0
- package/dist/core/bundle-rename.js +12 -4
- package/dist/core/closest-match.js +37 -0
- package/dist/core/common.js +37 -57
- package/dist/core/config/config-io.js +26 -18
- package/dist/core/config/config-schema.js +19 -106
- package/dist/core/config/config-sources.js +3 -3
- package/dist/core/config/config-types.js +4 -4
- package/dist/core/config/config-walker.js +50 -77
- package/dist/core/config/config.js +438 -109
- package/dist/core/config/convert-engine-references.js +114 -0
- package/dist/core/config/convert-engines-shared.js +40 -0
- package/dist/core/config/convert-engines.js +300 -0
- package/dist/core/config/convert-models-overlay.js +137 -0
- package/dist/core/config/credentials.js +304 -0
- package/dist/core/config/engine-semantics.js +3 -3
- package/dist/core/config/migrate-keys.js +222 -0
- package/dist/core/config/model-aliases.js +37 -0
- package/dist/core/config/models-file.js +34 -0
- package/dist/core/config/retired-engines.js +53 -0
- package/dist/core/config/schema/connections.js +41 -0
- package/dist/core/config/schema/embedding.js +2 -2
- package/dist/core/config/schema/harnesses.js +41 -0
- package/dist/core/config/schema/improve-processes.js +9 -28
- package/dist/core/config/schema/improve.js +36 -1
- package/dist/core/config/schema/index-config.js +18 -20
- package/dist/core/config/schema/primitives.js +42 -17
- package/dist/core/config/schema/search.js +6 -11
- package/dist/core/config/schema/sources-bundles.js +9 -9
- package/dist/core/config/schema/workflow.js +2 -6
- package/dist/core/config/unusable-entries.js +66 -0
- package/dist/core/content-safety.js +3 -6
- package/dist/core/endpoint-url.js +47 -0
- package/dist/core/env-secret-ref.js +84 -73
- package/dist/core/errors.js +10 -16
- package/dist/core/extra-params.js +3 -3
- package/dist/core/improve-result.js +8 -9
- package/dist/core/json-schema.js +1 -1
- package/dist/core/lesson-lint.js +1 -1
- package/dist/core/llm-inference.js +80 -0
- package/dist/core/parse.js +2 -2
- package/dist/core/paths.js +33 -10
- package/dist/core/recognition-util.js +8 -10
- package/dist/core/redaction.js +94 -55
- package/dist/core/ref-token.js +82 -0
- package/dist/core/secret-value.js +14 -0
- package/dist/core/state/migrations.js +17 -22
- package/dist/core/structured.js +2 -68
- package/dist/core/subprocess.js +63 -22
- package/dist/core/type-presentation.js +10 -14
- package/dist/core/write-source.js +20 -4
- package/dist/execution/input-contract.js +3 -6
- package/dist/execution/notices.js +49 -0
- package/dist/execution/resolved-request.js +24 -40
- package/dist/execution/source.js +21 -45
- package/dist/execution/target-ref.js +2 -2
- package/dist/indexer/bundle-identity-guard.js +6 -5
- package/dist/indexer/ensure-index.js +1 -1
- package/dist/indexer/index-writer-lock.js +1 -1
- package/dist/indexer/indexer.js +46 -42
- package/dist/indexer/installations.js +12 -22
- package/dist/indexer/lookup/adapter-concept-owner.js +40 -14
- package/dist/indexer/materialize-embeddings.js +20 -16
- package/dist/indexer/passes/memory-inference.js +21 -50
- package/dist/indexer/passes/metadata.js +5 -5
- package/dist/indexer/scan/doc-to-entry.js +1 -1
- package/dist/indexer/scan/drain-dir.js +9 -11
- package/dist/indexer/search/db-search.js +9 -7
- package/dist/indexer/search/search-source.js +42 -22
- package/dist/indexer/usage/usage-events.js +2 -3
- package/dist/indexer/walk/index-context.js +2 -1
- package/dist/indexer/walk/matchers.js +3 -11
- package/dist/indexer/walk/path-resolver.js +13 -68
- package/dist/indexer/walk/walker.js +32 -26
- package/dist/integrations/agent/akm-read-tools.js +81 -0
- package/dist/integrations/agent/config.js +1 -1
- package/dist/integrations/agent/detect.js +32 -36
- package/dist/integrations/agent/execution.js +130 -428
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +24 -28
- package/dist/integrations/agent/prompts.js +17 -30
- package/dist/integrations/agent/request-lowering.js +67 -101
- package/dist/integrations/agent/resolution.js +332 -0
- package/dist/integrations/agent/runner-dispatch.js +156 -181
- package/dist/integrations/agent/runner.js +20 -70
- package/dist/integrations/agent/runtime-port.js +4 -0
- package/dist/integrations/agent/runtime.js +10 -0
- package/dist/integrations/agent/spawn.js +65 -190
- package/dist/integrations/harnesses/aider/index.js +19 -39
- package/dist/integrations/harnesses/amazonq/index.js +17 -32
- package/dist/integrations/harnesses/claude/index.js +59 -28
- package/dist/integrations/harnesses/claude/session-log.js +7 -5
- package/dist/integrations/harnesses/codex/index.js +19 -31
- package/dist/integrations/harnesses/copilot/index.js +17 -35
- package/dist/integrations/harnesses/gemini/index.js +18 -34
- package/dist/integrations/harnesses/harness.js +36 -0
- package/dist/integrations/harnesses/index.js +20 -51
- package/dist/integrations/harnesses/opencode/agent-builder.js +132 -100
- package/dist/integrations/harnesses/opencode/index.js +11 -33
- package/dist/integrations/harnesses/opencode/roots.js +50 -0
- package/dist/integrations/harnesses/opencode/runtime/binary.js +206 -0
- package/dist/integrations/harnesses/opencode/runtime/command.js +152 -0
- package/dist/integrations/harnesses/opencode/runtime/index.js +177 -0
- package/dist/integrations/harnesses/opencode/runtime/tar.js +107 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +15 -7
- package/dist/integrations/harnesses/opencode/session-log-v2.js +72 -48
- package/dist/integrations/harnesses/opencode/session-log.js +58 -137
- package/dist/integrations/harnesses/opencode/version.js +34 -53
- package/dist/integrations/harnesses/openhands/index.js +13 -37
- package/dist/integrations/harnesses/pi/index.js +21 -32
- package/dist/integrations/lockfile.js +1 -1
- package/dist/integrations/session-logs/index.js +11 -31
- package/dist/llm/client.js +93 -111
- package/dist/llm/embedder.js +19 -34
- package/dist/llm/embedders/connection.js +31 -0
- package/dist/llm/embedders/local-model-files.js +56 -0
- package/dist/llm/embedders/local.js +146 -115
- package/dist/llm/embedders/remote.js +26 -23
- package/dist/llm/embedders/types.js +1 -1
- package/dist/llm/index-passes.js +33 -39
- package/dist/llm/memory-infer.js +67 -77
- package/dist/llm/model-list.js +35 -0
- package/dist/llm/rerank-client.js +8 -14
- package/dist/llm/structured-call.js +45 -99
- package/dist/llm/structured.js +60 -0
- package/dist/output/renderers.js +2 -8
- package/dist/output/shapes/helpers.js +18 -44
- package/dist/output/shapes/passthrough.js +1 -0
- package/dist/output/shapes.js +1 -7
- package/dist/output/text/command-format.js +41 -39
- package/dist/output/text/health-format.js +8 -2
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +12 -0
- package/dist/output/text/models.js +3 -2
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +16 -28
- package/dist/output/text/show-format.js +0 -2
- package/dist/output/text/targets-table.js +70 -0
- package/dist/output/text/workflow-format.js +44 -15
- package/dist/output/text.js +1 -1
- package/dist/registry/providers/skills-sh.js +1 -28
- package/dist/registry/providers/static-index.js +1 -71
- package/dist/runtime.js +6 -2
- package/dist/scripts/akm-migrate-node.js +47095 -44905
- package/dist/scripts/akm-migrate.js +46946 -44755
- package/dist/setup/detect.js +28 -273
- package/dist/setup/endpoint.js +36 -0
- package/dist/setup/semantic-assets.js +13 -19
- package/dist/setup/setup-flags.js +77 -0
- package/dist/setup/setup-plan.js +144 -0
- package/dist/setup/setup.js +134 -358
- package/dist/setup/steps/connection-shared.js +49 -101
- package/dist/setup/steps/connection.js +121 -524
- package/dist/setup/steps/embeddings.js +151 -0
- package/dist/setup/steps/harnesses.js +118 -0
- package/dist/setup/steps/platforms.js +2 -81
- package/dist/setup/steps/tasks.js +1 -2
- package/dist/setup/steps.js +10 -0
- package/dist/setup/summary.js +67 -0
- package/dist/sources/freshness.js +16 -21
- package/dist/sources/providers/git-provider.js +2 -9
- package/dist/sources/providers/provider-utils.js +13 -5
- package/dist/sources/resolve.js +12 -16
- package/dist/sources/snapshot-fetchers/robots.js +11 -12
- package/dist/sources/snapshot-fetchers/secret-seam.js +2 -4
- package/dist/sources/snapshot-fetchers/website-ingest.js +8 -15
- package/dist/sources/snapshot-fetchers/x.js +1 -1
- package/dist/standalone/onnxruntime-library.js +52 -0
- package/dist/storage/repositories/improve-ledger-repository.js +1 -1
- package/dist/storage/repositories/improve-runs-repository.js +0 -13
- package/dist/storage/repositories/index-entries-repository.js +2 -2
- package/dist/storage/repositories/proposals-repository.js +2 -2
- package/dist/storage/repositories/task-history-repository.js +2 -2
- package/dist/storage/repositories/workflow-runs-repository.js +44 -129
- package/dist/storage/sqlite-read-snapshot.js +33 -29
- package/dist/tasks/embedded.js +1 -1
- package/dist/tasks/log-redaction.js +7 -119
- package/dist/tasks/prepare/prepare-support.js +8 -7
- package/dist/tasks/prepare/prepare.js +8 -9
- package/dist/tasks/prepare/script-capture.js +9 -25
- package/dist/tasks/run/attempt-lifecycle.js +17 -35
- package/dist/tasks/run/load-task.js +54 -27
- package/dist/tasks/run/run-command-task.js +15 -10
- package/dist/tasks/run/run-native-task.js +8 -21
- package/dist/tasks/run/run-task.js +5 -8
- package/dist/tasks/run/run-workflow-task.js +14 -21
- package/dist/tasks/run/task-history.js +9 -17
- package/dist/tasks/run/task-log.js +1 -5
- package/dist/tasks/scheduler-invocation.js +13 -18
- package/dist/tasks/scheduler-sync.js +0 -1
- package/dist/tasks/source/bounded-document.js +31 -117
- package/dist/tasks/source/parse-task-source.js +0 -1
- package/dist/tasks/source/project-v4.js +5 -3
- package/dist/tasks/source/task-input-diagnostics.js +3 -4
- package/dist/tasks/source/task-source-v4.js +48 -72
- package/dist/tasks/source-v3.js +2 -5
- package/dist/tasks/task-run-reserved-flags.js +1 -2
- package/dist/workflows/authoring/authoring.js +2 -7
- package/dist/workflows/compile.js +1 -15
- package/dist/workflows/concurrency-policy.js +4 -4
- package/dist/workflows/exec/child-workflow.js +1 -4
- package/dist/workflows/exec/dispatch-redaction.js +35 -86
- package/dist/workflows/exec/environment.js +13 -77
- package/dist/workflows/exec/exec-unit.js +14 -55
- package/dist/workflows/exec/frozen-judge.js +26 -28
- package/dist/workflows/exec/native-executor.js +126 -71
- package/dist/workflows/exec/run-workflow.js +38 -42
- package/dist/workflows/exec/step-work.js +13 -17
- package/dist/workflows/exec/unit-dispatch.js +7 -21
- package/dist/workflows/freeze/environment.js +14 -119
- package/dist/workflows/freeze/freeze.js +14 -33
- package/dist/workflows/freeze/step-values.js +6 -13
- package/dist/workflows/freeze/targets/child-workflow.js +3 -5
- package/dist/workflows/freeze/targets/command.js +9 -15
- package/dist/workflows/freeze/targets/shell.js +0 -3
- package/dist/workflows/freeze/task-bindings.js +0 -1
- package/dist/workflows/parser.js +50 -59
- package/dist/workflows/plan.js +8 -2
- package/dist/workflows/renderer.js +83 -9
- package/dist/workflows/resource-limits.js +2 -2
- package/dist/workflows/runtime/run-plan.js +38 -23
- package/dist/workflows/runtime/runs.js +55 -93
- package/dist/workflows/runtime/workflow-asset-loader.js +55 -86
- package/dist/workflows/source-files.js +7 -19
- package/docs/README.md +10 -16
- package/docs/architecture/README.md +2 -37
- package/docs/architecture/adapters.md +2 -2
- package/docs/architecture/akm-core-principles.md +256 -118
- package/docs/architecture/architecture.md +283 -99
- package/docs/architecture/improvement.md +8 -2
- package/docs/architecture/internals/classification.md +1 -3
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +7 -6
- package/docs/architecture/internals/health-advisories.md +35 -74
- package/docs/architecture/internals/improve-workflow.md +27 -26
- package/docs/architecture/internals/indexing.md +3 -3
- package/docs/architecture/internals/storage-locations.md +48 -15
- package/docs/architecture/persisted-data-compat.md +10 -6
- package/docs/architecture/specs/okf-support.md +9 -11
- package/docs/architecture/specs/ref.md +7 -9
- package/docs/architecture/testing/testing-workflow.md +172 -52
- package/docs/architecture/workflow-engine.md +51 -34
- package/docs/guides/README.md +0 -1
- package/docs/guides/author-bundles.md +15 -20
- package/docs/guides/author-workflows.md +93 -71
- package/docs/guides/bundles.md +20 -16
- package/docs/guides/discover-and-load.md +1 -1
- package/docs/guides/getting-started.md +49 -3
- package/docs/guides/improve-the-library.md +10 -4
- package/docs/guides/recipes/headless-install.md +11 -16
- package/docs/guides/run-workflows.md +29 -20
- package/docs/guides/scheduling.md +2 -2
- package/docs/guides/use-with-any-agent.md +20 -22
- package/docs/integration/bundling-akm.md +19 -9
- package/docs/maintainers/README.md +2 -6
- package/docs/maintainers/release-checklist.md +73 -126
- package/docs/migration/README.md +10 -3
- package/docs/migration/release-notes/0.10.0.md +81 -16
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +1 -1
- package/docs/migration/release-notes/README.md +1 -1
- package/docs/migration/v0.9-to-v0.10.md +300 -60
- package/docs/migration/v0.9.1-to-v0.9.2.md +6 -5
- package/docs/posts/config-v2-lessons-16.md +1 -1
- package/docs/posts/llm-mode-reflect-13.md +1 -1
- package/docs/posts/release-0.6.0.md +11 -11
- package/docs/posts/release-0.8.0.md +4 -4
- package/docs/posts/workflows-vaults-09.md +1 -1
- package/docs/reference/README.md +1 -1
- package/docs/reference/asset-types.md +2 -2
- package/docs/reference/cli.md +477 -388
- package/docs/reference/configuration.md +569 -550
- package/docs/reference/data-and-telemetry.md +9 -6
- package/docs/reference/env-and-secrets.md +72 -15
- package/docs/reference/refs.md +3 -20
- package/docs/reference/registry.md +12 -38
- package/docs/reference/supported-formats.md +1 -1
- package/docs/reference/tasks.md +22 -11
- package/docs/reference/ui-api.md +14 -9
- package/docs/reference/workflow-schema.md +199 -154
- package/docs/reference/workflows.md +4 -6
- package/package.json +9 -11
- package/schemas/akm-config.json +1696 -2922
- package/schemas/akm-task.json +4 -4
- package/schemas/akm-workflow.json +36 -9
- package/ROADMAP.md +0 -112
- package/dist/assets/models.json +0 -35
- package/dist/commands/health/engine-usage.js +0 -45
- package/dist/commands/sources/dangerous-env-audit.js +0 -134
- package/dist/core/activation-policy.js +0 -67
- package/dist/core/config/schema/engines.js +0 -160
- package/dist/core/config/schema/execution.js +0 -23
- package/dist/core/spawn-env.js +0 -268
- package/dist/execution/directory-identity.js +0 -78
- package/dist/integrations/agent/builder-shared.js +0 -33
- package/dist/integrations/agent/builders.js +0 -43
- package/dist/integrations/agent/engine-fallback.js +0 -59
- package/dist/integrations/agent/engine-resolution.js +0 -333
- package/dist/integrations/agent/model-map.js +0 -475
- package/dist/integrations/harnesses/aider/agent-builder.js +0 -107
- package/dist/integrations/harnesses/aider/result-extractor.js +0 -53
- package/dist/integrations/harnesses/amazonq/agent-builder.js +0 -138
- package/dist/integrations/harnesses/amazonq/result-extractor.js +0 -48
- package/dist/integrations/harnesses/claude/agent-builder.js +0 -106
- package/dist/integrations/harnesses/claude/config-import.js +0 -67
- package/dist/integrations/harnesses/claude/result-extractor.js +0 -67
- package/dist/integrations/harnesses/codex/agent-builder.js +0 -150
- package/dist/integrations/harnesses/codex/result-extractor.js +0 -110
- package/dist/integrations/harnesses/copilot/agent-builder.js +0 -117
- package/dist/integrations/harnesses/copilot/result-extractor.js +0 -178
- package/dist/integrations/harnesses/gemini/agent-builder.js +0 -114
- package/dist/integrations/harnesses/gemini/result-extractor.js +0 -149
- package/dist/integrations/harnesses/opencode/config-import.js +0 -149
- package/dist/integrations/harnesses/opencode/model-config.js +0 -33
- package/dist/integrations/harnesses/opencode/model-work-agent.js +0 -115
- package/dist/integrations/harnesses/opencode/session-log-types.js +0 -12
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -44
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -1052
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +0 -199
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +0 -254
- package/dist/integrations/harnesses/opencode-sdk/wire.js +0 -66
- package/dist/integrations/harnesses/openhands/agent-builder.js +0 -120
- package/dist/integrations/harnesses/openhands/result-extractor.js +0 -135
- package/dist/integrations/harnesses/pi/agent-builder.js +0 -89
- package/dist/integrations/harnesses/pi/result-extractor.js +0 -168
- package/dist/integrations/harnesses/shared.js +0 -18
- package/dist/integrations/harnesses/types.js +0 -55
- package/dist/llm/feature-gate.js +0 -115
- package/dist/output/shapes/models-list.js +0 -16
- package/dist/output/shapes/registry-search.js +0 -10
- package/dist/setup/detected-engines.js +0 -136
- package/dist/setup/engine-config.js +0 -97
- package/dist/setup/harness-config-import.js +0 -47
- package/dist/setup/providers.js +0 -14
- package/dist/setup/steps/semantic.js +0 -39
- package/dist/workflows/authoring/scope-key.js +0 -79
- package/dist/workflows/exec/lowering-notices.js +0 -23
- package/dist/workflows/source-semantics.js +0 -110
- package/docs/architecture/0.10-process-rules.md +0 -832
- package/docs/architecture/akm-architecture-decision-history.md +0 -2055
- package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +0 -550
- package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +0 -72
- package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +0 -142
- package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +0 -189
- package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +0 -97
- package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +0 -108
- package/docs/architecture/decisions/0006-task-source-version-routing.md +0 -124
- package/docs/architecture/decisions/0007-workflow-composition-bounds.md +0 -83
- package/docs/architecture/decisions/0008-task-binding-normalization.md +0 -88
- package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +0 -80
- package/docs/architecture/decisions/0010-driver-protocol-cut.md +0 -36
- package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +0 -125
- package/docs/architecture/decisions/README.md +0 -62
- package/docs/architecture/internals/functional-contract-patterns.md +0 -340
- package/docs/architecture/internals/registry-network-boundary.md +0 -57
- package/docs/architecture/internals/search.md +0 -248
- package/docs/architecture/reviews/env-secret-access.md +0 -319
- package/docs/architecture/runtime-boundary-design.md +0 -153
- package/docs/architecture/specs/0.9.0-close-out-plan.md +0 -361
- package/docs/architecture/specs/0.9.0-decisions.md +0 -532
- package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +0 -745
- package/docs/architecture/specs/0.9.0-open-items-register.md +0 -135
- package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +0 -740
- package/docs/architecture/specs/0.9.0-release-surface-review.md +0 -636
- package/docs/architecture/specs/agent-command-engine-model-design.md +0 -513
- package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +0 -501
- package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +0 -291
- package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +0 -2059
- package/docs/architecture/specs/di-seams-plan.md +0 -539
- package/docs/architecture/specs/driver-protocol-keep-or-cut.md +0 -275
- package/docs/architecture/specs/fact-asset-type.md +0 -142
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +0 -634
- package/docs/architecture/specs/reviews/task-workflow-unification/README.md +0 -72
- package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +0 -152
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +0 -352
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +0 -300
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +0 -402
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +0 -758
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +0 -645
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +0 -602
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +0 -27
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +0 -27
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +0 -74
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +0 -15
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +0 -132
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +0 -147
- package/docs/architecture/specs/stash-conventions-code-spec.md +0 -275
- package/docs/architecture/specs/stash-organization-conventions.md +0 -377
- package/docs/architecture/specs/task-workflow-format-unification.md +0 -721
- package/docs/architecture/specs/workflow-engine-buy-vs-build.md +0 -231
- package/docs/architecture/specs/workflow-format-unification.md +0 -432
- package/docs/architecture/testing/manual-testing-checklist.md +0 -3411
- package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +0 -924
- package/docs/architecture/testing/task-workflow-manual-tests.md +0 -1720
- package/docs/guides/claude-code-vs-akm-workflows.md +0 -29
- package/docs/guides/knowledge-management.md +0 -18
- package/docs/maintainers/curate-workmap.md +0 -335
- package/docs/migration/v0.5-to-v0.6.md +0 -759
- package/docs/migration/v0.7-to-v0.8.md +0 -1378
- package/docs/plans/0.9.2-agent-command-workflow-plan.md +0 -423
|
@@ -2,31 +2,22 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
|
-
* `deriveInstallations
|
|
5
|
+
* `deriveInstallations`.
|
|
6
6
|
*
|
|
7
7
|
* Bridges the `SearchSource[]` model (the live indexer's source list,
|
|
8
8
|
* `search-source.ts`) onto the durable `BundleInstallation[]` /
|
|
9
|
-
* `BundleComponent[]` model
|
|
9
|
+
* `BundleComponent[]` model. Called from the indexer
|
|
10
10
|
* (provenance derivation), the proposal repository, and written-asset
|
|
11
|
-
* indexing.
|
|
12
|
-
* swap was superseded by the narrower Chunk-5 F4a drain-dir engine swap; the
|
|
13
|
-
* shadow-parity scaffolding module (`scan/scan-installations.ts`) was deleted
|
|
14
|
-
* as dead in the 0.9.0 close-out.
|
|
11
|
+
* indexing.
|
|
15
12
|
*
|
|
16
13
|
* Per source → one installation:
|
|
17
14
|
* - `id` = `source.registryId` ?? a deterministic slug of `source.path`
|
|
18
|
-
* (the `<bundle>` prefix of every ref this installation emits
|
|
19
|
-
*
|
|
15
|
+
* (the `<bundle>` prefix of every ref this installation emits).
|
|
16
|
+
* Slugs are made unique WITHIN a derivation batch
|
|
20
17
|
* by appending a short path-hash suffix on collision, so two
|
|
21
18
|
* sources sharing a basename never mint the same bundle id.
|
|
22
|
-
* - `trusted` = `source.writable === true`. 0.9.0 ships no first-class trust
|
|
23
|
-
* record (spec §1.3 — "no new trust machinery"); the writable
|
|
24
|
-
* primary/config stashes are the user's own and count as
|
|
25
|
-
* trusted, read-only registry caches do not. Nothing consumes
|
|
26
|
-
* `trusted` in the live path yet (installation grants nothing,
|
|
27
|
-
* History D8) — this is the Tier-A placeholder mapping.
|
|
28
19
|
* - components = ONE component for the current single-root akm layout
|
|
29
|
-
*
|
|
20
|
+
* `{ id, root: source.path, adapter }`. The
|
|
30
21
|
* akm layout's type dirs (`knowledge/`, `skills/`, …) are NOT
|
|
31
22
|
* separate components — they are type-derived leading path
|
|
32
23
|
* segments of the conceptId within the one component.
|
|
@@ -42,11 +33,11 @@
|
|
|
42
33
|
* from the installation) is a downstream contract refinement — nothing in the
|
|
43
34
|
* live path reads `IndexDocument.component` as distinct from `bundle` today.
|
|
44
35
|
*
|
|
45
|
-
* ── Adapter selection (
|
|
36
|
+
* ── Adapter selection (ordered probe) ──
|
|
46
37
|
*
|
|
47
38
|
* The adapter is chosen by the ordered `looksLikeRoot` probe over the built-in
|
|
48
39
|
* adapters (`getAdapters()`), first match wins. The registry is now a STATIC
|
|
49
|
-
* FROZEN map
|
|
40
|
+
* FROZEN map populated at module load, so this probe runs in
|
|
50
41
|
* production with the full 11-family set — no registration call is required
|
|
51
42
|
* first. Array order (`BUILTIN_ADAPTERS`) is the probe precedence, most-specific
|
|
52
43
|
* first, so a `.claude`/dotenv/wiki root is claimed by its tight probe before
|
|
@@ -56,17 +47,17 @@
|
|
|
56
47
|
* fallback is **`akm`** (see {@link FALLBACK_ADAPTER_ID}), preserving workspace
|
|
57
48
|
* root behavior. Explicit configured ownership always wins over probing.
|
|
58
49
|
*/
|
|
59
|
-
import { isSourceWriteActivated } from "../core/activation-policy.js";
|
|
60
50
|
import { detectAdapterId } from "../core/adapter/detect-adapter.js";
|
|
61
51
|
import { stashDirFor } from "../core/asset/asset-placement.js";
|
|
62
52
|
import { deriveBundleId, deriveBundleIds, slugForPath } from "../core/bundle-id.js";
|
|
53
|
+
import { isSourceWriteActivated } from "../core/write-source.js";
|
|
63
54
|
export { deriveBundleId, deriveBundleIds, slugForPath };
|
|
64
55
|
/**
|
|
65
56
|
* The no-probe-match fallback adapter id.
|
|
66
57
|
*
|
|
67
|
-
* The status-quo-preserving default
|
|
58
|
+
* The status-quo-preserving default:
|
|
68
59
|
*
|
|
69
|
-
* - Behavior discipline
|
|
60
|
+
* - Behavior discipline: the AKM workspace root's own indexing
|
|
70
61
|
* MUST stay classified `akm`. In this transitional model there is no
|
|
71
62
|
* depends on either explicit adapter configuration, `akm.looksLikeRoot`
|
|
72
63
|
* firing (type dirs / `.stash` present), or this fallback. A genuinely empty
|
|
@@ -78,7 +69,7 @@ export { deriveBundleId, deriveBundleIds, slugForPath };
|
|
|
78
69
|
const FALLBACK_ADAPTER_ID = "akm";
|
|
79
70
|
/**
|
|
80
71
|
* Resolve the adapter id for a component root via the ordered `looksLikeRoot`
|
|
81
|
-
* probe
|
|
72
|
+
* probe, first match wins; falls back to `akm` when no probe fires.
|
|
82
73
|
*/
|
|
83
74
|
export { detectAdapterId } from "../core/adapter/detect-adapter.js";
|
|
84
75
|
/**
|
|
@@ -98,7 +89,6 @@ export function deriveInstallations(sources) {
|
|
|
98
89
|
const adapter = source.adapterId ?? detectAdapterId(source.path, FALLBACK_ADAPTER_ID);
|
|
99
90
|
installations.push({
|
|
100
91
|
id,
|
|
101
|
-
trusted: writable,
|
|
102
92
|
components: [
|
|
103
93
|
{
|
|
104
94
|
// Single-component akm layout: the component id == the bundle id so
|
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
|
+
import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
|
|
6
7
|
import { adapterForId } from "../../core/adapter/registry.js";
|
|
7
|
-
import { compareCodePoints, hasErrnoCode
|
|
8
|
+
import { compareCodePoints, hasErrnoCode } from "../../core/common.js";
|
|
8
9
|
import { ConfigError, UsageError } from "../../core/errors.js";
|
|
9
10
|
import { canonicalizeWorkflowName } from "../../core/recognition-util.js";
|
|
11
|
+
import { sensitiveMarkerPath } from "../../core/sensitive-marker-path.js";
|
|
10
12
|
import { warnOnce } from "../../core/warn.js";
|
|
11
13
|
import { resolveUniqueWorkflowSource, workflowNameForConceptId, } from "../../workflows/source-files.js";
|
|
14
|
+
import { deriveInstallations } from "../installations.js";
|
|
12
15
|
import { buildFileContext } from "../walk/file-context.js";
|
|
13
16
|
const CONTENT_READ_REQUIRED = Symbol("adapter ownership probe requires content");
|
|
14
17
|
export class AdapterConceptOwnershipError extends UsageError {
|
|
@@ -40,22 +43,18 @@ function lexicallyWithin(candidate, root) {
|
|
|
40
43
|
return relative === "" || (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative));
|
|
41
44
|
}
|
|
42
45
|
/** Add case-only suffix spellings beside an adapter-authored read candidate. */
|
|
43
|
-
function candidateSpellings(candidate, sourcePath
|
|
46
|
+
function candidateSpellings(candidate, sourcePath) {
|
|
44
47
|
const authored = path.resolve(candidate.path);
|
|
45
48
|
if (!lexicallyWithin(authored, sourcePath))
|
|
46
49
|
return [{ ...candidate, path: authored }];
|
|
47
50
|
const parent = path.dirname(authored);
|
|
48
|
-
let realParent;
|
|
49
51
|
let entries;
|
|
50
52
|
try {
|
|
51
|
-
realParent = fs.realpathSync(parent);
|
|
52
53
|
entries = fs.readdirSync(parent, { withFileTypes: true });
|
|
53
54
|
}
|
|
54
55
|
catch {
|
|
55
56
|
return [{ ...candidate, path: authored }];
|
|
56
57
|
}
|
|
57
|
-
if (!isWithin(realParent, realRoot))
|
|
58
|
-
return [{ ...candidate, path: authored }];
|
|
59
58
|
const extension = path.extname(authored);
|
|
60
59
|
if (!extension)
|
|
61
60
|
return [{ ...candidate, path: authored }];
|
|
@@ -67,7 +66,7 @@ function candidateSpellings(candidate, sourcePath, realRoot) {
|
|
|
67
66
|
})
|
|
68
67
|
.map((entry) => ({ ...candidate, path: path.join(parent, entry.name) }));
|
|
69
68
|
}
|
|
70
|
-
function inspectCandidate(sourcePath,
|
|
69
|
+
function inspectCandidate(sourcePath, adapterId, candidate) {
|
|
71
70
|
const authoredPath = path.resolve(candidate.path);
|
|
72
71
|
if (!lexicallyWithin(authoredPath, sourcePath))
|
|
73
72
|
return undefined;
|
|
@@ -87,8 +86,6 @@ function inspectCandidate(sourcePath, realRoot, adapterId, candidate) {
|
|
|
87
86
|
catch {
|
|
88
87
|
return undefined;
|
|
89
88
|
}
|
|
90
|
-
if (!isWithin(realPath, realRoot))
|
|
91
|
-
return undefined;
|
|
92
89
|
try {
|
|
93
90
|
if (!fs.statSync(realPath).isFile())
|
|
94
91
|
return undefined;
|
|
@@ -118,6 +115,14 @@ function claimsWithoutContent(adapter, component, owner) {
|
|
|
118
115
|
throw error;
|
|
119
116
|
}
|
|
120
117
|
}
|
|
118
|
+
/** True for an env/secret file that a sibling `.sensitive` marker hides from the index. */
|
|
119
|
+
function isMarkedSensitive(owner) {
|
|
120
|
+
const head = owner.conceptId.split("/")[0];
|
|
121
|
+
if (head !== "env" && head !== "secrets")
|
|
122
|
+
return false;
|
|
123
|
+
const marker = sensitiveMarkerPath(owner.path, head === "env" ? "env" : "secret");
|
|
124
|
+
return marker !== owner.path && fs.existsSync(marker);
|
|
125
|
+
}
|
|
121
126
|
/**
|
|
122
127
|
* Resolve one adapter/component's exact physical concept owner without reading
|
|
123
128
|
* authored bytes. Native workflow arbitration is reused verbatim; every other
|
|
@@ -129,9 +134,8 @@ export function resolveAdapterConceptOwner(sourcePath, adapterId, conceptId, opt
|
|
|
129
134
|
const normalized = normalizedConceptId(conceptId);
|
|
130
135
|
if (!adapter || !normalized)
|
|
131
136
|
return undefined;
|
|
132
|
-
let realRoot;
|
|
133
137
|
try {
|
|
134
|
-
|
|
138
|
+
fs.realpathSync(sourcePath);
|
|
135
139
|
}
|
|
136
140
|
catch (error) {
|
|
137
141
|
// Genuinely absent — "no owner" is correct. Any other failure (e.g.
|
|
@@ -168,13 +172,13 @@ export function resolveAdapterConceptOwner(sourcePath, adapterId, conceptId, opt
|
|
|
168
172
|
// — see each adapter's own doc comment for its candidate classes), and
|
|
169
173
|
// `candidateSpellings` adds case-only siblings via one `readdirSync` of
|
|
170
174
|
// each candidate's own parent directory.
|
|
171
|
-
const spellings = (adapter.readCandidates?.(component, resolutionConceptId) ?? []).flatMap((candidate) => candidateSpellings(candidate, sourcePath
|
|
175
|
+
const spellings = (adapter.readCandidates?.(component, resolutionConceptId) ?? []).flatMap((candidate) => candidateSpellings(candidate, sourcePath));
|
|
172
176
|
const inspected = [
|
|
173
177
|
...new Map(spellings.map((candidate) => [`${path.resolve(candidate.path)}\0${candidate.conceptId}`, candidate])).values(),
|
|
174
178
|
]
|
|
175
179
|
.sort((left, right) => compareCodePoints(left.path, right.path))
|
|
176
180
|
.flatMap((candidate) => {
|
|
177
|
-
const owner = inspectCandidate(sourcePath,
|
|
181
|
+
const owner = inspectCandidate(sourcePath, adapterId, candidate);
|
|
178
182
|
return owner ? [owner] : [];
|
|
179
183
|
});
|
|
180
184
|
for (const candidate of inspected) {
|
|
@@ -183,8 +187,10 @@ export function resolveAdapterConceptOwner(sourcePath, adapterId, conceptId, opt
|
|
|
183
187
|
const identity = `${path.resolve(candidate.path)}\0${candidate.conceptId}`;
|
|
184
188
|
if (ownersByIdentity.has(identity))
|
|
185
189
|
continue;
|
|
186
|
-
if (claimsWithoutContent(adapter, component, candidate)
|
|
190
|
+
if (claimsWithoutContent(adapter, component, candidate) ||
|
|
191
|
+
(options?.includeSensitive && isMarkedSensitive(candidate))) {
|
|
187
192
|
ownersByIdentity.set(identity, candidate);
|
|
193
|
+
}
|
|
188
194
|
}
|
|
189
195
|
const owners = [...ownersByIdentity.values()]
|
|
190
196
|
.filter((owner) => owner.conceptId === resolutionConceptId)
|
|
@@ -202,6 +208,26 @@ export function resolveAdapterConceptOwner(sourcePath, adapterId, conceptId, opt
|
|
|
202
208
|
}
|
|
203
209
|
return owners[0];
|
|
204
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* The one "where is asset X right now?" walk. `sources` is the ordered source
|
|
213
|
+
* list (`resolveSourceEntries`: default bundle first, then installation
|
|
214
|
+
* priority). The first source with a physical owner for the ref ends the
|
|
215
|
+
* walk; a qualified ref only considers its own bundle. Synchronous and
|
|
216
|
+
* index-free: it never opens a database, so a caller may use it at dispatch.
|
|
217
|
+
*/
|
|
218
|
+
export function resolveConceptOwner(ref, sources, options) {
|
|
219
|
+
const installations = deriveInstallations([...sources]);
|
|
220
|
+
for (const [index, source] of sources.entries()) {
|
|
221
|
+
const bundleId = installations[index]?.id;
|
|
222
|
+
if (!bundleId || (ref.bundle !== undefined && bundleId !== ref.bundle))
|
|
223
|
+
continue;
|
|
224
|
+
const adapterId = source.adapterId ?? detectAdapterId(source.path);
|
|
225
|
+
const owner = resolveAdapterConceptOwner(source.path, adapterId, ref.conceptId, options);
|
|
226
|
+
if (owner)
|
|
227
|
+
return { owner, source, bundleId, adapterId };
|
|
228
|
+
}
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
205
231
|
export function indexedPathMatchesOwner(indexedPath, owner) {
|
|
206
232
|
if (path.resolve(indexedPath) !== path.resolve(owner.path))
|
|
207
233
|
return false;
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { getConfigPath } from "../core/paths.js";
|
|
5
|
+
import { redactUrlCredentials } from "../core/redaction.js";
|
|
5
6
|
import { isVerbose, warn, warnVerbose } from "../core/warn.js";
|
|
6
7
|
import { embedBatch } from "../llm/embedder.js";
|
|
8
|
+
import { effectiveEmbedding } from "../llm/embedders/connection.js";
|
|
7
9
|
import { DETERMINISTIC_EMBED_MODEL_ID, isDeterministicEmbedEnabled } from "../llm/embedders/deterministic.js";
|
|
8
|
-
import { DEFAULT_LOCAL_MODEL } from "../llm/embedders/local.js";
|
|
10
|
+
import { DEFAULT_LOCAL_MODEL, LocalRuntimeUnavailableError } from "../llm/embedders/local.js";
|
|
9
11
|
import { applyEmbeddingTemplate, documentTemplateFingerprint, resolveEmbeddingProfile } from "../llm/embedders/profile.js";
|
|
10
12
|
import { capEmbeddingText, DEFAULT_MAX_INPUT_TOKENS, describeEmbeddingCredential, estimateTokenCount, hasRemoteEndpoint, normalizeEmbeddingEndpoint, } from "../llm/embedders/remote.js";
|
|
11
13
|
import { getEmbeddableEntryCount } from "../storage/repositories/index-entries-repository.js";
|
|
@@ -80,27 +82,28 @@ export async function generateEmbeddingsForDb(db, config, onProgress, signal, en
|
|
|
80
82
|
onProgress({ phase: "embeddings", message: "Semantic search disabled; skipping embeddings." });
|
|
81
83
|
return { success: false, message: "Semantic search is disabled." };
|
|
82
84
|
}
|
|
85
|
+
const embedding = effectiveEmbedding(config);
|
|
83
86
|
// #953 field gap: the actionable outcome is a self-diagnosing run, not a
|
|
84
|
-
// fix (every RemoteEmbedder path
|
|
85
|
-
//
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
if (hasRemoteEndpoint(
|
|
90
|
-
const endpoint = normalizeEmbeddingEndpoint(
|
|
91
|
-
const credential = describeEmbeddingCredential(
|
|
87
|
+
// fix (every RemoteEmbedder path resolves its key through one boundary — a
|
|
88
|
+
// keyless request can only mean no key was configured in the config THIS run
|
|
89
|
+
// loaded). One default-level line, before the first provider request of the
|
|
90
|
+
// phase, naming the endpoint/model/credential SOURCE — never the credential
|
|
91
|
+
// value.
|
|
92
|
+
if (embedding && hasRemoteEndpoint(embedding)) {
|
|
93
|
+
const endpoint = redactUrlCredentials(normalizeEmbeddingEndpoint(embedding.endpoint ?? ""));
|
|
94
|
+
const credential = describeEmbeddingCredential(embedding);
|
|
92
95
|
const configFileSuffix = isVerbose() ? `; config: ${getConfigPath()}` : "";
|
|
93
96
|
onProgress({
|
|
94
97
|
phase: "embeddings",
|
|
95
|
-
message: `[embed] endpoint ${endpoint}, model ${
|
|
98
|
+
message: `[embed] endpoint ${endpoint}, model ${embedding.model ?? "unknown"}; credential: ${credential}${configFileSuffix}`,
|
|
96
99
|
});
|
|
97
100
|
}
|
|
98
|
-
const model = deriveSemanticProviderFingerprint(
|
|
101
|
+
const model = deriveSemanticProviderFingerprint(embedding);
|
|
99
102
|
const storedModel = getMeta(db, "embeddingFingerprint");
|
|
100
103
|
let targetEntryIds = entryIds;
|
|
101
104
|
/** Set only when every entry is (re)embedded, so the up-front "Re-embedding N entries" line names why. */
|
|
102
105
|
let rebuildReason;
|
|
103
|
-
const maxInputTokens =
|
|
106
|
+
const maxInputTokens = embedding?.maxInputTokens ?? DEFAULT_MAX_INPUT_TOKENS;
|
|
104
107
|
if (opts?.forceReembed) {
|
|
105
108
|
// The explicit operator override: purge and re-embed everything. The model
|
|
106
109
|
// is recorded in the SAME transaction as the purge, before any embedding
|
|
@@ -144,7 +147,7 @@ export async function generateEmbeddingsForDb(db, config, onProgress, signal, en
|
|
|
144
147
|
let truncatedCount = 0;
|
|
145
148
|
const texts = [];
|
|
146
149
|
const pendingEntries = [];
|
|
147
|
-
const { documentTemplate } = resolveEmbeddingProfile(
|
|
150
|
+
const { documentTemplate } = resolveEmbeddingProfile(embedding);
|
|
148
151
|
for (const entry of candidateEntries) {
|
|
149
152
|
const capped = capEmbeddingText(entry.searchText, maxInputTokens);
|
|
150
153
|
if (capped.text.length === 0)
|
|
@@ -240,7 +243,7 @@ export async function generateEmbeddingsForDb(db, config, onProgress, signal, en
|
|
|
240
243
|
// Whether the remote provider's endpoint/model/token language is
|
|
241
244
|
// meaningful for this run — the per-batch diagnostic line below is
|
|
242
245
|
// remote-only, same gate the credential diagnostic (#953) above uses.
|
|
243
|
-
const reportPerBatchLine = hasRemoteEndpoint(
|
|
246
|
+
const reportPerBatchLine = embedding !== undefined && hasRemoteEndpoint(embedding);
|
|
244
247
|
const onBatch = (indices, batchEmbeddings, outcome) => {
|
|
245
248
|
// #954 field-report follow-up: a "retrying" event carries nothing to
|
|
246
249
|
// commit — the request hasn't settled yet — only the notice that a
|
|
@@ -331,7 +334,7 @@ export async function generateEmbeddingsForDb(db, config, onProgress, signal, en
|
|
|
331
334
|
message: `Embedded ${storedCount}/${pendingEntries.length} entries.`,
|
|
332
335
|
});
|
|
333
336
|
};
|
|
334
|
-
await embedBatch(texts,
|
|
337
|
+
await embedBatch(texts, embedding, signal, onSkip, onBatch);
|
|
335
338
|
throwIfAborted(signal);
|
|
336
339
|
const elapsedSeconds = Math.max((Date.now() - embedStart) / 1000, 0.001);
|
|
337
340
|
if (skippedCount > 0) {
|
|
@@ -429,6 +432,7 @@ export async function generateEmbeddingsForDb(db, config, onProgress, signal, en
|
|
|
429
432
|
return {
|
|
430
433
|
success: false,
|
|
431
434
|
message: `Semantic search verification failed: ${message}`,
|
|
435
|
+
...(error instanceof LocalRuntimeUnavailableError ? { runtimeUnavailable: error.kind } : {}),
|
|
432
436
|
};
|
|
433
437
|
}
|
|
434
438
|
}
|
|
@@ -442,7 +446,7 @@ export function publishTargetedEmbeddingMeta(db, config) {
|
|
|
442
446
|
return;
|
|
443
447
|
}
|
|
444
448
|
const entryCount = getEmbeddableEntryCount(db);
|
|
445
|
-
const embeddingCount = getEmbeddingCount(db, deriveSemanticProviderFingerprint(config
|
|
449
|
+
const embeddingCount = getEmbeddingCount(db, deriveSemanticProviderFingerprint(effectiveEmbedding(config)));
|
|
446
450
|
const ready = entryCount > 0 && embeddingCount >= entryCount;
|
|
447
451
|
setMeta(db, "hasEmbeddings", ready ? "1" : "0");
|
|
448
452
|
}
|
|
@@ -18,15 +18,10 @@
|
|
|
18
18
|
* with `inferenceProcessed: true`. A subsequent `akm index` therefore skips
|
|
19
19
|
* the parent without re-running the LLM.
|
|
20
20
|
*
|
|
21
|
-
* Disabling —
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* profile shape.
|
|
26
|
-
* 2. `index.memory.llm = false` (or no resolvable LLM profile) opts the
|
|
27
|
-
* pass out at the per-pass layer (#208).
|
|
28
|
-
* A pass runs iff both layers allow it. Existing inferred children are
|
|
29
|
-
* NEVER deleted — the user keeps what was already produced.
|
|
21
|
+
* Disabling — one gate: `index.memory.enabled = false` (or no resolvable
|
|
22
|
+
* connection or harness) leaves the pass with no runner, and no model call is
|
|
23
|
+
* made (#208). Existing inferred children are NEVER deleted — the user keeps
|
|
24
|
+
* what was already produced.
|
|
30
25
|
*
|
|
31
26
|
* Scope sync: on every run, an existing derived child (`<name>.derived.md`,
|
|
32
27
|
* `inferred: true`, `derivedFrom` naming its parent) whose normalized scope
|
|
@@ -55,9 +50,7 @@ import { ConfigError } from "../../core/errors.js";
|
|
|
55
50
|
import { warn } from "../../core/warn.js";
|
|
56
51
|
import { beginWriteProvenance, recordWrittenPath } from "../../core/write-provenance.js";
|
|
57
52
|
import { writeAssetToSource } from "../../core/write-source.js";
|
|
58
|
-
import {
|
|
59
|
-
import { assertRunnerCredentials } from "../../integrations/agent/runner-dispatch.js";
|
|
60
|
-
import { isProcessEnabled } from "../../llm/feature-gate.js";
|
|
53
|
+
import { noticeSet } from "../../execution/notices.js";
|
|
61
54
|
import { resolveIndexPassExecution } from "../../llm/index-passes.js";
|
|
62
55
|
import * as memoryInfer from "../../llm/memory-infer.js";
|
|
63
56
|
import { computeBodyHash, getLlmCacheEntry } from "../../storage/repositories/index-llm-cache-repository.js";
|
|
@@ -125,7 +118,7 @@ function memoryExecutionForContext(ctx, config) {
|
|
|
125
118
|
}
|
|
126
119
|
async function inferPendingMemoryRecord(plan, ctx) {
|
|
127
120
|
const { record } = plan;
|
|
128
|
-
const {
|
|
121
|
+
const { signal, db, reEnrich, llmRunner, inferTelemetry, compressMemoryToDerivedMemory, onNotices, onConfigFailure } = ctx;
|
|
129
122
|
if (signal?.aborted || plan.kind === "aborted")
|
|
130
123
|
return { aborted: true };
|
|
131
124
|
// Existing children are complete, but the parent may be unmarked after a
|
|
@@ -154,7 +147,7 @@ async function inferPendingMemoryRecord(plan, ctx) {
|
|
|
154
147
|
const onRetryAttempt = () => {
|
|
155
148
|
retryAttempts += 1;
|
|
156
149
|
};
|
|
157
|
-
const infer = () => compressMemoryToDerivedMemory(llmRunner, record.effectiveInput, signal,
|
|
150
|
+
const infer = () => compressMemoryToDerivedMemory(llmRunner, record.effectiveInput, signal, inferTelemetry, onRetryAttempt, onNotices);
|
|
158
151
|
let derived = plan.kind === "cache-hit" ? plan.decision : undefined;
|
|
159
152
|
try {
|
|
160
153
|
if (plan.kind === "model") {
|
|
@@ -164,7 +157,7 @@ async function inferPendingMemoryRecord(plan, ctx) {
|
|
|
164
157
|
fromCache = true;
|
|
165
158
|
},
|
|
166
159
|
})
|
|
167
|
-
: await compressMemoryToDerivedMemory(llmRunner, record.effectiveInput, signal,
|
|
160
|
+
: await compressMemoryToDerivedMemory(llmRunner, record.effectiveInput, signal, inferTelemetry, onRetryAttempt, onNotices);
|
|
168
161
|
}
|
|
169
162
|
}
|
|
170
163
|
catch (error) {
|
|
@@ -230,7 +223,6 @@ export async function runMemoryInferencePass(ctx) {
|
|
|
230
223
|
}
|
|
231
224
|
async function runMemoryInferencePassBody(ctx, provenance) {
|
|
232
225
|
const { config, sources, signal, db, reEnrich, onProgress, options = {} } = ctx;
|
|
233
|
-
const invocationOwnsRunner = Object.hasOwn(ctx, "llmRunner");
|
|
234
226
|
const compressMemoryToDerivedMemory = options.compressMemoryToDerivedMemory ?? memoryInfer.compressMemoryToDerivedMemory;
|
|
235
227
|
const result = {
|
|
236
228
|
considered: 0,
|
|
@@ -248,36 +240,23 @@ async function runMemoryInferencePassBody(ctx, provenance) {
|
|
|
248
240
|
writtenPaths: [],
|
|
249
241
|
};
|
|
250
242
|
// Mutable sink threaded into compressMemoryToDerivedMemory so the per-call
|
|
251
|
-
// HTML-error categorization (which is otherwise
|
|
252
|
-
//
|
|
243
|
+
// HTML-error categorization (which is otherwise logged and dropped as a
|
|
244
|
+
// skipped memory) bubbles up into the pass result.
|
|
253
245
|
const inferTelemetry = {};
|
|
254
|
-
const
|
|
255
|
-
const onNotices = (notices) => {
|
|
256
|
-
for (const notice of notices)
|
|
257
|
-
noticesByKey.set(JSON.stringify(notice), notice);
|
|
258
|
-
};
|
|
246
|
+
const notices = noticeSet();
|
|
259
247
|
const completeResult = () => {
|
|
260
|
-
|
|
261
|
-
result.notices = Object.freeze([...noticesByKey.values()]);
|
|
248
|
+
Object.assign(result, notices.fields());
|
|
262
249
|
// Non-destructive read — the wrapper's `finally` owns closing the journal.
|
|
263
250
|
result.writtenPaths = provenance.writtenPaths();
|
|
264
251
|
return result;
|
|
265
252
|
};
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
// enabled when the key is absent.
|
|
269
|
-
if (!invocationOwnsRunner && !isProcessEnabled("index", "memory_inference", config))
|
|
270
|
-
return completeResult();
|
|
271
|
-
// Gate 2 — per-pass opt-out (#208). Returns the resolved llm config or
|
|
272
|
-
// `undefined` when the pass should not run.
|
|
253
|
+
// The one gate — per-pass opt-out (#208): no runner when `index.memory.enabled` is false or nothing is
|
|
254
|
+
// configured. A caller that owns the runner has decided to run.
|
|
273
255
|
const execution = memoryExecutionForContext(ctx, config);
|
|
274
|
-
|
|
256
|
+
notices.add(execution.notices);
|
|
275
257
|
const llmRunner = execution.runner;
|
|
276
258
|
if (!llmRunner)
|
|
277
259
|
return completeResult();
|
|
278
|
-
const featureConfig = invocationOwnsRunner
|
|
279
|
-
? { ...config, index: { ...config.index, memory: { ...config.index?.memory, enabled: true } } }
|
|
280
|
-
: config;
|
|
281
260
|
// The pass only writes to the default (working) stash, found by its
|
|
282
261
|
// `isDefault` flag and never by array position. Read-only caches (git, npm,
|
|
283
262
|
// website) are deliberately untouched — writing inferred children there
|
|
@@ -302,34 +281,26 @@ async function runMemoryInferencePassBody(ctx, provenance) {
|
|
|
302
281
|
result.considered = pending.length;
|
|
303
282
|
if (pending.length === 0)
|
|
304
283
|
return completeResult();
|
|
305
|
-
// Classify the whole batch without mutation.
|
|
306
|
-
// materialized only when at least one record will actually dispatch; this
|
|
307
|
-
// keeps aborted, existing-child, and validated-cache-only batches available
|
|
308
|
-
// offline while preserving all-or-nothing preflight for mixed batches.
|
|
284
|
+
// Classify the whole batch without mutation.
|
|
309
285
|
const plans = pending.map((record) => planPendingMemoryRecord(record, { signal, db, reEnrich }));
|
|
310
|
-
if (plans.some((plan) => plan.kind === "model"))
|
|
311
|
-
assertRunnerCredentials(llmRunner);
|
|
312
286
|
let processed = 0;
|
|
313
287
|
const total = pending.length;
|
|
314
288
|
onProgress?.({ processed, total, writtenFacts: 0, noChange: 0, skippedNoFacts: 0 });
|
|
315
289
|
let configFailure;
|
|
316
290
|
const perRecordResults = await concurrentMap(plans, (plan) => inferPendingMemoryRecord(plan, {
|
|
317
|
-
config,
|
|
318
|
-
featureConfig,
|
|
319
291
|
signal,
|
|
320
292
|
db,
|
|
321
293
|
reEnrich,
|
|
322
294
|
llmRunner,
|
|
323
295
|
inferTelemetry,
|
|
324
296
|
compressMemoryToDerivedMemory,
|
|
325
|
-
onNotices,
|
|
297
|
+
onNotices: notices.add,
|
|
326
298
|
onConfigFailure: (error) => {
|
|
327
299
|
configFailure ??= error;
|
|
328
300
|
},
|
|
329
301
|
}),
|
|
330
|
-
//
|
|
331
|
-
|
|
332
|
-
runnerLlmConnection(llmRunner)?.concurrency ?? 1);
|
|
302
|
+
// The connection's own `concurrency` when it sets one, else 1.
|
|
303
|
+
(llmRunner.kind === "connection" ? llmRunner.concurrency : undefined) ?? 1);
|
|
333
304
|
if (configFailure)
|
|
334
305
|
throw configFailure;
|
|
335
306
|
for (let i = 0; i < perRecordResults.length; i++) {
|
|
@@ -652,8 +623,8 @@ function markParentProcessed(parent) {
|
|
|
652
623
|
// Frontmatter-only rewrite of an existing asset: not a new asset write,
|
|
653
624
|
// so writeAssetToSource isn't a fit here (it would round-trip the body
|
|
654
625
|
// through the asset-spec rendering layer instead of preserving the
|
|
655
|
-
// user's original markdown bytes verbatim).
|
|
656
|
-
//
|
|
626
|
+
// user's original markdown bytes verbatim). This is the narrow exception
|
|
627
|
+
// to routing asset writes through writeAssetToSource.
|
|
657
628
|
let raw;
|
|
658
629
|
try {
|
|
659
630
|
raw = fs.readFileSync(parent.filePath, "utf8");
|
|
@@ -8,7 +8,7 @@ import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
|
8
8
|
import { asNonEmptyString } from "../../core/common.js";
|
|
9
9
|
import { isVerbose, warn } from "../../core/warn.js";
|
|
10
10
|
export const SCOPE_KEYS = ["user", "agent", "run", "channel"];
|
|
11
|
-
// ── Quality semantics
|
|
11
|
+
// ── Quality semantics ───────────────────────────────────────────────────────
|
|
12
12
|
/**
|
|
13
13
|
* Well-known quality values. `generated`, `curated`, and `enriched` are included in
|
|
14
14
|
* default search; `proposed` is excluded by default and opt-in via
|
|
@@ -28,7 +28,7 @@ export function normalizeQuality(raw) {
|
|
|
28
28
|
return raw;
|
|
29
29
|
if (!warnedUnknownQualityValues.has(raw)) {
|
|
30
30
|
warnedUnknownQualityValues.add(raw);
|
|
31
|
-
warn(`Warning: unknown quality value "${raw}" — entry remains searchable, but consider using "generated", "curated", or "proposed"
|
|
31
|
+
warn(`Warning: unknown quality value "${raw}" — entry remains searchable, but consider using "generated", "curated", or "proposed".`);
|
|
32
32
|
}
|
|
33
33
|
return raw;
|
|
34
34
|
}
|
|
@@ -41,7 +41,7 @@ export function _resetUnknownQualityWarnings() {
|
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* Returns true if an entry's quality marks it as "proposed". Proposed
|
|
44
|
-
* entries are excluded from default search
|
|
44
|
+
* entries are excluded from default search.
|
|
45
45
|
*/
|
|
46
46
|
export function isProposedQuality(quality) {
|
|
47
47
|
return quality === "proposed";
|
|
@@ -473,7 +473,7 @@ function isWikiRole(value) {
|
|
|
473
473
|
/**
|
|
474
474
|
* Parse one `verified:` family value into the `IndexDocument.provenance` shape.
|
|
475
475
|
* Accepts OKF v0.2's list form and its documented single-mapping shorthand
|
|
476
|
-
* ("consumers MUST treat a bare mapping as a one-element list",
|
|
476
|
+
* ("consumers MUST treat a bare mapping as a one-element list", per OKF v0.2).
|
|
477
477
|
* Tolerant: an entry without a usable `by` is dropped individually.
|
|
478
478
|
*/
|
|
479
479
|
function parseVerifiedFamily(value) {
|
|
@@ -823,7 +823,7 @@ function hasSessionMemoryMarker(fmData, body) {
|
|
|
823
823
|
* like a top-level `key:` mapping entry. Ordinary prose bracketed by two
|
|
824
824
|
* thematic-break `---` lines fails this test, so a decorative opening
|
|
825
825
|
* callout is treated as the paragraph it is instead of being discarded
|
|
826
|
-
* (
|
|
826
|
+
* (the block finder alone accepts ANY content up
|
|
827
827
|
* to an arbitrarily distant closing `---`).
|
|
828
828
|
*/
|
|
829
829
|
function isFrontmatterShaped(lines, block) {
|
|
@@ -52,7 +52,7 @@ export function indexDocumentToStashEntry(doc) {
|
|
|
52
52
|
// basename the old pipeline stored). Always present on a recognized doc.
|
|
53
53
|
filename: path.basename(doc.path ?? ""),
|
|
54
54
|
};
|
|
55
|
-
// ── First-class IndexDocument members
|
|
55
|
+
// ── First-class IndexDocument members ──
|
|
56
56
|
if (doc.description !== undefined)
|
|
57
57
|
entry.description = doc.description;
|
|
58
58
|
if (doc.tags !== undefined)
|
|
@@ -2,16 +2,14 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
|
-
* Per-directory document drain
|
|
6
|
-
*
|
|
7
|
-
* `IndexDocument`
|
|
8
|
-
* stream, reconstructing the durable `IndexDocument` via {@link
|
|
9
|
-
* indexDocumentToStashEntry} (proven lossless by the shadow-parity gate).
|
|
5
|
+
* Per-directory document drain: turns the `akm` adapter's `recognize`
|
|
6
|
+
* `IndexDocument` stream into durable entries, reconstructing the durable
|
|
7
|
+
* `IndexDocument` via {@link indexDocumentToStashEntry}.
|
|
10
8
|
*
|
|
11
9
|
* Two behaviors the adapter fold does NOT carry, restored here at the drain
|
|
12
|
-
* layer
|
|
10
|
+
* layer:
|
|
13
11
|
*
|
|
14
|
-
* - **Broken-workflow drop
|
|
12
|
+
* - **Broken-workflow drop.** The live path dropped a broken workflow
|
|
15
13
|
* via the renderer contributor's throw → metadata-pass skip-with-warning; the
|
|
16
14
|
* `akm` adapter's synchronous `foldRecognizedMetadata` SWALLOWS the parse
|
|
17
15
|
* error, so a broken workflow would otherwise silently index. We run the
|
|
@@ -20,7 +18,7 @@
|
|
|
20
18
|
* ({@link buildMetadataSkipWarning}), so the workflow-skip summary counts it.
|
|
21
19
|
*
|
|
22
20
|
* `doc.hash` (= sha256 of the file content) is surfaced per recognized file so
|
|
23
|
-
* the persist layer can populate the `content_hash` column
|
|
21
|
+
* the persist layer can populate the `content_hash` column. It is keyed
|
|
24
22
|
* by the file's absolute path rather than by the entry object.
|
|
25
23
|
*
|
|
26
24
|
* Pure of DB/global state; a new leaf (nothing imports it back), so it joins no
|
|
@@ -98,7 +96,7 @@ export function drainDirDocuments(adapter, component, fileContexts) {
|
|
|
98
96
|
const entry = indexDocumentToStashEntry(doc);
|
|
99
97
|
// Workflow docs: drop-with-warning if broken; otherwise cache a lossless
|
|
100
98
|
// runtime projection when the current executor can represent the source.
|
|
101
|
-
const dropWarning = handleWorkflowDoc(doc, file
|
|
99
|
+
const dropWarning = handleWorkflowDoc(doc, file);
|
|
102
100
|
if (dropWarning !== null) {
|
|
103
101
|
warnings.push(dropWarning);
|
|
104
102
|
if (workflowName !== undefined)
|
|
@@ -138,13 +136,13 @@ export function recognizeStashEntries(stashRoot, files) {
|
|
|
138
136
|
* `Skipped workflow …` drop warning when it is broken, or return `null` when
|
|
139
137
|
* it compiles. Non-workflow docs return `null` immediately.
|
|
140
138
|
*/
|
|
141
|
-
function handleWorkflowDoc(doc, file
|
|
139
|
+
function handleWorkflowDoc(doc, file) {
|
|
142
140
|
if (doc.type !== "workflow" ||
|
|
143
141
|
(doc.adapterId !== "akm" && doc.adapterId !== "akm-workflow") ||
|
|
144
142
|
(docRenderer(doc) !== WORKFLOW_MD_RENDERER && doc.adapterId !== "akm-workflow")) {
|
|
145
143
|
return null;
|
|
146
144
|
}
|
|
147
|
-
const result = compileWorkflowSource(file.content(), { path: file.relPath
|
|
145
|
+
const result = compileWorkflowSource(file.content(), { path: file.relPath });
|
|
148
146
|
if (!result.ok)
|
|
149
147
|
return workflowDropWarning(file, result.errors);
|
|
150
148
|
return null;
|