akm-cli 0.9.16 → 0.9.17-alpha.10
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 +2101 -0
- package/STABILITY.md +11 -10
- package/dist/akm +124 -193
- package/dist/akm-migrate +38 -19
- package/dist/assets/hints/cli-hints-full.md +6 -7
- package/dist/assets/improve-strategies/catchup.json +0 -3
- package/dist/assets/improve-strategies/consolidate.json +0 -1
- package/dist/assets/improve-strategies/default.json +1 -2
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
- package/dist/assets/improve-strategies/quick.json +1 -2
- package/dist/assets/improve-strategies/reflect-distill.json +1 -2
- package/dist/assets/improve-strategies/thorough.json +0 -3
- package/dist/assets/prompts/consolidate-pair.md +20 -0
- package/dist/assets/prompts/consolidate-system.md +4 -11
- package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
- package/dist/assets/templates/html/health.html +3 -5
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +6 -2
- package/dist/cli/unknown-flags.js +24 -1
- package/dist/cli.js +68 -10
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +6 -0
- package/dist/commands/health/archive-usage.js +92 -0
- package/dist/commands/health/checks.js +83 -74
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/data-dir-usage.js +25 -13
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +1 -42
- package/dist/commands/health/improve-metrics.js +136 -591
- package/dist/commands/health/md-report.js +1 -6
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +14 -120
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -74
- package/dist/commands/health.js +145 -143
- package/dist/commands/improve/consolidate/chunking.js +26 -117
- package/dist/commands/improve/consolidate/continuity-check.js +137 -0
- package/dist/commands/improve/consolidate/pair-pass.js +791 -0
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +589 -1127
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1041
- package/dist/commands/improve/eligibility.js +126 -390
- package/dist/commands/improve/execution.js +8 -10
- package/dist/commands/improve/extract-prompt.js +1 -2
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +75 -169
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +52 -4
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +480 -1074
- package/dist/commands/improve/ledger.js +119 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +415 -1073
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +16 -118
- package/dist/commands/improve/memory/memory-improve.js +266 -14
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -15
- package/dist/commands/improve/preparation.js +779 -2319
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +642 -1353
- package/dist/commands/improve/retrieval-gate.js +127 -0
- package/dist/commands/improve/retrieval-scope.js +92 -0
- package/dist/commands/improve/salience.js +41 -240
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +322 -0
- package/dist/commands/lint/base-linter.js +37 -15
- package/dist/commands/proposal/drain.js +261 -578
- package/dist/commands/proposal/proposal-cli.js +19 -20
- package/dist/commands/proposal/proposal-types.js +31 -24
- package/dist/commands/proposal/proposal.js +38 -8
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +1097 -1394
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +22 -89
- package/dist/commands/read/curate.js +105 -462
- package/dist/commands/read/knowledge.js +3 -2
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +57 -108
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +4 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +127 -29
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/source-manage.js +9 -2
- package/dist/commands/sources/stash-cli.js +24 -4
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +12 -13
- package/dist/commands/tasks/tasks.js +350 -936
- package/dist/commands/tasks/validate.js +26 -24
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +2 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +42 -12
- package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/asset-placement.js +4 -13
- package/dist/core/asset/frontmatter.js +106 -1
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +285 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +9 -34
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +184 -111
- package/dist/core/config/engine-semantics.js +0 -2
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +54 -125
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/index-config.js +9 -48
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-change.js +13 -5
- package/dist/core/file-lock.js +76 -173
- package/dist/core/improve-result.js +35 -7
- package/dist/core/improve-types.js +0 -1
- package/dist/core/logs-db.js +2 -2
- package/dist/core/loopback.js +7 -12
- package/dist/core/non-task-input.js +20 -0
- package/dist/core/parse.js +13 -16
- package/dist/core/paths.js +0 -24
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +123 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/time.js +0 -20
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +294 -1005
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/ensure-index.js +77 -73
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +141 -154
- package/dist/indexer/indexer.js +400 -1124
- package/dist/indexer/links/declared-links.js +90 -0
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +96 -90
- package/dist/indexer/passes/metadata.js +132 -219
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +2 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +190 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +36 -7
- package/dist/indexer/walk/walker.js +3 -4
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/client.js +18 -6
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +11 -17
- package/dist/llm/feature-gate.js +0 -8
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +25 -38
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +69 -31
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +48 -3
- package/dist/output/text/show-format.js +13 -17
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +42948 -92369
- package/dist/scripts/akm-migrate.js +42935 -92354
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/connection.js +5 -6
- package/dist/setup/steps/platforms.js +2 -2
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +83 -21
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +209 -0
- package/dist/storage/repositories/index-connection.js +39 -72
- package/dist/storage/repositories/index-entries-repository.js +131 -129
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +101 -268
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-links-repository.js +143 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +257 -325
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +104 -1
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/salience-repository.js +1 -19
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +130 -0
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +191 -302
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +141 -748
- package/dist/tasks/backends/schtasks.js +119 -623
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/run/load-task.js +1 -1
- package/dist/tasks/scheduler-binding.js +20 -238
- package/dist/tasks/scheduler-invocation.js +136 -244
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +368 -679
- package/dist/tasks/source/parse-task-source.js +55 -9
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +464 -88
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +43 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
- package/docs/reference/cli.md +232 -135
- package/docs/reference/configuration.md +71 -57
- package/docs/reference/data-and-telemetry.md +20 -21
- package/docs/reference/tasks.md +105 -39
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +115 -738
- package/schemas/akm-workflow.json +1 -0
- package/dist/assets/improve-strategies/graph-refresh.json +0 -15
- package/dist/assets/prompts/contradiction-judge.md +0 -33
- package/dist/assets/prompts/graph-extract-system.md +0 -1
- package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
- package/dist/assets/prompts/metadata-enhance-system.md +0 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -149
- package/dist/commands/improve/distill/promote-memory.js +0 -291
- package/dist/commands/improve/distill/quality-gate.js +0 -337
- package/dist/commands/improve/eval-cases.js +0 -52
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -31
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/db/graph-db.js +0 -444
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/graph/graph-extraction.js +0 -1108
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/search/ranking-types.js +0 -4
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/llm/graph-extract.js +0 -728
- package/dist/llm/metadata-enhance.js +0 -96
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/tasks/source/task-to-v3.js +0 -507
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -77
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -3,42 +3,73 @@
|
|
|
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 dotenv from "dotenv";
|
|
6
7
|
import { loadAdapterExecutionSource } from "../../commands/command/execution-source-loader.js";
|
|
7
8
|
import { makeBundleRef, parseBundleRef } from "../../core/asset/asset-ref.js";
|
|
9
|
+
import { compareCodePoints, isWithin, toPosix } from "../../core/common.js";
|
|
8
10
|
import { parseEnvRef } from "../../core/env-secret-ref.js";
|
|
9
11
|
import { UsageError } from "../../core/errors.js";
|
|
10
12
|
import { deriveInstallations } from "../../indexer/installations.js";
|
|
11
13
|
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
12
14
|
import { resolveAssetPath } from "../../sources/resolve.js";
|
|
13
|
-
import {
|
|
15
|
+
import { isInferredSecretName } from "../../tasks/log-redaction.js";
|
|
16
|
+
import { SECRET_TOKEN_RE } from "../exec/environment.js";
|
|
17
|
+
import { detectSecretShapedParams } from "../exec/param-secrets.js";
|
|
18
|
+
/**
|
|
19
|
+
* A step's frozen environment: literal `env:` values, `pass_env` names, then
|
|
20
|
+
* one value-free descriptor per `unit.env` ref (owner, key set, secret-token
|
|
21
|
+
* names). Values are read at dispatch (`exec/environment.ts`), never frozen.
|
|
22
|
+
*/
|
|
14
23
|
export function freezeEnvironment(source, exec, context) {
|
|
15
|
-
const literals = Object.entries(source.env ?? {}).map(([name,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (parsedEnv.type !== "env")
|
|
23
|
-
throw new UsageError(`Expected an env ref; got ${ref}.`, "WORKFLOW_SOURCE_INVALID");
|
|
24
|
-
const owned = resolveOwnedAssetSync(ref, "env", context);
|
|
25
|
-
return { ref: owned.ref, bundle: owned.bundle, adapter: owned.adapter, root: owned.root, path: owned.file };
|
|
26
|
-
},
|
|
24
|
+
const literals = Object.entries(source.env ?? {}).map(([name, raw]) => {
|
|
25
|
+
const value = String(raw);
|
|
26
|
+
// A literal is frozen into plan_json; a credential belongs in an env ref, as for task env.
|
|
27
|
+
if (isInferredSecretName(name) || detectSecretShapedParams({ [name]: value }).length > 0) {
|
|
28
|
+
throw new UsageError(`Workflow step ${source.id} env.${name} is a secret-shaped literal env value. Store credentials in an env asset (unit.env) rather than workflow source.`, "WORKFLOW_SOURCE_INVALID");
|
|
29
|
+
}
|
|
30
|
+
return Object.freeze({ kind: "literal", name, value });
|
|
27
31
|
});
|
|
32
|
+
const passThrough = (exec?.passEnv ?? []).map((name) => Object.freeze({ kind: "pass-through", name }));
|
|
33
|
+
const seen = new Set();
|
|
34
|
+
const envRefs = [];
|
|
35
|
+
for (const [precedence, ref] of (source.unit?.env ?? []).entries()) {
|
|
36
|
+
if (parseEnvRef(ref).type !== "env") {
|
|
37
|
+
throw new UsageError(`Expected an env ref; got ${ref}.`, "WORKFLOW_SOURCE_INVALID");
|
|
38
|
+
}
|
|
39
|
+
const owned = resolveOwnedAssetSync(ref, "env", context);
|
|
40
|
+
if (seen.has(owned.ref))
|
|
41
|
+
continue;
|
|
42
|
+
seen.add(owned.ref);
|
|
43
|
+
const parsed = dotenv.parse(fs.readFileSync(owned.file));
|
|
44
|
+
const secretNames = new Set();
|
|
45
|
+
for (const value of Object.values(parsed)) {
|
|
46
|
+
for (const match of value.matchAll(SECRET_TOKEN_RE))
|
|
47
|
+
if (match[1])
|
|
48
|
+
secretNames.add(match[1]);
|
|
49
|
+
}
|
|
50
|
+
envRefs.push(Object.freeze({
|
|
51
|
+
kind: "env-ref",
|
|
52
|
+
ref: owned.ref,
|
|
53
|
+
owner: Object.freeze({
|
|
54
|
+
bundle: owned.bundle,
|
|
55
|
+
adapter: owned.adapter,
|
|
56
|
+
requestedRoot: owned.root,
|
|
57
|
+
requestedPath: owned.file,
|
|
58
|
+
relativePath: toPosix(path.relative(owned.root, owned.file)),
|
|
59
|
+
}),
|
|
60
|
+
keys: Object.keys(parsed).sort(compareCodePoints),
|
|
61
|
+
secretNames: [...secretNames].sort(compareCodePoints),
|
|
62
|
+
precedence,
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
28
65
|
return [...literals, ...passThrough, ...envRefs];
|
|
29
66
|
}
|
|
30
|
-
|
|
67
|
+
/** Load a command or persona the workflow names, resolved through the workflow's own bundles. */
|
|
68
|
+
export async function workflowExecutionSource(ref, kind, context) {
|
|
31
69
|
const owned = await resolveOwnedAsset(ref, kind === "command" ? "command" : "agent", context);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
config: context.config
|
|
35
|
-
fileContext: () => context.collector.fileContext(owned.root, owned.file),
|
|
36
|
-
};
|
|
37
|
-
const rendered = kind === "command"
|
|
38
|
-
? await loadAdapterExecutionSource(owned.ref, "command", options)
|
|
39
|
-
: await loadAdapterExecutionSource(owned.ref, "persona", options);
|
|
40
|
-
context.collector.bindIdentity(owned.file, owned.root, rendered.identity);
|
|
41
|
-
return rendered;
|
|
70
|
+
return kind === "command"
|
|
71
|
+
? loadAdapterExecutionSource(owned.ref, "command", { config: context.config })
|
|
72
|
+
: loadAdapterExecutionSource(owned.ref, "persona", { config: context.config });
|
|
42
73
|
}
|
|
43
74
|
export async function resolveOwnedAsset(ref, type, context) {
|
|
44
75
|
return resolveOwnedAssetCore(ref, type, context, false);
|
|
@@ -46,44 +77,26 @@ export async function resolveOwnedAsset(ref, type, context) {
|
|
|
46
77
|
export function resolveOwnedAssetSync(ref, type, context) {
|
|
47
78
|
return resolveOwnedAssetCore(ref, type, context, true);
|
|
48
79
|
}
|
|
49
|
-
|
|
80
|
+
function resolveOwnedAssetCore(refInput, type, context, sync) {
|
|
50
81
|
const parsed = parseBundleRef(refInput);
|
|
51
82
|
const plural = type === "env" ? "env" : `${type}s`;
|
|
52
83
|
const conceptId = parsed.conceptId.startsWith(`${plural}/`) ? parsed.conceptId : `${plural}/${parsed.conceptId}`;
|
|
53
84
|
const name = conceptId.slice(plural.length + 1);
|
|
54
85
|
const direct = parsed.bundle ? configuredOwner(parsed.bundle, context.config) : undefined;
|
|
55
|
-
const
|
|
56
|
-
const installations = deriveInstallations(sources);
|
|
57
|
-
const candidates = direct
|
|
58
|
-
? [direct]
|
|
59
|
-
: sources.flatMap((source, index) => {
|
|
60
|
-
const installation = installations[index];
|
|
61
|
-
if (!installation || (parsed.bundle && installation.id !== parsed.bundle))
|
|
62
|
-
return [];
|
|
63
|
-
return [
|
|
64
|
-
{
|
|
65
|
-
bundle: installation.id,
|
|
66
|
-
root: source.path,
|
|
67
|
-
adapter: source.adapterId ?? installation.components[0]?.adapter ?? "akm",
|
|
68
|
-
},
|
|
69
|
-
];
|
|
70
|
-
});
|
|
86
|
+
const candidates = direct ? [direct] : installedOwners(parsed.bundle, context.config);
|
|
71
87
|
const findSync = () => {
|
|
72
88
|
for (const candidate of candidates) {
|
|
73
89
|
const directory = path.join(candidate.root, plural);
|
|
74
90
|
for (const extension of assetExtensions(type)) {
|
|
75
91
|
const file = path.resolve(directory, `${name}${extension}`);
|
|
76
92
|
if (fs.existsSync(file) && fs.statSync(file).isFile()) {
|
|
93
|
+
if (!isWithin(file, candidate.root)) {
|
|
94
|
+
throw new UsageError(`${file} resolves outside its owning root.`, "PATH_ESCAPE_VIOLATION");
|
|
95
|
+
}
|
|
77
96
|
return { ...candidate, ref: makeBundleRef(candidate.bundle, conceptId), file };
|
|
78
97
|
}
|
|
79
98
|
}
|
|
80
99
|
}
|
|
81
|
-
// P4 (docs/plans/specs/p4-deletions-closeout.md §5.2, row B-11 preservation
|
|
82
|
-
// gate): PRESERVED, not re-coded — tests/workflows/child-workflow-freeze.test.ts's
|
|
83
|
-
// "B-11: workflows/<ref> that does not resolve fails the existing
|
|
84
|
-
// asset-resolution failure, unchanged in code and shape" pins this exact
|
|
85
|
-
// code by name and by its own title. Recorded deviation from §5.2's flat
|
|
86
|
-
// "→ WORKFLOW_SOURCE_INVALID" for this file's 3 sites.
|
|
87
100
|
throw new UsageError(`Workflow source target ${refInput} was not found.`, "INVALID_FLAG_VALUE");
|
|
88
101
|
};
|
|
89
102
|
if (sync)
|
|
@@ -101,7 +114,24 @@ export function resolveOwnedAssetCore(refInput, type, context, sync) {
|
|
|
101
114
|
return findSync();
|
|
102
115
|
})();
|
|
103
116
|
}
|
|
104
|
-
|
|
117
|
+
/** Every installed bundle root (or just `bundle`'s), in installation priority order. */
|
|
118
|
+
function installedOwners(bundle, config) {
|
|
119
|
+
const sources = resolveSourceEntries(undefined, config);
|
|
120
|
+
const installations = deriveInstallations(sources);
|
|
121
|
+
return sources.flatMap((source, index) => {
|
|
122
|
+
const installation = installations[index];
|
|
123
|
+
if (!installation || (bundle && installation.id !== bundle))
|
|
124
|
+
return [];
|
|
125
|
+
return [
|
|
126
|
+
{
|
|
127
|
+
bundle: installation.id,
|
|
128
|
+
root: source.path,
|
|
129
|
+
adapter: source.adapterId ?? installation.components[0]?.adapter ?? "akm",
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function configuredOwner(bundle, config) {
|
|
105
135
|
const entry = config.bundles?.[bundle];
|
|
106
136
|
if (!entry || typeof entry.path !== "string")
|
|
107
137
|
return undefined;
|
|
@@ -113,55 +143,32 @@ export function configuredOwner(bundle, config) {
|
|
|
113
143
|
adapter: component?.adapter ?? "akm",
|
|
114
144
|
};
|
|
115
145
|
}
|
|
116
|
-
|
|
146
|
+
const SCRIPT_EXTENSIONS = [
|
|
147
|
+
"",
|
|
148
|
+
".sh",
|
|
149
|
+
".ts",
|
|
150
|
+
".js",
|
|
151
|
+
".py",
|
|
152
|
+
".rb",
|
|
153
|
+
".go",
|
|
154
|
+
".pl",
|
|
155
|
+
".php",
|
|
156
|
+
".lua",
|
|
157
|
+
".r",
|
|
158
|
+
".swift",
|
|
159
|
+
".kt",
|
|
160
|
+
".kts",
|
|
161
|
+
".ps1",
|
|
162
|
+
".cmd",
|
|
163
|
+
".bat",
|
|
164
|
+
];
|
|
165
|
+
function assetExtensions(type) {
|
|
117
166
|
if (type === "script")
|
|
118
|
-
return
|
|
119
|
-
"",
|
|
120
|
-
".sh",
|
|
121
|
-
".ts",
|
|
122
|
-
".js",
|
|
123
|
-
".py",
|
|
124
|
-
".rb",
|
|
125
|
-
".go",
|
|
126
|
-
".pl",
|
|
127
|
-
".php",
|
|
128
|
-
".lua",
|
|
129
|
-
".r",
|
|
130
|
-
".swift",
|
|
131
|
-
".kt",
|
|
132
|
-
".kts",
|
|
133
|
-
".ps1",
|
|
134
|
-
".cmd",
|
|
135
|
-
".bat",
|
|
136
|
-
];
|
|
167
|
+
return SCRIPT_EXTENSIONS;
|
|
137
168
|
if (type === "env")
|
|
138
169
|
return ["", ".env"];
|
|
139
170
|
return ["", ".md", ".yml"];
|
|
140
171
|
}
|
|
141
|
-
export function captureOwned(owned, collector) {
|
|
142
|
-
trackAncestry(collector, owned.root, owned.file);
|
|
143
|
-
const retained = collector.capture(owned.file, owned.root, { authored: true });
|
|
144
|
-
return collector.bindIdentity(owned.file, owned.root, {
|
|
145
|
-
ref: owned.ref,
|
|
146
|
-
bundle: owned.bundle,
|
|
147
|
-
adapter: owned.adapter,
|
|
148
|
-
file: retained.relativePath,
|
|
149
|
-
hash: retained.sha256,
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
export function trackAncestry(collector, rootInput, file) {
|
|
153
|
-
const root = path.resolve(rootInput);
|
|
154
|
-
collector.trackDirectory(root, root);
|
|
155
|
-
const relative = path.relative(root, path.dirname(file));
|
|
156
|
-
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
157
|
-
throw new UsageError(`${file} resolves outside its owning root.`, "PATH_ESCAPE_VIOLATION");
|
|
158
|
-
}
|
|
159
|
-
let current = root;
|
|
160
|
-
for (const segment of relative === "" ? [] : relative.split(path.sep)) {
|
|
161
|
-
current = path.join(current, segment);
|
|
162
|
-
collector.trackDirectory(current, root);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
172
|
export function qualifyRef(ref, plural, asset, config) {
|
|
166
173
|
const parsed = parseBundleRef(ref);
|
|
167
174
|
if (parsed.bundle)
|
|
@@ -0,0 +1,172 @@
|
|
|
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
|
+
* Freeze a compiled workflow plan into the plan a run executes. Every step's
|
|
6
|
+
* authored spec resolves through the shared command/task authorities into a
|
|
7
|
+
* frozen `root` (engine, model, timeout, concurrency, dispatch target and
|
|
8
|
+
* environment descriptors); gates get their judge; the compile-only fields are
|
|
9
|
+
* dropped; the source file's sha256 is recorded. Nothing is published here.
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
12
|
+
import { ConfigError, UsageError } from "../../core/errors.js";
|
|
13
|
+
import { warn } from "../../core/warn.js";
|
|
14
|
+
import { NO_ENGINE_MESSAGE_SUFFIX } from "../../integrations/agent/engine-fallback.js";
|
|
15
|
+
import { resolveExecution } from "../../integrations/agent/execution.js";
|
|
16
|
+
import { checkWorkflowPlan } from "../compile.js";
|
|
17
|
+
import { defaultMapConcurrency, workflowMaxConcurrency } from "../concurrency-policy.js";
|
|
18
|
+
import { canonicalJson } from "../ir/plan-hash.js";
|
|
19
|
+
import { WORKFLOW_PLAN_VERSION, } from "../plan.js";
|
|
20
|
+
import { classifyWorkflowStepUses } from "../source-semantics.js";
|
|
21
|
+
import { assertChildOutputReferences } from "./child-output-references.js";
|
|
22
|
+
import { qualifyRef } from "./environment.js";
|
|
23
|
+
import { baseUnitOf } from "./step-values.js";
|
|
24
|
+
import { childWorkflowDispatch } from "./targets/child-workflow.js";
|
|
25
|
+
import { commandDispatch, commandResult } from "./targets/command.js";
|
|
26
|
+
import { directScript } from "./targets/script.js";
|
|
27
|
+
import { directShell } from "./targets/shell.js";
|
|
28
|
+
import { taskDispatch } from "./targets/task.js";
|
|
29
|
+
/** Resolve and freeze one workflow (and, recursively, every child it composes). */
|
|
30
|
+
export async function freezeWorkflow(asset, config, refPath = [asset.ref]) {
|
|
31
|
+
const compiled = asset.plan;
|
|
32
|
+
const checked = checkWorkflowPlan(compiled);
|
|
33
|
+
if (!checked.ok) {
|
|
34
|
+
throw new UsageError(checked.errors.map((error) => `${asset.path}:${error.line}: ${error.message}`).join("\n"), "WORKFLOW_SOURCE_INVALID");
|
|
35
|
+
}
|
|
36
|
+
const context = {
|
|
37
|
+
asset,
|
|
38
|
+
config,
|
|
39
|
+
plan: compiled,
|
|
40
|
+
refPath,
|
|
41
|
+
freezeChild: (child, childRefPath) => freezeWorkflow(child, config, childRefPath),
|
|
42
|
+
};
|
|
43
|
+
let engineAnnouncement;
|
|
44
|
+
const steps = [];
|
|
45
|
+
for (const step of compiled.steps) {
|
|
46
|
+
const { spec, ...frozenStep } = step;
|
|
47
|
+
const source = { ...(spec ?? { source: { path: asset.path, start: 1, end: 1 } }), id: step.stepId };
|
|
48
|
+
let root;
|
|
49
|
+
if (!step.route) {
|
|
50
|
+
const resolved = await resolveStep(source, context);
|
|
51
|
+
engineAnnouncement ??= resolved.engineAnnouncement;
|
|
52
|
+
root = frozenRoot(step.stepId, source, resolved, compiled, config);
|
|
53
|
+
}
|
|
54
|
+
let frozenJudge = null;
|
|
55
|
+
if (step.gate.criteria.length > 0) {
|
|
56
|
+
const judge = resolveJudge(source, step.gate.criteria[0] ?? "", context);
|
|
57
|
+
if (judge) {
|
|
58
|
+
frozenJudge = judge.target;
|
|
59
|
+
engineAnnouncement ??= judge.engineAnnouncement;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
warn(`Workflow step "${step.stepId}" has completion criteria but no verification engine is available ` +
|
|
63
|
+
"(set workflow.judgeEngine, defaults.engine, or install an opencode-sdk binary). The step will block " +
|
|
64
|
+
"for `akm workflow resume` once it is reached.");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
steps.push({ ...frozenStep, ...(root ? { root } : {}), gate: { ...step.gate, frozenJudge } });
|
|
68
|
+
}
|
|
69
|
+
assertChildOutputReferences(steps);
|
|
70
|
+
const plan = {
|
|
71
|
+
irVersion: WORKFLOW_PLAN_VERSION,
|
|
72
|
+
title: asset.title,
|
|
73
|
+
...(compiled.params ? { params: compiled.params } : {}),
|
|
74
|
+
...(compiled.paramSchemas ? { paramSchemas: compiled.paramSchemas } : {}),
|
|
75
|
+
...(compiled.budget ? { budget: compiled.budget } : {}),
|
|
76
|
+
...(compiled.outputs ? { outputs: compiled.outputs } : {}),
|
|
77
|
+
execution: { maxConcurrency: workflowMaxConcurrency(config.workflow?.maxConcurrency) },
|
|
78
|
+
sourceHash: asset.sourceHash,
|
|
79
|
+
steps,
|
|
80
|
+
};
|
|
81
|
+
return { plan, warnings: checked.warnings, ...(engineAnnouncement ? { engineAnnouncement } : {}) };
|
|
82
|
+
}
|
|
83
|
+
async function resolveStep(source, context) {
|
|
84
|
+
const baseUnit = baseUnitOf(source);
|
|
85
|
+
if (source.exec)
|
|
86
|
+
return directShell(source, baseUnit, context);
|
|
87
|
+
if (!source.uses)
|
|
88
|
+
throw new Error(`workflow step ${source.id} has neither exec nor uses`);
|
|
89
|
+
const target = classifyWorkflowStepUses(source.uses);
|
|
90
|
+
if (target.kind === "task")
|
|
91
|
+
return taskDispatch(source, baseUnit, target.ref, context);
|
|
92
|
+
if (target.kind === "workflow") {
|
|
93
|
+
return childWorkflowDispatch({
|
|
94
|
+
source,
|
|
95
|
+
baseUnit,
|
|
96
|
+
childRefInput: target.ref,
|
|
97
|
+
context,
|
|
98
|
+
via: "direct",
|
|
99
|
+
authoredInputs: { kind: "with", value: source.with },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// `commands/<ref>` and `scripts/<ref>` are not binding surfaces; `akm/command`'s
|
|
103
|
+
// `with:` is its own argument bag.
|
|
104
|
+
if (target.kind !== "builtin-command" && source.with !== undefined) {
|
|
105
|
+
const family = target.kind === "command" ? "commands" : "scripts";
|
|
106
|
+
throw new UsageError(`Workflow step ${source.id} cannot pass with: to ${family} target ${target.ref}; a ${target.kind} ref is not a binding surface.`, "COMPOSITION_INVALID");
|
|
107
|
+
}
|
|
108
|
+
if (target.kind === "script")
|
|
109
|
+
return directScript(source, baseUnit, target.ref, context);
|
|
110
|
+
const action = target.kind === "builtin-command"
|
|
111
|
+
? source.with
|
|
112
|
+
: { ref: qualifyRef(target.ref, "commands", context.asset, context.config) };
|
|
113
|
+
return commandDispatch(source, baseUnit, action, context);
|
|
114
|
+
}
|
|
115
|
+
/** The gate judge's frozen command target, or undefined when no engine is available and none is configured. */
|
|
116
|
+
function resolveJudge(source, rubric, context) {
|
|
117
|
+
const configuredEngine = context.config.workflow?.judgeEngine;
|
|
118
|
+
try {
|
|
119
|
+
const prepared = resolveExecution({
|
|
120
|
+
content: rubric.trim() || "Judge workflow completion.",
|
|
121
|
+
config: context.config,
|
|
122
|
+
...(configuredEngine ? { current: { engine: configuredEngine } } : {}),
|
|
123
|
+
});
|
|
124
|
+
return commandResult(source, { onError: "fail", source: source.source }, prepared, context);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
if (configuredEngine || !(err instanceof ConfigError && err.message.includes(NO_ENGINE_MESSAGE_SUFFIX)))
|
|
128
|
+
throw err;
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function frozenRoot(stepId, source, resolved, plan, config) {
|
|
133
|
+
const unit = resolved.unit;
|
|
134
|
+
const target = resolved.target.kind === "shell"
|
|
135
|
+
? {
|
|
136
|
+
...resolved.target,
|
|
137
|
+
contentHash: createHash("sha256")
|
|
138
|
+
.update("akm.workflow.shell.v1\0")
|
|
139
|
+
.update(canonicalJson({
|
|
140
|
+
exec: resolved.target.exec,
|
|
141
|
+
environment: resolved.environment,
|
|
142
|
+
cwdIdentity: resolved.target.cwdIdentity,
|
|
143
|
+
}))
|
|
144
|
+
.digest("hex"),
|
|
145
|
+
}
|
|
146
|
+
: resolved.target;
|
|
147
|
+
const node = {
|
|
148
|
+
kind: "unit",
|
|
149
|
+
id: source.map ? `${stepId}.unit` : stepId,
|
|
150
|
+
instructions: resolved.instructions,
|
|
151
|
+
...(source.inputs && source.inputs.length > 0 ? { inputs: [...source.inputs] } : {}),
|
|
152
|
+
...(unit.output !== undefined ? { schema: unit.output } : {}),
|
|
153
|
+
...(unit.retry ? { retry: { max: unit.retry.max, on: [...unit.retry.on] } } : {}),
|
|
154
|
+
onError: unit.onError ?? plan.defaults?.onError ?? "fail",
|
|
155
|
+
...(unit.env ? { env: [...unit.env] } : {}),
|
|
156
|
+
isolation: unit.isolation ?? "none",
|
|
157
|
+
source: { ...source.source },
|
|
158
|
+
frozenTarget: target,
|
|
159
|
+
environment: [...resolved.environment],
|
|
160
|
+
};
|
|
161
|
+
if (!source.map)
|
|
162
|
+
return node;
|
|
163
|
+
return {
|
|
164
|
+
kind: "map",
|
|
165
|
+
id: `${stepId}.map`,
|
|
166
|
+
over: source.map.over,
|
|
167
|
+
template: node,
|
|
168
|
+
concurrency: source.map.concurrency ?? defaultMapConcurrency(config.workflow?.defaultMapConcurrency),
|
|
169
|
+
reducer: source.map.reducer ?? "collect",
|
|
170
|
+
source: { ...source.source },
|
|
171
|
+
};
|
|
172
|
+
}
|
|
@@ -4,11 +4,20 @@
|
|
|
4
4
|
import { canonicalResolvedExecutionRequest, decodeResolvedExecutionRequest, } from "../../execution/resolved-request.js";
|
|
5
5
|
import { defaultLlmEngineConcurrency } from "../concurrency-policy.js";
|
|
6
6
|
import { DEFAULT_EXEC_TIMEOUT_MS } from "../resource-limits.js";
|
|
7
|
+
/** The unit's authored settings plus its source span and argv, before any target resolution. */
|
|
8
|
+
export function baseUnitOf(source) {
|
|
9
|
+
return {
|
|
10
|
+
...(source.unit ? structuredClone(source.unit) : {}),
|
|
11
|
+
source: { ...source.source },
|
|
12
|
+
...(source.exec ? { exec: { ...source.exec } } : {}),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** Resolve an exec's timeout: unit `timeout:` → document `defaults.timeout` → the default. */
|
|
7
16
|
export function freezeExecSpec(source, exec, context) {
|
|
8
17
|
const declared = Object.hasOwn(source.unit ?? {}, "timeoutMs")
|
|
9
18
|
? source.unit?.timeoutMs
|
|
10
|
-
: context.
|
|
11
|
-
? context.
|
|
19
|
+
: context.plan.defaults && Object.hasOwn(context.plan.defaults, "timeoutMs")
|
|
20
|
+
? context.plan.defaults.timeoutMs
|
|
12
21
|
: undefined;
|
|
13
22
|
return {
|
|
14
23
|
...exec,
|
|
@@ -28,6 +37,7 @@ export function targetConcurrency(runner, config) {
|
|
|
28
37
|
const fallback = fallbackName ? config.engines?.[fallbackName] : undefined;
|
|
29
38
|
return defaultLlmEngineConcurrency(runner.fallbackConnection.endpoint, fallback?.kind === "llm" ? fallback.concurrency : undefined);
|
|
30
39
|
}
|
|
40
|
+
/** The request as it may be persisted: its live runtime environment removed. */
|
|
31
41
|
export function durableRequest(request) {
|
|
32
42
|
const wire = JSON.parse(canonicalResolvedExecutionRequest(request));
|
|
33
43
|
const runtime = { ...wire.runtime };
|
|
@@ -35,9 +45,6 @@ export function durableRequest(request) {
|
|
|
35
45
|
wire.runtime = runtime;
|
|
36
46
|
return decodeResolvedExecutionRequest(wire);
|
|
37
47
|
}
|
|
38
|
-
export function executionValues(source, workspace) {
|
|
39
|
-
return executionUnitValues(source.unit, workspace);
|
|
40
|
-
}
|
|
41
48
|
export function executionUnitValues(unit, workspace) {
|
|
42
49
|
return Object.freeze({
|
|
43
50
|
...(unit && Object.hasOwn(unit, "engine") ? { engine: unit.engine } : {}),
|
|
@@ -48,21 +55,12 @@ export function executionUnitValues(unit, workspace) {
|
|
|
48
55
|
workspace,
|
|
49
56
|
});
|
|
50
57
|
}
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
* `targets/child-workflow.ts` (the SAME step's effective inputs, re-bound
|
|
56
|
-
* against a composed child workflow's declared `params:`, spec A-N8) — moved
|
|
57
|
-
* here rather than duplicated so both can import it without either importing
|
|
58
|
-
* the other.
|
|
59
|
-
*/
|
|
60
|
-
export function earlierStepIds(sourceIr, stepId) {
|
|
61
|
-
const steps = sourceIr.jobs[0]?.steps ?? [];
|
|
62
|
-
const index = steps.findIndex((step) => step.id === stepId);
|
|
63
|
-
return new Set(index < 0 ? [] : steps.slice(0, index).map((step) => step.id));
|
|
58
|
+
/** Step ids declared BEFORE `stepId` — the same ordering `map.over` and `inputs:` rely on. */
|
|
59
|
+
export function earlierStepIds(plan, stepId) {
|
|
60
|
+
const index = plan.steps.findIndex((step) => step.stepId === stepId);
|
|
61
|
+
return new Set(index < 0 ? [] : plan.steps.slice(0, index).map((step) => step.stepId));
|
|
64
62
|
}
|
|
65
|
-
/** THIS workflow's own declared param names
|
|
66
|
-
export function declaredParamNames(
|
|
67
|
-
return new Set(
|
|
63
|
+
/** THIS workflow's own declared param names — never an outer composing task's. */
|
|
64
|
+
export function declaredParamNames(plan) {
|
|
65
|
+
return new Set(plan.paramSchemas ? Object.keys(plan.paramSchemas) : (plan.params ?? []));
|
|
68
66
|
}
|