akm-cli 0.9.31 → 0.10.26101002-alpha
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 +265 -0
- package/STABILITY.md +79 -53
- package/dist/api-node.mjs +20 -0
- package/dist/api.d.ts +23 -0
- package/dist/api.js +45 -0
- package/dist/assets/hints/cli-hints-full.md +13 -27
- package/dist/assets/hints/cli-hints-short.md +1 -1
- package/dist/assets/improve-strategies/default.json +3 -3
- package/dist/assets/prompts/consolidate-pair.md +9 -7
- package/dist/cli/shared.js +31 -48
- package/dist/cli/unknown-flags.js +6 -43
- package/dist/cli.js +8 -34
- package/dist/commands/agent/contribute-cli.js +1 -1
- package/dist/commands/completions.js +1 -2
- package/dist/commands/config-cli.js +5 -28
- package/dist/commands/env/env-cli.js +5 -5
- package/dist/commands/env/secret-cli.js +2 -2
- package/dist/commands/health/checks.js +41 -16
- package/dist/commands/health/plugin-staleness.js +52 -22
- package/dist/commands/improve/autonomy-gate.js +5 -3
- package/dist/commands/improve/consolidate/pair-pass.js +7 -1
- package/dist/commands/improve/consolidate.js +6 -35
- package/dist/commands/improve/distill/lesson-update.js +91 -0
- package/dist/commands/improve/distill-guards.js +1 -43
- package/dist/commands/improve/distill.js +140 -20
- package/dist/commands/improve/eligibility.js +14 -1
- package/dist/commands/improve/extract-cli.js +1 -1
- package/dist/commands/improve/improve-cli.js +87 -102
- package/dist/commands/improve/improve-strategies.js +8 -12
- package/dist/commands/improve/improve.js +2 -2
- package/dist/commands/improve/loop-stages.js +0 -1
- package/dist/commands/improve/planner.js +0 -1
- package/dist/commands/improve/preparation.js +40 -99
- package/dist/commands/improve/proactive-maintenance.js +2 -2
- package/dist/commands/improve/reflect-noise.js +3 -55
- package/dist/commands/improve/reflect.js +3 -8
- package/dist/commands/improve/retrieval-scope.js +2 -2
- package/dist/commands/improve/salience.js +2 -9
- package/dist/commands/improve/stage.js +14 -9
- package/dist/commands/lint/index.js +5 -20
- package/dist/commands/observability-cli.js +3 -9
- package/dist/commands/proposal/drain.js +39 -6
- package/dist/commands/proposal/proposal-cli.js +11 -31
- package/dist/commands/proposal/repository.js +3 -3
- package/dist/commands/read/knowledge.js +3 -3
- package/dist/commands/read/remember-cli.js +0 -13
- package/dist/commands/read/search-cli.js +29 -97
- package/dist/commands/read/search.js +0 -11
- package/dist/commands/read/show.js +0 -19
- package/dist/commands/sources/plugin-upgrade.js +164 -101
- package/dist/commands/sources/sources-cli.js +1 -15
- package/dist/commands/sources/stash-cli.js +4 -12
- package/dist/commands/tasks/tasks-cli.js +4 -115
- package/dist/commands/workflow/plan.js +11 -33
- package/dist/commands/workflow-cli.js +2 -7
- package/dist/core/adapter/adapter-ids.js +1 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
- package/dist/core/adapter/adapters/akm-adapter.js +9 -48
- package/dist/core/adapter/adapters/akm-lint.js +10 -26
- package/dist/core/adapter/adapters/akm-metadata.js +2 -72
- package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
- package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
- package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
- package/dist/core/adapter/recognize-match.js +3 -4
- package/dist/core/common.js +18 -2
- package/dist/core/config/config-schema.js +12 -15
- package/dist/core/config/config-types.js +6 -15
- package/dist/core/config/config-walker.js +6 -23
- package/dist/core/config/config.js +17 -80
- package/dist/core/config/engine-semantics.js +7 -3
- package/dist/core/config/schema/engines.js +7 -7
- package/dist/core/config/schema/improve-processes.js +8 -61
- package/dist/core/config/schema/improve.js +2 -21
- package/dist/core/config/schema/index-config.js +6 -39
- package/dist/core/env-secret-ref.js +2 -45
- package/dist/core/errors.js +1 -2
- package/dist/core/extra-params.js +2 -86
- package/dist/core/improve-result.js +11 -1
- package/dist/core/mutation-target.js +2 -2
- package/dist/core/recognition-util.js +4 -5
- package/dist/core/warn.js +21 -4
- package/dist/core/write-source.js +3 -3
- package/dist/execution/target-ref.js +1 -2
- package/dist/indexer/search/db-search.js +4 -19
- package/dist/indexer/search/fts-query.js +0 -19
- package/dist/integrations/agent/engine-resolution.js +5 -2
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +41 -98
- package/dist/integrations/agent/request-lowering.js +3 -3
- package/dist/integrations/harnesses/aider/index.js +5 -0
- package/dist/integrations/harnesses/amazonq/index.js +1 -0
- package/dist/integrations/harnesses/claude/config-import.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +5 -0
- package/dist/integrations/harnesses/codex/index.js +1 -0
- package/dist/integrations/harnesses/copilot/index.js +1 -0
- package/dist/integrations/harnesses/gemini/index.js +1 -0
- package/dist/integrations/harnesses/index.js +18 -39
- package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
- package/dist/integrations/harnesses/opencode/config-import.js +121 -52
- package/dist/integrations/harnesses/opencode/index.js +22 -0
- package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
- package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
- package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
- package/dist/integrations/harnesses/opencode/session-log.js +104 -115
- package/dist/integrations/harnesses/opencode/version.js +98 -0
- package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +228 -0
- package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
- package/dist/integrations/harnesses/openhands/index.js +1 -0
- package/dist/integrations/harnesses/pi/index.js +1 -0
- package/dist/integrations/harnesses/shared.js +2 -0
- package/dist/integrations/harnesses/types.js +2 -0
- package/dist/llm/client.js +41 -11
- package/dist/output/cli-hints.js +1 -1
- package/dist/output/context.js +10 -19
- package/dist/output/format-exempt.js +5 -8
- package/dist/output/shapes/helpers.js +1 -22
- package/dist/output/shapes/passthrough.js +0 -1
- package/dist/output/shapes.js +3 -31
- package/dist/output/stdout.js +5 -1
- package/dist/output/text/command-format.js +6 -1
- package/dist/output/text/workflow-format.js +4 -22
- package/dist/scripts/akm-migrate-node.js +13049 -14013
- package/dist/scripts/akm-migrate.js +16316 -17276
- package/dist/setup/detect.js +10 -4
- package/dist/setup/harness-config-import.js +5 -14
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +12 -13
- package/dist/storage/repositories/task-history-repository.js +0 -5
- package/dist/storage/repositories/workflow-runs-repository.js +5 -15
- package/dist/tasks/embedded.js +2 -1
- package/dist/tasks/run/task-history.js +0 -2
- package/dist/tasks/schedule-gates.js +39 -0
- package/dist/tasks/scheduler-binding.js +0 -16
- package/dist/tasks/scheduler-sync.js +3 -97
- package/dist/tasks/source/bounded-document.js +1 -1
- package/dist/tasks/source/task-source-v4.js +2 -12
- package/dist/tasks/task-run-reserved-flags.js +2 -31
- package/dist/workflows/authoring/authoring.js +6 -6
- package/dist/workflows/compile.js +8 -65
- package/dist/workflows/exec/child-workflow.js +22 -3
- package/dist/workflows/exec/native-executor.js +12 -147
- package/dist/workflows/exec/run-workflow.js +31 -103
- package/dist/workflows/exec/step-work.js +9 -178
- package/dist/workflows/exec/unit-dispatch.js +0 -10
- package/dist/workflows/freeze/environment.js +3 -44
- package/dist/workflows/freeze/freeze.js +8 -41
- package/dist/workflows/freeze/targets/child-workflow.js +27 -63
- package/dist/workflows/freeze/targets/command.js +2 -16
- package/dist/workflows/freeze/targets/shell.js +0 -2
- package/dist/workflows/freeze/task-bindings.js +2 -28
- package/dist/workflows/ir/params.js +12 -2
- package/dist/workflows/parser.js +82 -232
- package/dist/workflows/plan.js +1 -1
- package/dist/workflows/renderer.js +10 -19
- package/dist/workflows/runtime/run-plan.js +11 -53
- package/dist/workflows/runtime/runs.js +4 -27
- package/dist/workflows/source-files.js +12 -16
- package/dist/workflows/source-semantics.js +1 -93
- package/docs/README.md +1 -1
- package/docs/agents/README.md +3 -3
- package/docs/agents/agent-install.md +1 -1
- package/docs/architecture/adapters.md +17 -31
- package/docs/architecture/architecture.md +4 -5
- package/docs/architecture/improvement.md +52 -21
- package/docs/architecture/internals/improve-workflow.md +15 -8
- package/docs/architecture/internals/indexing.md +1 -1
- package/docs/architecture/internals/search.md +1 -2
- package/docs/architecture/internals/storage-locations.md +5 -5
- package/docs/architecture/persisted-data-compat.md +13 -4
- package/docs/architecture/specs/0.9.0-decisions.md +6 -2
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +2 -2
- package/docs/architecture/specs/workflow-format-unification.md +1 -6
- package/docs/architecture/testing/manual-testing-checklist.md +20 -29
- package/docs/architecture/testing/task-workflow-manual-tests.md +106 -203
- package/docs/architecture/testing/testing-workflow.md +1 -1
- package/docs/architecture/workflow-engine.md +5 -56
- package/docs/guides/author-workflows.md +39 -69
- package/docs/guides/capture-knowledge.md +1 -1
- package/docs/guides/claude-code-vs-akm-workflows.md +1 -2
- package/docs/guides/discover-and-load.md +4 -4
- package/docs/guides/getting-started.md +1 -1
- package/docs/guides/improve-the-library.md +7 -7
- package/docs/guides/recipes/headless-install.md +2 -2
- package/docs/guides/run-workflows.md +1 -1
- package/docs/guides/use-with-any-agent.md +49 -4
- package/docs/integration/bundling-akm.md +7 -6
- package/docs/maintainers/curate-workmap.md +1 -2
- package/docs/maintainers/release-checklist.md +30 -1
- package/docs/posts/akm-command-tour.md +3 -3
- package/docs/product-surface.md +1 -1
- package/docs/reference/README.md +1 -0
- package/docs/reference/api.md +65 -0
- package/docs/reference/asset-types.md +3 -5
- package/docs/reference/bundle-types.md +2 -4
- package/docs/reference/cli.md +129 -171
- package/docs/reference/configuration.md +84 -19
- package/docs/reference/data-and-telemetry.md +1 -1
- package/docs/reference/env-and-secrets.md +2 -2
- package/docs/reference/supported-formats.md +3 -4
- package/docs/reference/tasks.md +12 -19
- package/docs/reference/website-sources.md +1 -1
- package/docs/reference/workflow-schema.md +89 -317
- package/docs/reference/workflows.md +20 -48
- package/package.json +12 -2
- package/schemas/akm-config.json +2 -243
- package/schemas/akm-task.json +2 -3
- package/schemas/akm-workflow.json +47 -84
- package/dist/assets/improve-strategies/catchup.json +0 -41
- package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
- package/dist/assets/improve-strategies/quick.json +0 -17
- package/dist/assets/improve-strategies/reflect-distill.json +0 -29
- package/dist/assets/improve-strategies/thorough.json +0 -49
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
- package/dist/cli/retired-commands.js +0 -118
- package/dist/commands/tasks/validate.js +0 -176
- package/dist/core/config/legacy-source-shape-shim.js +0 -117
- package/dist/integrations/harnesses/ids.js +0 -28
- package/dist/tasks/source/task-source-v3-frozen.js +0 -424
- package/dist/tasks/source/task-to-v4.js +0 -863
- package/dist/workflows/exec/worktree.js +0 -372
- package/dist/workflows/freeze/child-output-references.js +0 -83
- package/dist/workflows/freeze/identity.js +0 -22
- package/dist/workflows/freeze/targets/script.js +0 -50
- package/dist/workflows/freeze/targets/task.js +0 -124
- package/dist/workflows/github-yaml.js +0 -506
- package/dist/workflows/runtime/run-outputs.js +0 -80
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
-
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
-
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
/**
|
|
5
|
-
* `akm task validate <path>` (#907) — parse ONE task file by filesystem
|
|
6
|
-
* path, not a concept ref/id, and report the same diagnostic `akm task
|
|
7
|
-
* sync` would produce for it. The file need not live in any configured
|
|
8
|
-
* bundle: unlike every other `akm task` subcommand, this one never resolves
|
|
9
|
-
* a bundle/adapter/concept id at all — it reads exactly the path it was
|
|
10
|
-
* given and classifies it.
|
|
11
|
-
*
|
|
12
|
-
* Reuses the exact version router `parseTaskSource`
|
|
13
|
-
* (`src/tasks/source/parse-task-source.ts`) every other task-source reader
|
|
14
|
-
* uses (`akm task sync`'s `compileTaskSources` included) — this module never
|
|
15
|
-
* forks a second parser. `readBoundedTaskSourceYaml` /
|
|
16
|
-
* `peekTaskSourceVersion` / `own` are the SAME front-end helpers the router
|
|
17
|
-
* calls first; they are used here only to recover the file's DECLARED schema
|
|
18
|
-
* version for the report and to tell `blocked` from `invalid`.
|
|
19
|
-
*
|
|
20
|
-
* Beyond parsing, this module also runs the SAME two per-source gates
|
|
21
|
-
* `akm task sync`'s `compileTaskSources` runs before it ever installs a
|
|
22
|
-
* schedule — `assertTaskScheduleInputsSatisfyContract` and
|
|
23
|
-
* `assertTaskScheduleCronValid` (both extracted from `scheduler-sync.ts` for
|
|
24
|
-
* exactly this reuse) — so a file `sync` would reject can never
|
|
25
|
-
* be reported `valid` here. Cron dialect is checked against
|
|
26
|
-
* `backendNameForPlatform()`, the same platform default `sync` falls back
|
|
27
|
-
* to whenever it has no injected/native-inspected backend to hand (see
|
|
28
|
-
* `akmTasksAdd`, `src/commands/tasks/tasks.ts`); a bare file was never
|
|
29
|
-
* installed anywhere; there is no native scheduler state to inspect for it.
|
|
30
|
-
*
|
|
31
|
-
* Deliberately DOES NOT call `prepareTaskV3Execution` (the function
|
|
32
|
-
* `compileTaskSources` calls between those two gates) or resolve an
|
|
33
|
-
* execution engine: that path resolves a composed command/persona ref
|
|
34
|
-
* against the local index and lowers the task's cascade-composed
|
|
35
|
-
* engine/model — both of which assume a real, indexed bundle and a
|
|
36
|
-
* configured engine. A bare file passed to `validate` has neither, so
|
|
37
|
-
* running that step would make an otherwise-valid command-kind task report
|
|
38
|
-
* `invalid` on any machine with no engine configured. `resolved`
|
|
39
|
-
* is therefore the compiled task shape `sync` itself would build a
|
|
40
|
-
* scheduler binding from — id, the compiled v4 `version`, `target`
|
|
41
|
-
* (`uses`/`run`), the declared `inputs` contract, and `schedule` bindings —
|
|
42
|
-
* never an execution-lowered plan.
|
|
43
|
-
*
|
|
44
|
-
* Outcome classification (mirrors `parse-task-source.ts`'s own routing
|
|
45
|
-
* table in its header, extended for the two gates above):
|
|
46
|
-
* - `valid` — parses as task source v4 and passes both sync gates.
|
|
47
|
-
* - `blocked` — declared `version: 2` or `3`, or a `version: 4`
|
|
48
|
-
* document still carrying the retired
|
|
49
|
-
* `schedule[].enabled`: what `akm migrate apply`
|
|
50
|
-
* rewrites. The runtime reads only v4 (#987), so the
|
|
51
|
-
* reason names that command.
|
|
52
|
-
* - `invalid` — the document declares SOME version (`4`, or anything
|
|
53
|
-
* other than 2/3/4) but fails to parse/validate, OR it
|
|
54
|
-
* parsed but fails one of the two sync gates above, OR
|
|
55
|
-
* the YAML itself does not parse at all (a genuine
|
|
56
|
-
* syntax error, not merely a non-task shape) — reported
|
|
57
|
-
* with the parser's own reason.
|
|
58
|
-
* - `not-a-task` — the document parses as YAML but never declares a
|
|
59
|
-
* `version:` field at all (or isn't a YAML mapping) —
|
|
60
|
-
* the strongest signal available that the file was
|
|
61
|
-
* never intended as a task source in the first place.
|
|
62
|
-
*/
|
|
63
|
-
import fs from "node:fs";
|
|
64
|
-
import path from "node:path";
|
|
65
|
-
import { UsageError } from "../../core/errors.js";
|
|
66
|
-
import { backendNameForPlatform } from "../../tasks/backends/index.js";
|
|
67
|
-
import { assertTaskScheduleCronValid, assertTaskScheduleInputsSatisfyContract } from "../../tasks/scheduler-sync.js";
|
|
68
|
-
import { own, readBoundedTaskSourceYaml } from "../../tasks/source/bounded-document.js";
|
|
69
|
-
import { parseTaskSource, peekTaskSourceVersion, v4ScheduleHasRetiredEnabledKey, } from "../../tasks/source/parse-task-source.js";
|
|
70
|
-
/** True when `root` is a YAML mapping that itself declares a `version:` key, regardless of that key's type/value. */
|
|
71
|
-
function declaresVersionKey(root) {
|
|
72
|
-
return root !== null && typeof root === "object" && !Array.isArray(root) && own(root, "version");
|
|
73
|
-
}
|
|
74
|
-
function buildResolved(id, v4) {
|
|
75
|
-
return {
|
|
76
|
-
id,
|
|
77
|
-
version: v4.version,
|
|
78
|
-
...(v4.name !== undefined ? { name: v4.name } : {}),
|
|
79
|
-
...(v4.description !== undefined ? { description: v4.description } : {}),
|
|
80
|
-
target: v4.target,
|
|
81
|
-
inputs: v4.inputs ?? {},
|
|
82
|
-
schedule: v4.schedule,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
export async function akmTaskValidate(filePath) {
|
|
86
|
-
const resolvedPath = path.resolve(filePath);
|
|
87
|
-
let stat;
|
|
88
|
-
try {
|
|
89
|
-
stat = fs.statSync(resolvedPath);
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
throw new UsageError(`Task file not found: ${JSON.stringify(filePath)}.`, "INVALID_FLAG_VALUE");
|
|
93
|
-
}
|
|
94
|
-
if (!stat.isFile()) {
|
|
95
|
-
throw new UsageError(`${JSON.stringify(filePath)} is not a regular file.`, "INVALID_FLAG_VALUE");
|
|
96
|
-
}
|
|
97
|
-
let yaml;
|
|
98
|
-
try {
|
|
99
|
-
yaml = fs.readFileSync(resolvedPath, "utf8");
|
|
100
|
-
}
|
|
101
|
-
catch (cause) {
|
|
102
|
-
throw new UsageError(`Task file ${JSON.stringify(filePath)} could not be read: ${cause instanceof Error ? cause.message : String(cause)}`, "INVALID_FLAG_VALUE");
|
|
103
|
-
}
|
|
104
|
-
// Peek the declared version BEFORE the real parse, using the identical
|
|
105
|
-
// bounded YAML front end `parseTaskSource` calls internally — never a
|
|
106
|
-
// second/looser YAML reader. A front-end failure here (unparseable YAML,
|
|
107
|
-
// not a mapping, exceeds a resource bound) means the document itself does
|
|
108
|
-
// not parse at all — tracked as `peekFailed` so that case reports
|
|
109
|
-
// `invalid`, never `not-a-task` (`not-a-task` is reserved for
|
|
110
|
-
// YAML that DOES parse but never declared a task shape). The real parse
|
|
111
|
-
// below throws the identical error either way, so nothing is lost by
|
|
112
|
-
// swallowing it here.
|
|
113
|
-
let root;
|
|
114
|
-
let peekFailed = false;
|
|
115
|
-
try {
|
|
116
|
-
root = readBoundedTaskSourceYaml({ yaml, filePath: resolvedPath }, { sourceLabel: "task source" }).root;
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
peekFailed = true;
|
|
120
|
-
}
|
|
121
|
-
const declaredVersion = peekFailed ? undefined : peekTaskSourceVersion(root);
|
|
122
|
-
const hasVersionKey = !peekFailed && declaresVersionKey(root);
|
|
123
|
-
const workspaceRoot = path.dirname(resolvedPath);
|
|
124
|
-
const backend = backendNameForPlatform();
|
|
125
|
-
let parsed;
|
|
126
|
-
try {
|
|
127
|
-
parsed = parseTaskSource({ yaml, filePath: resolvedPath, workspaceRoot });
|
|
128
|
-
}
|
|
129
|
-
catch (cause) {
|
|
130
|
-
if (!(cause instanceof UsageError))
|
|
131
|
-
throw cause;
|
|
132
|
-
const reason = cause.message;
|
|
133
|
-
// What `akm migrate apply` rewrites is the only refusal for these
|
|
134
|
-
// shapes (`parse-task-source.ts`), so no message-text sniffing is needed.
|
|
135
|
-
if (declaredVersion === 2 ||
|
|
136
|
-
declaredVersion === 3 ||
|
|
137
|
-
(declaredVersion === 4 && v4ScheduleHasRetiredEnabledKey(root))) {
|
|
138
|
-
return { ok: false, path: resolvedPath, sourceVersion: declaredVersion, outcome: "blocked", reason };
|
|
139
|
-
}
|
|
140
|
-
if (peekFailed) {
|
|
141
|
-
return { ok: false, path: resolvedPath, outcome: "invalid", reason };
|
|
142
|
-
}
|
|
143
|
-
if (!hasVersionKey) {
|
|
144
|
-
return { ok: false, path: resolvedPath, outcome: "not-a-task", reason };
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
ok: false,
|
|
148
|
-
path: resolvedPath,
|
|
149
|
-
...(declaredVersion !== undefined ? { sourceVersion: declaredVersion } : {}),
|
|
150
|
-
outcome: "invalid",
|
|
151
|
-
reason,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
// Success is unreachable from any path that leaves `declaredVersion`
|
|
155
|
-
// undefined — the router requires a numeric version 4 to reach here.
|
|
156
|
-
const sourceVersion = declaredVersion ?? 4;
|
|
157
|
-
// The document itself parsed — now the two gates `compileTaskSources`
|
|
158
|
-
// runs before accepting it. A violation here is `invalid`.
|
|
159
|
-
try {
|
|
160
|
-
assertTaskScheduleInputsSatisfyContract(parsed.v4, resolvedPath);
|
|
161
|
-
assertTaskScheduleCronValid(parsed.v4, backend);
|
|
162
|
-
}
|
|
163
|
-
catch (cause) {
|
|
164
|
-
if (!(cause instanceof UsageError))
|
|
165
|
-
throw cause;
|
|
166
|
-
return { ok: false, path: resolvedPath, sourceVersion, outcome: "invalid", reason: cause.message };
|
|
167
|
-
}
|
|
168
|
-
const id = path.parse(resolvedPath).name;
|
|
169
|
-
return {
|
|
170
|
-
ok: true,
|
|
171
|
-
path: resolvedPath,
|
|
172
|
-
sourceVersion,
|
|
173
|
-
outcome: "valid",
|
|
174
|
-
resolved: buildResolved(id, parsed.v4),
|
|
175
|
-
};
|
|
176
|
-
}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { isBundleSlug } from "../asset/asset-ref.js";
|
|
3
|
-
import { warnOnce } from "../warn.js";
|
|
4
|
-
function isPlainRecord(value) {
|
|
5
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
-
}
|
|
7
|
-
const DEFAULT_WRITABLE_BY_TYPE = {
|
|
8
|
-
filesystem: true,
|
|
9
|
-
git: false,
|
|
10
|
-
website: false,
|
|
11
|
-
npm: false,
|
|
12
|
-
};
|
|
13
|
-
function bundleFromLegacySource(entry, index) {
|
|
14
|
-
if (!isPlainRecord(entry))
|
|
15
|
-
return undefined;
|
|
16
|
-
const type = typeof entry.type === "string" ? entry.type : undefined;
|
|
17
|
-
const bundle = {};
|
|
18
|
-
switch (type) {
|
|
19
|
-
case "filesystem":
|
|
20
|
-
if (typeof entry.path !== "string" || !entry.path)
|
|
21
|
-
return undefined;
|
|
22
|
-
bundle.path = entry.path;
|
|
23
|
-
break;
|
|
24
|
-
case "git":
|
|
25
|
-
if (typeof entry.url !== "string" || !entry.url)
|
|
26
|
-
return undefined;
|
|
27
|
-
bundle.git = entry.url;
|
|
28
|
-
break;
|
|
29
|
-
case "website":
|
|
30
|
-
if (typeof entry.url !== "string" || !entry.url)
|
|
31
|
-
return undefined;
|
|
32
|
-
bundle.website = { url: entry.url };
|
|
33
|
-
break;
|
|
34
|
-
case "npm": {
|
|
35
|
-
const spec = typeof entry.url === "string" && entry.url ? entry.url : entry.path;
|
|
36
|
-
if (typeof spec !== "string" || !spec)
|
|
37
|
-
return undefined;
|
|
38
|
-
bundle.npm = spec;
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
default:
|
|
42
|
-
return undefined;
|
|
43
|
-
}
|
|
44
|
-
const writable = typeof entry.writable === "boolean" ? entry.writable : DEFAULT_WRITABLE_BY_TYPE[type ?? ""];
|
|
45
|
-
if (writable !== undefined)
|
|
46
|
-
bundle.writable = writable;
|
|
47
|
-
if (typeof entry.enabled === "boolean")
|
|
48
|
-
bundle.enabled = entry.enabled;
|
|
49
|
-
const name = typeof entry.name === "string" ? entry.name : undefined;
|
|
50
|
-
const key = name && isBundleSlug(name) ? name : `source-${index + 1}`;
|
|
51
|
-
return [key, bundle];
|
|
52
|
-
}
|
|
53
|
-
function filesystemLocator(bundle) {
|
|
54
|
-
if (!isPlainRecord(bundle) || typeof bundle.path !== "string" || bundle.path.length === 0)
|
|
55
|
-
return undefined;
|
|
56
|
-
return path.resolve(bundle.path);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Pure legacy `stashDir`/`sources[]`/`installed` -> `bundles`/`defaultBundle`
|
|
60
|
-
* conversion. Triggers on key *presence* (not on the value being usable), so
|
|
61
|
-
* an unusable value — `stashDir: ""`, `sources: []` — is still removed along
|
|
62
|
-
* with the rest of the legacy shape; only a usable `stashDir` or `sources[]`
|
|
63
|
-
* entry is actually folded into `bundles`. Never warns — see
|
|
64
|
-
* {@link migrateLegacySourceShape} for the warn-once wrapper callers use.
|
|
65
|
-
*/
|
|
66
|
-
export function convertLegacySourceShape(raw) {
|
|
67
|
-
const hasStashDir = "stashDir" in raw;
|
|
68
|
-
const hasSources = "sources" in raw;
|
|
69
|
-
const hasInstalled = "installed" in raw && raw.installed !== undefined;
|
|
70
|
-
if (!hasStashDir && !hasSources && !hasInstalled)
|
|
71
|
-
return { config: raw, converted: [] };
|
|
72
|
-
const { stashDir: _stashDir, sources: _sources, installed: _installed, ...rest } = raw;
|
|
73
|
-
const bundles = isPlainRecord(rest.bundles) ? { ...rest.bundles } : {};
|
|
74
|
-
let defaultBundle = typeof rest.defaultBundle === "string" ? rest.defaultBundle : undefined;
|
|
75
|
-
const usableStashDir = typeof raw.stashDir === "string" && raw.stashDir.trim().length > 0;
|
|
76
|
-
if (usableStashDir) {
|
|
77
|
-
bundles.stash = { path: raw.stashDir, writable: true };
|
|
78
|
-
defaultBundle ??= "stash";
|
|
79
|
-
}
|
|
80
|
-
if (Array.isArray(raw.sources)) {
|
|
81
|
-
raw.sources.forEach((entry, index) => {
|
|
82
|
-
const converted = bundleFromLegacySource(entry, index);
|
|
83
|
-
if (!converted)
|
|
84
|
-
return;
|
|
85
|
-
const [key, bundle] = converted;
|
|
86
|
-
const locator = filesystemLocator(bundle);
|
|
87
|
-
if (locator && Object.values(bundles).some((candidate) => filesystemLocator(candidate) === locator))
|
|
88
|
-
return;
|
|
89
|
-
bundles[key] = bundle;
|
|
90
|
-
defaultBundle ??= key;
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
const converted = [hasStashDir && "stashDir", hasSources && "sources", hasInstalled && "installed"].filter((key) => typeof key === "string");
|
|
94
|
-
// Only add a `bundles` key when there is something to say: either a
|
|
95
|
-
// legacy entry actually converted into one, or the config already had a
|
|
96
|
-
// `bundles` map (preserved as-is). An unusable `stashDir: ""` / `sources: []`
|
|
97
|
-
// with no pre-existing `bundles` should just disappear, not leave behind
|
|
98
|
-
// an empty `bundles: {}`.
|
|
99
|
-
const hasBundles = Object.keys(bundles).length > 0 || isPlainRecord(rest.bundles);
|
|
100
|
-
return {
|
|
101
|
-
config: { ...rest, ...(hasBundles ? { bundles } : {}), ...(defaultBundle !== undefined ? { defaultBundle } : {}) },
|
|
102
|
-
converted,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Warn-once wrapper around {@link convertLegacySourceShape} for the
|
|
107
|
-
* in-memory read path: converts the legacy shape and, when it removed
|
|
108
|
-
* anything, warns once that `akm migrate apply` will persist the rewrite.
|
|
109
|
-
*/
|
|
110
|
-
export function migrateLegacySourceShape(raw, sourcePath) {
|
|
111
|
-
const { config, converted } = convertLegacySourceShape(raw);
|
|
112
|
-
if (converted.length === 0)
|
|
113
|
-
return config;
|
|
114
|
-
const where = sourcePath ? ` at ${sourcePath}` : "";
|
|
115
|
-
warnOnce(`legacy-source-shape${sourcePath ? `:${sourcePath}` : ""}`, `Config${where} uses the retired ${converted.join("/")} shape — auto-migrated in memory to \`bundles\`/\`defaultBundle\`. Run \`akm migrate apply\` to rewrite the config file and silence this warning.`);
|
|
116
|
-
return config;
|
|
117
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
-
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
-
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
export const HARNESS_ID_TABLE = [
|
|
5
|
-
{ id: "opencode", agentDispatch: true, enforcesModelWorkTools: true, nativeAgentSelector: true },
|
|
6
|
-
{ id: "claude", agentDispatch: true, enforcesModelWorkTools: true, nativeAgentSelector: true },
|
|
7
|
-
{ id: "opencode-sdk", agentDispatch: true, enforcesModelWorkTools: true, nativeAgentSelector: true },
|
|
8
|
-
{ id: "codex", agentDispatch: true, enforcesModelWorkTools: false, nativeAgentSelector: false },
|
|
9
|
-
{ id: "copilot", agentDispatch: true, enforcesModelWorkTools: false, nativeAgentSelector: false },
|
|
10
|
-
{ id: "pi", agentDispatch: true, enforcesModelWorkTools: false, nativeAgentSelector: false },
|
|
11
|
-
{ id: "gemini", agentDispatch: true, enforcesModelWorkTools: false, nativeAgentSelector: false },
|
|
12
|
-
{ id: "aider", agentDispatch: true, enforcesModelWorkTools: false, nativeAgentSelector: false },
|
|
13
|
-
{ id: "amazonq", agentDispatch: true, enforcesModelWorkTools: false, nativeAgentSelector: false },
|
|
14
|
-
{ id: "openhands", agentDispatch: true, enforcesModelWorkTools: false, nativeAgentSelector: false },
|
|
15
|
-
];
|
|
16
|
-
/**
|
|
17
|
-
* Canonical, ordered list of valid harness / platform ids — the
|
|
18
|
-
* dependency-free counterpart of `./index.ts`'s `VALID_HARNESS_IDS` (which
|
|
19
|
-
* remains the barrel's own derivation for its own consumers). Both are
|
|
20
|
-
* asserted equal at `HARNESS_REGISTRY` construction time.
|
|
21
|
-
*/
|
|
22
|
-
export const VALID_HARNESS_IDS = Object.freeze(HARNESS_ID_TABLE.map((h) => h.id));
|
|
23
|
-
/** Harness ids whose `capabilities.agentDispatch` is `true`. */
|
|
24
|
-
export const HARNESS_AGENT_DISPATCH_IDS = new Set(HARNESS_ID_TABLE.filter((h) => h.agentDispatch).map((h) => h.id));
|
|
25
|
-
/** Harness ids that confine the model-work tool policy, so unattended model work may run on them. */
|
|
26
|
-
export const HARNESS_MODEL_WORK_IDS = new Set(HARNESS_ID_TABLE.filter((h) => h.enforcesModelWorkTools).map((h) => h.id));
|
|
27
|
-
/** Harness ids that can run a named native agent, so an engine may name a default `agent`. */
|
|
28
|
-
export const HARNESS_NATIVE_AGENT_IDS = new Set(HARNESS_ID_TABLE.filter((h) => h.nativeAgentSelector).map((h) => h.id));
|