akm-cli 0.9.1 → 0.9.2-alpha.2
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 +103 -28
- package/README.md +3 -1
- package/SECURITY.md +1 -1
- package/STABILITY.md +1 -1
- package/dist/akm +2 -2
- package/dist/akm-migrate +2 -2
- package/dist/assets/hints/cli-hints-full.md +14 -9
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/models.json +35 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +3 -4
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +1 -3
- package/dist/assets/tasks/core/extract.yml +6 -5
- package/dist/assets/tasks/core/improve.yml +6 -5
- package/dist/assets/tasks/core/index-refresh.yml +6 -5
- package/dist/assets/tasks/core/sync.yml +6 -5
- package/dist/assets/tasks/core/version-check.yml +6 -5
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
- package/dist/cli/confirm.js +2 -2
- package/dist/cli/parse-args.js +3 -24
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +2 -2
- package/dist/cli.js +11 -9
- package/dist/commands/agent/agent-dispatch.js +55 -89
- package/dist/commands/agent/contribute-cli.js +12 -45
- package/dist/commands/command/builtin-action.js +32 -0
- package/dist/commands/command/command-cli.js +99 -0
- package/dist/commands/command/command-execution.js +308 -0
- package/dist/commands/command/execution-source-loader.js +176 -0
- package/dist/commands/command/portable-template.js +60 -0
- package/dist/commands/config-cli.js +10 -4
- package/dist/commands/env/env.js +4 -2
- package/dist/commands/feedback-cli.js +1 -1
- package/dist/commands/health/checks.js +241 -29
- package/dist/commands/health/html-report.js +0 -14
- package/dist/commands/health/report-view-model.js +0 -1
- package/dist/commands/health/surfaces.js +6 -7
- package/dist/commands/health/types.js +0 -2
- package/dist/commands/health.js +63 -18
- package/dist/commands/improve/collapse-detector.js +5 -6
- package/dist/commands/improve/consolidate.js +251 -214
- package/dist/commands/improve/distill/promote-memory.js +71 -34
- package/dist/commands/improve/distill/quality-gate.js +17 -5
- package/dist/commands/improve/distill.js +232 -155
- package/dist/commands/improve/eligibility.js +112 -79
- package/dist/commands/improve/execution.js +57 -0
- package/dist/commands/improve/extract-cli.js +5 -5
- package/dist/commands/improve/extract-prompt.js +64 -22
- package/dist/commands/improve/extract.js +608 -360
- package/dist/commands/improve/improve-strategies.js +43 -14
- package/dist/commands/improve/improve.js +249 -29
- package/dist/commands/improve/loop-stages.js +11 -17
- package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
- package/dist/commands/improve/outcome-loop.js +22 -38
- package/dist/commands/improve/planner.js +134 -0
- package/dist/commands/improve/preparation.js +730 -409
- package/dist/commands/improve/reflect.js +386 -223
- package/dist/commands/improve/run-context.js +3 -4
- package/dist/commands/improve/salience.js +6 -58
- package/dist/commands/improve/session-asset.js +12 -12
- package/dist/commands/lint/index.js +101 -29
- package/dist/commands/migrate-cli.js +11 -69
- package/dist/commands/migration-tool.js +6 -9
- package/dist/commands/models-cli.js +27 -0
- package/dist/commands/proposal/drain.js +258 -186
- package/dist/commands/proposal/proposal-cli.js +32 -10
- package/dist/commands/proposal/proposal.js +2 -5
- package/dist/commands/proposal/propose.js +192 -172
- package/dist/commands/proposal/repository.js +54 -91
- package/dist/commands/proposal/validators/proposal-validators.js +9 -7
- package/dist/commands/read/curate.js +53 -22
- package/dist/commands/read/registry-search.js +25 -9
- package/dist/commands/read/remember-cli.js +14 -2
- package/dist/commands/read/search.js +10 -4
- package/dist/commands/read/show.js +139 -153
- package/dist/commands/registry-cli.js +16 -7
- package/dist/commands/remember.js +33 -18
- package/dist/commands/sources/add-cli.js +19 -178
- package/dist/commands/sources/bundle-cli.js +15 -3
- package/dist/commands/sources/dangerous-env-audit.js +135 -0
- package/dist/commands/sources/info.js +2 -1
- package/dist/commands/sources/installed-stashes.js +901 -177
- package/dist/commands/sources/schema-repair.js +174 -95
- package/dist/commands/sources/self-update.js +30 -74
- package/dist/commands/sources/source-add.js +3 -5
- package/dist/commands/sources/sources-cli.js +2 -15
- package/dist/commands/sources/update-transaction.js +220 -0
- package/dist/commands/tasks/tasks-cli.js +3 -3
- package/dist/commands/tasks/tasks.js +736 -317
- package/dist/commands/workflow-cli.js +2 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
- package/dist/core/adapter/adapters/akm-adapter.js +85 -35
- package/dist/core/adapter/adapters/akm-lint.js +54 -39
- package/dist/core/adapter/adapters/akm-metadata.js +45 -45
- package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
- package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
- package/dist/core/adapter/adapters/index.js +0 -9
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
- package/dist/core/adapter/adapters/okf-adapter.js +4 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
- package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
- package/dist/core/adapter/execution-source.js +308 -0
- package/dist/core/adapter/recognize-match.js +36 -13
- package/dist/core/adapter/registry.js +0 -9
- package/dist/core/asset/stash-meta.js +94 -4
- package/dist/core/common.js +6 -11
- package/dist/core/config/config-io.js +3 -3
- package/dist/core/config/config-schema.js +18 -40
- package/dist/core/config/config-sources.js +11 -21
- package/dist/core/config/config-walker.js +31 -13
- package/dist/core/config/config.js +23 -26
- package/dist/core/config/schema/engines.js +8 -7
- package/dist/core/config/schema/improve-processes.js +29 -5
- package/dist/core/config/schema/index-config.js +0 -27
- package/dist/core/config/schema/primitives.js +1 -23
- package/dist/core/config/schema/sources-bundles.js +13 -16
- package/dist/core/errors.js +2 -0
- package/dist/core/events.js +68 -32
- package/dist/core/extra-params.js +1 -0
- package/dist/core/improve-result.js +315 -0
- package/dist/core/lesson-lint.js +0 -6
- package/dist/core/maintenance-barrier.js +4 -4
- package/dist/core/network-policy.js +152 -0
- package/dist/core/paths.js +1 -1
- package/dist/core/recognition-util.js +4 -4
- package/dist/core/registry-url.js +456 -0
- package/dist/core/state/migrations.js +161 -47
- package/dist/core/state-db.js +453 -80
- package/dist/core/system-error.js +32 -0
- package/dist/core/time.js +2 -12
- package/dist/core/write-source.js +0 -18
- package/dist/execution/directory-identity.js +52 -0
- package/dist/execution/executable-identity.js +107 -0
- package/dist/execution/guarded-source.js +398 -0
- package/dist/execution/json.js +95 -0
- package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
- package/dist/execution/record.js +55 -0
- package/dist/execution/resolved-request.js +730 -0
- package/dist/execution/source.js +320 -0
- package/dist/indexer/bundle-identity-guard.js +5 -4
- package/dist/indexer/db/graph-db.js +33 -0
- package/dist/indexer/graph/graph-boost.js +3 -4
- package/dist/indexer/graph/graph-extraction.js +562 -373
- package/dist/indexer/index-written-assets.js +78 -39
- package/dist/indexer/indexer.js +471 -432
- package/dist/indexer/installations.js +6 -0
- package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
- package/dist/indexer/materialize-embeddings.js +155 -0
- package/dist/indexer/passes/memory-inference.js +227 -174
- package/dist/indexer/passes/metadata.js +263 -118
- package/dist/indexer/scan/doc-to-entry.js +7 -10
- package/dist/indexer/scan/drain-dir.js +51 -23
- package/dist/indexer/search/db-search.js +156 -50
- package/dist/indexer/search/fts-query.js +40 -40
- package/dist/indexer/search/ranking.js +36 -1
- package/dist/indexer/search/search-attribution.js +3 -1
- package/dist/indexer/search/search-fields.js +23 -14
- package/dist/indexer/search/search-hit-enrichers.js +1 -1
- package/dist/indexer/search/search-source.js +7 -16
- package/dist/indexer/search/semantic-status.js +10 -1
- package/dist/indexer/usage/show-usage.js +105 -0
- package/dist/indexer/usage/usage-events.js +7 -2
- package/dist/indexer/walk/matchers.js +40 -10
- package/dist/indexer/walk/path-resolver.js +5 -2
- package/dist/indexer/walk/walker.js +20 -2
- package/dist/integrations/agent/builder-shared.js +3 -6
- package/dist/integrations/agent/conversation-fallback.js +16 -0
- package/dist/integrations/agent/engine-resolution.js +87 -87
- package/dist/integrations/agent/execution-cascade.js +566 -0
- package/dist/integrations/agent/execution-definitions.js +211 -0
- package/dist/integrations/agent/execution-lowering.js +811 -0
- package/dist/integrations/agent/execution-preparation.js +67 -0
- package/dist/integrations/agent/index.js +0 -2
- package/dist/integrations/agent/inline-execution.js +74 -0
- package/dist/integrations/agent/model-map.js +515 -0
- package/dist/integrations/agent/persona-fallback.js +30 -0
- package/dist/integrations/agent/request-lowering.js +186 -0
- package/dist/integrations/agent/runner-dispatch.js +230 -37
- package/dist/integrations/agent/runner.js +12 -83
- package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
- package/dist/integrations/harnesses/aider/index.js +0 -1
- package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
- package/dist/integrations/harnesses/amazonq/index.js +0 -1
- package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
- package/dist/integrations/harnesses/claude/index.js +1 -5
- package/dist/integrations/harnesses/claude/session-log.js +3 -33
- package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
- package/dist/integrations/harnesses/codex/index.js +0 -1
- package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
- package/dist/integrations/harnesses/copilot/index.js +0 -1
- package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
- package/dist/integrations/harnesses/gemini/index.js +0 -1
- package/dist/integrations/harnesses/index.js +4 -44
- package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
- package/dist/integrations/harnesses/opencode/index.js +0 -2
- package/dist/integrations/harnesses/opencode/session-log.js +14 -204
- package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
- package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
- package/dist/integrations/harnesses/openhands/index.js +0 -1
- package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
- package/dist/integrations/harnesses/pi/index.js +0 -1
- package/dist/integrations/harnesses/shared.js +0 -1
- package/dist/integrations/harnesses/types.js +1 -3
- package/dist/integrations/lockfile.js +82 -79
- package/dist/integrations/session-logs/index.js +6 -17
- package/dist/integrations/session-logs/provider-base.js +1 -29
- package/dist/llm/client.js +10 -5
- package/dist/llm/embedder.js +6 -7
- package/dist/llm/embedders/local.js +37 -88
- package/dist/llm/embedders/types.js +1 -1
- package/dist/llm/graph-extract.js +75 -50
- package/dist/llm/index-passes.js +43 -5
- package/dist/llm/memory-infer.js +8 -6
- package/dist/llm/metadata-enhance.js +5 -3
- package/dist/llm/structured-call.js +122 -25
- package/dist/output/format-exempt.js +1 -1
- package/dist/output/render-registry.js +0 -16
- package/dist/output/renderers.js +12 -7
- package/dist/output/shapes/curate.js +1 -0
- package/dist/output/shapes/helpers.js +10 -2
- package/dist/output/shapes/passthrough.js +2 -0
- package/dist/output/text/command-format.js +31 -33
- package/dist/output/text/health-format.js +1 -29
- package/dist/output/text/migrate.js +6 -56
- package/dist/output/text/proposal-format.js +16 -1
- package/dist/output/text/workflow-format.js +16 -0
- package/dist/registry/network.js +279 -0
- package/dist/registry/pinned-request-helper.js +247 -0
- package/dist/registry/pinned-transport.js +717 -0
- package/dist/registry/providers/skills-sh.js +18 -6
- package/dist/registry/providers/static-index.js +20 -7
- package/dist/registry/resolve.js +53 -28
- package/dist/scripts/akm-migrate-node.js +19334 -52269
- package/dist/scripts/akm-migrate.js +19270 -51612
- package/dist/setup/registry-stash-loader.js +64 -20
- package/dist/setup/semantic-assets.js +9 -34
- package/dist/setup/setup.js +12 -30
- package/dist/setup/source-identity.js +17 -0
- package/dist/setup/steps/sources.js +36 -15
- package/dist/setup/steps/tasks.js +39 -11
- package/dist/sources/providers/git-provider.js +3 -3
- package/dist/sources/providers/npm.js +2 -2
- package/dist/sources/providers/provider-utils.js +4 -3
- package/dist/sources/providers/website.js +11 -7
- package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
- package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
- package/dist/sources/website-url.js +73 -0
- package/dist/storage/engines/sqlite-migrations.js +81 -26
- package/dist/storage/managed-db.js +27 -24
- package/dist/storage/repositories/events-repository.js +3 -0
- package/dist/storage/repositories/index-connection.js +42 -10
- package/dist/storage/repositories/index-entries-repository.js +203 -229
- package/dist/storage/repositories/index-entry-mapper.js +8 -12
- package/dist/storage/repositories/index-entry-schema.js +255 -0
- package/dist/storage/repositories/index-fts-repository.js +64 -71
- package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
- package/dist/storage/repositories/index-meta-repository.js +0 -11
- package/dist/storage/repositories/index-schema.js +74 -350
- package/dist/storage/repositories/index-utility-repository.js +12 -17
- package/dist/storage/repositories/index-vec-repository.js +56 -7
- package/dist/storage/repositories/proposals-repository.js +4 -127
- package/dist/storage/repositories/registry-cache.js +2 -1
- package/dist/storage/repositories/task-history-repository.js +20 -40
- package/dist/storage/repositories/workflow-runs-repository.js +228 -129
- package/dist/storage/sqlite-read-snapshot.js +148 -0
- package/dist/tasks/backends/cron.js +170 -42
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +787 -202
- package/dist/tasks/backends/schtasks.js +282 -83
- package/dist/tasks/embedded.js +7 -7
- package/dist/tasks/frozen-script.js +50 -0
- package/dist/tasks/resolve-akm-bin.js +5 -1
- package/dist/tasks/runner.js +239 -251
- package/dist/tasks/runtime-v3.js +281 -0
- package/dist/tasks/scheduler-binding.js +272 -0
- package/dist/tasks/scheduler-invocation.js +57 -43
- package/dist/tasks/scheduler-sync.js +654 -0
- package/dist/tasks/source-v3.js +752 -0
- package/dist/tasks/standalone-script-entry.js +5 -0
- package/dist/tasks/task-id.js +29 -0
- package/dist/workflows/authoring/authoring.js +15 -32
- package/dist/workflows/exec/dispatch-redaction.js +14 -8
- package/dist/workflows/exec/exec-unit.js +7 -28
- package/dist/workflows/exec/frozen-judge.js +57 -89
- package/dist/workflows/exec/lowering-notices.js +23 -0
- package/dist/workflows/exec/native-executor.js +301 -458
- package/dist/workflows/exec/param-secrets.js +4 -3
- package/dist/workflows/exec/run-workflow.js +26 -32
- package/dist/workflows/exec/step-work.js +105 -109
- package/dist/workflows/exec/unit-dispatch.js +103 -27
- package/dist/workflows/exec/unit-writer.js +3 -3
- package/dist/workflows/exec/worktree.js +2 -2
- package/dist/workflows/ir/compile.js +86 -72
- package/dist/workflows/ir/environment-v4.js +328 -0
- package/dist/workflows/ir/freeze-v4.js +122 -0
- package/dist/workflows/ir/plan-hash.js +13 -7
- package/dist/workflows/ir/schema-v4.js +525 -0
- package/dist/workflows/ir/schema.js +25 -284
- package/dist/workflows/ir/source-freeze-v4.js +506 -0
- package/dist/workflows/parser.js +27 -24
- package/dist/workflows/program/schema.js +1 -2
- package/dist/workflows/renderer.js +42 -29
- package/dist/workflows/resource-limits.js +4 -5
- package/dist/workflows/runtime/agent-identity.js +11 -13
- package/dist/workflows/runtime/plan-classifier.js +8 -8
- package/dist/workflows/runtime/runs.js +27 -43
- package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
- package/dist/workflows/source-files.js +373 -0
- package/dist/workflows/source-ir/compile.js +196 -0
- package/dist/workflows/source-ir/github-yaml.js +577 -0
- package/dist/workflows/source-ir/ordering.js +38 -0
- package/dist/workflows/source-ir/program.js +50 -0
- package/dist/workflows/source-ir/result.js +26 -0
- package/dist/workflows/source-ir/schema.js +772 -0
- package/dist/workflows/source-ir/semantics.js +242 -0
- package/dist/workflows/source-ir/uses.js +14 -0
- package/docs/README.md +2 -0
- package/docs/migration/README.md +3 -1
- package/docs/migration/release-notes/0.9.2.md +55 -0
- package/docs/migration/release-notes/README.md +5 -0
- package/docs/migration/v0.8-to-v0.9.md +76 -1077
- package/docs/migration/v0.9.0-troubleshooting.md +104 -516
- package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
- package/docs/reference/README.md +1 -0
- package/docs/reference/cli.md +230 -98
- package/docs/reference/configuration.md +159 -36
- package/docs/reference/data-and-telemetry.md +19 -1
- package/docs/reference/supported-formats.md +23 -3
- package/docs/reference/tasks.md +182 -0
- package/docs/reference/workflow-schema.md +91 -40
- package/docs/reference/workflows.md +33 -6
- package/package.json +10 -6
- package/schemas/akm-config.json +372 -224
- package/schemas/akm-task.json +324 -80
- package/schemas/akm-workflow.json +6 -9
- package/dist/core/migration-operation.js +0 -75
- package/dist/integrations/agent/model-aliases.js +0 -74
- package/dist/tasks/parser.js +0 -380
- package/dist/tasks/schema.js +0 -123
- package/dist/tasks/validator.js +0 -80
- package/dist/workflows/ir/freeze.js +0 -320
- package/dist/workflows/runtime/document-cache.js +0 -13
|
@@ -2,23 +2,18 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import fs from "node:fs";
|
|
5
|
-
import path from "node:path";
|
|
6
5
|
import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
|
|
7
|
-
import { adapterForId } from "../../core/adapter/registry.js";
|
|
8
6
|
import { makeBundleRef, parseBundleRef } from "../../core/asset/asset-ref.js";
|
|
9
|
-
import { isWithin } from "../../core/common.js";
|
|
10
7
|
import { loadConfig } from "../../core/config/config.js";
|
|
11
8
|
import { NotFoundError, UsageError } from "../../core/errors.js";
|
|
12
9
|
import { getDbPath } from "../../core/paths.js";
|
|
13
|
-
import { canonicalizeWorkflowName
|
|
10
|
+
import { canonicalizeWorkflowName } from "../../core/recognition-util.js";
|
|
14
11
|
import { deriveInstallations } from "../../indexer/installations.js";
|
|
12
|
+
import { resolveAdapterConceptOwner } from "../../indexer/lookup/adapter-concept-owner.js";
|
|
15
13
|
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
16
|
-
import { buildFileContext } from "../../indexer/walk/file-context.js";
|
|
17
|
-
import { resolveAssetPath } from "../../sources/resolve.js";
|
|
18
14
|
import { withIndexDb } from "../../storage/repositories/index-db.js";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { WORKFLOW_SCHEMA_VERSION } from "../schema.js";
|
|
15
|
+
import { compileWorkflowSource } from "../source-ir/compile.js";
|
|
16
|
+
import { sourceStepInstructions } from "../source-ir/program.js";
|
|
22
17
|
/**
|
|
23
18
|
* Build the canonical `workflow_runs.workflow_ref` for an AKM workflow asset.
|
|
24
19
|
*/
|
|
@@ -41,9 +36,7 @@ export async function canonicalizeWorkflowRefInput(ref) {
|
|
|
41
36
|
return (await loadWorkflowAsset(ref)).ref;
|
|
42
37
|
}
|
|
43
38
|
/**
|
|
44
|
-
* Resolve a workflow ref
|
|
45
|
-
* parsed document cached in `index.db` (fast path) and falls back to reading +
|
|
46
|
-
* parsing the source file from disk.
|
|
39
|
+
* Resolve a workflow ref and compile its authored bytes into source IR.
|
|
47
40
|
*/
|
|
48
41
|
export async function loadWorkflowAsset(ref) {
|
|
49
42
|
const bundleRef = parseWorkflowRefInput(ref);
|
|
@@ -67,34 +60,21 @@ export async function loadWorkflowAsset(ref) {
|
|
|
67
60
|
let rejectedSource;
|
|
68
61
|
for (const candidateSource of searchSources) {
|
|
69
62
|
const { source, bundleId } = candidateSource;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
const candidate = await resolveNativeWorkflowPath(source.path, adapterId, candidateName);
|
|
82
|
-
if (!ownsNativeWorkflowRuntime(ownedSource)) {
|
|
83
|
-
rejectedSource ??= { source: ownedSource, bundleId };
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
assetPath = candidate;
|
|
87
|
-
sourcePath = source.path;
|
|
88
|
-
sourceBundleId = bundleId;
|
|
89
|
-
workflowName = candidateName;
|
|
90
|
-
workflowAdapterId = adapterId;
|
|
63
|
+
const adapterId = source.adapterId ?? detectAdapterId(source.path);
|
|
64
|
+
const ownedSource = source.adapterId ? source : { ...source, adapterId };
|
|
65
|
+
const owner = resolveAdapterConceptOwner(source.path, adapterId, bundleRef.conceptId);
|
|
66
|
+
if (!owner)
|
|
67
|
+
continue;
|
|
68
|
+
if (!ownsNativeWorkflowRuntime(ownedSource) || !owner.workflowSource) {
|
|
69
|
+
rejectedSource ??= { source: ownedSource, bundleId };
|
|
91
70
|
break;
|
|
92
71
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
72
|
+
assetPath = owner.path;
|
|
73
|
+
sourcePath = source.path;
|
|
74
|
+
sourceBundleId = bundleId;
|
|
75
|
+
workflowName = owner.workflowSource.canonicalName;
|
|
76
|
+
workflowAdapterId = adapterId;
|
|
77
|
+
break;
|
|
98
78
|
}
|
|
99
79
|
if (!assetPath) {
|
|
100
80
|
if (rejectedSource) {
|
|
@@ -111,185 +91,45 @@ export async function loadWorkflowAsset(ref) {
|
|
|
111
91
|
const fullRef = workflowAdapterId === "akm-workflow"
|
|
112
92
|
? makeBundleRef(sourceBundleId, canonicalName)
|
|
113
93
|
: canonicalWorkflowRunRef(sourceBundleId, canonicalName);
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
return projectAsset(document, fullRef, assetPath, resolvedSourcePath, workflowAdapterId, canonicalName);
|
|
94
|
+
const sourceIr = compileWorkflowSourceFromDisk(assetPath, resolvedSourcePath);
|
|
95
|
+
return projectAsset(sourceIr, fullRef, assetPath, resolvedSourcePath, workflowAdapterId, canonicalName);
|
|
117
96
|
}
|
|
118
97
|
function ownsNativeWorkflowRuntime(source) {
|
|
119
98
|
return source.adapterId === "akm" || source.adapterId === "akm-workflow";
|
|
120
99
|
}
|
|
121
|
-
function workflowNameFromConceptId(conceptId) {
|
|
122
|
-
const prefix = "workflows/";
|
|
123
|
-
return conceptId.startsWith(prefix) && conceptId.length > prefix.length ? conceptId.slice(prefix.length) : undefined;
|
|
124
|
-
}
|
|
125
|
-
function adapterOwnsConcept(sourcePath, adapterId, conceptId) {
|
|
126
|
-
const adapter = adapterForId(adapterId);
|
|
127
|
-
if (!adapter)
|
|
128
|
-
return false;
|
|
129
|
-
const normalized = conceptId.replaceAll("\\", "/");
|
|
130
|
-
if (!normalized ||
|
|
131
|
-
path.posix.isAbsolute(normalized) ||
|
|
132
|
-
normalized === ".." ||
|
|
133
|
-
normalized.startsWith("../") ||
|
|
134
|
-
path.posix.normalize(normalized) !== normalized) {
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
const extensions = [...adapter.extensions].sort((left, right) => right.length - left.length);
|
|
138
|
-
const extension = extensions.find((candidate) => normalized.toLowerCase().endsWith(candidate.toLowerCase()));
|
|
139
|
-
const extensionless = extension ? normalized.slice(0, -extension.length) : normalized;
|
|
140
|
-
const parent = path.join(sourcePath, path.posix.dirname(extensionless));
|
|
141
|
-
let realRoot;
|
|
142
|
-
let realParent;
|
|
143
|
-
try {
|
|
144
|
-
realRoot = fs.realpathSync(sourcePath);
|
|
145
|
-
realParent = fs.realpathSync(parent);
|
|
146
|
-
}
|
|
147
|
-
catch {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
if (!isWithin(realParent, realRoot))
|
|
151
|
-
return false;
|
|
152
|
-
const basename = path.posix.basename(extensionless);
|
|
153
|
-
let entries;
|
|
154
|
-
try {
|
|
155
|
-
entries = fs.readdirSync(realParent, { withFileTypes: true });
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
for (const entry of entries) {
|
|
161
|
-
if (!entry.isFile())
|
|
162
|
-
continue;
|
|
163
|
-
const recognizedExtension = extensions.find((candidate) => entry.name.toLowerCase().endsWith(candidate.toLowerCase()) &&
|
|
164
|
-
entry.name.slice(0, -candidate.length) === basename);
|
|
165
|
-
if (!recognizedExtension)
|
|
166
|
-
continue;
|
|
167
|
-
const candidatePath = path.join(realParent, entry.name);
|
|
168
|
-
try {
|
|
169
|
-
const document = adapter.recognize({ id: adapterId, adapter: adapterId, root: realRoot, writable: false }, buildFileContext(realRoot, candidatePath));
|
|
170
|
-
if (document)
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
173
|
-
catch {
|
|
174
|
-
// A malformed matching file still belongs to the earlier adapter and cannot be bypassed for execution.
|
|
175
|
-
return true;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
async function resolveNativeWorkflowPath(sourcePath, adapterId, name) {
|
|
181
|
-
if (adapterId !== "akm-workflow")
|
|
182
|
-
return resolveAssetPath(sourcePath, "workflow", name);
|
|
183
|
-
const canonicalName = canonicalizeWorkflowName(name);
|
|
184
|
-
let realRoot;
|
|
185
|
-
try {
|
|
186
|
-
realRoot = fs.realpathSync(sourcePath);
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
throw new NotFoundError(`Workflow bundle root not found: ${sourcePath}`);
|
|
190
|
-
}
|
|
191
|
-
const parent = path.join(sourcePath, path.dirname(canonicalName));
|
|
192
|
-
if (!isWithin(parent, realRoot)) {
|
|
193
|
-
throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
|
|
194
|
-
}
|
|
195
|
-
let entries;
|
|
196
|
-
try {
|
|
197
|
-
entries = fs.readdirSync(parent, { withFileTypes: true });
|
|
198
|
-
}
|
|
199
|
-
catch {
|
|
200
|
-
throw new NotFoundError(`Workflow not found: ${name}`);
|
|
201
|
-
}
|
|
202
|
-
const basename = path.basename(canonicalName);
|
|
203
|
-
for (const extension of WORKFLOW_EXTENSIONS) {
|
|
204
|
-
const matches = entries.filter((entry) => {
|
|
205
|
-
if (!entry.isFile() && !entry.isSymbolicLink())
|
|
206
|
-
return false;
|
|
207
|
-
const entryExtension = path.extname(entry.name);
|
|
208
|
-
return entryExtension.toLowerCase() === extension && entry.name.slice(0, -entryExtension.length) === basename;
|
|
209
|
-
});
|
|
210
|
-
if (matches.length > 1) {
|
|
211
|
-
throw new UsageError(`Workflow "${canonicalName}" has multiple ${extension} files that differ only by extension case.`, "RESOURCE_ALREADY_EXISTS");
|
|
212
|
-
}
|
|
213
|
-
const match = matches[0];
|
|
214
|
-
if (!match)
|
|
215
|
-
continue;
|
|
216
|
-
const candidate = path.join(parent, match.name);
|
|
217
|
-
let realTarget;
|
|
218
|
-
try {
|
|
219
|
-
if (!fs.statSync(candidate).isFile())
|
|
220
|
-
continue;
|
|
221
|
-
realTarget = fs.realpathSync(candidate);
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
if (!isWithin(realTarget, realRoot)) {
|
|
227
|
-
throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
|
|
228
|
-
}
|
|
229
|
-
return realTarget;
|
|
230
|
-
}
|
|
231
|
-
throw new NotFoundError(`Workflow not found: ${name}`);
|
|
232
|
-
}
|
|
233
100
|
/**
|
|
234
101
|
* Resolve the `entries.id` for an indexed workflow, or null when the index
|
|
235
102
|
* database does not yet exist or has no matching entry.
|
|
236
103
|
*/
|
|
237
|
-
export function resolveWorkflowEntryId(
|
|
104
|
+
export function resolveWorkflowEntryId(_sourcePath, ref, adapterId) {
|
|
238
105
|
if (!fs.existsSync(getDbPath()))
|
|
239
106
|
return null;
|
|
240
|
-
const
|
|
107
|
+
const parsed = parseBundleRef(ref);
|
|
108
|
+
if (!parsed.bundle)
|
|
109
|
+
throw new UsageError(`Expected a bundle-qualified workflow ref, got "${ref}".`);
|
|
110
|
+
const itemRef = makeBundleRef(parsed.bundle, parsed.conceptId);
|
|
241
111
|
return withIndexDb((db) => {
|
|
242
112
|
const row = db
|
|
243
113
|
.prepare(`SELECT id
|
|
244
114
|
FROM entries
|
|
245
|
-
WHERE
|
|
246
|
-
|
|
115
|
+
WHERE type = 'workflow'
|
|
116
|
+
AND item_ref = ?
|
|
117
|
+
${adapterId ? "AND adapter_id = ?" : ""}
|
|
247
118
|
LIMIT 1`)
|
|
248
|
-
.get(
|
|
119
|
+
.get(itemRef, ...(adapterId ? [adapterId] : []));
|
|
249
120
|
return row?.id ?? null;
|
|
250
121
|
});
|
|
251
122
|
}
|
|
252
|
-
function
|
|
123
|
+
function compileWorkflowSourceFromDisk(assetPath, workspaceRoot) {
|
|
253
124
|
const content = fs.readFileSync(assetPath, "utf8");
|
|
254
|
-
const result =
|
|
125
|
+
const result = compileWorkflowSource(content, { path: assetPath, workspaceRoot });
|
|
255
126
|
if (!result.ok) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return result.document;
|
|
259
|
-
}
|
|
260
|
-
function readWorkflowDocumentFromIndex(sourcePath, ref, adapterId) {
|
|
261
|
-
if (!fs.existsSync(getDbPath()))
|
|
262
|
-
return null;
|
|
263
|
-
const entryKey = workflowEntryKey(sourcePath, ref, adapterId);
|
|
264
|
-
return withIndexDb((db) => {
|
|
265
|
-
const row = db
|
|
266
|
-
.prepare(`SELECT wd.document_json AS document_json, wd.schema_version AS schema_version
|
|
267
|
-
FROM workflow_documents wd
|
|
268
|
-
JOIN entries e ON e.id = wd.entry_id
|
|
269
|
-
WHERE e.entry_type = 'workflow' AND e.entry_key = ?
|
|
270
|
-
LIMIT 1`)
|
|
271
|
-
.get(entryKey);
|
|
272
|
-
if (!row || row.schema_version !== WORKFLOW_SCHEMA_VERSION)
|
|
273
|
-
return null;
|
|
274
|
-
try {
|
|
275
|
-
return JSON.parse(row.document_json);
|
|
276
|
-
}
|
|
277
|
-
catch {
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
function workflowEntryKey(sourcePath, ref, adapterId) {
|
|
283
|
-
const bundleRef = parseBundleRef(ref);
|
|
284
|
-
if ((adapterId ?? detectAdapterId(sourcePath)) === "akm-workflow") {
|
|
285
|
-
return `${sourcePath}:concept:${bundleRef.conceptId}`;
|
|
127
|
+
const details = result.errors.map((error) => ` ${error.path}:${error.line} — ${error.message}`).join("\n");
|
|
128
|
+
throw new UsageError(`Workflow source has ${result.errors.length} error(s):\n${details}`);
|
|
286
129
|
}
|
|
287
|
-
|
|
288
|
-
if (!name)
|
|
289
|
-
throw new UsageError(`Expected a workflow ref, got "${ref}".`);
|
|
290
|
-
return `${sourcePath}:workflow:${name}`;
|
|
130
|
+
return result.ir;
|
|
291
131
|
}
|
|
292
|
-
function projectAsset(
|
|
132
|
+
function projectAsset(sourceIr, ref, assetPath, sourcePath, adapterId, canonicalName) {
|
|
293
133
|
const title = canonicalName.split("/").pop() || canonicalName;
|
|
294
134
|
return {
|
|
295
135
|
ref,
|
|
@@ -297,22 +137,22 @@ function projectAsset(doc, ref, assetPath, sourcePath, adapterId, canonicalName)
|
|
|
297
137
|
sourcePath,
|
|
298
138
|
adapterId,
|
|
299
139
|
title,
|
|
300
|
-
...(
|
|
140
|
+
...(sourceIr.params
|
|
301
141
|
? {
|
|
302
|
-
parameters: Object.entries(
|
|
142
|
+
parameters: Object.entries(sourceIr.params).map(([name, schema]) => {
|
|
303
143
|
const description = schema.description;
|
|
304
144
|
return { name, ...(typeof description === "string" && description ? { description } : {}) };
|
|
305
145
|
}),
|
|
306
146
|
}
|
|
307
147
|
: {}),
|
|
308
|
-
steps:
|
|
309
|
-
id:
|
|
310
|
-
title:
|
|
311
|
-
instructions:
|
|
312
|
-
...(
|
|
313
|
-
sequenceIndex
|
|
314
|
-
})),
|
|
315
|
-
|
|
148
|
+
steps: sourceIr.jobs.flatMap((job) => job.steps.map((step, sequenceIndex) => ({
|
|
149
|
+
id: step.id,
|
|
150
|
+
title: step.id,
|
|
151
|
+
instructions: step.route ? stepFallbackInstructions(step) : sourceStepInstructions(step),
|
|
152
|
+
...(step.gate?.rubric?.trim() ? { completionCriteria: [step.gate.rubric] } : {}),
|
|
153
|
+
sequenceIndex,
|
|
154
|
+
}))),
|
|
155
|
+
sourceIr,
|
|
316
156
|
};
|
|
317
157
|
}
|
|
318
158
|
/** A route-only step with no body section still needs a non-empty spine instructions string. */
|