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
package/dist/core/redaction.js
CHANGED
|
@@ -1,35 +1,6 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
const ENV_PASSTHROUGH_REDACTION_POLICY = {
|
|
5
|
-
HOME: "path",
|
|
6
|
-
PATH: "path",
|
|
7
|
-
USER: "identifier",
|
|
8
|
-
LANG: "identifier",
|
|
9
|
-
LC_ALL: "identifier",
|
|
10
|
-
TERM: "identifier",
|
|
11
|
-
TMPDIR: "path",
|
|
12
|
-
SYSTEMROOT: "path",
|
|
13
|
-
COMSPEC: "path",
|
|
14
|
-
PATHEXT: "path",
|
|
15
|
-
WINDIR: "path",
|
|
16
|
-
TEMP: "path",
|
|
17
|
-
TMP: "path",
|
|
18
|
-
AKM_EVENT_SOURCE: "identifier",
|
|
19
|
-
OPENCODE_CONFIG: "path",
|
|
20
|
-
CLAUDE_CONFIG: "path",
|
|
21
|
-
CODEX_CONFIG: "path",
|
|
22
|
-
XDG_CONFIG_HOME: "path",
|
|
23
|
-
XDG_DATA_HOME: "path",
|
|
24
|
-
XDG_CACHE_HOME: "path",
|
|
25
|
-
XDG_STATE_HOME: "path",
|
|
26
|
-
AWS_PROFILE: "identifier",
|
|
27
|
-
AWS_REGION: "identifier",
|
|
28
|
-
LLM_MODEL: "identifier",
|
|
29
|
-
LLM_BASE_URL: "url",
|
|
30
|
-
};
|
|
31
|
-
/** Environment names whose ordinary values identify runtime configuration rather than credentials. */
|
|
32
|
-
export const ENV_PASSTHROUGH_REDACTION_ALLOWLIST = new Set(Object.keys(ENV_PASSTHROUGH_REDACTION_POLICY));
|
|
33
4
|
const SIGNED_QUERY_KEYS = new Set([
|
|
34
5
|
"accesskey",
|
|
35
6
|
"accesskeyid",
|
|
@@ -190,6 +161,56 @@ function inspectCredentialBearingUrl(value, values) {
|
|
|
190
161
|
return found;
|
|
191
162
|
}
|
|
192
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Shortest value an INFERRED (name-heuristic) match may contribute as a
|
|
166
|
+
* redaction needle. Declared secrets bypass this entirely.
|
|
167
|
+
*
|
|
168
|
+
* Redaction replaces substrings, so a short needle is not merely useless — it
|
|
169
|
+
* corrupts unrelated output. Below 8 the noise tier is fully intact (`1`, `0`,
|
|
170
|
+
* `/`, `80`, `true`, `xhigh`, `31999`); at 8 a chance collision with ordinary
|
|
171
|
+
* log vocabulary is negligible, and every credential format in real use is far
|
|
172
|
+
* longer. It also matches the conventional minimum password length, so a
|
|
173
|
+
* secret shorter than this is already outside normal policy.
|
|
174
|
+
*/
|
|
175
|
+
export const MIN_INFERRED_SECRET_LENGTH = 8;
|
|
176
|
+
/**
|
|
177
|
+
* Environment names whose VALUE is treated as a credential on shape alone.
|
|
178
|
+
*
|
|
179
|
+
* The keyword must be a whole `_`-delimited word. Anchoring on only one side
|
|
180
|
+
* would drag in ordinary configuration from whichever side is left open:
|
|
181
|
+
* a leading anchor alone matches `KEYBOARD_LAYOUT` and `AUTHOR`, a trailing one
|
|
182
|
+
* matches `MONKEY` and `BYPASS`. Whole-word matching gets `GH_TOKEN`,
|
|
183
|
+
* `NPM_AUTH_TOKEN`, `MY_API_KEY`, `DB_PASS` and `AWS_SECRET_ACCESS_KEY` right.
|
|
184
|
+
*/
|
|
185
|
+
const INFERRED_SECRET_NAME = /(?:^|_)(?:API_?KEY|KEY|TOKEN|SECRET|PASSWORD|PASSWD|PASS|CREDENTIALS?|AUTH)(?:_|$)/i;
|
|
186
|
+
/**
|
|
187
|
+
* Credential variables whose name is a single glued word, which no
|
|
188
|
+
* word-boundary rule can see. Enumerated rather than matched: loosening the
|
|
189
|
+
* pattern enough to catch `PGPASSWORD` also catches `MONKEY`.
|
|
190
|
+
*
|
|
191
|
+
* `PWD` cannot be a keyword above for the same reason it appears here as part
|
|
192
|
+
* of `MYSQL_PWD` — on its own it is the working directory.
|
|
193
|
+
*/
|
|
194
|
+
const KNOWN_SECRET_NAMES = new Set(["PGPASSWORD", "MYSQL_PWD"]);
|
|
195
|
+
/** True when the NAME alone marks this variable as holding a credential. */
|
|
196
|
+
export function isInferredSecretName(name) {
|
|
197
|
+
return KNOWN_SECRET_NAMES.has(name.toUpperCase()) || INFERRED_SECRET_NAME.test(name);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* The values in `env` whose variable NAME marks them as credentials ({@link isInferredSecretName}), at or above
|
|
201
|
+
* {@link MIN_INFERRED_SECRET_LENGTH}. Every process akm starts inherits akm's environment, so a reply or a log that
|
|
202
|
+
* echoes one of these must be scrubbed of it; this is the one place that rule lives (task logs and dispatch replies).
|
|
203
|
+
*/
|
|
204
|
+
export function collectInferredSecretValues(env) {
|
|
205
|
+
const values = [];
|
|
206
|
+
for (const [name, value] of Object.entries(env)) {
|
|
207
|
+
if (value === undefined || value.length < MIN_INFERRED_SECRET_LENGTH)
|
|
208
|
+
continue;
|
|
209
|
+
if (isInferredSecretName(name))
|
|
210
|
+
values.push(value);
|
|
211
|
+
}
|
|
212
|
+
return values;
|
|
213
|
+
}
|
|
193
214
|
/** Collect exact secrets plus decoded values embedded in credential-bearing URLs. */
|
|
194
215
|
export function collectSensitiveValues(rawValues) {
|
|
195
216
|
const values = new Set();
|
|
@@ -203,29 +224,6 @@ export function collectSensitiveValues(rawValues) {
|
|
|
203
224
|
}
|
|
204
225
|
return [...values];
|
|
205
226
|
}
|
|
206
|
-
/**
|
|
207
|
-
* Decide whether an allowlisted passthrough value may cross an output boundary.
|
|
208
|
-
* The name allowlist never overrides value inspection: URL userinfo and signed
|
|
209
|
-
* query credentials remain secret even under ordinarily non-secret names.
|
|
210
|
-
*/
|
|
211
|
-
export function isEnvPassthroughValueSafeToExpose(name, value) {
|
|
212
|
-
if (value === undefined)
|
|
213
|
-
return true;
|
|
214
|
-
const policy = ENV_PASSTHROUGH_REDACTION_POLICY[name];
|
|
215
|
-
if (!policy)
|
|
216
|
-
return false;
|
|
217
|
-
const classifiedPolicy = policy;
|
|
218
|
-
switch (classifiedPolicy) {
|
|
219
|
-
case "identifier":
|
|
220
|
-
case "path":
|
|
221
|
-
case "url":
|
|
222
|
-
return !inspectCredentialBearingUrl(value);
|
|
223
|
-
default: {
|
|
224
|
-
const exhaustive = classifiedPolicy;
|
|
225
|
-
return exhaustive;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
227
|
function utf8SequenceLength(firstByte) {
|
|
230
228
|
if (firstByte <= 0x7f)
|
|
231
229
|
return 1;
|
|
@@ -499,10 +497,23 @@ export function redactErrorBody(input) {
|
|
|
499
497
|
}
|
|
500
498
|
return out;
|
|
501
499
|
}
|
|
500
|
+
/**
|
|
501
|
+
* The spellings a JSON encoder gives a value inside a string literal: the
|
|
502
|
+
* `JSON.stringify` form, and the ASCII-only form with non-ASCII as `\uXXXX`
|
|
503
|
+
* (what Python's `json.dumps` writes). Empty for a value that needs no escaping.
|
|
504
|
+
*/
|
|
505
|
+
function jsonEscapedSpellings(value) {
|
|
506
|
+
const json = JSON.stringify(value).slice(1, -1);
|
|
507
|
+
// ASCII-only encoders (Python's ensure_ascii) also escape DEL; some (Java's) write uppercase hex.
|
|
508
|
+
const ascii = json.replace(/[\u007f-\uffff]/g, (char) => `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
509
|
+
const upper = ascii.replace(/\\u([0-9a-f]{4})/g, (_match, hex) => `\\u${hex.toUpperCase()}`);
|
|
510
|
+
return [...new Set([json, ascii, upper])].filter((spelling) => spelling !== value);
|
|
511
|
+
}
|
|
502
512
|
export function redactSensitiveText(text, sensitiveValues) {
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
513
|
+
const exact = [...sensitiveValues].filter((value) => value.length > 0);
|
|
514
|
+
// A child that prints JSON writes a secret's escaped spelling (`\"`, `\\`, `\n`, `\uXXXX`),
|
|
515
|
+
// which the exact value never matches. Each escaped spelling is just another needle.
|
|
516
|
+
const values = [...new Set([...exact, ...exact.flatMap(jsonEscapedSpellings)])].sort((a, b) => b.length - a.length || a.localeCompare(b));
|
|
506
517
|
if (values.length === 0)
|
|
507
518
|
return text;
|
|
508
519
|
const coverageDelta = new Int32Array(text.length + 1);
|
|
@@ -569,3 +580,31 @@ export function redactSensitiveValue(value, sensitiveValues) {
|
|
|
569
580
|
};
|
|
570
581
|
return redact(value);
|
|
571
582
|
}
|
|
583
|
+
/** What stands in for a masked value where configuration is shown. */
|
|
584
|
+
export const REDACTED = "[redacted]";
|
|
585
|
+
/** Query parameters that carry a credential in a URL. */
|
|
586
|
+
const SECRET_QUERY_PARAM = /^(api[-_]?key|key|token|access[-_]?token|auth|password|secret|sig|signature)$/i;
|
|
587
|
+
/** `scheme://user:pass@host/?token=x` with the credentials masked. Anything that is not a URL is returned as is. */
|
|
588
|
+
export function redactUrlCredentials(value) {
|
|
589
|
+
if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(value))
|
|
590
|
+
return value;
|
|
591
|
+
try {
|
|
592
|
+
const url = new URL(value);
|
|
593
|
+
let changed = false;
|
|
594
|
+
if (url.username || url.password) {
|
|
595
|
+
url.username = "";
|
|
596
|
+
url.password = "";
|
|
597
|
+
changed = true;
|
|
598
|
+
}
|
|
599
|
+
for (const key of [...url.searchParams.keys()]) {
|
|
600
|
+
if (SECRET_QUERY_PARAM.test(key)) {
|
|
601
|
+
url.searchParams.set(key, REDACTED);
|
|
602
|
+
changed = true;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return changed ? url.toString() : value;
|
|
606
|
+
}
|
|
607
|
+
catch {
|
|
608
|
+
return value;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
* The one substitution token akm hands to a process or a provider: `${ref}`,
|
|
6
|
+
* where `ref` is an akm ref (`[bundle//]conceptId`). A `secrets/…` ref stands
|
|
7
|
+
* for the secret's value; any other asset ref stands for the asset's absolute
|
|
8
|
+
* path. A `${…}` body that is not an akm ref (`${HOME}`, `${PATH//:/ }`,
|
|
9
|
+
* `${v//-/_}`, `${x/a/b}`: not led by a native type and not qualified by an
|
|
10
|
+
* installed bundle) is plain text and is left alone.
|
|
11
|
+
*
|
|
12
|
+
* Kept free of the commands layer so config credentials and env values share
|
|
13
|
+
* this one function.
|
|
14
|
+
*/
|
|
15
|
+
import { parseBundleRef } from "./asset/asset-ref.js";
|
|
16
|
+
import { typeNameFromConceptId } from "./asset/resolve-ref.js";
|
|
17
|
+
export const REF_TOKEN_RE = /\$\{([^}\s]+)\}/g;
|
|
18
|
+
/**
|
|
19
|
+
* Does a `${…}` body parse as an akm ref (no export fragment) that either
|
|
20
|
+
* leads with a native asset type (bundle-qualified or not) or is bundle-qualified
|
|
21
|
+
* with a bundle `isBundleInstalled` accepts? Anything else stays text, so shell
|
|
22
|
+
* syntax (`${v//-/_}`, `${x/a/b}`) is never read as a ref. A qualified opaque body
|
|
23
|
+
* follows the core ref grammar and the owner walk, whatever adapter owns it, but
|
|
24
|
+
* only for an installed bundle; with no predicate no bundle is installed.
|
|
25
|
+
*/
|
|
26
|
+
function isRefBody(body, isBundleInstalled) {
|
|
27
|
+
try {
|
|
28
|
+
const ref = parseBundleRef(body);
|
|
29
|
+
if (ref.fragment !== undefined)
|
|
30
|
+
return false;
|
|
31
|
+
if (typeNameFromConceptId(ref.conceptId) !== undefined)
|
|
32
|
+
return true;
|
|
33
|
+
return ref.bundle !== undefined && isBundleInstalled?.(ref.bundle) === true;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Is the whole string exactly one `${ref}` token? */
|
|
40
|
+
export function isRefToken(value) {
|
|
41
|
+
const body = /^\$\{([^}\s]+)\}$/.exec(value)?.[1];
|
|
42
|
+
return body !== undefined && isRefBody(body);
|
|
43
|
+
}
|
|
44
|
+
/** Is the whole string exactly one `${ref}` token whose ref names a `secrets/` asset? */
|
|
45
|
+
export function isSecretRefToken(value) {
|
|
46
|
+
const body = /^\$\{([^}\s]+)\}$/.exec(value)?.[1];
|
|
47
|
+
return (body !== undefined && isRefBody(body) && typeNameFromConceptId(parseBundleRef(body).conceptId)?.type === "secret");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Replace every `${ref}` token in each value. Keys are never touched, and
|
|
51
|
+
* tokens embedded in larger strings are all substituted. `isBundleInstalled`
|
|
52
|
+
* lets a bundle-qualified body that is not led by a native type be a ref when
|
|
53
|
+
* its bundle is installed. An unresolved ref is
|
|
54
|
+
* collected in `missing` and its token left in place. Resolved secret values
|
|
55
|
+
* must never be logged or printed by callers.
|
|
56
|
+
*/
|
|
57
|
+
export function substituteRefTokens(values, resolve, isBundleInstalled) {
|
|
58
|
+
const missing = [];
|
|
59
|
+
const secretValues = new Set();
|
|
60
|
+
const cache = new Map();
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const [key, value] of Object.entries(values)) {
|
|
63
|
+
out[key] = value.replace(REF_TOKEN_RE, (token, body) => {
|
|
64
|
+
if (!isRefBody(body, isBundleInstalled))
|
|
65
|
+
return token;
|
|
66
|
+
if (!cache.has(body))
|
|
67
|
+
cache.set(body, resolve(body));
|
|
68
|
+
const resolved = cache.get(body);
|
|
69
|
+
if (resolved === undefined) {
|
|
70
|
+
if (!missing.includes(body))
|
|
71
|
+
missing.push(body);
|
|
72
|
+
return token;
|
|
73
|
+
}
|
|
74
|
+
if (resolved.kind === "path")
|
|
75
|
+
return resolved.path;
|
|
76
|
+
if (resolved.value)
|
|
77
|
+
secretValues.add(resolved.value);
|
|
78
|
+
return resolved.value;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return { values: out, missing, secretValues: [...secretValues] };
|
|
82
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
import fs from "node:fs";
|
|
5
|
+
/**
|
|
6
|
+
* Read a secret's value: the file content as UTF-8 with surrounding whitespace
|
|
7
|
+
* trimmed. The one read every consumer uses (`secret run`, env `${ref}`
|
|
8
|
+
* tokens, config credentials, website fetchers), so a hand-written file's
|
|
9
|
+
* trailing newline never lands in an HTTP header. Callers MUST NOT write the
|
|
10
|
+
* returned value to stdout or any log.
|
|
11
|
+
*/
|
|
12
|
+
export function readValue(secretPath) {
|
|
13
|
+
return fs.readFileSync(secretPath, "utf8").trim();
|
|
14
|
+
}
|
|
@@ -1037,17 +1037,16 @@ export const STATE_MIGRATIONS = [
|
|
|
1037
1037
|
ON workflow_run_unit_attempts(run_id, status, claim_expires_at);
|
|
1038
1038
|
`,
|
|
1039
1039
|
},
|
|
1040
|
-
// ── Migration 023 — child workflow run parentage
|
|
1040
|
+
// ── Migration 023 — child workflow run parentage ──────────────────────────
|
|
1041
1041
|
//
|
|
1042
1042
|
// Adds the columns and partial unique index `publishChildWorkflowRun`
|
|
1043
1043
|
// (src/storage/repositories/workflow-runs-repository.ts) needs to record a
|
|
1044
1044
|
// durable child workflow run under the parent unit that spawned it, and to
|
|
1045
|
-
// make that publication idempotent per invocation
|
|
1046
|
-
// (docs/plans/specs/p3a-plan-v5-child-freeze.md §5.1).
|
|
1045
|
+
// make that publication idempotent per invocation.
|
|
1047
1046
|
//
|
|
1048
1047
|
// Disambiguation: this migration's `workflow_runs.parent_unit_id` is the
|
|
1049
1048
|
// PARENT RUN's unit that spawned this CHILD RUN — a cross-run composition
|
|
1050
|
-
// edge
|
|
1049
|
+
// edge. It is NOT the same concept as the pre-existing
|
|
1051
1050
|
// `workflow_run_units.parent_unit_id` (migration 004, consolidated above
|
|
1052
1051
|
// into migration 020's `workflow_run_units` table, migrations.ts:934),
|
|
1053
1052
|
// which records MAP FAN-OUT TEMPLATE PARENTAGE — one expanded unit's row
|
|
@@ -1076,12 +1075,11 @@ export const STATE_MIGRATIONS = [
|
|
|
1076
1075
|
WHERE parent_run_id IS NOT NULL;
|
|
1077
1076
|
`,
|
|
1078
1077
|
},
|
|
1079
|
-
// ── Migration 024 — workflow run outputs
|
|
1078
|
+
// ── Migration 024 — workflow run outputs ───────────────────────────────────
|
|
1080
1079
|
//
|
|
1081
1080
|
// Adds workflow_runs.outputs_json — the resolved map of a plan's declared
|
|
1082
1081
|
// outputs:, persisted once at run completion in the SAME transaction as the
|
|
1083
|
-
// final step's completion (
|
|
1084
|
-
// B-N13). NULL for every run whose plan declares no outputs: (the
|
|
1082
|
+
// final step's completion. NULL for every run whose plan declares no outputs: (the
|
|
1085
1083
|
// overwhelming majority, including every run before this migration) and for
|
|
1086
1084
|
// every run that fails or blocks before completing — never `{}`.
|
|
1087
1085
|
// `WorkflowRunsRepository.setRunOutputs` is the only writer;
|
|
@@ -1092,28 +1090,25 @@ export const STATE_MIGRATIONS = [
|
|
|
1092
1090
|
ALTER TABLE workflow_runs ADD COLUMN outputs_json TEXT;
|
|
1093
1091
|
`,
|
|
1094
1092
|
},
|
|
1095
|
-
// ── Migration 025 — task_history
|
|
1096
|
-
//
|
|
1097
|
-
// The
|
|
1098
|
-
//
|
|
1099
|
-
//
|
|
1100
|
-
//
|
|
1101
|
-
//
|
|
1102
|
-
//
|
|
1103
|
-
//
|
|
1104
|
-
//
|
|
1105
|
-
// keeping "forever" — SUPERSEDED here: `task_history` is DB-owned data, the
|
|
1106
|
-
// remap is deterministic and total, so it belongs in a one-time migration,
|
|
1107
|
-
// not three permanently-recurring read-side shims.
|
|
1093
|
+
// ── Migration 025 — task_history result-vocabulary backfill ────────────────
|
|
1094
|
+
//
|
|
1095
|
+
// The written `target_kind` vocabulary was renamed and every new row is
|
|
1096
|
+
// marked `targetVocab: 2` in `metadata_json`, but every row written before
|
|
1097
|
+
// that stayed in the OLD vocabulary, which would push the "which generation
|
|
1098
|
+
// is this row" decision onto three separate read sites
|
|
1099
|
+
// (src/tasks/run/task-history.ts, src/commands/health/
|
|
1100
|
+
// improve-metrics.ts, src/commands/health/windows.ts). `task_history` is
|
|
1101
|
+
// DB-owned data and the remap is deterministic and total, so it is a
|
|
1102
|
+
// one-time migration, not three permanently-recurring read-side shims.
|
|
1108
1103
|
//
|
|
1109
1104
|
// The remap, applied only to rows with no `targetVocab` marker yet (a
|
|
1110
1105
|
// NULL/absent `$.targetVocab` in the JSON column — already-marked or
|
|
1111
1106
|
// malformed metadata_json is left untouched; malformed rows are a
|
|
1112
1107
|
// pre-existing, unrelated skip-and-warn concern at read time):
|
|
1113
1108
|
// - target_kind 'prompt' -> 'command' (the prepared command/agent-LLM
|
|
1114
|
-
// arm;
|
|
1109
|
+
// arm; its written label was renamed, this backfills the old one)
|
|
1115
1110
|
// - target_kind 'command' -> 'shell' (the legacy native shell/script
|
|
1116
|
-
// arm's shared old label;
|
|
1111
|
+
// arm's shared old label; it was split into 'shell'/'script', and only
|
|
1117
1112
|
// 'shell' is reconstructable — the old vocabulary never distinguished
|
|
1118
1113
|
// script from shell, matching the read mapping this migration retires)
|
|
1119
1114
|
// Only 'prompt' and legacy 'command' rows actually change meaning between
|
package/dist/core/structured.js
CHANGED
|
@@ -1,79 +1,13 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
/**
|
|
5
|
-
* `runStructured<T>()` — transport-free structured-output core (P0.5 seam).
|
|
6
|
-
*
|
|
7
|
-
* akm has two structured-output paths that share no code: the LLM HTTP path
|
|
8
|
-
* (`llm/structured-call.ts` + `responseSchema`) and the agent JSON path
|
|
9
|
-
* (`agent/spawn.ts` `parseOutput: "json"` — embedded-JSON scan, no schema,
|
|
10
|
-
* no retry). This module is the ONE validation-driven retry loop both are
|
|
11
|
-
* meant to converge on: the workflow engine's schema units compose it with a
|
|
12
|
-
* dispatch adapter per runner (llm = `chatCompletion` + `responseSchema`;
|
|
13
|
-
* agent/sdk = `runAgent`/`runOpencodeSdk` + prompt-injected schema;
|
|
14
|
-
* native-schema CLIs pass the schema through and still validate).
|
|
15
|
-
*
|
|
16
|
-
* Layering: this file lives in `core/` — NOT `llm/` — because the agent path
|
|
17
|
-
* must be able to reach it and `agent/ ⇏ llm/` is an enforced invariant
|
|
18
|
-
* (`tests/integration/architecture/agent-no-llm-sdk-guard.test.ts`). The transport is
|
|
19
|
-
* always injected; this module never performs IO of its own.
|
|
20
|
-
*
|
|
21
|
-
* Retry semantics: only parse/validation misses are retried (with corrective
|
|
22
|
-
* feedback appended to the re-dispatch). Transport errors PROPAGATE — the
|
|
23
|
-
* transports own their own retry discipline (`chatCompletion` has a bounded
|
|
24
|
-
* jittered retry; `runAgent` has timeout/abort semantics).
|
|
25
|
-
*/
|
|
26
|
-
import { parseEmbeddedJsonResponse } from "./parse.js";
|
|
27
4
|
/**
|
|
28
5
|
* Append the one structured-output instruction to a prompt. Agent lowering
|
|
29
|
-
* appends it to every schema-bearing request, alongside a
|
|
30
|
-
* channel where one exists (
|
|
6
|
+
* appends it to every schema-bearing request, alongside a transport's native
|
|
7
|
+
* channel where one exists (a chat's `response_format`); the workflow engine
|
|
31
8
|
* appends it for a direct-LLM unit. Resumed workflow runs depend on these
|
|
32
9
|
* exact bytes, so do not reword it.
|
|
33
10
|
*/
|
|
34
11
|
export function withSchemaInstruction(prompt, schema) {
|
|
35
12
|
return `${prompt}\n\nRespond with ONLY a JSON value matching this JSON Schema (no prose, no code fences):\n${JSON.stringify(schema)}`;
|
|
36
13
|
}
|
|
37
|
-
export function defaultFeedback(failure) {
|
|
38
|
-
if (failure.reason === "parse_error") {
|
|
39
|
-
return "Your previous response contained no parseable JSON. Respond with ONLY a JSON value that matches the requested schema — no prose, no code fences.";
|
|
40
|
-
}
|
|
41
|
-
return `Your previous JSON response failed validation:\n- ${failure.errors.join("\n- ")}\nRespond again with ONLY a corrected JSON value.`;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Run the dispatch→parse→validate loop, re-dispatching with corrective
|
|
45
|
-
* feedback on parse/validation misses, up to `maxAttempts` total attempts.
|
|
46
|
-
* Never throws for structure problems (returns a typed failure); transport
|
|
47
|
-
* throws propagate untouched.
|
|
48
|
-
*/
|
|
49
|
-
export async function runStructured(options) {
|
|
50
|
-
const parse = options.parse ?? ((raw) => parseEmbeddedJsonResponse(raw));
|
|
51
|
-
const buildFeedback = options.buildFeedback ?? defaultFeedback;
|
|
52
|
-
const maxAttempts = Math.max(1, options.maxAttempts ?? 2);
|
|
53
|
-
let feedback;
|
|
54
|
-
let lastFailure;
|
|
55
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
56
|
-
const raw = await options.dispatch(feedback);
|
|
57
|
-
const candidate = parse(raw);
|
|
58
|
-
if (candidate === undefined) {
|
|
59
|
-
lastFailure = {
|
|
60
|
-
ok: false,
|
|
61
|
-
reason: "parse_error",
|
|
62
|
-
errors: ["no JSON structure found in response"],
|
|
63
|
-
attempts: attempt,
|
|
64
|
-
raw,
|
|
65
|
-
};
|
|
66
|
-
feedback = buildFeedback({ reason: "parse_error", errors: lastFailure.errors, raw });
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
const verdict = options.validate(candidate);
|
|
70
|
-
if (verdict.ok) {
|
|
71
|
-
return { ok: true, value: verdict.value, attempts: attempt };
|
|
72
|
-
}
|
|
73
|
-
lastFailure = { ok: false, reason: "validation_error", errors: verdict.errors, attempts: attempt, raw };
|
|
74
|
-
feedback = buildFeedback({ reason: "validation_error", errors: verdict.errors, raw });
|
|
75
|
-
}
|
|
76
|
-
// maxAttempts >= 1 guarantees at least one loop iteration set lastFailure
|
|
77
|
-
// (a success would have returned), so the non-null assertion is safe.
|
|
78
|
-
return lastFailure;
|
|
79
|
-
}
|
package/dist/core/subprocess.js
CHANGED
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
* • Process-GROUP spawn (`detached: true` when capturing ON POSIX) so a
|
|
12
12
|
* negative-pid kill reaps the whole descendant tree — no orphaned children.
|
|
13
13
|
* See {@link spawnsOwnProcessGroup} for why Windows is excluded.
|
|
14
|
-
* • A SIGTERM→SIGKILL kill ladder on timeout/abort —
|
|
15
|
-
*
|
|
14
|
+
* • A SIGINT→SIGTERM→SIGKILL kill ladder on timeout/abort — SIGINT first, as
|
|
15
|
+
* a Ctrl-C would, so a program that treats an interrupt as a stop can wind
|
|
16
|
+
* the run down; a child that ignores it is terminated, and one that ignores
|
|
17
|
+
* that is force-killed, each after a grace period, instead of wedging forever.
|
|
16
18
|
* • Time-bounded output capture ({@link readStream}) that cannot block past
|
|
17
19
|
* the wall budget even when the child leaves a pipe endpoint open, plus an
|
|
18
20
|
* OPT-IN RETENTION cap (`maxOutputBytes`); see {@link readStream} for what
|
|
@@ -94,27 +96,58 @@ export function killGroup(proc, signal) {
|
|
|
94
96
|
/* ignore */
|
|
95
97
|
}
|
|
96
98
|
}
|
|
99
|
+
/** Whether anything still runs in `proc`'s process group (the leader included), or the leader has not exited. */
|
|
100
|
+
function groupRunning(proc) {
|
|
101
|
+
if (typeof proc.pid === "number") {
|
|
102
|
+
try {
|
|
103
|
+
process.kill(-proc.pid, 0);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// No member is left, or the child leads no group of its own: only the leader's own exit tells.
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return proc.exitCode === null;
|
|
111
|
+
}
|
|
97
112
|
/**
|
|
98
|
-
* SIGTERM→SIGKILL kill ladder shared by the timeout and abort paths
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
113
|
+
* SIGINT→SIGTERM→SIGKILL kill ladder shared by the timeout and abort paths.
|
|
114
|
+
* No-op when the child has already exited; otherwise runs `onKill`
|
|
115
|
+
* (the caller's reason flag — `timedOut` / `aborted` — set BEFORE the first
|
|
116
|
+
* signal, exactly as the inlined copies did) and interrupts the process group.
|
|
117
|
+
* SIGTERM follows when `graceMs` runs out or as soon as the leader exits,
|
|
118
|
+
* whichever is first, because members of the group can outlive it: a job a
|
|
119
|
+
* shell started in the background ignores SIGINT. SIGKILL follows another
|
|
120
|
+
* `graceMs` later if anything in the group still runs. The timers are unref'ed
|
|
121
|
+
* so they never pin the event loop.
|
|
122
|
+
*
|
|
123
|
+
* SIGINT goes first because it is what a person's Ctrl-C sends, and a program
|
|
124
|
+
* that records how a run ended acts on it: the OpenCode 2 CLI marks its session
|
|
125
|
+
* interrupted and releases its claim, where on SIGTERM or SIGKILL the session
|
|
126
|
+
* stays suspended and OpenCode's own service may resume it later.
|
|
105
127
|
*/
|
|
106
128
|
export function scheduleKillLadder(proc, opts) {
|
|
107
129
|
if (!proc || proc.exitCode !== null)
|
|
108
130
|
return;
|
|
109
131
|
opts.onKill();
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (
|
|
132
|
+
const afterGrace = (run) => {
|
|
133
|
+
const timer = opts.setTimeoutFn(run, opts.graceMs ?? 5000);
|
|
134
|
+
if (typeof timer !== "number")
|
|
135
|
+
timer.unref?.();
|
|
136
|
+
};
|
|
137
|
+
killGroup(proc, "SIGINT");
|
|
138
|
+
let terminated = false;
|
|
139
|
+
const terminate = () => {
|
|
140
|
+
if (terminated || !groupRunning(proc))
|
|
113
141
|
return;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
142
|
+
terminated = true;
|
|
143
|
+
killGroup(proc, "SIGTERM");
|
|
144
|
+
afterGrace(() => {
|
|
145
|
+
if (groupRunning(proc))
|
|
146
|
+
killGroup(proc, "SIGKILL");
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
afterGrace(terminate);
|
|
150
|
+
proc.exited.then(terminate, terminate);
|
|
118
151
|
}
|
|
119
152
|
const liveGroupChildren = new Set();
|
|
120
153
|
let signalGuardHandlers;
|
|
@@ -211,7 +244,7 @@ function utf8BoundaryAtOrBefore(value, limit) {
|
|
|
211
244
|
}
|
|
212
245
|
/**
|
|
213
246
|
* Drain a readable stream to text, optionally racing each read against a
|
|
214
|
-
* timeout so a process that is killed via SIGTERM/SIGKILL but whose pipe
|
|
247
|
+
* timeout so a process that is killed via SIGINT/SIGTERM/SIGKILL but whose pipe
|
|
215
248
|
* endpoints stay open (e.g. background threads still holding the fd) cannot
|
|
216
249
|
* block the caller indefinitely. On timeout we return whatever was decoded
|
|
217
250
|
* before the pipe stopped draining.
|
|
@@ -368,7 +401,7 @@ function toError(err) {
|
|
|
368
401
|
}
|
|
369
402
|
/**
|
|
370
403
|
* Spawn `cmd` and manage its lifecycle: process-group spawn, hard timeout and
|
|
371
|
-
* cooperative abort (both via the SIGTERM→SIGKILL {@link scheduleKillLadder}),
|
|
404
|
+
* cooperative abort (both via the SIGINT→SIGTERM→SIGKILL {@link scheduleKillLadder}),
|
|
372
405
|
* bounded output capture, and an optional stdin payload. Never throws for a
|
|
373
406
|
* spawn/exit failure — those surface as {@link ManagedSubprocessResult.spawnError}.
|
|
374
407
|
*/
|
|
@@ -413,7 +446,7 @@ export async function runManagedSubprocess(cmd, opts) {
|
|
|
413
446
|
};
|
|
414
447
|
}
|
|
415
448
|
opts.onSpawn?.(proc);
|
|
416
|
-
// Hard timeout:
|
|
449
|
+
// Hard timeout: SIGINT now, SIGTERM and SIGKILL after each grace period if ignored.
|
|
417
450
|
// Skipped entirely when timeoutMs is null.
|
|
418
451
|
let timedOut = false;
|
|
419
452
|
let timer;
|
|
@@ -495,9 +528,17 @@ export async function runManagedSubprocess(cmd, opts) {
|
|
|
495
528
|
const stdinStream = proc.stdin;
|
|
496
529
|
const stdinDone = (async () => {
|
|
497
530
|
try {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
531
|
+
// Bun.spawn's pipe is a FileSink (write/end), not a WritableStream.
|
|
532
|
+
const sink = stdinStream;
|
|
533
|
+
if (typeof sink.write === "function" && typeof sink.end === "function" && !("getWriter" in stdinStream)) {
|
|
534
|
+
sink.write(stdinPayload);
|
|
535
|
+
await sink.end();
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
const writer = stdinStream.getWriter();
|
|
539
|
+
await writer.write(new TextEncoder().encode(stdinPayload));
|
|
540
|
+
await writer.close();
|
|
541
|
+
}
|
|
501
542
|
}
|
|
502
543
|
catch {
|
|
503
544
|
// Best-effort: ignore stdin write failures, the child will get EOF.
|
|
@@ -2,33 +2,29 @@
|
|
|
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
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* renderer NAME + action builder, so this table becomes the `TYPE_PRESENTATION`
|
|
9
|
-
* data table §2 mandates ("Renderer/action = data table keyed on the open
|
|
10
|
-
* `type`, pointing at a named-function core module").
|
|
5
|
+
* The `TYPE_PRESENTATION` table of AKM's own presentation metadata: the per-`type`
|
|
6
|
+
* renderer NAME + action builder, a data table keyed on the open
|
|
7
|
+
* `type`, pointing at a named-function core module.
|
|
11
8
|
*
|
|
12
|
-
* The open type token
|
|
9
|
+
* The open type token trades the deleted closed asset-type
|
|
13
10
|
* union's exhaustiveness checking for a runtime lookup. `TYPE_PRESENTATION`
|
|
14
11
|
* restores that exhaustiveness for AKM's OWN known types (the compiler
|
|
15
12
|
* demands an entry whenever {@link KnownType} gains a member), while
|
|
16
13
|
* {@link presentationFor} stays open over `string` so foreign/adapter types
|
|
17
14
|
* still resolve to a sane generic fallback instead of `undefined`/a throw.
|
|
18
15
|
*
|
|
19
|
-
* ── renderer/action provenance
|
|
16
|
+
* ── renderer/action provenance ──
|
|
20
17
|
*
|
|
21
18
|
* The `renderer` NAMES and `action` builders below are the SINGLE SOURCE OF
|
|
22
|
-
* TRUTH for search-hit rendering
|
|
23
|
-
*
|
|
24
|
-
* {@link presentationFor}). They cover all built-in types — INCLUDING
|
|
19
|
+
* TRUTH for search-hit rendering (reached via {@link presentationFor}).
|
|
20
|
+
* They cover all built-in types — INCLUDING
|
|
25
21
|
* the 15th type `instruction` (a read-like-knowledge markdown doc added for the
|
|
26
22
|
* format-family adapters) and the 6 "static-only" mappings
|
|
27
|
-
* (script/skill/command/agent/knowledge/memory)
|
|
23
|
+
* (script/skill/command/agent/knowledge/memory).
|
|
28
24
|
* The workflow action is the one function-valued builder; its
|
|
29
25
|
* `buildWorkflowAction` body (`output/renderers.ts` — a cycle-sensitive module)
|
|
30
26
|
* is reproduced inline here rather than imported, to keep this leaf import-free
|
|
31
|
-
* (only `recognition-util`,
|
|
27
|
+
* (only `recognition-util`, a pure sink); `tests/core/adapter/
|
|
32
28
|
* akm-presentation.test.ts` pins the renderer/action values against drift.
|
|
33
29
|
*/
|
|
34
30
|
import { isKnownType } from "./recognition-util.js";
|
|
@@ -119,7 +115,7 @@ export const TYPE_PRESENTATION = {
|
|
|
119
115
|
action: (ref) => `akm show ${ref} -> read the stash fact and apply it as durable context`,
|
|
120
116
|
},
|
|
121
117
|
// `instruction` (CLAUDE.md / AGENTS.md) is a read-like-knowledge markdown
|
|
122
|
-
// doc
|
|
118
|
+
// doc: it REUSES
|
|
123
119
|
// the `knowledge-md` renderer and mirrors knowledge's read action, so an
|
|
124
120
|
// instruction hit renders exactly like knowledge instead of the generic
|
|
125
121
|
// fallback (the parity guard in akm-presentation.test.ts pins this).
|