akm-cli 0.9.30 → 0.10.261001-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 +438 -0
- package/README.md +10 -10
- package/ROADMAP.md +112 -0
- package/STABILITY.md +99 -57
- package/dist/api-node.mjs +20 -0
- package/dist/api.d.ts +23 -0
- package/dist/api.js +45 -0
- package/dist/assets/hints/cli-hints-full.md +15 -29
- package/dist/assets/hints/cli-hints-short.md +2 -2
- package/dist/assets/improve-strategies/default.json +3 -3
- package/dist/assets/prompts/consolidate-pair.md +9 -7
- package/dist/assets/stash-skeleton/README.md +1 -1
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
- package/dist/cli/shared.js +31 -48
- package/dist/cli/unknown-flags.js +6 -43
- package/dist/cli.js +8 -34
- package/dist/commands/agent/contribute-cli.js +1 -1
- package/dist/commands/completions.js +1 -2
- package/dist/commands/config-cli.js +5 -28
- package/dist/commands/env/env-cli.js +5 -5
- package/dist/commands/env/secret-cli.js +2 -2
- package/dist/commands/feedback-cli.js +75 -49
- package/dist/commands/health/checks.js +41 -16
- package/dist/commands/health/plugin-staleness.js +52 -22
- package/dist/commands/improve/autonomy-gate.js +5 -3
- package/dist/commands/improve/consolidate/chunking.js +3 -10
- package/dist/commands/improve/consolidate/continuity-check.js +4 -4
- package/dist/commands/improve/consolidate/pair-pass.js +29 -10
- package/dist/commands/improve/consolidate.js +10 -65
- package/dist/commands/improve/distill/lesson-update.js +91 -0
- package/dist/commands/improve/distill-guards.js +1 -43
- package/dist/commands/improve/distill.js +148 -21
- package/dist/commands/improve/eligibility.js +14 -1
- package/dist/commands/improve/extract-cli.js +1 -1
- package/dist/commands/improve/extract-prompt.js +17 -7
- package/dist/commands/improve/extract.js +5 -7
- package/dist/commands/improve/improve-cli.js +125 -118
- package/dist/commands/improve/improve-strategies.js +8 -12
- package/dist/commands/improve/improve.js +134 -52
- package/dist/commands/improve/loop-stages.js +18 -5
- package/dist/commands/improve/planner.js +0 -1
- package/dist/commands/improve/preparation.js +40 -99
- package/dist/commands/improve/proactive-maintenance.js +2 -2
- package/dist/commands/improve/reflect-noise.js +3 -55
- package/dist/commands/improve/reflect.js +29 -34
- package/dist/commands/improve/retrieval-queries.js +37 -0
- package/dist/commands/improve/retrieval-scope.js +2 -2
- package/dist/commands/improve/salience.js +2 -9
- package/dist/commands/improve/session-asset.js +4 -1
- package/dist/commands/improve/stage.js +23 -12
- package/dist/commands/lint/index.js +5 -20
- package/dist/commands/observability-cli.js +3 -9
- package/dist/commands/proposal/drain.js +43 -6
- package/dist/commands/proposal/proposal-cli.js +11 -31
- package/dist/commands/proposal/repository.js +20 -14
- package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -3
- package/dist/commands/read/knowledge.js +3 -3
- package/dist/commands/read/remember-cli.js +0 -13
- package/dist/commands/read/search-cli.js +29 -97
- package/dist/commands/read/search.js +0 -11
- package/dist/commands/read/show.js +0 -19
- package/dist/commands/sources/plugin-upgrade.js +164 -101
- package/dist/commands/sources/sources-cli.js +1 -15
- package/dist/commands/sources/stash-cli.js +6 -14
- package/dist/commands/tasks/tasks-cli.js +4 -115
- package/dist/commands/workflow/plan.js +11 -33
- package/dist/commands/workflow-cli.js +2 -7
- package/dist/core/adapter/adapter-ids.js +1 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
- package/dist/core/adapter/adapters/akm-adapter.js +9 -48
- package/dist/core/adapter/adapters/akm-lint.js +10 -26
- package/dist/core/adapter/adapters/akm-metadata.js +2 -72
- package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
- package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
- package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
- package/dist/core/adapter/recognize-match.js +3 -4
- package/dist/core/common.js +18 -2
- package/dist/core/config/config-schema.js +12 -15
- package/dist/core/config/config-types.js +6 -15
- package/dist/core/config/config-walker.js +6 -23
- package/dist/core/config/config.js +17 -80
- package/dist/core/config/engine-semantics.js +7 -3
- package/dist/core/config/schema/engines.js +7 -7
- package/dist/core/config/schema/improve-processes.js +10 -63
- package/dist/core/config/schema/improve.js +2 -21
- package/dist/core/config/schema/index-config.js +6 -39
- package/dist/core/env-secret-ref.js +2 -45
- package/dist/core/errors.js +1 -2
- package/dist/core/extra-params.js +2 -86
- package/dist/core/file-lock.js +12 -7
- package/dist/core/improve-result.js +13 -1
- package/dist/core/mutation-target.js +2 -2
- package/dist/core/paths.js +4 -0
- package/dist/core/recognition-util.js +4 -5
- package/dist/core/run-lock.js +1 -1
- package/dist/core/subprocess.js +49 -0
- package/dist/core/warn.js +21 -4
- package/dist/core/write-source.js +3 -3
- package/dist/execution/target-ref.js +1 -2
- package/dist/indexer/indexer.js +15 -6
- package/dist/indexer/passes/memory-inference.js +15 -6
- package/dist/indexer/search/db-search.js +49 -36
- package/dist/indexer/search/fts-query.js +0 -19
- package/dist/indexer/search/ranking.js +29 -1
- package/dist/indexer/usage/usage-events.js +21 -16
- package/dist/integrations/agent/engine-resolution.js +5 -2
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +41 -98
- package/dist/integrations/agent/request-lowering.js +3 -3
- package/dist/integrations/harnesses/aider/index.js +5 -0
- package/dist/integrations/harnesses/amazonq/index.js +1 -0
- package/dist/integrations/harnesses/claude/config-import.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +5 -0
- package/dist/integrations/harnesses/codex/index.js +1 -0
- package/dist/integrations/harnesses/copilot/index.js +1 -0
- package/dist/integrations/harnesses/gemini/index.js +1 -0
- package/dist/integrations/harnesses/index.js +18 -39
- package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
- package/dist/integrations/harnesses/opencode/config-import.js +121 -52
- package/dist/integrations/harnesses/opencode/index.js +22 -0
- package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
- package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
- package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
- package/dist/integrations/harnesses/opencode/session-log.js +104 -115
- package/dist/integrations/harnesses/opencode/version.js +98 -0
- package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +254 -0
- package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
- package/dist/integrations/harnesses/openhands/index.js +1 -0
- package/dist/integrations/harnesses/pi/index.js +1 -0
- package/dist/integrations/harnesses/shared.js +2 -0
- package/dist/integrations/harnesses/types.js +2 -0
- package/dist/llm/client.js +74 -14
- package/dist/output/cli-hints.js +1 -1
- package/dist/output/context.js +10 -19
- package/dist/output/format-exempt.js +5 -8
- package/dist/output/shapes/helpers.js +1 -22
- package/dist/output/shapes/passthrough.js +0 -1
- package/dist/output/shapes.js +3 -31
- package/dist/output/stdout.js +5 -1
- package/dist/output/text/command-format.js +6 -1
- package/dist/output/text/workflow-format.js +4 -22
- package/dist/scripts/akm-migrate-node.js +15769 -16731
- package/dist/scripts/akm-migrate.js +16339 -17297
- package/dist/setup/detect.js +10 -4
- package/dist/setup/harness-config-import.js +5 -14
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +12 -13
- package/dist/sources/providers/git-stash.js +94 -13
- package/dist/storage/repositories/index-utility-repository.js +2 -32
- package/dist/storage/repositories/index-vec-repository.js +4 -0
- package/dist/storage/repositories/task-history-repository.js +0 -5
- package/dist/storage/repositories/workflow-runs-repository.js +5 -15
- package/dist/tasks/embedded.js +2 -1
- package/dist/tasks/run/run-command-task.js +9 -1
- package/dist/tasks/run/run-workflow-task.js +4 -3
- package/dist/tasks/run/task-history.js +0 -2
- package/dist/tasks/run/task-log.js +38 -1
- package/dist/tasks/schedule-gates.js +39 -0
- package/dist/tasks/scheduler-binding.js +0 -16
- package/dist/tasks/scheduler-sync.js +3 -97
- package/dist/tasks/source/bounded-document.js +1 -1
- package/dist/tasks/source/task-source-v4.js +2 -12
- package/dist/tasks/task-run-reserved-flags.js +2 -31
- package/dist/workflows/authoring/authoring.js +6 -6
- package/dist/workflows/compile.js +8 -65
- package/dist/workflows/exec/child-workflow.js +22 -3
- package/dist/workflows/exec/native-executor.js +12 -147
- package/dist/workflows/exec/run-workflow.js +31 -103
- package/dist/workflows/exec/step-work.js +9 -178
- package/dist/workflows/exec/unit-dispatch.js +0 -10
- package/dist/workflows/freeze/environment.js +3 -44
- package/dist/workflows/freeze/freeze.js +8 -41
- package/dist/workflows/freeze/targets/child-workflow.js +27 -63
- package/dist/workflows/freeze/targets/command.js +2 -16
- package/dist/workflows/freeze/targets/shell.js +0 -2
- package/dist/workflows/freeze/task-bindings.js +2 -28
- package/dist/workflows/ir/params.js +12 -2
- package/dist/workflows/parser.js +82 -232
- package/dist/workflows/plan.js +1 -1
- package/dist/workflows/renderer.js +10 -19
- package/dist/workflows/runtime/run-plan.js +11 -53
- package/dist/workflows/runtime/runs.js +4 -27
- package/dist/workflows/source-files.js +12 -16
- package/dist/workflows/source-semantics.js +1 -93
- package/docs/README.md +43 -42
- package/docs/agents/README.md +15 -0
- package/docs/agents/agent-install.md +14 -0
- package/docs/architecture/0.10-process-rules.md +827 -0
- package/docs/architecture/README.md +67 -0
- package/docs/architecture/adapters.md +258 -0
- package/docs/architecture/akm-architecture-decision-history.md +2055 -0
- package/docs/architecture/akm-core-principles.md +126 -0
- package/docs/architecture/architecture.md +578 -0
- package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
- package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
- package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
- package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
- package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
- package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
- package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
- package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
- package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
- package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
- package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
- package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
- package/docs/architecture/decisions/README.md +62 -0
- package/docs/architecture/improvement.md +479 -0
- package/docs/architecture/internals/classification.md +154 -0
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
- package/docs/architecture/internals/functional-contract-patterns.md +340 -0
- package/docs/architecture/internals/health-advisories.md +110 -0
- package/docs/architecture/internals/improve-workflow.md +719 -0
- package/docs/architecture/internals/indexing.md +498 -0
- package/docs/architecture/internals/registry-network-boundary.md +57 -0
- package/docs/architecture/internals/search.md +248 -0
- package/docs/architecture/internals/storage-locations.md +943 -0
- package/docs/architecture/persisted-data-compat.md +68 -0
- package/docs/architecture/reviews/env-secret-access.md +319 -0
- package/docs/architecture/runtime-boundary-design.md +153 -0
- package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
- package/docs/architecture/specs/0.9.0-decisions.md +532 -0
- package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
- package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
- package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
- package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
- package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
- package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
- package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
- package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
- package/docs/architecture/specs/di-seams-plan.md +539 -0
- package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
- package/docs/architecture/specs/fact-asset-type.md +142 -0
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
- package/docs/architecture/specs/okf-support.md +148 -0
- package/docs/architecture/specs/ref.md +329 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
- package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
- package/docs/architecture/specs/stash-organization-conventions.md +377 -0
- package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
- package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
- package/docs/architecture/specs/workflow-format-unification.md +432 -0
- package/docs/architecture/testing/manual-testing-checklist.md +3411 -0
- package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
- package/docs/architecture/testing/task-workflow-manual-tests.md +1720 -0
- package/docs/architecture/testing/testing-workflow.md +446 -0
- package/docs/architecture/workflow-engine.md +223 -0
- package/docs/guides/README.md +33 -0
- package/docs/guides/author-bundles.md +310 -0
- package/docs/guides/author-workflows.md +490 -0
- package/docs/guides/bundles.md +323 -0
- package/docs/guides/capture-knowledge.md +136 -0
- package/docs/guides/claude-code-vs-akm-workflows.md +29 -0
- package/docs/guides/concepts.md +93 -0
- package/docs/guides/discover-and-load.md +158 -0
- package/docs/guides/getting-started.md +240 -0
- package/docs/guides/improve-the-library.md +247 -0
- package/docs/guides/knowledge-management.md +18 -0
- package/docs/guides/recipes/headless-install.md +97 -0
- package/docs/guides/recipes/website-source.md +28 -0
- package/docs/guides/run-workflows.md +279 -0
- package/docs/guides/scheduling.md +131 -0
- package/docs/guides/use-with-any-agent.md +174 -0
- package/docs/guides/wikis.md +81 -0
- package/docs/integration/bundling-akm.md +7 -6
- package/docs/maintainers/README.md +19 -0
- package/docs/maintainers/curate-workmap.md +335 -0
- package/docs/maintainers/eval.md +3 -0
- package/docs/maintainers/local-development.md +108 -0
- package/docs/maintainers/release-checklist.md +135 -0
- package/docs/migration/README.md +4 -2
- package/docs/migration/release-notes/0.0.13.md +1 -1
- package/docs/migration/release-notes/0.1.0.md +1 -1
- package/docs/migration/release-notes/0.10.0.md +201 -0
- package/docs/migration/release-notes/0.2.0.md +1 -1
- package/docs/migration/release-notes/0.3.0.md +1 -1
- package/docs/migration/release-notes/0.5.0.md +1 -1
- 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.7.3.md +2 -2
- package/docs/migration/release-notes/0.7.4.md +1 -1
- package/docs/migration/release-notes/0.7.5.md +1 -1
- package/docs/migration/release-notes/0.8.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +1 -1
- package/docs/migration/release-notes/0.9.14.md +1 -1
- package/docs/migration/release-notes/0.9.15.md +1 -1
- package/docs/migration/release-notes/0.9.16.md +1 -1
- package/docs/migration/release-notes/0.9.17.md +1 -1
- package/docs/migration/release-notes/0.9.19.md +1 -1
- package/docs/migration/release-notes/0.9.2.md +1 -1
- package/docs/migration/release-notes/README.md +28 -31
- package/docs/migration/v0.5-to-v0.6.md +759 -0
- package/docs/migration/v0.8-to-v0.9.md +1 -1
- package/docs/migration/v0.9-to-v0.10.md +507 -0
- package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
- package/docs/posts/README.md +30 -0
- package/docs/posts/akm-command-tour.md +495 -0
- package/docs/posts/akm-logo-sized.webp +0 -0
- package/docs/posts/belief-aware-memory-12.md +139 -0
- package/docs/posts/config-v2-lessons-16.md +191 -0
- package/docs/posts/improve-loop-autonomous-10.md +225 -0
- package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
- package/docs/posts/intro-part-01.md +76 -0
- package/docs/posts/intro-part-02.md +221 -0
- package/docs/posts/intro-part-03.md +190 -0
- package/docs/posts/intro-part-04.md +221 -0
- package/docs/posts/llm-mode-reflect-13.md +166 -0
- package/docs/posts/openpalm-built-on-akm.md +86 -0
- package/docs/posts/progressive-disclosure-06.md +129 -0
- package/docs/posts/proposal-safety-net-15.md +112 -0
- package/docs/posts/release-0.5.0.md +247 -0
- package/docs/posts/release-0.6.0.md +117 -0
- package/docs/posts/release-0.7.0.md +159 -0
- package/docs/posts/release-0.8.0.md +332 -0
- package/docs/posts/scattered-skills-05.md +100 -0
- package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
- package/docs/posts/team-skills-07.md +198 -0
- package/docs/posts/wiki-agent-knowledge-08.md +223 -0
- package/docs/posts/workflows-vaults-09.md +321 -0
- package/docs/product-surface.md +54 -0
- package/docs/reference/README.md +2 -2
- package/docs/reference/api.md +65 -0
- package/docs/reference/asset-types.md +166 -0
- package/docs/reference/bundle-types.md +2 -4
- package/docs/reference/cli.md +163 -192
- package/docs/reference/configuration.md +101 -20
- package/docs/reference/data-and-telemetry.md +2 -2
- package/docs/reference/env-and-secrets.md +126 -0
- package/docs/reference/memory.md +124 -0
- package/docs/reference/refs.md +156 -0
- package/docs/reference/registry.md +489 -0
- package/docs/reference/supported-formats.md +3 -4
- package/docs/reference/tasks.md +12 -19
- package/docs/reference/website-sources.md +141 -0
- package/docs/reference/workflow-schema.md +89 -317
- package/docs/reference/workflows.md +20 -48
- package/package.json +23 -16
- package/schemas/akm-config.json +2 -243
- package/schemas/akm-task.json +2 -3
- package/schemas/akm-workflow.json +47 -84
- package/dist/assets/improve-strategies/catchup.json +0 -41
- package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
- package/dist/assets/improve-strategies/quick.json +0 -17
- package/dist/assets/improve-strategies/reflect-distill.json +0 -29
- package/dist/assets/improve-strategies/thorough.json +0 -49
- package/dist/assets/prompts/retrieval-relevance-judge.md +0 -6
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
- package/dist/cli/retired-commands.js +0 -118
- package/dist/commands/improve/retrieval-gate.js +0 -132
- package/dist/commands/tasks/validate.js +0 -176
- package/dist/core/config/legacy-source-shape-shim.js +0 -117
- package/dist/indexer/feedback/utility-policy.js +0 -75
- package/dist/integrations/harnesses/ids.js +0 -28
- package/dist/tasks/source/task-source-v3-frozen.js +0 -424
- package/dist/tasks/source/task-to-v4.js +0 -863
- package/dist/workflows/exec/worktree.js +0 -372
- package/dist/workflows/freeze/child-output-references.js +0 -83
- package/dist/workflows/freeze/identity.js +0 -22
- package/dist/workflows/freeze/targets/script.js +0 -50
- package/dist/workflows/freeze/targets/task.js +0 -124
- package/dist/workflows/github-yaml.js +0 -506
- package/dist/workflows/runtime/run-outputs.js +0 -80
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { captureFrozenDirectoryIdentity } from "../../../execution/directory-identity.js";
|
|
5
5
|
import { freezeEnvironment } from "../environment.js";
|
|
6
|
-
import { gitIdentity } from "../identity.js";
|
|
7
6
|
import { freezeExecSpec, } from "../step-values.js";
|
|
8
7
|
export function directShell(source, baseUnit, context) {
|
|
9
8
|
const authoredExec = baseUnit.exec;
|
|
@@ -17,7 +16,6 @@ export function directShell(source, baseUnit, context) {
|
|
|
17
16
|
contentHash: "",
|
|
18
17
|
exec,
|
|
19
18
|
cwdIdentity,
|
|
20
|
-
...gitIdentity(baseUnit, cwdIdentity.realRoot),
|
|
21
19
|
});
|
|
22
20
|
return {
|
|
23
21
|
target,
|
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* Pure freeze-time binding of a composing step's inputs.
|
|
6
6
|
* {@link freezeTaskInputBindings} classifies an authored `with:` against a
|
|
7
|
-
* contract
|
|
8
|
-
*
|
|
9
|
-
* against a child workflow's `params:`) without re-deriving their kind. A
|
|
10
|
-
* reference's resolved value is validated before each attempt (`exec/step-work.ts`).
|
|
7
|
+
* child workflow's `params:` contract. A reference's resolved value is
|
|
8
|
+
* validated before each attempt (`exec/step-work.ts`).
|
|
11
9
|
* See docs/architecture/decisions/0008-task-binding-normalization.md.
|
|
12
10
|
*/
|
|
13
11
|
import { isRecord } from "../../core/common.js";
|
|
@@ -41,30 +39,6 @@ export function freezeTaskInputBindings(input) {
|
|
|
41
39
|
}
|
|
42
40
|
return finalizeBindings(stepId, targetRef, contract, byName);
|
|
43
41
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Re-bind already-normalized bindings by name against a different contract,
|
|
46
|
-
* keeping each entry's kind (a literal shaped like `{from}` stays a literal).
|
|
47
|
-
* A literal is validated against the new contract; a reference keeps its
|
|
48
|
-
* `from` and takes the new contract's schema; undeclared names are
|
|
49
|
-
* `INPUT_BINDING_INVALID`; missing keys are defaulted or required as usual.
|
|
50
|
-
*/
|
|
51
|
-
export function rebindTaskInputBindings(input) {
|
|
52
|
-
const { stepId, targetRef, contract } = input;
|
|
53
|
-
const declaredNames = Object.keys(contract).sort();
|
|
54
|
-
const byName = new Map();
|
|
55
|
-
for (const binding of input.bindings ?? []) {
|
|
56
|
-
if (!Object.hasOwn(contract, binding.name)) {
|
|
57
|
-
throw unknownBindingNameError(stepId, targetRef, binding.name, declaredNames);
|
|
58
|
-
}
|
|
59
|
-
const declaration = contract[binding.name];
|
|
60
|
-
if (!declaration)
|
|
61
|
-
throw inputBindingInvalid(`Workflow step ${stepId} targets ${targetRef} with.${binding.name} is invalid.`);
|
|
62
|
-
byName.set(binding.name, binding.kind === "literal"
|
|
63
|
-
? binding
|
|
64
|
-
: Object.freeze({ kind: "reference", name: binding.name, from: binding.from, schema: declaration.schema }));
|
|
65
|
-
}
|
|
66
|
-
return finalizeBindings(stepId, targetRef, contract, byName);
|
|
67
|
-
}
|
|
68
42
|
/** Shared tail: apply defaults (or require), schema-validate every literal, and sort by name. */
|
|
69
43
|
function finalizeBindings(stepId, targetRef, contract, byName) {
|
|
70
44
|
for (const [name, declaration] of Object.entries(contract)) {
|
|
@@ -7,13 +7,16 @@
|
|
|
7
7
|
* every declared param is optional, and the messages are the workflow ones.
|
|
8
8
|
*/
|
|
9
9
|
import { UsageError } from "../../core/errors.js";
|
|
10
|
-
import { materializeInputFlags, validateInputs, } from "../../execution/input-contract.js";
|
|
10
|
+
import { applyInputDefaults, materializeInputFlags, validateInputs, } from "../../execution/input-contract.js";
|
|
11
11
|
/** Every declared workflow param as an `InputDeclaration`, `required: false` — workflow params declare nothing required. */
|
|
12
12
|
function contractFromPlan(plan) {
|
|
13
13
|
const names = plan.params ?? Object.keys(plan.paramSchemas ?? {});
|
|
14
14
|
const contract = {};
|
|
15
15
|
for (const name of names) {
|
|
16
|
-
|
|
16
|
+
const schema = plan.paramSchemas?.[name] ?? {};
|
|
17
|
+
contract[name] = Object.hasOwn(schema, "default")
|
|
18
|
+
? { schema, default: schema.default, required: false }
|
|
19
|
+
: { schema, required: false };
|
|
17
20
|
}
|
|
18
21
|
return contract;
|
|
19
22
|
}
|
|
@@ -45,6 +48,13 @@ export function materializeWorkflowParameterFlags(plan, flags) {
|
|
|
45
48
|
return {};
|
|
46
49
|
return materializeInputFlags(contractFromPlan(plan), flags, WORKFLOW_PARAMETER_DIAGNOSTICS);
|
|
47
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Fill each declared param the run did not supply with its `default:`. An
|
|
53
|
+
* explicit value always wins; params without a default stay absent.
|
|
54
|
+
*/
|
|
55
|
+
export function applyWorkflowParamDefaults(plan, params) {
|
|
56
|
+
return applyInputDefaults(contractFromPlan(plan), params);
|
|
57
|
+
}
|
|
48
58
|
/**
|
|
49
59
|
* Validate a run's supplied params against the plan's frozen param schemas.
|
|
50
60
|
* Returns a flat list of human-readable, path-prefixed error strings (empty =
|
package/dist/workflows/parser.js
CHANGED
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
*
|
|
20
20
|
* 1. Every level-2 heading must be `## <step-id>` for a DECLARED step,
|
|
21
21
|
* exactly (fenced code blocks are skipped when scanning for headings).
|
|
22
|
-
* 2. A
|
|
23
|
-
* the next H2 or EOF)
|
|
22
|
+
* 2. A step MUST have a section (its instructions, byte-exact to
|
|
23
|
+
* the next H2 or EOF). Everything before the first H2
|
|
24
24
|
* is free preamble.
|
|
25
25
|
* 3. Inside a step section, an optional `### gate` sub-heading starts the
|
|
26
26
|
* step's gate rubric (to the section end) — the format's single
|
|
@@ -28,24 +28,24 @@
|
|
|
28
28
|
*
|
|
29
29
|
* Prose (instructions, gate rubrics, preamble) is NEVER templated or scanned
|
|
30
30
|
* for reference syntax — it reaches the dispatched unit byte-exact. Only
|
|
31
|
-
*
|
|
32
|
-
* (`program/expressions.ts`): `map.over`, `
|
|
31
|
+
* two whole-value frontmatter positions carry the closed reference grammar
|
|
32
|
+
* (`program/expressions.ts`): `map.over`, `inputs[]`.
|
|
33
33
|
*/
|
|
34
34
|
import { LineCounter, parseDocument } from "yaml";
|
|
35
35
|
import { bundleRefToString, parseBundleRef } from "../core/asset/asset-ref.js";
|
|
36
36
|
import { parseFrontmatterBlock } from "../core/asset/frontmatter.js";
|
|
37
37
|
import { parseMarkdownToc } from "../core/asset/markdown.js";
|
|
38
|
-
import {
|
|
38
|
+
import { isContainedRelativePath, isRecord } from "../core/common.js";
|
|
39
39
|
import { formatExtraParamsIssue, validateExtraParams } from "../core/extra-params.js";
|
|
40
40
|
import { checkJsonSchemaDefinition, JSON_SCHEMA_SUBSET_SUPPORTED_KEYWORDS } from "../core/json-schema.js";
|
|
41
41
|
import { INPUT_NAME_PATTERN } from "../execution/input-contract.js";
|
|
42
|
+
import { classifyTargetRef } from "../execution/target-ref.js";
|
|
42
43
|
import { WORKFLOW_PLAN_VERSION, } from "./plan.js";
|
|
43
44
|
import { parseReference } from "./program/expressions.js";
|
|
44
45
|
import { jsonBytes, utf8Bytes, WORKFLOW_ENGINE_NAME_PATTERN, WORKFLOW_ENV_VAR_NAME_PATTERN, WORKFLOW_MAX_CONCURRENCY, WORKFLOW_MAX_ENGINE_NAME_LENGTH, WORKFLOW_MAX_EXTRA_PARAMS_BYTES, WORKFLOW_MAX_INSTRUCTION_BYTES, WORKFLOW_MAX_SCHEMA_BYTES, WORKFLOW_MAX_SOURCE_BYTES, WORKFLOW_MAX_TIMEOUT_MS, } from "./resource-limits.js";
|
|
45
46
|
// ── The Markdown grammar's vocabulary (pinned against schemas/akm-workflow.json) ──
|
|
46
47
|
export const PROGRAM_REDUCERS = ["collect", "vote"];
|
|
47
48
|
export const PROGRAM_ON_ERROR = ["fail", "continue"];
|
|
48
|
-
export const PROGRAM_ISOLATION_KINDS = ["none", "worktree"];
|
|
49
49
|
/** `retry.on`: exactly the persisted `AgentFailureReason` taxonomy (the `satisfies` fails typecheck on drift). */
|
|
50
50
|
const RETRY_REASON_SET = {
|
|
51
51
|
timeout: true,
|
|
@@ -86,22 +86,30 @@ const ENVELOPE_KEYS = [
|
|
|
86
86
|
"status",
|
|
87
87
|
"stale_after",
|
|
88
88
|
];
|
|
89
|
-
const WORKFLOW_KEYS = ["params", "
|
|
89
|
+
const WORKFLOW_KEYS = ["params", "defaults", "budget", "steps"];
|
|
90
90
|
const TOP_LEVEL_KEYS = [...ENVELOPE_KEYS, ...WORKFLOW_KEYS];
|
|
91
91
|
const DEFAULTS_KEYS = ["engine", "model", "timeout", "on_error", "llm"];
|
|
92
92
|
const BUDGET_KEYS = ["max_tokens", "max_units"];
|
|
93
|
-
const STEP_KEYS = ["id", "unit", "map", "
|
|
94
|
-
const UNIT_KEYS = [
|
|
93
|
+
const STEP_KEYS = ["id", "unit", "map", "inputs", "output", "gate"];
|
|
94
|
+
const UNIT_KEYS = [
|
|
95
|
+
"exec",
|
|
96
|
+
"workflow",
|
|
97
|
+
"with",
|
|
98
|
+
"engine",
|
|
99
|
+
"model",
|
|
100
|
+
"llm",
|
|
101
|
+
"timeout",
|
|
102
|
+
"retry",
|
|
103
|
+
"on_error",
|
|
104
|
+
"output",
|
|
105
|
+
"env",
|
|
106
|
+
];
|
|
95
107
|
const EXEC_KEYS = ["command", "cwd", "pass_env"];
|
|
96
108
|
/** Unit keys that name an ENGINE dispatch and therefore cannot appear beside `exec:`. */
|
|
97
109
|
const UNIT_ENGINE_KEYS = ["engine", "model", "llm"];
|
|
98
110
|
const MAP_KEYS = ["over", "concurrency", "reducer", "unit"];
|
|
99
|
-
const ROUTE_KEYS = ["input", "when", "default"];
|
|
100
111
|
const RETRY_KEYS = ["max", "on"];
|
|
101
112
|
const GATE_KEYS = ["max_loops"];
|
|
102
|
-
const ROUTE_BRANCH_KEYS = ["match", "step"];
|
|
103
|
-
/** Closed key set of one `outputs:` entry — mirrors `params:`'s bare-schema shape, plus `from`. */
|
|
104
|
-
const OUTPUT_ENTRY_KEYS = ["from", "schema"];
|
|
105
113
|
const ACTOR_STAMP_KEYS = ["by", "at"];
|
|
106
114
|
const TIMEOUT_VALUE = /^(\d+)(ms|s|m)?$/;
|
|
107
115
|
const TIMEOUT_HINT = `Use "<n>ms", "<n>s", "<n>m" (e.g. "10m"), or "none"`;
|
|
@@ -206,7 +214,6 @@ export function parseWorkflow(markdown, source) {
|
|
|
206
214
|
const description = typeof root.description === "string" ? root.description : undefined;
|
|
207
215
|
readTags(ctx, root.tags, frontmatterEndLine);
|
|
208
216
|
const params = parseParams(ctx, root.params);
|
|
209
|
-
const outputs = parseOutputs(ctx, root.outputs);
|
|
210
217
|
const defaults = parseDefaults(ctx, root.defaults);
|
|
211
218
|
const budget = parseBudget(ctx, root.budget);
|
|
212
219
|
const parsedSteps = parseSteps(ctx, root.steps);
|
|
@@ -217,14 +224,12 @@ export function parseWorkflow(markdown, source) {
|
|
|
217
224
|
const steps = parsedSteps.map((step, index) => {
|
|
218
225
|
const section = sections.get(step.id);
|
|
219
226
|
if (!section) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
});
|
|
225
|
-
}
|
|
227
|
+
errors.push({
|
|
228
|
+
line: step.source.start,
|
|
229
|
+
message: `Step "${step.id}" must have a "## ${step.id}" body section with its instructions.`,
|
|
230
|
+
});
|
|
226
231
|
}
|
|
227
|
-
else if (
|
|
232
|
+
else if (!section.instructions) {
|
|
228
233
|
errors.push({
|
|
229
234
|
line: section.headingLine,
|
|
230
235
|
message: `Step "${step.id}" section ("## ${step.id}") is empty. Add the step's instructions below the heading.`,
|
|
@@ -244,15 +249,6 @@ export function parseWorkflow(markdown, source) {
|
|
|
244
249
|
title: step.id,
|
|
245
250
|
sequenceIndex: index,
|
|
246
251
|
spec: stepSpec(step, section),
|
|
247
|
-
...(step.route
|
|
248
|
-
? {
|
|
249
|
-
route: {
|
|
250
|
-
input: step.route.input,
|
|
251
|
-
when: Object.fromEntries(step.route.branches.map((branch) => [branch.match, branch.stepId])),
|
|
252
|
-
...(step.route.defaultStepId !== undefined ? { defaultStepId: step.route.defaultStepId } : {}),
|
|
253
|
-
},
|
|
254
|
-
}
|
|
255
|
-
: {}),
|
|
256
252
|
...(step.output !== undefined ? { outputSchema: step.output } : {}),
|
|
257
253
|
gate: {
|
|
258
254
|
kind: "gate",
|
|
@@ -272,7 +268,6 @@ export function parseWorkflow(markdown, source) {
|
|
|
272
268
|
irVersion: WORKFLOW_PLAN_VERSION,
|
|
273
269
|
title: source.title ?? path.replace(/^.*[\\/]/, "").replace(/\.[^.]*$/, ""),
|
|
274
270
|
...(params && paramNames.length > 0 ? { params: paramNames, paramSchemas: params } : {}),
|
|
275
|
-
...(outputs ? { outputs: sortedByName(outputs) } : {}),
|
|
276
271
|
...(budget ? { budget } : {}),
|
|
277
272
|
...(defaults ? { defaults } : {}),
|
|
278
273
|
...(description ? { description } : {}),
|
|
@@ -284,14 +279,18 @@ export function parseWorkflow(markdown, source) {
|
|
|
284
279
|
/** The authored step as the plan carries it. A prose step is inline `akm/command` literal content. */
|
|
285
280
|
function stepSpec(step, section) {
|
|
286
281
|
const prose = section?.instructions?.text;
|
|
287
|
-
if (step.route)
|
|
288
|
-
return { ...(prose?.trim() ? { instructions: prose } : {}), source: step.source };
|
|
289
282
|
const dispatchUnit = step.map?.unit ?? step.unit;
|
|
290
|
-
const { exec, source: _unitSource, ...unit } = dispatchUnit ?? { source: step.source };
|
|
283
|
+
const { exec, workflow, with: childWith, source: _unitSource, ...unit } = dispatchUnit ?? { source: step.source };
|
|
291
284
|
return {
|
|
292
|
-
...(
|
|
293
|
-
? {
|
|
294
|
-
|
|
285
|
+
...(workflow
|
|
286
|
+
? {
|
|
287
|
+
workflow,
|
|
288
|
+
...(childWith ? { with: childWith } : {}),
|
|
289
|
+
...(prose?.trim() ? { instructions: prose } : {}),
|
|
290
|
+
}
|
|
291
|
+
: exec
|
|
292
|
+
? { exec: { ...exec }, ...(prose?.trim() ? { instructions: prose } : {}) }
|
|
293
|
+
: { uses: "akm/command", with: { content: prose ?? "" } }),
|
|
295
294
|
...(Object.keys(unit).length > 0 ? { unit } : {}),
|
|
296
295
|
...(step.map
|
|
297
296
|
? {
|
|
@@ -306,12 +305,6 @@ function stepSpec(step, section) {
|
|
|
306
305
|
source: step.source,
|
|
307
306
|
};
|
|
308
307
|
}
|
|
309
|
-
/** `outputs:` in canonical wire order (code-point ascending by name). */
|
|
310
|
-
function sortedByName(entries) {
|
|
311
|
-
return Object.fromEntries(Object.keys(entries)
|
|
312
|
-
.sort(compareCodePoints)
|
|
313
|
-
.map((name) => [name, entries[name]]));
|
|
314
|
-
}
|
|
315
308
|
/** `xrefs` entries must be canonical asset refs. */
|
|
316
309
|
function checkCanonicalXrefs(value, line, errors) {
|
|
317
310
|
if (!Array.isArray(value))
|
|
@@ -521,71 +514,6 @@ function parseParams(ctx, raw) {
|
|
|
521
514
|
}
|
|
522
515
|
return Object.keys(params).length > 0 ? params : undefined;
|
|
523
516
|
}
|
|
524
|
-
/**
|
|
525
|
-
* `outputs:`: named, optionally schema-validated projections
|
|
526
|
-
* of step artifacts, exported when the run completes. Symmetrical with
|
|
527
|
-
* `parseParams` above — same authoring surface, same name grammar,
|
|
528
|
-
* same schema-subset validator, same per-schema byte bound — but each entry
|
|
529
|
-
* is a STRUCTURED `{from, schema?}` mapping rather than a bare JSON Schema.
|
|
530
|
-
*
|
|
531
|
-
* `from` is validated for GRAMMAR only here: it must parse and it must be a
|
|
532
|
-
* `steps.<id>.output(.<seg>)*` reference (never `params.<name>` — an output
|
|
533
|
-
* projects a step artifact, never a param, B-07). Whether the named step is
|
|
534
|
-
* actually DECLARED in this document is a semantic, cross-step check left to
|
|
535
|
-
* `compile.ts`'s `checkWorkflowPlan`, mirroring how `inputs[]` /
|
|
536
|
-
* `map.over` / `route.input` already split "syntax here, semantics there".
|
|
537
|
-
*/
|
|
538
|
-
function parseOutputs(ctx, raw) {
|
|
539
|
-
if (raw === undefined)
|
|
540
|
-
return undefined;
|
|
541
|
-
if (!isRecord(raw)) {
|
|
542
|
-
ctx.err(["outputs"], `"outputs" must be a mapping of output name to { from, schema? } (e.g. report: { from: steps.summarize.output }).`);
|
|
543
|
-
return undefined;
|
|
544
|
-
}
|
|
545
|
-
const outputs = {};
|
|
546
|
-
for (const [outputName, value] of Object.entries(raw)) {
|
|
547
|
-
const path = ["outputs", outputName];
|
|
548
|
-
if (!PROGRAM_PARAM_NAME_PATTERN.test(outputName)) {
|
|
549
|
-
ctx.err(path, `Output name "${outputName}" is invalid. Use letters, digits, and underscores, starting with a letter or ` +
|
|
550
|
-
`underscore, so "steps.<child>.output.${outputName}" can address it.`);
|
|
551
|
-
continue;
|
|
552
|
-
}
|
|
553
|
-
if (!isRecord(value)) {
|
|
554
|
-
ctx.err(path, `Output "${outputName}" must be a mapping with "from" (and optional "schema").`);
|
|
555
|
-
continue;
|
|
556
|
-
}
|
|
557
|
-
checkUnknownKeys(ctx, value, path, OUTPUT_ENTRY_KEYS, `output "${outputName}"`);
|
|
558
|
-
if (typeof value.from !== "string" || value.from.trim() === "") {
|
|
559
|
-
ctx.err([...path, "from"], `Output "${outputName}" must declare "from": a steps.<id>.output(.<seg>)* reference.`);
|
|
560
|
-
continue;
|
|
561
|
-
}
|
|
562
|
-
const parsedFrom = parseReference(value.from);
|
|
563
|
-
if (!parsedFrom.ok) {
|
|
564
|
-
ctx.err([...path, "from"], `Output "${outputName}" "from": ${parsedFrom.message}`);
|
|
565
|
-
continue;
|
|
566
|
-
}
|
|
567
|
-
if (parsedFrom.expr.kind !== "stepOutput") {
|
|
568
|
-
ctx.err([...path, "from"], `Output "${outputName}" "from" must reference a step output (steps.<id>.output...), not a param — an ` +
|
|
569
|
-
`output projects a step artifact, never a param (got "${value.from}").`);
|
|
570
|
-
continue;
|
|
571
|
-
}
|
|
572
|
-
const entry = { from: value.from };
|
|
573
|
-
if (value.schema !== undefined) {
|
|
574
|
-
if (!isRecord(value.schema)) {
|
|
575
|
-
ctx.err([...path, "schema"], `Output "${outputName}" "schema" must be a JSON Schema object.`);
|
|
576
|
-
}
|
|
577
|
-
else {
|
|
578
|
-
if (jsonBytes(value.schema) > WORKFLOW_MAX_SCHEMA_BYTES) {
|
|
579
|
-
ctx.err([...path, "schema"], `Output "${outputName}" schema exceeds the 256 KiB resource limit.`);
|
|
580
|
-
}
|
|
581
|
-
checkSchemaDefinition(ctx, value.schema, [...path, "schema"], `Output "${outputName}" schema`);
|
|
582
|
-
entry.schema = value.schema;
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
outputs[outputName] = entry;
|
|
586
|
-
}
|
|
587
|
-
return Object.keys(outputs).length > 0 ? outputs : undefined;
|
|
588
|
-
}
|
|
589
517
|
function parseDefaults(ctx, raw) {
|
|
590
518
|
if (raw === undefined)
|
|
591
519
|
return undefined;
|
|
@@ -651,17 +579,8 @@ function parseSteps(ctx, raw) {
|
|
|
651
579
|
ctx.err(["steps"], `"steps" is required and must be a list with at least one step.`);
|
|
652
580
|
return [];
|
|
653
581
|
}
|
|
654
|
-
// First pass: collect ids so route targets can be checked against ALL steps
|
|
655
|
-
// (including ones that fail their own validation).
|
|
656
|
-
const idIndex = new Map();
|
|
657
|
-
raw.forEach((rawStep, index) => {
|
|
658
|
-
if (isRecord(rawStep) && typeof rawStep.id === "string" && !idIndex.has(rawStep.id)) {
|
|
659
|
-
idIndex.set(rawStep.id, index);
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
582
|
const steps = [];
|
|
663
583
|
const seenIds = new Map();
|
|
664
|
-
const routeChecks = [];
|
|
665
584
|
raw.forEach((rawStep, index) => {
|
|
666
585
|
const path = ["steps", index];
|
|
667
586
|
if (!isRecord(rawStep)) {
|
|
@@ -689,27 +608,13 @@ function parseSteps(ctx, raw) {
|
|
|
689
608
|
seenIds.set(id, index);
|
|
690
609
|
}
|
|
691
610
|
}
|
|
692
|
-
const declaredKinds = ["map", "route"].filter((kind) => rawStep[kind] !== undefined);
|
|
693
|
-
if (declaredKinds.length > 1) {
|
|
694
|
-
ctx.err(path, `${label} must declare at most one of "map" or "route" (found ${declaredKinds.join(" + ")}).`);
|
|
695
|
-
}
|
|
696
|
-
const isRoute = rawStep.route !== undefined;
|
|
697
611
|
const isMapStep = rawStep.map !== undefined;
|
|
698
|
-
if (isRoute && rawStep.unit !== undefined) {
|
|
699
|
-
ctx.err(path, `${label} is a route step and cannot also declare "unit" (route steps dispatch no unit).`);
|
|
700
|
-
}
|
|
701
612
|
if (isMapStep && rawStep.unit !== undefined) {
|
|
702
613
|
ctx.err(path, `${label} is a map step; the per-item dispatch-override bag belongs at "map.unit", not top-level "unit".`);
|
|
703
614
|
}
|
|
704
|
-
|
|
705
|
-
ctx.err(path, `${label} is a route step and cannot declare "inputs" (route steps dispatch no unit).`);
|
|
706
|
-
}
|
|
707
|
-
const unit = rawStep.unit !== undefined && !isRoute && !isMapStep
|
|
708
|
-
? parseUnit(ctx, rawStep.unit, [...path, "unit"], label)
|
|
709
|
-
: undefined;
|
|
615
|
+
const unit = rawStep.unit !== undefined && !isMapStep ? parseUnit(ctx, rawStep.unit, [...path, "unit"], label) : undefined;
|
|
710
616
|
const map = isMapStep ? parseMap(ctx, rawStep.map, [...path, "map"], label) : undefined;
|
|
711
|
-
const
|
|
712
|
-
const inputs = !isRoute ? parseInputs(ctx, rawStep.inputs, [...path, "inputs"], label) : undefined;
|
|
617
|
+
const inputs = parseInputs(ctx, rawStep.inputs, [...path, "inputs"], label);
|
|
713
618
|
const output = parseSchemaObject(ctx, rawStep.output, [...path, "output"], `${label} "output"`);
|
|
714
619
|
const gate = rawStep.gate !== undefined ? parseGate(ctx, rawStep.gate, [...path, "gate"], label) : undefined;
|
|
715
620
|
const step = { id, source: ctx.refAt(path) };
|
|
@@ -717,8 +622,6 @@ function parseSteps(ctx, raw) {
|
|
|
717
622
|
step.unit = unit;
|
|
718
623
|
if (map)
|
|
719
624
|
step.map = map;
|
|
720
|
-
if (route)
|
|
721
|
-
step.route = route;
|
|
722
625
|
if (inputs)
|
|
723
626
|
step.inputs = inputs;
|
|
724
627
|
if (output !== undefined)
|
|
@@ -727,31 +630,12 @@ function parseSteps(ctx, raw) {
|
|
|
727
630
|
step.gate = gate;
|
|
728
631
|
steps.push(step);
|
|
729
632
|
});
|
|
730
|
-
// Route target post-pass: targets exist, come after the routing step, and
|
|
731
|
-
// never point back at it.
|
|
732
|
-
for (const check of routeChecks) {
|
|
733
|
-
const targets = [...check.branches.map((b) => ({ stepId: b.stepId, line: b.line }))];
|
|
734
|
-
if (check.defaultTarget)
|
|
735
|
-
targets.push(check.defaultTarget);
|
|
736
|
-
for (const target of targets) {
|
|
737
|
-
const targetIndex = idIndex.get(target.stepId);
|
|
738
|
-
if (targetIndex === undefined) {
|
|
739
|
-
ctx.errAtLine(target.line, `${check.stepLabel} routes to unknown step "${target.stepId}". Route targets must name a step id in this workflow.`);
|
|
740
|
-
}
|
|
741
|
-
else if (targetIndex === check.stepIndex) {
|
|
742
|
-
ctx.errAtLine(target.line, `${check.stepLabel} must not route to itself.`);
|
|
743
|
-
}
|
|
744
|
-
else if (targetIndex < check.stepIndex) {
|
|
745
|
-
ctx.errAtLine(target.line, `${check.stepLabel} routes backward to "${target.stepId}" (step ${targetIndex + 1}). Route targets must come after the routing step.`);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
633
|
return steps;
|
|
750
634
|
}
|
|
751
635
|
// ---------------------------------------------------------------------------
|
|
752
636
|
// Step blocks
|
|
753
637
|
// ---------------------------------------------------------------------------
|
|
754
|
-
function parseUnit(ctx, raw, path, stepLabel) {
|
|
638
|
+
function parseUnit(ctx, raw, path, stepLabel, allowWorkflow = true) {
|
|
755
639
|
if (!isRecord(raw)) {
|
|
756
640
|
ctx.err(path, `${stepLabel} "unit" must be a mapping (a dispatch-override bag).`);
|
|
757
641
|
return undefined;
|
|
@@ -772,6 +656,32 @@ function parseUnit(ctx, raw, path, stepLabel) {
|
|
|
772
656
|
`reaches an engine, so "${key}" would have no effect — remove one of the two.`);
|
|
773
657
|
}
|
|
774
658
|
}
|
|
659
|
+
if (raw.workflow !== undefined) {
|
|
660
|
+
const workflow = parseChildWorkflowRef(ctx, raw.workflow, [...path, "workflow"], stepLabel, allowWorkflow);
|
|
661
|
+
if (workflow !== undefined)
|
|
662
|
+
unit.workflow = workflow;
|
|
663
|
+
if (raw.exec !== undefined) {
|
|
664
|
+
ctx.err([...path, "workflow"], `${stepLabel} "unit" declares both "exec" and "workflow" — a unit runs one or the other.`);
|
|
665
|
+
}
|
|
666
|
+
// A workflow unit starts a child run: it reaches no engine and the child carries its own environment.
|
|
667
|
+
for (const key of [...UNIT_ENGINE_KEYS, "env"]) {
|
|
668
|
+
if (raw[key] === undefined)
|
|
669
|
+
continue;
|
|
670
|
+
ctx.err([...path, key], `${stepLabel} "unit" declares both "workflow" and "${key}". A workflow unit starts a child run and never ` +
|
|
671
|
+
`reaches an engine or an environment of its own, so "${key}" would have no effect — set it in the child workflow.`);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
if (raw.with !== undefined) {
|
|
675
|
+
if (raw.workflow === undefined) {
|
|
676
|
+
ctx.err([...path, "with"], `${stepLabel} "unit" declares "with" without "workflow" — it binds a child workflow's params.`);
|
|
677
|
+
}
|
|
678
|
+
else if (!isRecord(raw.with)) {
|
|
679
|
+
ctx.err([...path, "with"], `${stepLabel} "with" must be a mapping of the child's param name to a literal value or { from: <reference> }.`);
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
unit.with = raw.with;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
775
685
|
if (raw.engine !== undefined) {
|
|
776
686
|
const engine = parseEngineName(ctx, raw.engine, [...path, "engine"], `${stepLabel} "engine"`);
|
|
777
687
|
if (engine !== undefined)
|
|
@@ -815,11 +725,24 @@ function parseUnit(ctx, raw, path, stepLabel) {
|
|
|
815
725
|
ctx.err([...path, "env"], `${stepLabel} "env" must be a list of non-empty env asset refs.`);
|
|
816
726
|
}
|
|
817
727
|
}
|
|
818
|
-
const isolation = parseEnumField(ctx, raw.isolation, [...path, "isolation"], `${stepLabel} "isolation"`, PROGRAM_ISOLATION_KINDS);
|
|
819
|
-
if (isolation !== undefined)
|
|
820
|
-
unit.isolation = isolation;
|
|
821
728
|
return unit;
|
|
822
729
|
}
|
|
730
|
+
/** `unit.workflow` (Experimental): the canonical ref of a child workflow, `workflows/<name>` or `<bundle>//workflows/<name>`. */
|
|
731
|
+
function parseChildWorkflowRef(ctx, raw, path, stepLabel, allowed) {
|
|
732
|
+
if (!allowed) {
|
|
733
|
+
ctx.err(path, `${stepLabel} "workflow" is not supported inside "map.unit": a child workflow runs once per step.`);
|
|
734
|
+
return undefined;
|
|
735
|
+
}
|
|
736
|
+
try {
|
|
737
|
+
if (typeof raw === "string" && classifyTargetRef(raw).kind === "workflow")
|
|
738
|
+
return raw;
|
|
739
|
+
}
|
|
740
|
+
catch {
|
|
741
|
+
// falls through to the message below
|
|
742
|
+
}
|
|
743
|
+
ctx.err(path, `${stepLabel} "workflow" must be a canonical workflow ref such as "workflows/<name>".`);
|
|
744
|
+
return undefined;
|
|
745
|
+
}
|
|
823
746
|
/**
|
|
824
747
|
* Parse `unit.exec` — the argv-array shell-command surface.
|
|
825
748
|
*
|
|
@@ -952,7 +875,7 @@ function parseMap(ctx, raw, path, stepLabel) {
|
|
|
952
875
|
}
|
|
953
876
|
}
|
|
954
877
|
const reducer = parseEnumField(ctx, raw.reducer, [...path, "reducer"], `${stepLabel} "reducer"`, PROGRAM_REDUCERS);
|
|
955
|
-
const unit = raw.unit !== undefined ? parseUnit(ctx, raw.unit, [...path, "unit"], stepLabel) : undefined;
|
|
878
|
+
const unit = raw.unit !== undefined ? parseUnit(ctx, raw.unit, [...path, "unit"], stepLabel, false) : undefined;
|
|
956
879
|
const map = { over };
|
|
957
880
|
if (concurrency !== undefined)
|
|
958
881
|
map.concurrency = concurrency;
|
|
@@ -962,79 +885,6 @@ function parseMap(ctx, raw, path, stepLabel) {
|
|
|
962
885
|
map.unit = unit;
|
|
963
886
|
return map;
|
|
964
887
|
}
|
|
965
|
-
function parseRoute(ctx, raw, path, stepLabel, stepIndex, routeChecks) {
|
|
966
|
-
if (!isRecord(raw)) {
|
|
967
|
-
ctx.err(path, `${stepLabel} "route" must be a mapping with "input" and "when" keys.`);
|
|
968
|
-
return undefined;
|
|
969
|
-
}
|
|
970
|
-
checkUnknownKeys(ctx, raw, path, ROUTE_KEYS, `${stepLabel} "route"`);
|
|
971
|
-
let input = "";
|
|
972
|
-
if (typeof raw.input === "string" && raw.input.trim() !== "") {
|
|
973
|
-
input = raw.input.trim();
|
|
974
|
-
checkReferenceSyntax(ctx, input, [...path, "input"], `${stepLabel} "route.input"`);
|
|
975
|
-
}
|
|
976
|
-
else {
|
|
977
|
-
ctx.err([...path, "input"], `${stepLabel} "route" requires "input": a reference naming the value to route on.`);
|
|
978
|
-
}
|
|
979
|
-
const check = { stepIndex, stepLabel, branches: [] };
|
|
980
|
-
const whenPath = [...path, "when"];
|
|
981
|
-
if (!Array.isArray(raw.when) || raw.when.length === 0) {
|
|
982
|
-
ctx.err(whenPath, `${stepLabel} "route" requires "when": a non-empty list of { match, step } branches (e.g. when: [{ match: pass, step: ship }]).`);
|
|
983
|
-
}
|
|
984
|
-
else {
|
|
985
|
-
const seenMatches = new Map();
|
|
986
|
-
raw.when.forEach((branch, i) => {
|
|
987
|
-
const branchPath = [...whenPath, i];
|
|
988
|
-
if (!isRecord(branch)) {
|
|
989
|
-
ctx.err(branchPath, `${stepLabel} "when[${i}]" must be a mapping: { match, step }.`);
|
|
990
|
-
return;
|
|
991
|
-
}
|
|
992
|
-
checkUnknownKeys(ctx, branch, branchPath, ROUTE_BRANCH_KEYS, `${stepLabel} "when[${i}]"`);
|
|
993
|
-
const matchLine = ctx.lineAt([...branchPath, "match"]);
|
|
994
|
-
if (branch.match === undefined ||
|
|
995
|
-
(typeof branch.match !== "string" && typeof branch.match !== "number" && typeof branch.match !== "boolean")) {
|
|
996
|
-
ctx.err([...branchPath, "match"], `${stepLabel} "when[${i}].match" must be a string, number, or boolean.`);
|
|
997
|
-
return;
|
|
998
|
-
}
|
|
999
|
-
const match = String(branch.match);
|
|
1000
|
-
// The frozen-plan decoder requires every `when` key to be non-empty, so an
|
|
1001
|
-
// empty match parsed and linted clean and then failed the run with an
|
|
1002
|
-
// unlocated "Invalid frozen workflow plan". Reject it here, at the line.
|
|
1003
|
-
if (match === "") {
|
|
1004
|
-
ctx.errAtLine(matchLine, `${stepLabel} "when[${i}].match" must not be empty.`);
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
|
-
if (typeof branch.step !== "string" || branch.step.trim() === "") {
|
|
1008
|
-
ctx.err([...branchPath, "step"], `${stepLabel} "when[${i}].step" must be a step id string.`);
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
|
-
const stepId = branch.step.trim();
|
|
1012
|
-
const stepLine = ctx.lineAt([...branchPath, "step"]);
|
|
1013
|
-
const firstLine = seenMatches.get(match);
|
|
1014
|
-
if (firstLine !== undefined) {
|
|
1015
|
-
ctx.errAtLine(matchLine, `${stepLabel} has a duplicate "when" match "${match}" (first declared on line ${firstLine}). Matches must be unique.`);
|
|
1016
|
-
return;
|
|
1017
|
-
}
|
|
1018
|
-
seenMatches.set(match, matchLine);
|
|
1019
|
-
check.branches.push({ match, stepId, line: stepLine });
|
|
1020
|
-
});
|
|
1021
|
-
}
|
|
1022
|
-
let defaultStepId;
|
|
1023
|
-
if (raw.default !== undefined) {
|
|
1024
|
-
if (typeof raw.default === "string" && raw.default.trim() !== "") {
|
|
1025
|
-
defaultStepId = raw.default.trim();
|
|
1026
|
-
check.defaultTarget = { stepId: defaultStepId, line: ctx.lineAt([...path, "default"]) };
|
|
1027
|
-
}
|
|
1028
|
-
else {
|
|
1029
|
-
ctx.err([...path, "default"], `${stepLabel} "route.default" must be a step id string.`);
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
routeChecks.push(check);
|
|
1033
|
-
const route = { input, branches: check.branches.map(({ match, stepId }) => ({ match, stepId })) };
|
|
1034
|
-
if (defaultStepId !== undefined)
|
|
1035
|
-
route.defaultStepId = defaultStepId;
|
|
1036
|
-
return route;
|
|
1037
|
-
}
|
|
1038
888
|
function parseInputs(ctx, raw, path, stepLabel) {
|
|
1039
889
|
if (raw === undefined)
|
|
1040
890
|
return undefined;
|
package/dist/workflows/plan.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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
|
-
/** Stored plans record this;
|
|
4
|
+
/** Stored plans record this; 0.9.15 and 0.9.16 wrote 5, which still decodes (the 0.9.15 floor, #1091). */
|
|
5
5
|
export const WORKFLOW_PLAN_VERSION = 6;
|
|
@@ -2,15 +2,15 @@
|
|
|
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
|
-
* Show renderer for
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* Show renderer for workflow sources. A `.md` source compiles through
|
|
6
|
+
* `compileWorkflowSource` into a plan, which is projected down to the public
|
|
7
|
+
* `ShowResponse` shape, including a compact per-step orchestration summary
|
|
8
|
+
* (engine/model or an exec unit's argv, `map.over` reference) when the step
|
|
9
|
+
* declares one.
|
|
10
10
|
*/
|
|
11
11
|
import { displayRef } from "../core/asset/resolve-ref.js";
|
|
12
12
|
import { UsageError } from "../core/errors.js";
|
|
13
|
-
import { compileWorkflowSource,
|
|
13
|
+
import { compileWorkflowSource, workflowStepInstructions } from "./compile.js";
|
|
14
14
|
function shellQuote(value) {
|
|
15
15
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
16
16
|
}
|
|
@@ -45,7 +45,7 @@ function projectParameters(plan) {
|
|
|
45
45
|
* Compact, show-facing orchestration summary for one step. Field mapping:
|
|
46
46
|
* `engine`/`model`/`timeoutMs` merge the run-level `defaults` exactly like the
|
|
47
47
|
* compiler does (per-unit override wins), `fanOut.over` carries the raw
|
|
48
|
-
* reference string
|
|
48
|
+
* reference string.
|
|
49
49
|
* Returns undefined when the step declares nothing worth summarizing.
|
|
50
50
|
*
|
|
51
51
|
* ## exec units
|
|
@@ -54,8 +54,8 @@ function projectParameters(plan) {
|
|
|
54
54
|
* `engine`/`model`/`llm` alongside `exec:`. Merging `defaults.engine` into its
|
|
55
55
|
* summary would make `show` state something untrue about what will run, so the
|
|
56
56
|
* two fields are suppressed and the argv is projected instead, under `exec`
|
|
57
|
-
* (field presence carries the dispatch kind, exactly like `fanOut
|
|
58
|
-
*
|
|
57
|
+
* (field presence carries the dispatch kind, exactly like `fanOut`
|
|
58
|
+
* carries the step kind).
|
|
59
59
|
*
|
|
60
60
|
* `timeoutMs` still merges the defaults: an exec unit really does inherit
|
|
61
61
|
* `defaults.timeout`, so that number stays true for it.
|
|
@@ -94,15 +94,6 @@ function summarizeStepOrchestration(step, defaults) {
|
|
|
94
94
|
: {}),
|
|
95
95
|
...(unit?.output !== undefined || step.outputSchema !== undefined ? { hasSchema: true } : {}),
|
|
96
96
|
...(unit?.env !== undefined ? { env: [...unit.env] } : {}),
|
|
97
|
-
...(step.route
|
|
98
|
-
? {
|
|
99
|
-
route: {
|
|
100
|
-
input: step.route.input,
|
|
101
|
-
branches: Object.entries(step.route.when).map(([match, stepId]) => ({ match, stepId })),
|
|
102
|
-
...(step.route.defaultStepId !== undefined ? { defaultStepId: step.route.defaultStepId } : {}),
|
|
103
|
-
},
|
|
104
|
-
}
|
|
105
|
-
: {}),
|
|
106
97
|
};
|
|
107
98
|
return Object.keys(summary).length > 0 ? summary : undefined;
|
|
108
99
|
}
|
|
@@ -113,7 +104,7 @@ function projectStepDefinitions(plan) {
|
|
|
113
104
|
return {
|
|
114
105
|
id: step.stepId,
|
|
115
106
|
title: step.stepId,
|
|
116
|
-
instructions
|
|
107
|
+
instructions,
|
|
117
108
|
...(step.gate.criteria.length > 0 ? { completionCriteria: [...step.gate.criteria] } : {}),
|
|
118
109
|
sequenceIndex,
|
|
119
110
|
...(orchestration ? { orchestration } : {}),
|