akm-cli 0.9.0-rc.8 → 0.9.0
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 +1063 -44
- package/README.md +51 -25
- package/SECURITY.md +14 -1
- package/STABILITY.md +497 -0
- package/dist/akm +148 -35
- package/dist/{akm-migrate-storage → akm-migrate} +6 -9
- package/dist/assets/hints/cli-hints-full.md +223 -95
- package/dist/assets/hints/cli-hints-short.md +85 -22
- package/dist/assets/improve-strategies/default.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/stash-skeleton/README.md +6 -5
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
- package/dist/assets/tasks/core/extract.yml +1 -1
- package/dist/assets/tasks/core/version-check.yml +1 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +1 -3
- package/dist/assets/workflows/workflow-template.md +32 -15
- package/dist/cli/invocation.js +40 -15
- package/dist/cli/parse-args.js +0 -22
- package/dist/cli/retired-commands.js +121 -0
- package/dist/cli/shared.js +154 -22
- package/dist/cli/unknown-flags.js +236 -0
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +696 -258
- package/dist/commands/agent/agent-dispatch.js +14 -3
- package/dist/commands/agent/contribute-cli.js +73 -88
- package/dist/commands/completions.js +79 -22
- package/dist/commands/config-cli.js +17 -150
- package/dist/commands/env/env-cli.js +59 -143
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +36 -66
- package/dist/commands/env/secret.js +24 -57
- package/dist/commands/feedback-cli.js +141 -87
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +3 -4
- package/dist/commands/health/checks.js +85 -23
- package/dist/commands/health/html-report.js +7 -10
- package/dist/commands/health/improve-metrics.js +25 -83
- package/dist/commands/health/md-report.js +5 -9
- package/dist/commands/health/metrics.js +62 -20
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +4 -5
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +3 -48
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/commands/health/types-improve.js +7 -0
- package/dist/commands/health.js +99 -28
- package/dist/commands/improve/anti-collapse.js +2 -2
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +41 -40
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +140 -1000
- package/dist/commands/improve/distill/promote-memory.js +12 -12
- package/dist/commands/improve/distill/quality-gate.js +6 -6
- package/dist/commands/improve/distill.js +58 -69
- package/dist/commands/improve/eligibility.js +105 -57
- package/dist/commands/improve/extract-cli.js +14 -133
- package/dist/commands/improve/improve-cli.js +98 -114
- package/dist/commands/improve/improve-result-file.js +1 -28
- package/dist/commands/improve/improve-strategies.js +8 -5
- package/dist/commands/improve/improve.js +128 -91
- package/dist/commands/improve/loop-stages.js +182 -20
- package/dist/commands/improve/memory/derived-ref.js +45 -43
- package/dist/commands/improve/memory/memory-belief.js +1 -1
- package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
- package/dist/commands/improve/memory/memory-improve.js +6 -5
- package/dist/commands/improve/outcome-loop.js +22 -65
- package/dist/commands/improve/preparation.js +114 -123
- package/dist/commands/improve/proactive-maintenance.js +2 -5
- package/dist/commands/improve/reflect.js +56 -160
- package/dist/commands/improve/salience.js +11 -122
- package/dist/commands/improve/source-identity.js +10 -38
- package/dist/commands/lint/base-linter.js +20 -124
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +249 -43
- package/dist/commands/{events.js → log.js} +33 -38
- package/dist/commands/migrate-cli.js +92 -12
- package/dist/commands/migration-tool.js +46 -0
- package/dist/commands/observability-cli.js +70 -209
- package/dist/commands/proposal/drain.js +101 -29
- package/dist/commands/proposal/proposal-cli.js +76 -48
- package/dist/commands/proposal/proposal.js +54 -18
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +23 -15
- package/dist/commands/proposal/repository.js +701 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
- package/dist/commands/proposal/validators/proposal-validators.js +55 -7
- package/dist/commands/proposal/validators/proposals.js +4 -7
- package/dist/commands/read/curate.js +34 -53
- package/dist/commands/read/knowledge.js +150 -95
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +42 -15
- package/dist/commands/read/search-cli.js +180 -78
- package/dist/commands/read/search.js +58 -43
- package/dist/commands/read/show.js +197 -141
- package/dist/commands/registry-cli.js +12 -51
- package/dist/commands/remember.js +14 -57
- package/dist/commands/sources/add-cli.js +100 -31
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +7 -2
- package/dist/commands/sources/info.js +18 -5
- package/dist/commands/sources/init.js +12 -12
- package/dist/commands/sources/installed-stashes.js +382 -98
- package/dist/commands/sources/schema-repair.js +3 -2
- package/dist/commands/sources/self-update.js +131 -38
- package/dist/commands/sources/source-add.js +72 -17
- package/dist/commands/sources/source-clone.js +129 -45
- package/dist/commands/sources/source-manage.js +43 -23
- package/dist/commands/sources/sources-cli.js +57 -208
- package/dist/commands/sources/stash-cli.js +46 -53
- package/dist/commands/tasks/tasks-cli.js +91 -97
- package/dist/commands/tasks/tasks.js +276 -421
- package/dist/commands/workflow-cli.js +175 -450
- package/dist/core/adapter/adapters/akm-adapter.js +47 -28
- package/dist/core/adapter/adapters/akm-lint.js +42 -27
- package/dist/core/adapter/adapters/akm-metadata.js +15 -44
- package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
- package/dist/core/adapter/adapters/index.js +6 -6
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
- package/dist/core/adapter/adapters/okf-adapter.js +187 -19
- package/dist/core/adapter/adapters/shared.js +3 -19
- package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +6 -4
- package/dist/core/adapter/validate-context.js +214 -0
- package/dist/core/asset/akm-markdown.js +63 -0
- package/dist/core/asset/asset-placement.js +20 -6
- package/dist/core/asset/asset-ref.js +11 -9
- package/dist/core/asset/frontmatter-lint.js +30 -0
- package/dist/core/asset/frontmatter.js +37 -9
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +89 -18
- package/dist/core/asset/stash-meta.js +1 -1
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +152 -38
- package/dist/core/config/config-io.js +12 -1
- package/dist/core/config/config-schema.js +35 -8
- package/dist/core/config/config-sources.js +55 -11
- package/dist/core/config/config-walker.js +25 -9
- package/dist/core/config/config.js +9 -48
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +5 -1
- package/dist/core/config/schema/experimental.js +30 -0
- package/dist/core/config/schema/improve-processes.js +0 -6
- package/dist/core/config/schema/improve.js +21 -3
- package/dist/core/config/schema/index-config.js +8 -15
- package/dist/core/config/schema/output.js +4 -1
- package/dist/core/config/schema/setup.js +9 -18
- package/dist/core/config/schema/sources-bundles.js +49 -33
- package/dist/core/config/schema/workflow.js +3 -3
- package/dist/core/env-secret-ref.js +76 -46
- package/dist/core/errors.js +18 -12
- package/dist/core/events.js +46 -128
- package/dist/core/file-change.js +6 -5
- package/dist/core/fs-txn.js +83 -7
- package/dist/core/git-message.js +2 -2
- package/dist/core/improve-result.js +1 -100
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +2 -1
- package/dist/core/migration-operation.js +16 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/parse.js +4 -1
- package/dist/core/paths.js +17 -20
- package/dist/core/recognition-util.js +12 -14
- package/dist/core/redaction.js +34 -0
- package/dist/core/standards/resolve-standards-context.js +2 -14
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +2 -2
- package/dist/core/state/migrations.js +41 -18
- package/dist/core/state-db.js +5 -14
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +6 -4
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/type-presentation.js +3 -3
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +771 -95
- package/dist/indexer/bundle-identity-guard.js +3 -2
- package/dist/indexer/db/graph-db.js +0 -24
- package/dist/indexer/ensure-index.js +1 -0
- package/dist/indexer/graph/graph-boost.js +9 -34
- package/dist/indexer/graph/graph-extraction.js +8 -5
- package/dist/indexer/index-writer-lock.js +53 -17
- package/dist/indexer/index-written-assets.js +16 -22
- package/dist/indexer/indexer.js +497 -239
- package/dist/indexer/installations.js +14 -96
- package/dist/indexer/passes/dir-staleness.js +16 -9
- package/dist/indexer/passes/memory-inference.js +11 -9
- package/dist/indexer/passes/metadata.js +113 -47
- package/dist/indexer/scan/doc-to-entry.js +38 -1
- package/dist/indexer/scan/drain-dir.js +13 -23
- package/dist/indexer/search/db-search.js +99 -54
- package/dist/indexer/search/fts-query.js +47 -24
- package/dist/indexer/search/ranking-contributors.js +42 -20
- package/dist/indexer/search/ranking.js +18 -99
- package/dist/indexer/search/search-fields.js +7 -2
- package/dist/indexer/search/search-source.js +82 -93
- package/dist/indexer/usage/usage-events.js +0 -89
- package/dist/indexer/walk/file-context.js +2 -1
- package/dist/indexer/walk/matchers.js +30 -43
- package/dist/indexer/walk/path-resolver.js +7 -2
- package/dist/indexer/walk/walker.js +38 -12
- package/dist/integrations/agent/builders.js +0 -6
- package/dist/integrations/agent/config.js +2 -2
- package/dist/integrations/agent/detect.js +49 -19
- package/dist/integrations/agent/engine-fallback.js +76 -0
- package/dist/integrations/agent/profiles.js +14 -0
- package/dist/integrations/agent/prompts.js +12 -8
- package/dist/integrations/agent/runner-dispatch.js +4 -2
- package/dist/integrations/agent/runner.js +0 -1
- package/dist/integrations/agent/spawn.js +5 -6
- package/dist/integrations/github.js +1 -1
- package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
- package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
- package/dist/integrations/harnesses/claude/session-log.js +0 -10
- package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
- package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
- package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
- package/dist/integrations/harnesses/index.js +3 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
- package/dist/integrations/harnesses/opencode/session-log.js +0 -15
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
- package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
- package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
- package/dist/integrations/lockfile.js +101 -6
- package/dist/integrations/session-logs/index.js +3 -28
- package/dist/llm/client.js +136 -100
- package/dist/llm/embedders/remote.js +13 -5
- package/dist/llm/feature-gate.js +4 -12
- package/dist/llm/graph-extract.js +5 -11
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +5 -7
- package/dist/llm/structured-call.js +1 -1
- package/dist/llm/usage-persist.js +26 -5
- package/dist/llm/usage-telemetry.js +25 -2
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +259 -0
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -36
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +56 -83
- package/dist/output/shapes/migrate.js +8 -0
- package/dist/output/shapes/passthrough.js +7 -41
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes.js +2 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +164 -96
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/health-format.js +103 -0
- package/dist/output/text/health.js +7 -0
- package/dist/output/text/helpers.js +10 -8
- package/dist/output/text/lint-format.js +43 -0
- package/dist/output/text/{save.js → lint.js} +2 -2
- package/dist/output/text/migrate.js +88 -0
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +44 -72
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +15 -7
- package/dist/output/text/status-list.js +32 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +24 -203
- package/dist/output/text/workflow.js +1 -7
- package/dist/output/text.js +16 -17
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +13 -23
- package/dist/registry/resolve.js +42 -7
- package/dist/registry/semver.js +34 -84
- package/dist/runtime.js +2 -23
- package/dist/scripts/akm-migrate-node.js +60290 -0
- package/dist/scripts/akm-migrate.js +59628 -0
- package/dist/setup/detect.js +42 -15
- package/dist/setup/registry-stash-loader.js +2 -2
- package/dist/setup/setup.js +236 -136
- package/dist/setup/steps/connection.js +7 -9
- package/dist/setup/steps/platforms.js +9 -9
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +12 -13
- package/dist/setup/steps/stashdir.js +2 -3
- package/dist/setup/steps/tasks.js +237 -120
- package/dist/sources/freshness.js +1 -1
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +25 -23
- package/dist/sources/providers/git-stash.js +395 -106
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +7 -4
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +6 -1
- package/dist/sources/resolve.js +6 -5
- package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
- package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
- package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
- package/dist/sources/snapshot-fetchers/github.js +100 -0
- package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
- package/dist/sources/snapshot-fetchers/registry.js +17 -1
- package/dist/sources/snapshot-fetchers/robots.js +348 -0
- package/dist/sources/snapshot-fetchers/rss.js +282 -0
- package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
- package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
- package/dist/sources/snapshot-fetchers/x.js +910 -0
- package/dist/storage/database.js +7 -0
- package/dist/storage/engines/sqlite-migrations.js +23 -111
- package/dist/storage/managed-db.js +2 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +27 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -12
- package/dist/storage/repositories/index-connection.js +17 -6
- package/dist/storage/repositories/index-entries-repository.js +151 -240
- package/dist/storage/repositories/index-entry-mapper.js +15 -11
- package/dist/storage/repositories/index-fts-repository.js +5 -2
- package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
- package/dist/storage/repositories/index-meta-repository.js +2 -3
- package/dist/storage/repositories/index-schema.js +10 -25
- package/dist/storage/repositories/index-utility-repository.js +15 -28
- package/dist/storage/repositories/index-vec-repository.js +6 -1
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +296 -59
- package/dist/storage/repositories/registry-cache.js +19 -0
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +15 -13
- package/dist/storage/repositories/workflow-runs-repository.js +52 -40
- package/dist/tasks/backends/cron.js +105 -15
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +85 -38
- package/dist/tasks/backends/schtasks.js +135 -15
- package/dist/tasks/embedded.js +56 -40
- package/dist/tasks/parser.js +7 -157
- package/dist/tasks/resolve-akm-bin.js +137 -59
- package/dist/tasks/runner.js +79 -42
- package/dist/tasks/scheduler-invocation.js +220 -10
- package/dist/tasks/schema.js +24 -1
- package/dist/tasks/task-id.js +1 -3
- package/dist/tasks/validator.js +20 -6
- package/dist/workflows/authoring/authoring.js +94 -143
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/exec/frozen-judge.js +28 -2
- package/dist/workflows/exec/native-executor.js +77 -57
- package/dist/workflows/exec/param-secrets.js +9 -9
- package/dist/workflows/exec/run-workflow.js +133 -79
- package/dist/workflows/exec/step-work.js +219 -346
- package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
- package/dist/workflows/ir/compile.js +141 -270
- package/dist/workflows/ir/freeze.js +40 -30
- package/dist/workflows/ir/params.js +135 -11
- package/dist/workflows/ir/plan-hash.js +1 -1
- package/dist/workflows/ir/schema.js +25 -26
- package/dist/workflows/parser.js +872 -307
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +95 -68
- package/dist/workflows/resource-limits.js +2 -0
- package/dist/workflows/runtime/checkin.js +3 -3
- package/dist/workflows/runtime/plan-classifier.js +16 -75
- package/dist/workflows/runtime/runs.js +186 -127
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +2 -2
- package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +30 -36
- package/dist/workflows/validator.js +21 -62
- package/docs/README.md +68 -0
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.7.0.md +11 -11
- package/docs/migration/release-notes/0.9.0.md +208 -27
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +564 -208
- package/docs/migration/v0.9.0-troubleshooting.md +561 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/cli.md +2253 -0
- package/docs/reference/configuration.md +358 -0
- package/docs/reference/data-and-telemetry.md +105 -42
- package/docs/reference/workflows.md +647 -0
- package/package.json +22 -11
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +81 -128
- package/schemas/akm-workflow.json +74 -73
- package/dist/assets/tasks/core/backup.yml +0 -5
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/cli/config-migrate.js +0 -1806
- package/dist/cli/config-validate.js +0 -41
- package/dist/commands/backup-cli.js +0 -56
- package/dist/commands/bundle/bundle-cli.js +0 -68
- package/dist/commands/bundle/bundle.js +0 -219
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -489
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/mv-cli.js +0 -1221
- package/dist/commands/sources/history.js +0 -201
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/core/migration-backup.js +0 -1234
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/migrate/legacy/config-source-migration.js +0 -223
- package/dist/migrate/legacy/content-migration.js +0 -305
- package/dist/migrate/legacy/legacy-layout.js +0 -779
- package/dist/migrate/legacy/legacy-paths.js +0 -25
- package/dist/migrate/legacy/legacy-stash-json.js +0 -72
- package/dist/migrate/legacy/proposal-fs-import.js +0 -168
- package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
- package/dist/migrate/legacy/three-db-cutover.js +0 -841
- package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
- package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
- package/dist/migrate/legacy-ref-grammar.js +0 -214
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/registry/build-index.js +0 -382
- package/dist/schemas/akm-config.json +0 -4704
- package/dist/schemas/akm-task.json +0 -87
- package/dist/schemas/akm-workflow.json +0 -372
- package/dist/scripts/migrate-storage.js +0 -3816
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/cli.js +0 -53
- package/dist/workflows/exec/brief.js +0 -481
- package/dist/workflows/exec/report.js +0 -1460
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -813
- package/dist/workflows/program/project.js +0 -104
|
@@ -2,140 +2,19 @@
|
|
|
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
|
-
* `akm workflow` command family.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* which emits the same JSON envelope (stdout/stderr/exit-code) as the inline
|
|
10
|
-
* form. `workflow template` keeps a plain `defineCommand` because it writes the
|
|
11
|
-
* template straight to stdout with no JSON envelope. The private helpers
|
|
12
|
-
* `looksLikeWorkflowRunId` and `resolveWorkflowFilePath` move with the family.
|
|
5
|
+
* `akm workflow` command family. `run` is the canonical start/resume/execute
|
|
6
|
+
* surface; the former public `start`, `next`, and `complete` lifecycle is gone.
|
|
7
|
+
* Workflows are markdown-only; authoring uses `create --print` and validation
|
|
8
|
+
* uses `akm lint --type workflows`.
|
|
13
9
|
*/
|
|
14
|
-
import { defineCommand } from "citty";
|
|
15
|
-
import { getParsedInvocation } from "../cli/invocation.js";
|
|
16
10
|
import { getStringArg } from "../cli/parse-args.js";
|
|
17
|
-
import { defineJsonCommand,
|
|
11
|
+
import { defineGroupCommand, defineJsonCommand, EXIT_CODES, output } from "../cli/shared.js";
|
|
18
12
|
import { assertFlatAssetName, combineCreatePath, normalizeCreateSubPath } from "../core/asset/asset-create.js";
|
|
19
|
-
import { parseRefInput } from "../core/asset/resolve-ref.js";
|
|
20
|
-
import { loadConfig } from "../core/config/config.js";
|
|
21
13
|
import { NotFoundError, UsageError } from "../core/errors.js";
|
|
22
14
|
import { akmIndex } from "../indexer/indexer.js";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { createWorkflowAsset, formatWorkflowErrors, getWorkflowProgramTemplate, getWorkflowTemplate, validateWorkflowProgramSource, validateWorkflowSource, } from "../workflows/authoring/authoring.js";
|
|
27
|
-
import { hasWorkflowSubcommand, parseWorkflowJsonObject, parseWorkflowStepState, WORKFLOW_STEP_STATES, } from "../workflows/cli.js";
|
|
28
|
-
import { isWorkflowProgramPath } from "../workflows/program/project.js";
|
|
29
|
-
import { abandonWorkflowRun, completeWorkflowStep, getNextWorkflowStep, getWorkflowStatus, listWorkflowRuns, resumeWorkflowRun, startWorkflowRun, } from "../workflows/runtime/runs.js";
|
|
30
|
-
import { canonicalWorkflowRunRef } from "../workflows/runtime/workflow-asset-loader.js";
|
|
31
|
-
const workflowStartCommand = defineJsonCommand({
|
|
32
|
-
meta: {
|
|
33
|
-
name: "start",
|
|
34
|
-
description: "Start a new workflow run in the current working scope",
|
|
35
|
-
},
|
|
36
|
-
args: {
|
|
37
|
-
ref: { type: "positional", description: "Workflow ref (workflows/<name>)", required: true },
|
|
38
|
-
params: { type: "string", description: "Workflow parameters as a JSON object" },
|
|
39
|
-
force: {
|
|
40
|
-
type: "boolean",
|
|
41
|
-
description: "Allow a parallel run when an active run already exists in this scope (#485)",
|
|
42
|
-
default: false,
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
async run({ args }) {
|
|
46
|
-
const result = await startWorkflowRun(args.ref, parseWorkflowJsonObject(args.params, "--params"), {
|
|
47
|
-
force: args.force === true,
|
|
48
|
-
});
|
|
49
|
-
output("workflow-start", result);
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
const workflowNextCommand = defineJsonCommand({
|
|
53
|
-
meta: {
|
|
54
|
-
name: "next",
|
|
55
|
-
description: "Show the next actionable workflow step in the current scope, auto-starting a run when passed a workflow ref",
|
|
56
|
-
},
|
|
57
|
-
args: {
|
|
58
|
-
target: { type: "positional", description: "Workflow run id or workflow ref", required: true },
|
|
59
|
-
params: { type: "string", description: "Workflow parameters as a JSON object (only for auto-started runs)" },
|
|
60
|
-
},
|
|
61
|
-
async run({ args }) {
|
|
62
|
-
// `--dry-run` is intentionally NOT a declared arg (so it stays out of
|
|
63
|
-
// --help). The guard reads it straight from the invocation singleton so
|
|
64
|
-
// existing callers still get a clear, actionable error instead of a
|
|
65
|
-
// generic "unknown flag" from citty.
|
|
66
|
-
if (getParsedInvocation().hasFlag("--dry-run")) {
|
|
67
|
-
throw new UsageError("`akm workflow next` does not support --dry-run. Remove the flag to start or resume a run.", "INVALID_FLAG_VALUE");
|
|
68
|
-
}
|
|
69
|
-
const parsedParams = args.params ? parseWorkflowJsonObject(args.params, "--params") : undefined;
|
|
70
|
-
// If the target looks like a UUID-style run id (no `:` and matches the
|
|
71
|
-
// run-id shape), short-circuit with a structured WORKFLOW_NOT_FOUND
|
|
72
|
-
// error before the ref parser throws an unhelpful ref-parse error.
|
|
73
|
-
if (looksLikeWorkflowRunId(args.target)) {
|
|
74
|
-
const { hasWorkflowRun } = await import("../workflows/runtime/runs.js");
|
|
75
|
-
if (!(await hasWorkflowRun(args.target))) {
|
|
76
|
-
throw new NotFoundError(`Workflow run "${args.target}" not found.`, "WORKFLOW_NOT_FOUND", "Run `akm workflow list --active` to see runs.");
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
const result = await getNextWorkflowStep(args.target, parsedParams);
|
|
80
|
-
output("workflow-next", result);
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
/**
|
|
84
|
-
* Heuristic: a workflow run id is a UUID-shaped or hex-id-shaped string with
|
|
85
|
-
* no `/` separator (canonical refs contain `workflows/<name>`). When this
|
|
86
|
-
* matches we can give a much better
|
|
87
|
-
* error than the ref parser's "Invalid asset type" failure.
|
|
88
|
-
*/
|
|
89
|
-
function looksLikeWorkflowRunId(target) {
|
|
90
|
-
if (target.includes(":"))
|
|
91
|
-
return false;
|
|
92
|
-
if (target.includes("/"))
|
|
93
|
-
return false;
|
|
94
|
-
// UUID v4-ish: 8-4-4-4-12 hex digits separated by dashes.
|
|
95
|
-
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(target))
|
|
96
|
-
return true;
|
|
97
|
-
// Bare hex/alphanumeric run ids of >=8 chars (covers shortened ids).
|
|
98
|
-
if (/^[0-9a-z][0-9a-z_-]{7,}$/i.test(target) && /[0-9]/.test(target))
|
|
99
|
-
return true;
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
const workflowCompleteCommand = defineJsonCommand({
|
|
103
|
-
meta: {
|
|
104
|
-
name: "complete",
|
|
105
|
-
description: "Update a workflow step state and persist notes/evidence",
|
|
106
|
-
},
|
|
107
|
-
args: {
|
|
108
|
-
runId: { type: "positional", description: "Workflow run id", required: true },
|
|
109
|
-
step: { type: "string", description: "Workflow step id", required: true },
|
|
110
|
-
state: {
|
|
111
|
-
type: "string",
|
|
112
|
-
description: `Step state (default: completed). One of: ${WORKFLOW_STEP_STATES.join(", ")}.`,
|
|
113
|
-
},
|
|
114
|
-
notes: { type: "string", description: "Notes for the completed step" },
|
|
115
|
-
summary: {
|
|
116
|
-
type: "string",
|
|
117
|
-
description: "Summary of work done (required when completing a step); validated against completion criteria",
|
|
118
|
-
},
|
|
119
|
-
evidence: { type: "string", description: "Evidence JSON object for the step" },
|
|
120
|
-
},
|
|
121
|
-
async run({ args }) {
|
|
122
|
-
const result = await completeWorkflowStep({
|
|
123
|
-
runId: args.runId,
|
|
124
|
-
stepId: args.step,
|
|
125
|
-
status: parseWorkflowStepState(args.state),
|
|
126
|
-
notes: args.notes,
|
|
127
|
-
summary: args.summary,
|
|
128
|
-
evidence: args.evidence ? parseWorkflowJsonObject(args.evidence, "--evidence") : undefined,
|
|
129
|
-
});
|
|
130
|
-
if ("ok" in result && result.ok === false) {
|
|
131
|
-
// Summary failed the completion-criteria validation gate (#506): the
|
|
132
|
-
// step stays pending and the agent receives corrective feedback.
|
|
133
|
-
output("workflow-complete-rejected", result);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
output("workflow-complete", result);
|
|
137
|
-
},
|
|
138
|
-
});
|
|
15
|
+
import { assertWorkflowMarkdownName, createWorkflowAsset, getWorkflowTemplate } from "../workflows/authoring/authoring.js";
|
|
16
|
+
import { WORKFLOW_MAX_RETRIES, WORKFLOW_MAX_TIMEOUT_MS } from "../workflows/ir/schema.js";
|
|
17
|
+
import { abandonWorkflowRun, getWorkflowStatus, hasWorkflowRun, listWorkflowRuns, resumeWorkflowRun, } from "../workflows/runtime/runs.js";
|
|
139
18
|
const workflowStatusCommand = defineJsonCommand({
|
|
140
19
|
meta: {
|
|
141
20
|
name: "status",
|
|
@@ -146,38 +25,33 @@ const workflowStatusCommand = defineJsonCommand({
|
|
|
146
25
|
units: {
|
|
147
26
|
type: "boolean",
|
|
148
27
|
description: "Also list per-unit rows from the run journal (unit id, status, failure_reason, and any result/error " +
|
|
149
|
-
"diagnostic text). Diagnostics only — step evidence stays deterministic and is unaffected
|
|
28
|
+
"diagnostic text). Diagnostics only — step evidence stays deterministic and is unaffected.",
|
|
150
29
|
default: false,
|
|
151
30
|
},
|
|
152
31
|
},
|
|
153
32
|
async run({ args }) {
|
|
154
33
|
const target = args.target;
|
|
155
34
|
const includeUnits = args.units === true;
|
|
156
|
-
|
|
157
|
-
const parsed = (() => {
|
|
158
|
-
try {
|
|
159
|
-
return parseRefInput(target);
|
|
160
|
-
}
|
|
161
|
-
catch {
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
})();
|
|
165
|
-
if (parsed?.type === "workflow") {
|
|
166
|
-
const ref = canonicalWorkflowRunRef(parsed.origin, parsed.name);
|
|
167
|
-
const { runs } = await listWorkflowRuns({ workflowRef: ref });
|
|
168
|
-
if (runs.length === 0) {
|
|
169
|
-
throw new NotFoundError(`No workflow runs found for ${ref}`, "WORKFLOW_NOT_FOUND");
|
|
170
|
-
}
|
|
171
|
-
const mostRecent = runs[0];
|
|
172
|
-
if (!mostRecent)
|
|
173
|
-
throw new NotFoundError(`No workflow runs found for ${ref}`, "WORKFLOW_NOT_FOUND");
|
|
174
|
-
const result = await getWorkflowStatus(mostRecent.id, { includeUnits });
|
|
175
|
-
output("workflow-status", result);
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
35
|
+
if (await hasWorkflowRun(target)) {
|
|
178
36
|
const result = await getWorkflowStatus(target, { includeUnits });
|
|
179
37
|
output("workflow-status", result);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
let runs;
|
|
41
|
+
try {
|
|
42
|
+
({ runs } = await listWorkflowRuns({ workflowRef: target }));
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (!target.includes(":") && !target.includes("/")) {
|
|
46
|
+
throw new NotFoundError(`Workflow run "${target}" not found.`, "WORKFLOW_NOT_FOUND");
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
180
49
|
}
|
|
50
|
+
const mostRecent = runs[0];
|
|
51
|
+
if (!mostRecent)
|
|
52
|
+
throw new NotFoundError(`No workflow runs found for ${target}`, "WORKFLOW_NOT_FOUND");
|
|
53
|
+
const result = await getWorkflowStatus(mostRecent.id, { includeUnits });
|
|
54
|
+
output("workflow-status", result);
|
|
181
55
|
},
|
|
182
56
|
});
|
|
183
57
|
const workflowListCommand = defineJsonCommand({
|
|
@@ -197,12 +71,12 @@ const workflowListCommand = defineJsonCommand({
|
|
|
197
71
|
const workflowCreateCommand = defineJsonCommand({
|
|
198
72
|
meta: {
|
|
199
73
|
name: "create",
|
|
200
|
-
description: "Create a workflow
|
|
74
|
+
description: "Create a workflow (markdown document) in the working bundle",
|
|
201
75
|
},
|
|
202
76
|
args: {
|
|
203
77
|
name: {
|
|
204
78
|
type: "positional",
|
|
205
|
-
description: "Workflow name (flat, no '/'; use --path for a subdirectory).
|
|
79
|
+
description: "Workflow name (flat, no '/'; use --path for a subdirectory).",
|
|
206
80
|
required: true,
|
|
207
81
|
},
|
|
208
82
|
path: {
|
|
@@ -211,7 +85,7 @@ const workflowCreateCommand = defineJsonCommand({
|
|
|
211
85
|
},
|
|
212
86
|
from: {
|
|
213
87
|
type: "string",
|
|
214
|
-
description: "Import and validate content from an existing file
|
|
88
|
+
description: "Import and validate content from an existing file",
|
|
215
89
|
},
|
|
216
90
|
force: {
|
|
217
91
|
type: "boolean",
|
|
@@ -223,6 +97,11 @@ const workflowCreateCommand = defineJsonCommand({
|
|
|
223
97
|
description: "Explicitly replace an existing workflow with a fresh template (use with --force)",
|
|
224
98
|
default: false,
|
|
225
99
|
},
|
|
100
|
+
print: {
|
|
101
|
+
type: "boolean",
|
|
102
|
+
description: "Print the RAW template that would be written to stdout without creating anything — pipe it to a file as a starter document",
|
|
103
|
+
default: false,
|
|
104
|
+
},
|
|
226
105
|
},
|
|
227
106
|
async run({ args }) {
|
|
228
107
|
// `name` is flat; subdirectory placement is `--path`'s job.
|
|
@@ -232,6 +111,14 @@ const workflowCreateCommand = defineJsonCommand({
|
|
|
232
111
|
if (!namePattern.test(effectiveName)) {
|
|
233
112
|
throw new UsageError("Workflow name must start with a lowercase letter or digit and contain only lowercase letters, digits, hyphens, dots, underscores, and slashes.");
|
|
234
113
|
}
|
|
114
|
+
assertWorkflowMarkdownName(effectiveName);
|
|
115
|
+
if (args.print) {
|
|
116
|
+
// Raw document, not an envelope — the retired `workflow template` was
|
|
117
|
+
// format-exempt for the same reason: `--print > starter.md` must yield
|
|
118
|
+
// a usable starter file, not `{ok,template,kind}` JSON.
|
|
119
|
+
process.stdout.write(getWorkflowTemplate());
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
235
122
|
if (args.force && !args.from && !args.reset) {
|
|
236
123
|
throw new UsageError("Refusing to overwrite with template: pass --from <file> to replace content, or --reset to explicitly replace with a fresh template.");
|
|
237
124
|
}
|
|
@@ -240,312 +127,159 @@ const workflowCreateCommand = defineJsonCommand({
|
|
|
240
127
|
from: args.from,
|
|
241
128
|
force: args.force,
|
|
242
129
|
});
|
|
243
|
-
// Index the newly-written workflow so `akm workflow
|
|
130
|
+
// Index the newly-written workflow so `akm workflow run` can resolve
|
|
244
131
|
// a workflowEntryId without requiring an explicit `akm index` call
|
|
245
132
|
// first. Uses the same incremental index path that `akm add` uses.
|
|
246
133
|
await akmIndex({ stashDir: result.stashDir });
|
|
247
134
|
output("workflow-create", { ok: true, ...result });
|
|
248
135
|
},
|
|
249
136
|
});
|
|
250
|
-
const workflowTemplateCommand = defineCommand({
|
|
251
|
-
meta: {
|
|
252
|
-
name: "template",
|
|
253
|
-
description: "Print a valid workflow template (markdown by default, --yaml for a YAML program)",
|
|
254
|
-
},
|
|
255
|
-
args: {
|
|
256
|
-
yaml: {
|
|
257
|
-
type: "boolean",
|
|
258
|
-
description: "Print a minimal valid YAML workflow program instead of the markdown template",
|
|
259
|
-
default: false,
|
|
260
|
-
},
|
|
261
|
-
},
|
|
262
|
-
run({ args }) {
|
|
263
|
-
process.stdout.write(args.yaml ? getWorkflowProgramTemplate() : getWorkflowTemplate());
|
|
264
|
-
},
|
|
265
|
-
});
|
|
266
|
-
const workflowValidateCommand = defineJsonCommand({
|
|
267
|
-
meta: {
|
|
268
|
-
name: "validate",
|
|
269
|
-
description: "Validate a workflow file or ref (markdown document or YAML program) and print any errors",
|
|
270
|
-
},
|
|
271
|
-
args: {
|
|
272
|
-
target: {
|
|
273
|
-
type: "positional",
|
|
274
|
-
description: "Workflow ref (workflows/<name>) or filesystem path to a workflow .md/.yaml",
|
|
275
|
-
required: true,
|
|
276
|
-
},
|
|
277
|
-
},
|
|
278
|
-
async run({ args }) {
|
|
279
|
-
const filePath = await resolveWorkflowFilePath(args.target);
|
|
280
|
-
// YAML programs (redesign addendum, R1) validate through the program
|
|
281
|
-
// parser AND compiler so expression/reference errors surface at lint
|
|
282
|
-
// time; both error lists carry line numbers. Markdown is unchanged.
|
|
283
|
-
if (isWorkflowProgramPath(filePath)) {
|
|
284
|
-
const { result } = validateWorkflowProgramSource(filePath);
|
|
285
|
-
if (!result.ok) {
|
|
286
|
-
throw new UsageError(formatWorkflowErrors(filePath, result.errors));
|
|
287
|
-
}
|
|
288
|
-
// Non-fatal WARNINGS ride the envelope additively — `ok` stays true. The
|
|
289
|
-
// text formatter renders them clearly marked for humans; the JSON key is
|
|
290
|
-
// the machine channel. Empty array when the program is fully typed/declared.
|
|
291
|
-
output("workflow-validate", {
|
|
292
|
-
ok: true,
|
|
293
|
-
path: filePath,
|
|
294
|
-
format: "program",
|
|
295
|
-
title: result.program.name,
|
|
296
|
-
stepCount: result.program.steps.length,
|
|
297
|
-
warnings: result.warnings.map((w) => ({ line: w.line, message: w.message })),
|
|
298
|
-
});
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
const { parse } = validateWorkflowSource(filePath);
|
|
302
|
-
if (parse.ok) {
|
|
303
|
-
output("workflow-validate", {
|
|
304
|
-
ok: true,
|
|
305
|
-
path: filePath,
|
|
306
|
-
title: parse.document.title,
|
|
307
|
-
stepCount: parse.document.steps.length,
|
|
308
|
-
});
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
throw new UsageError(formatWorkflowErrors(filePath, parse.errors));
|
|
312
|
-
},
|
|
313
|
-
});
|
|
314
|
-
async function resolveWorkflowFilePath(target) {
|
|
315
|
-
// Canonical workflow refs resolve through the source search; anything else is
|
|
316
|
-
// treated as a filesystem path.
|
|
317
|
-
const looksLikeWorkflowRef = target.startsWith("workflows/") || target.includes("//workflows/");
|
|
318
|
-
if (!looksLikeWorkflowRef)
|
|
319
|
-
return target;
|
|
320
|
-
const parsed = parseRefInput(target);
|
|
321
|
-
if (parsed.type !== "workflow") {
|
|
322
|
-
throw new UsageError(`Expected a workflow ref (workflows/<name>), got "${target}".`);
|
|
323
|
-
}
|
|
324
|
-
const config = loadConfig();
|
|
325
|
-
const allSources = resolveSourceEntries(undefined, config);
|
|
326
|
-
const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
|
|
327
|
-
for (const source of searchSources) {
|
|
328
|
-
try {
|
|
329
|
-
return await resolveAssetPath(source.path, "workflow", parsed.name);
|
|
330
|
-
}
|
|
331
|
-
catch {
|
|
332
|
-
/* try next source */
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
throw new UsageError(`Workflow not found for ref: workflows/${parsed.name}`);
|
|
336
|
-
}
|
|
337
137
|
const workflowRunCommand = defineJsonCommand({
|
|
338
138
|
meta: {
|
|
339
139
|
name: "run",
|
|
340
|
-
description: "
|
|
341
|
-
"(fan-out, schema output) to the configured runner and advances the run through the normal completion gates",
|
|
140
|
+
description: "Start or resume a workflow and execute it through completion, failure, a verification gate, or an explicit limit",
|
|
342
141
|
},
|
|
343
142
|
args: {
|
|
344
143
|
target: { type: "positional", description: "Workflow run id or workflow ref (auto-starts a run)", required: true },
|
|
345
|
-
params: { type: "string", description: "Workflow parameters as a JSON object (only for auto-started runs)" },
|
|
346
144
|
"max-steps": { type: "string", description: "Stop after executing this many steps" },
|
|
347
|
-
"
|
|
348
|
-
|
|
349
|
-
description: "Treat every criteria-bearing completion gate as required: if no LLM judge is available, BLOCK the step " +
|
|
350
|
-
"(for a human to resolve via `akm workflow resume`) instead of failing open. A per-step `gate.required: true` " +
|
|
351
|
-
"in the workflow does the same on every surface; this is the run-wide override (#18).",
|
|
352
|
-
default: false,
|
|
353
|
-
},
|
|
145
|
+
"max-retries": { type: "string", description: "Retry a failed workflow step this many additional times" },
|
|
146
|
+
timeout: { type: "string", description: "Whole-run timeout: N, Nms, Ns, or Nm (bare N is milliseconds)" },
|
|
354
147
|
},
|
|
355
|
-
async run({ args }) {
|
|
148
|
+
async run({ args, rawArgs }) {
|
|
356
149
|
const { runWorkflowSteps } = await import("../workflows/exec/run-workflow.js");
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
150
|
+
const parameterFlags = parseWorkflowParameterFlags(rawArgs, args.target);
|
|
151
|
+
const maxSteps = parseIntegerFlag(getStringArg(args, "max-steps"), "--max-steps", 1);
|
|
152
|
+
const maxRetries = parseIntegerFlag(getStringArg(args, "max-retries"), "--max-retries", 0, WORKFLOW_MAX_RETRIES);
|
|
153
|
+
const timeoutMs = parseWorkflowTimeout(getStringArg(args, "timeout"));
|
|
154
|
+
const controller = new AbortController();
|
|
155
|
+
let timedOut = false;
|
|
156
|
+
let signalExitCode;
|
|
157
|
+
const interrupt = (signal) => {
|
|
158
|
+
signalExitCode = signal === "SIGINT" ? 130 : 143;
|
|
159
|
+
controller.abort(new Error(`Workflow run interrupted by ${signal}.`));
|
|
160
|
+
};
|
|
161
|
+
const onSigint = () => interrupt("SIGINT");
|
|
162
|
+
const onSigterm = () => interrupt("SIGTERM");
|
|
163
|
+
process.once("SIGINT", onSigint);
|
|
164
|
+
process.once("SIGTERM", onSigterm);
|
|
165
|
+
const timer = timeoutMs === undefined
|
|
166
|
+
? undefined
|
|
167
|
+
: setTimeout(() => {
|
|
168
|
+
timedOut = true;
|
|
169
|
+
controller.abort(new Error(`Workflow run timed out after ${timeoutMs}ms.`));
|
|
170
|
+
}, timeoutMs);
|
|
171
|
+
timer?.unref?.();
|
|
172
|
+
try {
|
|
173
|
+
const result = await runWorkflowSteps({
|
|
174
|
+
target: args.target,
|
|
175
|
+
parameterFlags,
|
|
176
|
+
...(maxSteps !== undefined ? { maxSteps } : {}),
|
|
177
|
+
...(maxRetries !== undefined ? { maxRetries } : {}),
|
|
178
|
+
signal: controller.signal,
|
|
179
|
+
});
|
|
180
|
+
const rendered = { ...result, ...(timedOut ? { timedOut: true } : {}) };
|
|
181
|
+
output("workflow-run", rendered);
|
|
182
|
+
if (result.run.status === "failed" || result.gateRejection || result.aborted) {
|
|
183
|
+
process.exitCode = signalExitCode ?? EXIT_CODES.GENERAL;
|
|
363
184
|
}
|
|
364
185
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
371
|
-
output("workflow-run", result);
|
|
372
|
-
},
|
|
373
|
-
});
|
|
374
|
-
const workflowBriefCommand = defineJsonCommand({
|
|
375
|
-
meta: {
|
|
376
|
-
name: "brief",
|
|
377
|
-
description: "EXPERIMENTAL: describe a run's active step as an executable work-list for ANY agent session (the " +
|
|
378
|
-
"harness-neutral driver protocol) — read-only, takes no engine lease, mutates nothing; prints per-unit " +
|
|
379
|
-
"instructions, output schema, env binding names, and the exact `akm workflow report` command lines",
|
|
380
|
-
},
|
|
381
|
-
args: {
|
|
382
|
-
target: {
|
|
383
|
-
type: "positional",
|
|
384
|
-
description: "Workflow run id (or a workflow ref with an active run)",
|
|
385
|
-
required: true,
|
|
386
|
-
},
|
|
387
|
-
},
|
|
388
|
-
async run({ args }) {
|
|
389
|
-
const { buildWorkflowBrief } = await import("../workflows/exec/brief.js");
|
|
390
|
-
const result = await buildWorkflowBrief(args.target);
|
|
391
|
-
output("workflow-brief", result);
|
|
186
|
+
finally {
|
|
187
|
+
if (timer)
|
|
188
|
+
clearTimeout(timer);
|
|
189
|
+
process.off("SIGINT", onSigint);
|
|
190
|
+
process.off("SIGTERM", onSigterm);
|
|
191
|
+
}
|
|
392
192
|
},
|
|
393
193
|
});
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
description: "Guard: the step id you briefed against. Refuses the report if the run's active step has since moved (from the `brief` report/settle command line)",
|
|
422
|
-
},
|
|
423
|
-
status: { type: "string", description: `Unit status: ${WORKFLOW_REPORT_STATES.join(", ")}` },
|
|
424
|
-
result: { type: "string", description: "Result payload (JSON for a schema unit, else text). completed only." },
|
|
425
|
-
"result-file": { type: "string", description: "Read the result payload from this file instead of --result/stdin" },
|
|
426
|
-
tokens: { type: "string", description: "Tokens spent on this unit (counts against a declared budget)" },
|
|
427
|
-
"session-id": { type: "string", description: "Harness-native session id revealed while executing the unit" },
|
|
428
|
-
"failure-reason": { type: "string", description: "Structured failure vocabulary for a --status failed report" },
|
|
429
|
-
note: { type: "string", description: "Short progress note for a --status running heartbeat (not persisted)" },
|
|
430
|
-
rerun: {
|
|
431
|
-
type: "boolean",
|
|
432
|
-
description: "Re-run an already-FAILED unit: record a NEW attempt (re-applies budget) instead of refusing a differing re-report",
|
|
433
|
-
default: false,
|
|
434
|
-
},
|
|
435
|
-
},
|
|
436
|
-
async run({ args }) {
|
|
437
|
-
// --settle: the unit-less verb that advances a run parked on a
|
|
438
|
-
// non-dispatching step. Mutually exclusive with the per-unit report flags.
|
|
439
|
-
if (args.settle === true) {
|
|
440
|
-
if (getStringArg(args, "unit") !== undefined || getStringArg(args, "status") !== undefined) {
|
|
441
|
-
throw new UsageError("--settle advances a route-only/empty step and takes no --unit or --status. Drop them, or report a " +
|
|
442
|
-
"specific unit with `--unit <id> --status <state>` instead.", "INVALID_FLAG_VALUE");
|
|
194
|
+
const WORKFLOW_RUN_VALUE_FLAGS = new Set([
|
|
195
|
+
"max-steps",
|
|
196
|
+
"maxSteps",
|
|
197
|
+
"max-retries",
|
|
198
|
+
"maxRetries",
|
|
199
|
+
"timeout",
|
|
200
|
+
"format",
|
|
201
|
+
"detail",
|
|
202
|
+
"shape",
|
|
203
|
+
"output",
|
|
204
|
+
]);
|
|
205
|
+
const WORKFLOW_RUN_BOOLEAN_FLAGS = new Set(["quiet", "verbose", "help", "no-quiet", "no-verbose"]);
|
|
206
|
+
export function parseWorkflowParameterFlags(rawArgs, target) {
|
|
207
|
+
const flags = [];
|
|
208
|
+
let targetSeen = false;
|
|
209
|
+
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
210
|
+
const token = rawArgs[index];
|
|
211
|
+
if (token === "--") {
|
|
212
|
+
throw new UsageError("`akm workflow run` does not accept positional arguments after `--`.", "INVALID_FLAG_VALUE");
|
|
213
|
+
}
|
|
214
|
+
if (!token.startsWith("-") || token === "-" || /^-\d/.test(token)) {
|
|
215
|
+
if (!targetSeen) {
|
|
216
|
+
if (token !== target) {
|
|
217
|
+
throw new UsageError("Workflow parameter flags must come after the workflow ref or run id.", "INVALID_FLAG_VALUE");
|
|
218
|
+
}
|
|
219
|
+
targetSeen = true;
|
|
220
|
+
continue;
|
|
443
221
|
}
|
|
444
|
-
|
|
445
|
-
const result = await settleWorkflowSpine({
|
|
446
|
-
target: args.target,
|
|
447
|
-
...(getStringArg(args, "expect-step") !== undefined ? { expectStep: getStringArg(args, "expect-step") } : {}),
|
|
448
|
-
});
|
|
449
|
-
output("workflow-report", result);
|
|
450
|
-
return;
|
|
222
|
+
throw new UsageError(`Unexpected positional workflow argument "${token}".`, "INVALID_FLAG_VALUE");
|
|
451
223
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
224
|
+
if (!token.startsWith("--"))
|
|
225
|
+
continue;
|
|
226
|
+
const body = token.slice(2);
|
|
227
|
+
const equalsAt = body.indexOf("=");
|
|
228
|
+
const name = equalsAt === -1 ? body : body.slice(0, equalsAt);
|
|
229
|
+
const inlineValue = equalsAt === -1 ? undefined : body.slice(equalsAt + 1);
|
|
230
|
+
if (name === "params") {
|
|
231
|
+
throw new UsageError("--params was removed. Pass each declared workflow parameter as its own flag, for example `--version=1.2.3`.", "INVALID_FLAG_VALUE");
|
|
455
232
|
}
|
|
456
|
-
if (
|
|
457
|
-
|
|
233
|
+
if (WORKFLOW_RUN_VALUE_FLAGS.has(name)) {
|
|
234
|
+
if (inlineValue === undefined)
|
|
235
|
+
index += 1;
|
|
236
|
+
continue;
|
|
458
237
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
238
|
+
if (WORKFLOW_RUN_BOOLEAN_FLAGS.has(name))
|
|
239
|
+
continue;
|
|
240
|
+
if (!targetSeen) {
|
|
241
|
+
throw new UsageError("Workflow parameter flags must come after the workflow ref or run id.", "INVALID_FLAG_VALUE");
|
|
462
242
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
tokens = Number.parseInt(rawTokens, 10);
|
|
467
|
-
if (!/^\d+$/.test(rawTokens)) {
|
|
468
|
-
throw new UsageError(`--tokens must be a non-negative integer, got "${rawTokens}".`, "INVALID_FLAG_VALUE");
|
|
469
|
-
}
|
|
243
|
+
if (inlineValue !== undefined) {
|
|
244
|
+
flags.push({ name, value: inlineValue });
|
|
245
|
+
continue;
|
|
470
246
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const resultFile = getStringArg(args, "result-file");
|
|
476
|
-
if (args.result !== undefined && resultFile !== undefined) {
|
|
477
|
-
throw new UsageError("Pass at most one of --result or --result-file.", "INVALID_FLAG_VALUE");
|
|
478
|
-
}
|
|
479
|
-
if (args.result !== undefined) {
|
|
480
|
-
resultRaw = String(args.result);
|
|
481
|
-
}
|
|
482
|
-
else if (resultFile !== undefined) {
|
|
483
|
-
const fs = await import("node:fs");
|
|
484
|
-
resultRaw = fs.readFileSync(resultFile, "utf8");
|
|
485
|
-
}
|
|
486
|
-
else if (!process.stdin.isTTY) {
|
|
487
|
-
resultRaw = await readStdin();
|
|
488
|
-
}
|
|
247
|
+
const next = rawArgs[index + 1];
|
|
248
|
+
if (next !== undefined && (!next.startsWith("-") || /^-\d/.test(next))) {
|
|
249
|
+
flags.push({ name, value: next });
|
|
250
|
+
index += 1;
|
|
489
251
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
target: args.target,
|
|
493
|
-
unitId,
|
|
494
|
-
status: status,
|
|
495
|
-
...(getStringArg(args, "expect-step") !== undefined ? { expectStep: getStringArg(args, "expect-step") } : {}),
|
|
496
|
-
...(resultRaw !== undefined ? { resultRaw } : {}),
|
|
497
|
-
...(tokens !== undefined ? { tokens } : {}),
|
|
498
|
-
...(args.rerun === true ? { rerun: true } : {}),
|
|
499
|
-
...(getStringArg(args, "session-id") !== undefined ? { sessionId: getStringArg(args, "session-id") } : {}),
|
|
500
|
-
...(getStringArg(args, "failure-reason") !== undefined
|
|
501
|
-
? { failureReason: getStringArg(args, "failure-reason") }
|
|
502
|
-
: {}),
|
|
503
|
-
...(getStringArg(args, "note") !== undefined ? { note: getStringArg(args, "note") } : {}),
|
|
504
|
-
});
|
|
505
|
-
output("workflow-report", result);
|
|
506
|
-
},
|
|
507
|
-
});
|
|
508
|
-
async function readStdin() {
|
|
509
|
-
const chunks = [];
|
|
510
|
-
for await (const chunk of process.stdin)
|
|
511
|
-
chunks.push(chunk);
|
|
512
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
513
|
-
}
|
|
514
|
-
const workflowWatchCommand = defineJsonCommand({
|
|
515
|
-
meta: {
|
|
516
|
-
name: "watch",
|
|
517
|
-
description: "Print a run's workflow_* events (state.db events table) as NDJSON and exit; --stream polls in the " +
|
|
518
|
-
"foreground until the run reaches a terminal status (no daemon)",
|
|
519
|
-
},
|
|
520
|
-
args: {
|
|
521
|
-
runId: { type: "positional", description: "Workflow run id", required: true },
|
|
522
|
-
stream: {
|
|
523
|
-
type: "boolean",
|
|
524
|
-
description: "Keep polling for new events until the run leaves 'active' (completed/failed/blocked)",
|
|
525
|
-
default: false,
|
|
526
|
-
},
|
|
527
|
-
"interval-ms": { type: "string", description: "Poll interval in milliseconds for --stream (default: 1000)" },
|
|
528
|
-
},
|
|
529
|
-
async run({ args }) {
|
|
530
|
-
const rawInterval = getStringArg(args, "interval-ms");
|
|
531
|
-
let intervalMs;
|
|
532
|
-
if (rawInterval !== undefined) {
|
|
533
|
-
intervalMs = Number.parseInt(rawInterval, 10);
|
|
534
|
-
if (!/^\d+$/.test(rawInterval) || intervalMs <= 0) {
|
|
535
|
-
throw new UsageError(`--interval-ms must be a positive integer, got "${rawInterval}".`, "INVALID_FLAG_VALUE");
|
|
536
|
-
}
|
|
252
|
+
else {
|
|
253
|
+
flags.push({ name, value: true });
|
|
537
254
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
}
|
|
255
|
+
}
|
|
256
|
+
return flags;
|
|
257
|
+
}
|
|
258
|
+
function parseIntegerFlag(raw, name, minimum, maximum) {
|
|
259
|
+
if (raw === undefined)
|
|
260
|
+
return undefined;
|
|
261
|
+
const value = Number.parseInt(raw, 10);
|
|
262
|
+
if (!/^\d+$/.test(raw) || value < minimum || (maximum !== undefined && value > maximum)) {
|
|
263
|
+
const range = maximum === undefined ? `at least ${minimum}` : `from ${minimum} through ${maximum}`;
|
|
264
|
+
throw new UsageError(`${name} must be an integer ${range}, got "${raw}".`, "INVALID_FLAG_VALUE");
|
|
265
|
+
}
|
|
266
|
+
return value;
|
|
267
|
+
}
|
|
268
|
+
function parseWorkflowTimeout(raw) {
|
|
269
|
+
if (raw === undefined)
|
|
270
|
+
return undefined;
|
|
271
|
+
const match = /^(\d+)(ms|s|m)?$/.exec(raw);
|
|
272
|
+
if (!match) {
|
|
273
|
+
throw new UsageError(`--timeout must be N, Nms, Ns, or Nm, got "${raw}".`, "INVALID_FLAG_VALUE");
|
|
274
|
+
}
|
|
275
|
+
const amount = Number(match[1]);
|
|
276
|
+
const multiplier = match[2] === "m" ? 60_000 : match[2] === "s" ? 1_000 : 1;
|
|
277
|
+
const timeoutMs = amount * multiplier;
|
|
278
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > WORKFLOW_MAX_TIMEOUT_MS) {
|
|
279
|
+
throw new UsageError(`--timeout must resolve to 1 through ${WORKFLOW_MAX_TIMEOUT_MS} milliseconds, got "${raw}".`, "INVALID_FLAG_VALUE");
|
|
280
|
+
}
|
|
281
|
+
return timeoutMs;
|
|
282
|
+
}
|
|
549
283
|
const workflowAbandonCommand = defineJsonCommand({
|
|
550
284
|
meta: {
|
|
551
285
|
name: "abandon",
|
|
@@ -572,32 +306,23 @@ const workflowResumeCommand = defineJsonCommand({
|
|
|
572
306
|
output("workflow-resume", result);
|
|
573
307
|
},
|
|
574
308
|
});
|
|
575
|
-
export const workflowCommand =
|
|
309
|
+
export const workflowCommand = defineGroupCommand({
|
|
576
310
|
meta: {
|
|
577
311
|
name: "workflow",
|
|
578
312
|
description: "Author, inspect, and execute step-by-step workflow assets",
|
|
579
313
|
},
|
|
580
314
|
subCommands: {
|
|
581
|
-
start: workflowStartCommand,
|
|
582
|
-
next: workflowNextCommand,
|
|
583
|
-
complete: workflowCompleteCommand,
|
|
584
315
|
status: workflowStatusCommand,
|
|
585
316
|
list: workflowListCommand,
|
|
586
317
|
create: workflowCreateCommand,
|
|
587
|
-
template: workflowTemplateCommand,
|
|
588
318
|
resume: workflowResumeCommand,
|
|
589
319
|
abandon: workflowAbandonCommand,
|
|
590
|
-
validate: workflowValidateCommand,
|
|
591
320
|
run: workflowRunCommand,
|
|
592
|
-
brief: workflowBriefCommand,
|
|
593
|
-
report: workflowReportCommand,
|
|
594
|
-
watch: workflowWatchCommand,
|
|
595
|
-
},
|
|
596
|
-
run({ args }) {
|
|
597
|
-
return runWithJsonErrors(async () => {
|
|
598
|
-
if (hasWorkflowSubcommand(args))
|
|
599
|
-
return;
|
|
600
|
-
output("workflow-list", await listWorkflowRuns({ activeOnly: true }));
|
|
601
|
-
});
|
|
602
321
|
},
|
|
322
|
+
// No `defaultRun`: bare `akm workflow` is a usage error (exit 2), the
|
|
323
|
+
// canonical bare-group behavior — owner ruling 12. Run `akm workflow list
|
|
324
|
+
// --active` for what the bare form used to print. This group was previously
|
|
325
|
+
// hand-rolled on `defineCommand` with its own `hasWorkflowSubcommand` guard,
|
|
326
|
+
// which duplicated the subcommand names in a second hand-maintained set;
|
|
327
|
+
// `defineGroupCommand` derives the guard from `subCommands` directly.
|
|
603
328
|
});
|