akm-cli 0.9.31 → 0.10.261002-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +420 -0
- package/STABILITY.md +99 -57
- package/dist/api-node.mjs +20 -0
- package/dist/api.d.ts +23 -0
- package/dist/api.js +45 -0
- package/dist/assets/hints/cli-hints-full.md +15 -29
- package/dist/assets/hints/cli-hints-short.md +2 -2
- package/dist/assets/improve-strategies/default.json +3 -3
- package/dist/assets/prompts/consolidate-pair.md +9 -7
- package/dist/assets/stash-skeleton/README.md +1 -1
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
- package/dist/cli/shared.js +31 -48
- package/dist/cli/unknown-flags.js +6 -43
- package/dist/cli.js +8 -34
- package/dist/commands/agent/contribute-cli.js +1 -1
- package/dist/commands/completions.js +1 -2
- package/dist/commands/config-cli.js +5 -28
- package/dist/commands/env/env-cli.js +5 -5
- package/dist/commands/env/secret-cli.js +2 -2
- package/dist/commands/feedback-cli.js +75 -49
- package/dist/commands/health/checks.js +41 -16
- package/dist/commands/health/plugin-staleness.js +52 -22
- package/dist/commands/improve/autonomy-gate.js +5 -3
- package/dist/commands/improve/consolidate/chunking.js +3 -10
- package/dist/commands/improve/consolidate/continuity-check.js +4 -4
- package/dist/commands/improve/consolidate/pair-pass.js +29 -10
- package/dist/commands/improve/consolidate.js +10 -65
- package/dist/commands/improve/distill/lesson-update.js +91 -0
- package/dist/commands/improve/distill-guards.js +1 -43
- package/dist/commands/improve/distill.js +148 -21
- package/dist/commands/improve/eligibility.js +14 -1
- package/dist/commands/improve/extract-cli.js +1 -1
- package/dist/commands/improve/extract-prompt.js +17 -7
- package/dist/commands/improve/extract.js +5 -7
- package/dist/commands/improve/improve-cli.js +92 -106
- package/dist/commands/improve/improve-strategies.js +8 -12
- package/dist/commands/improve/improve.js +134 -52
- package/dist/commands/improve/loop-stages.js +18 -5
- package/dist/commands/improve/planner.js +0 -1
- package/dist/commands/improve/preparation.js +40 -99
- package/dist/commands/improve/proactive-maintenance.js +2 -2
- package/dist/commands/improve/reflect-noise.js +3 -55
- package/dist/commands/improve/reflect.js +29 -34
- package/dist/commands/improve/retrieval-queries.js +37 -0
- package/dist/commands/improve/retrieval-scope.js +2 -2
- package/dist/commands/improve/salience.js +2 -9
- package/dist/commands/improve/session-asset.js +4 -1
- package/dist/commands/improve/stage.js +23 -12
- package/dist/commands/lint/index.js +5 -20
- package/dist/commands/observability-cli.js +3 -9
- package/dist/commands/proposal/drain.js +43 -6
- package/dist/commands/proposal/proposal-cli.js +11 -31
- package/dist/commands/proposal/repository.js +20 -14
- package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -3
- package/dist/commands/read/knowledge.js +3 -3
- package/dist/commands/read/remember-cli.js +0 -13
- package/dist/commands/read/search-cli.js +29 -97
- package/dist/commands/read/search.js +0 -11
- package/dist/commands/read/show.js +0 -19
- package/dist/commands/sources/plugin-upgrade.js +164 -101
- package/dist/commands/sources/sources-cli.js +1 -15
- package/dist/commands/sources/stash-cli.js +6 -14
- package/dist/commands/tasks/tasks-cli.js +4 -115
- package/dist/commands/workflow/plan.js +11 -33
- package/dist/commands/workflow-cli.js +2 -7
- package/dist/core/adapter/adapter-ids.js +1 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
- package/dist/core/adapter/adapters/akm-adapter.js +9 -48
- package/dist/core/adapter/adapters/akm-lint.js +10 -26
- package/dist/core/adapter/adapters/akm-metadata.js +2 -72
- package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
- package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
- package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
- package/dist/core/adapter/recognize-match.js +3 -4
- package/dist/core/common.js +18 -2
- package/dist/core/config/config-schema.js +12 -15
- package/dist/core/config/config-types.js +6 -15
- package/dist/core/config/config-walker.js +6 -23
- package/dist/core/config/config.js +17 -80
- package/dist/core/config/engine-semantics.js +7 -3
- package/dist/core/config/schema/engines.js +7 -7
- package/dist/core/config/schema/improve-processes.js +10 -63
- package/dist/core/config/schema/improve.js +2 -21
- package/dist/core/config/schema/index-config.js +6 -39
- package/dist/core/env-secret-ref.js +2 -45
- package/dist/core/errors.js +1 -2
- package/dist/core/extra-params.js +2 -86
- package/dist/core/file-lock.js +2 -6
- package/dist/core/improve-result.js +13 -1
- package/dist/core/mutation-target.js +2 -2
- package/dist/core/paths.js +4 -0
- package/dist/core/recognition-util.js +4 -5
- package/dist/core/run-lock.js +1 -1
- package/dist/core/subprocess.js +49 -0
- package/dist/core/warn.js +21 -4
- package/dist/core/write-source.js +3 -3
- package/dist/execution/target-ref.js +1 -2
- package/dist/indexer/indexer.js +15 -6
- package/dist/indexer/passes/memory-inference.js +15 -6
- package/dist/indexer/search/db-search.js +49 -36
- package/dist/indexer/search/fts-query.js +0 -19
- package/dist/indexer/search/ranking.js +29 -1
- package/dist/indexer/usage/usage-events.js +21 -16
- package/dist/integrations/agent/engine-resolution.js +5 -2
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +41 -98
- package/dist/integrations/agent/request-lowering.js +3 -3
- package/dist/integrations/harnesses/aider/index.js +5 -0
- package/dist/integrations/harnesses/amazonq/index.js +1 -0
- package/dist/integrations/harnesses/claude/config-import.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +5 -0
- package/dist/integrations/harnesses/codex/index.js +1 -0
- package/dist/integrations/harnesses/copilot/index.js +1 -0
- package/dist/integrations/harnesses/gemini/index.js +1 -0
- package/dist/integrations/harnesses/index.js +18 -39
- package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
- package/dist/integrations/harnesses/opencode/config-import.js +121 -52
- package/dist/integrations/harnesses/opencode/index.js +22 -0
- package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
- package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
- package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
- package/dist/integrations/harnesses/opencode/session-log.js +104 -115
- package/dist/integrations/harnesses/opencode/version.js +98 -0
- package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +254 -0
- package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
- package/dist/integrations/harnesses/openhands/index.js +1 -0
- package/dist/integrations/harnesses/pi/index.js +1 -0
- package/dist/integrations/harnesses/shared.js +2 -0
- package/dist/integrations/harnesses/types.js +2 -0
- package/dist/llm/client.js +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 +15745 -16711
- package/dist/scripts/akm-migrate.js +16318 -17280
- package/dist/setup/detect.js +10 -4
- package/dist/setup/harness-config-import.js +5 -14
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +12 -13
- package/dist/sources/providers/git-stash.js +113 -16
- package/dist/storage/repositories/index-utility-repository.js +2 -32
- package/dist/storage/repositories/index-vec-repository.js +4 -0
- package/dist/storage/repositories/task-history-repository.js +0 -5
- package/dist/storage/repositories/workflow-runs-repository.js +5 -15
- package/dist/tasks/embedded.js +2 -1
- package/dist/tasks/run/run-command-task.js +9 -1
- package/dist/tasks/run/run-workflow-task.js +4 -3
- package/dist/tasks/run/task-history.js +0 -2
- package/dist/tasks/run/task-log.js +38 -1
- package/dist/tasks/schedule-gates.js +39 -0
- package/dist/tasks/scheduler-binding.js +0 -16
- package/dist/tasks/scheduler-sync.js +3 -97
- package/dist/tasks/source/bounded-document.js +1 -1
- package/dist/tasks/source/task-source-v4.js +2 -12
- package/dist/tasks/task-run-reserved-flags.js +2 -31
- package/dist/workflows/authoring/authoring.js +6 -6
- package/dist/workflows/compile.js +8 -65
- package/dist/workflows/exec/child-workflow.js +22 -3
- package/dist/workflows/exec/native-executor.js +12 -147
- package/dist/workflows/exec/run-workflow.js +31 -103
- package/dist/workflows/exec/step-work.js +9 -178
- package/dist/workflows/exec/unit-dispatch.js +0 -10
- package/dist/workflows/freeze/environment.js +3 -44
- package/dist/workflows/freeze/freeze.js +8 -41
- package/dist/workflows/freeze/targets/child-workflow.js +27 -63
- package/dist/workflows/freeze/targets/command.js +2 -16
- package/dist/workflows/freeze/targets/shell.js +0 -2
- package/dist/workflows/freeze/task-bindings.js +2 -28
- package/dist/workflows/ir/params.js +12 -2
- package/dist/workflows/parser.js +82 -232
- package/dist/workflows/plan.js +1 -1
- package/dist/workflows/renderer.js +10 -19
- package/dist/workflows/runtime/run-plan.js +11 -53
- package/dist/workflows/runtime/runs.js +4 -27
- package/dist/workflows/source-files.js +12 -16
- package/dist/workflows/source-semantics.js +1 -93
- package/docs/README.md +1 -1
- package/docs/agents/README.md +3 -3
- package/docs/agents/agent-install.md +1 -1
- package/docs/architecture/0.10-process-rules.md +827 -0
- package/docs/architecture/adapters.md +17 -31
- package/docs/architecture/architecture.md +4 -5
- package/docs/architecture/improvement.md +115 -76
- package/docs/architecture/internals/improve-workflow.md +22 -16
- package/docs/architecture/internals/indexing.md +1 -1
- package/docs/architecture/internals/search.md +1 -2
- package/docs/architecture/internals/storage-locations.md +6 -6
- 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 +21 -30
- 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/bundles.md +3 -1
- 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 +10 -9
- package/docs/guides/recipes/headless-install.md +2 -2
- package/docs/guides/run-workflows.md +1 -1
- package/docs/guides/scheduling.md +9 -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 +33 -1
- package/docs/migration/README.md +2 -0
- package/docs/migration/release-notes/0.10.0.md +201 -0
- package/docs/migration/release-notes/README.md +1 -0
- package/docs/migration/v0.9-to-v0.10.md +507 -0
- 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 +160 -188
- package/docs/reference/configuration.md +101 -20
- package/docs/reference/data-and-telemetry.md +2 -2
- 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/prompts/retrieval-relevance-judge.md +0 -6
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
- package/dist/cli/retired-commands.js +0 -118
- package/dist/commands/improve/retrieval-gate.js +0 -132
- package/dist/commands/tasks/validate.js +0 -176
- package/dist/core/config/legacy-source-shape-shim.js +0 -117
- package/dist/indexer/feedback/utility-policy.js +0 -75
- package/dist/integrations/harnesses/ids.js +0 -28
- package/dist/tasks/source/task-source-v3-frozen.js +0 -424
- package/dist/tasks/source/task-to-v4.js +0 -863
- package/dist/workflows/exec/worktree.js +0 -372
- package/dist/workflows/freeze/child-output-references.js +0 -83
- package/dist/workflows/freeze/identity.js +0 -22
- package/dist/workflows/freeze/targets/script.js +0 -50
- package/dist/workflows/freeze/targets/task.js +0 -124
- package/dist/workflows/github-yaml.js +0 -506
- package/dist/workflows/runtime/run-outputs.js +0 -80
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* Reading a run row's frozen plan: the ONE plan decoder and its tolerant
|
|
6
6
|
* row-level wrapper.
|
|
7
7
|
*
|
|
8
|
-
* {@link decodeWorkflowPlan} accepts every plan shape a release
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* {@link decodeWorkflowPlan} accepts every plan shape a release at or above
|
|
9
|
+
* the 0.9.15 floor has stored — irVersion 5 (with its `sourceReadSet` and
|
|
10
|
+
* host-identity fields, which 0.9.15 and 0.9.16 wrote) as well as the current
|
|
11
|
+
* one — and keeps keys it does not know rather than
|
|
11
12
|
* refusing them. It rejects only a plan it cannot run: no steps, a unit with
|
|
12
13
|
* no frozen target, a request that does not decode. `plan_ir_version` and
|
|
13
14
|
* `plan_hash` are informational columns: neither gates execution. A plan that
|
|
@@ -62,30 +63,17 @@ export function frozenStepRows(plan) {
|
|
|
62
63
|
? step.root.kind === "map"
|
|
63
64
|
? step.root.template.instructions
|
|
64
65
|
: step.root.instructions
|
|
65
|
-
:
|
|
66
|
+
: "",
|
|
66
67
|
completionJson: step.gate.criteria.length > 0 ? JSON.stringify(step.gate.criteria) : null,
|
|
67
68
|
sequenceIndex: step.sequenceIndex,
|
|
68
69
|
}));
|
|
69
70
|
}
|
|
70
|
-
function routeInstructions(route) {
|
|
71
|
-
const branches = Object.entries(route.when)
|
|
72
|
-
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
73
|
-
.map(([match, stepId]) => `"${match}" -> ${stepId}`);
|
|
74
|
-
if (route.defaultStepId !== undefined)
|
|
75
|
-
branches.push(`default -> ${route.defaultStepId}`);
|
|
76
|
-
return `Route on ${route.input}: ${branches.join(", ")}.`;
|
|
77
|
-
}
|
|
78
71
|
/** Decode a stored plan (any release's) into the one plan type. */
|
|
79
72
|
export function decodeWorkflowPlan(input, options = {}) {
|
|
80
73
|
const raw = record(input, "plan");
|
|
81
74
|
if (!Array.isArray(raw.steps) || raw.steps.length === 0)
|
|
82
75
|
fail("steps must be a non-empty array");
|
|
83
76
|
const steps = raw.steps.map((value, index) => decodeStep(value, index));
|
|
84
|
-
if (raw.outputs !== undefined) {
|
|
85
|
-
for (const [name, entry] of Object.entries(record(raw.outputs, "outputs"))) {
|
|
86
|
-
string(record(entry, `outputs.${name}`).from, `outputs.${name}.from`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
77
|
const sourceHash = typeof raw.sourceHash === "string" ? raw.sourceHash : legacySourceHash(raw.sourceReadSet, options.workflowRef);
|
|
90
78
|
return {
|
|
91
79
|
...raw,
|
|
@@ -109,28 +97,18 @@ function legacySourceHash(readSet, workflowRef) {
|
|
|
109
97
|
function decodeStep(value, index) {
|
|
110
98
|
const step = record(value, `step ${index}`);
|
|
111
99
|
const stepId = string(step.stepId, `step ${index} stepId`);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
fail(`step ${stepId} has neither a frozen root nor a route`);
|
|
100
|
+
if (step.root === undefined)
|
|
101
|
+
fail(`step ${stepId} has no frozen root`);
|
|
102
|
+
const root = decodeNode(step.root, stepId);
|
|
116
103
|
return {
|
|
117
104
|
...step,
|
|
118
105
|
stepId,
|
|
119
106
|
title: typeof step.title === "string" ? step.title : stepId,
|
|
120
107
|
sequenceIndex: index,
|
|
121
|
-
|
|
122
|
-
...(route ? { route } : {}),
|
|
108
|
+
root,
|
|
123
109
|
gate: decodeGate(step.gate, stepId),
|
|
124
110
|
};
|
|
125
111
|
}
|
|
126
|
-
function decodeRoute(value, stepId) {
|
|
127
|
-
const route = record(value, `step ${stepId} route`);
|
|
128
|
-
string(route.input, `step ${stepId} route.input`);
|
|
129
|
-
const when = record(route.when, `step ${stepId} route.when`);
|
|
130
|
-
for (const target of Object.values(when))
|
|
131
|
-
string(target, `step ${stepId} route target`);
|
|
132
|
-
return route;
|
|
133
|
-
}
|
|
134
112
|
function decodeNode(value, stepId) {
|
|
135
113
|
const node = record(value, `step ${stepId} root`);
|
|
136
114
|
if (node.kind !== "map")
|
|
@@ -154,7 +132,6 @@ function decodeUnit(node, stepId) {
|
|
|
154
132
|
id,
|
|
155
133
|
instructions: typeof node.instructions === "string" ? node.instructions : "",
|
|
156
134
|
onError: node.onError === "continue" ? "continue" : "fail",
|
|
157
|
-
isolation: node.isolation === "worktree" ? "worktree" : "none",
|
|
158
135
|
frozenTarget: decodeTarget(node.frozenTarget, label),
|
|
159
136
|
environment: Array.isArray(node.environment)
|
|
160
137
|
? node.environment.map((binding, index) => decodeEnvironmentBinding(binding, `${label} environment[${index}]`))
|
|
@@ -180,11 +157,7 @@ function decodeGate(value, stepId) {
|
|
|
180
157
|
function decodeTarget(value, label) {
|
|
181
158
|
const target = record(value, `${label} frozenTarget`);
|
|
182
159
|
const inputBindings = decodeInputBindings(target.inputBindings, label);
|
|
183
|
-
const
|
|
184
|
-
const optional = {
|
|
185
|
-
...(gitCommitOid ? { gitCommitOid } : {}),
|
|
186
|
-
...(inputBindings ? { inputBindings } : {}),
|
|
187
|
-
};
|
|
160
|
+
const optional = inputBindings ? { inputBindings } : {};
|
|
188
161
|
switch (target.kind) {
|
|
189
162
|
case "command":
|
|
190
163
|
return decodeCommandTarget(target, label);
|
|
@@ -196,20 +169,6 @@ function decodeTarget(value, label) {
|
|
|
196
169
|
cwdIdentity: record(target.cwdIdentity, `${label} cwdIdentity`),
|
|
197
170
|
...optional,
|
|
198
171
|
};
|
|
199
|
-
case "script":
|
|
200
|
-
return {
|
|
201
|
-
kind: "script",
|
|
202
|
-
ref: string(target.ref, `${label} script ref`),
|
|
203
|
-
contentHash: string(target.contentHash, `${label} contentHash`),
|
|
204
|
-
exec: decodeExec(target.exec, label),
|
|
205
|
-
interpreter: string(target.interpreter, `${label} interpreter`),
|
|
206
|
-
extension: string(target.extension, `${label} extension`),
|
|
207
|
-
bytesBase64: typeof target.bytesBase64 === "string" ? target.bytesBase64 : fail(`${label} has no script bytes`),
|
|
208
|
-
byteLength: typeof target.byteLength === "number" ? target.byteLength : 0,
|
|
209
|
-
cwdIdentity: record(target.cwdIdentity, `${label} cwdIdentity`),
|
|
210
|
-
materialization: "ephemeral-0700-delete",
|
|
211
|
-
...optional,
|
|
212
|
-
};
|
|
213
172
|
case "child-workflow":
|
|
214
173
|
return {
|
|
215
174
|
kind: "child-workflow",
|
|
@@ -217,7 +176,7 @@ function decodeTarget(value, label) {
|
|
|
217
176
|
planHash: string(target.planHash, `${label} planHash`),
|
|
218
177
|
frozenPlan: decodeWorkflowPlan(target.frozenPlan),
|
|
219
178
|
contentHash: string(target.contentHash, `${label} contentHash`),
|
|
220
|
-
|
|
179
|
+
...(target.via === "task" || target.via === "direct" ? { via: target.via } : {}),
|
|
221
180
|
...(typeof target.taskRef === "string" ? { taskRef: target.taskRef } : {}),
|
|
222
181
|
...(inputBindings ? { inputBindings } : {}),
|
|
223
182
|
};
|
|
@@ -247,7 +206,6 @@ function decodeCommandTarget(target, label) {
|
|
|
247
206
|
...(target.cwdIdentity && typeof target.cwdIdentity === "object"
|
|
248
207
|
? { cwdIdentity: target.cwdIdentity }
|
|
249
208
|
: {}),
|
|
250
|
-
...(typeof target.gitCommitOid === "string" ? { gitCommitOid: target.gitCommitOid } : {}),
|
|
251
209
|
...(inputBindings ? { inputBindings } : {}),
|
|
252
210
|
};
|
|
253
211
|
}
|
|
@@ -13,12 +13,11 @@ import { getCurrentWorkflowScopeKey } from "../authoring/scope-key.js";
|
|
|
13
13
|
import { frozenSummaryJudge } from "../exec/frozen-judge.js";
|
|
14
14
|
import { detectSecretShapedParams } from "../exec/param-secrets.js";
|
|
15
15
|
import { freezeWorkflow } from "../freeze/freeze.js";
|
|
16
|
-
import { materializeWorkflowParameterFlags, validateWorkflowParams } from "../ir/params.js";
|
|
16
|
+
import { applyWorkflowParamDefaults, materializeWorkflowParameterFlags, validateWorkflowParams, } from "../ir/params.js";
|
|
17
17
|
import { canonicalPlanJson, computePlanHash } from "../ir/plan-hash.js";
|
|
18
18
|
import { clip, WORKFLOW_UNIT_DIAGNOSTIC_CLIP } from "../resource-limits.js";
|
|
19
19
|
import { validateStepSummary } from "../validate-summary.js";
|
|
20
20
|
import { resolveAgentIdentity } from "./agent-identity.js";
|
|
21
|
-
import { resolveWorkflowRunOutputs } from "./run-outputs.js";
|
|
22
21
|
import { frozenStepRows, readRunPlan } from "./run-plan.js";
|
|
23
22
|
import { canonicalizeWorkflowRefInput, loadWorkflowAsset, resolveWorkflowEntryId } from "./workflow-asset-loader.js";
|
|
24
23
|
/**
|
|
@@ -76,9 +75,7 @@ export async function startWorkflowRun(ref, params = {}, options) {
|
|
|
76
75
|
if (options?.parameterFlags?.length && Object.keys(params).length > 0) {
|
|
77
76
|
throw new UsageError("Workflow parameters must use either an object or per-parameter flags, not both.");
|
|
78
77
|
}
|
|
79
|
-
const effectiveParams = options?.parameterFlags?.length
|
|
80
|
-
? materializeWorkflowParameterFlags(plan, options.parameterFlags)
|
|
81
|
-
: params;
|
|
78
|
+
const effectiveParams = applyWorkflowParamDefaults(plan, options?.parameterFlags?.length ? materializeWorkflowParameterFlags(plan, options.parameterFlags) : params);
|
|
82
79
|
// Non-fatal WARNINGS: untyped-step and undeclared-param advisories surface
|
|
83
80
|
// as `warn()` lines at start (stderr, consistent with the repo's other
|
|
84
81
|
// author-facing warnings) without blocking the run.
|
|
@@ -394,10 +391,9 @@ export async function completeWorkflowStep(input) {
|
|
|
394
391
|
return withWorkflowRunsRepo((repo) => {
|
|
395
392
|
let updatedRun;
|
|
396
393
|
let refreshedSteps = [];
|
|
397
|
-
let outputWarnings;
|
|
398
394
|
repo.transaction(() => {
|
|
399
395
|
const run = readWorkflowRun(repo, input.runId);
|
|
400
|
-
const
|
|
396
|
+
const _plan = requireRunPlan(run);
|
|
401
397
|
if (run.status !== "active") {
|
|
402
398
|
throw new UsageError(`Workflow run ${run.id} is ${run.status} and cannot be updated.`);
|
|
403
399
|
}
|
|
@@ -428,15 +424,6 @@ export async function completeWorkflowStep(input) {
|
|
|
428
424
|
});
|
|
429
425
|
refreshedSteps = readWorkflowRunSteps(repo, run.id);
|
|
430
426
|
const state = deriveRunState(refreshedSteps);
|
|
431
|
-
// Declared outputs resolve inside this transaction once the run
|
|
432
|
-
// completes; a failure rolls the step completion back whole.
|
|
433
|
-
let outputsJson; // undefined = untouched, keep the row's existing value
|
|
434
|
-
if (state.status === "completed" && plan.outputs) {
|
|
435
|
-
const resolved = resolveWorkflowRunOutputs(plan, refreshedSteps);
|
|
436
|
-
outputsJson = JSON.stringify(resolved.outputs);
|
|
437
|
-
repo.setRunOutputs(run.id, outputsJson);
|
|
438
|
-
outputWarnings = resolved.errors;
|
|
439
|
-
}
|
|
440
427
|
repo.updateRunState({
|
|
441
428
|
status: state.status,
|
|
442
429
|
currentStepId: state.currentStepId,
|
|
@@ -450,16 +437,9 @@ export async function completeWorkflowStep(input) {
|
|
|
450
437
|
current_step_id: state.currentStepId,
|
|
451
438
|
updated_at: completedAt,
|
|
452
439
|
completed_at: state.completedAt,
|
|
453
|
-
...(outputsJson !== undefined ? { outputs_json: outputsJson } : {}),
|
|
454
440
|
};
|
|
455
441
|
});
|
|
456
442
|
const detail = buildWorkflowRunDetail(repo, updatedRun, refreshedSteps);
|
|
457
|
-
if (outputWarnings?.length) {
|
|
458
|
-
const messages = outputWarnings.map((e) => `Workflow run ${input.runId} declared ${e}`);
|
|
459
|
-
for (const message of messages)
|
|
460
|
-
warn(message);
|
|
461
|
-
detail.warnings = [...(detail.warnings ?? []), ...messages];
|
|
462
|
-
}
|
|
463
443
|
// #11: emit `workflow_step_completed` ONLY for a genuine `completed`
|
|
464
444
|
// transition; every other non-pending status (failed/skipped/blocked)
|
|
465
445
|
// carries the honest `workflow_step_updated` name. The status is ALWAYS
|
|
@@ -680,10 +660,7 @@ function toWorkflowRunSummary(run) {
|
|
|
680
660
|
agentHarness: run.agent_harness ?? null,
|
|
681
661
|
agentSessionId: run.agent_session_id ?? null,
|
|
682
662
|
planIrVersion: run.plan_ir_version ?? null,
|
|
683
|
-
//
|
|
684
|
-
// pre-existing (non-child, no-outputs-declared) run's envelope is
|
|
685
|
-
// byte-identical.
|
|
686
|
-
...(run.outputs_json ? { outputs: parseJsonObject(run.outputs_json) ?? {} } : {}),
|
|
663
|
+
// Optional and conditionally spread, so a non-child run's envelope is unchanged.
|
|
687
664
|
...(run.parent_run_id ? { parentRunId: run.parent_run_id } : {}),
|
|
688
665
|
...(run.parent_unit_id ? { spawnedByUnitId: run.parent_unit_id } : {}),
|
|
689
666
|
};
|
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* Authoritative workflow-source ownership.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* cache reuse, lookup/show, and runtime load/start. It never chooses one
|
|
11
|
-
* extension by priority: two recognized siblings are a hard collision.
|
|
7
|
+
* One canonical workflow ref must have exactly one source file. This module
|
|
8
|
+
* is the shared filesystem arbitration point used before indexing, cache
|
|
9
|
+
* reuse, lookup/show, and runtime load/start.
|
|
12
10
|
*/
|
|
13
11
|
import fs from "node:fs";
|
|
14
12
|
import path from "node:path";
|
|
@@ -29,7 +27,7 @@ export class WorkflowSourceCollisionError extends WorkflowSourceRejectionError {
|
|
|
29
27
|
constructor(canonicalName, sourcePaths) {
|
|
30
28
|
const sorted = [...sourcePaths].sort(compareCodePoints);
|
|
31
29
|
super(`Workflow "${canonicalName}" resolves to multiple workflow source files: ${sorted.join(", ")}. ` +
|
|
32
|
-
"A canonical workflow ref must be owned by exactly one recognized .md
|
|
30
|
+
"A canonical workflow ref must be owned by exactly one recognized .md source; remove or rename the duplicate.", "RESOURCE_ALREADY_EXISTS", sorted);
|
|
33
31
|
this.name = "WorkflowSourceCollisionError";
|
|
34
32
|
this.canonicalName = canonicalName;
|
|
35
33
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
@@ -46,15 +44,15 @@ export class WorkflowSourceIdentityError extends UsageError {
|
|
|
46
44
|
export class WorkflowSourceNameError extends WorkflowSourceRejectionError {
|
|
47
45
|
constructor(sourcePath, nestedSuffix) {
|
|
48
46
|
super(`Workflow source filename ${sourcePath} has an extensionless stem ending in recognized workflow suffix "${nestedSuffix}". ` +
|
|
49
|
-
"Nested workflow suffixes are invalid; remove the inner .md
|
|
47
|
+
"Nested workflow suffixes are invalid; remove the inner .md suffix instead of relying on repeated stripping.", "WORKFLOW_SOURCE_INVALID", [sourcePath]);
|
|
50
48
|
this.name = "WorkflowSourceNameError";
|
|
51
49
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
export class WorkflowSourceLinkIdentityError extends WorkflowSourceRejectionError {
|
|
55
53
|
constructor(sourcePath, targetPath) {
|
|
56
|
-
super(`Workflow source ${sourcePath} resolves through a symlink to ${targetPath} with a different
|
|
57
|
-
"The authored workflow path and resolved source must
|
|
54
|
+
super(`Workflow source ${sourcePath} resolves through a symlink to ${targetPath} with a different extension. ` +
|
|
55
|
+
"The authored workflow path and resolved source must both be .md.", "WORKFLOW_SOURCE_INVALID", [sourcePath]);
|
|
58
56
|
this.name = "WorkflowSourceLinkIdentityError";
|
|
59
57
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
60
58
|
}
|
|
@@ -240,13 +238,13 @@ function inspectWorkflowSourceDomain(candidates, canonicalName, realRoot) {
|
|
|
240
238
|
function pickWorkflowSource(adapterId, canonicalName, sources) {
|
|
241
239
|
if (sources.length <= 1)
|
|
242
240
|
return sources[0];
|
|
243
|
-
const winner =
|
|
241
|
+
const winner = sources[0];
|
|
244
242
|
const shadowed = sources.filter((source) => source !== winner);
|
|
245
243
|
const displayName = adapterId === "akm" ? `workflows/${canonicalName}` : canonicalName;
|
|
246
|
-
warnOnce(`workflow-source-collision:${displayName}`, `Workflow "${displayName}" has
|
|
244
|
+
warnOnce(`workflow-source-collision:${displayName}`, `Workflow "${displayName}" has several sources (${shadowed
|
|
247
245
|
.map((source) => source.relativePath)
|
|
248
|
-
.join(", ")} shadowed by ${winner?.relativePath}); using
|
|
249
|
-
"silence this warning.");
|
|
246
|
+
.join(", ")} shadowed by ${winner?.relativePath}); using ${winner?.relativePath}. Remove the shadowed ` +
|
|
247
|
+
"sibling to silence this warning.");
|
|
250
248
|
return winner;
|
|
251
249
|
}
|
|
252
250
|
function inspectWorkflowSourceCandidate(candidate, canonicalName, realRoot) {
|
|
@@ -297,7 +295,6 @@ function inspectWorkflowSourceCandidate(candidate, canonicalName, realRoot) {
|
|
|
297
295
|
realPath,
|
|
298
296
|
relativePath: candidate.relativePath,
|
|
299
297
|
canonicalName,
|
|
300
|
-
format: candidate.lowerExtension === ".md" ? "markdown" : "github-yaml",
|
|
301
298
|
},
|
|
302
299
|
};
|
|
303
300
|
}
|
|
@@ -321,8 +318,7 @@ export function assertIndexedWorkflowSourceIdentity(ref, indexedPath, authoritat
|
|
|
321
318
|
throw new WorkflowSourceIdentityError(ref, indexedPath, authoritative.path);
|
|
322
319
|
}
|
|
323
320
|
const indexedExtension = path.extname(indexedPath).toLowerCase();
|
|
324
|
-
|
|
325
|
-
if (indexedExtension !== authoritativeExtension) {
|
|
321
|
+
if (indexedExtension !== ".md") {
|
|
326
322
|
throw new WorkflowSourceIdentityError(ref, indexedPath, authoritative.path);
|
|
327
323
|
}
|
|
328
324
|
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
/** Semantic checks
|
|
4
|
+
/** Semantic checks for the Markdown workflow grammar (`parser.ts`). */
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import { parseBuiltinCommandAction } from "../commands/command/builtin-action.js";
|
|
8
|
-
import { classifyTargetRef } from "../execution/target-ref.js";
|
|
9
|
-
import { parseSchedule } from "../tasks/schedule.js";
|
|
10
7
|
export class WorkflowSourceSemanticError extends Error {
|
|
11
8
|
code;
|
|
12
9
|
constructor(code, message) {
|
|
@@ -15,36 +12,6 @@ export class WorkflowSourceSemanticError extends Error {
|
|
|
15
12
|
this.name = "WorkflowSourceSemanticError";
|
|
16
13
|
}
|
|
17
14
|
}
|
|
18
|
-
/** The argv a `run:` string executes under `shell`. */
|
|
19
|
-
export function workflowShellCommand(shell, content) {
|
|
20
|
-
if (shell === "cmd")
|
|
21
|
-
return ["cmd", "/d", "/s", "/c", content];
|
|
22
|
-
if (shell === "pwsh" || shell === "powershell")
|
|
23
|
-
return [shell, "-Command", content];
|
|
24
|
-
return [shell, "-c", content];
|
|
25
|
-
}
|
|
26
|
-
export function canonicalizeWorkflowCron(value) {
|
|
27
|
-
const canonical = value.trim().split(/\s+/).join(" ");
|
|
28
|
-
if (canonical.startsWith("@") || canonical.split(" ").length !== 5) {
|
|
29
|
-
throw new WorkflowSourceSemanticError("invalid-cron", "GitHub schedule cron must use exactly five fields.");
|
|
30
|
-
}
|
|
31
|
-
try {
|
|
32
|
-
parseSchedule(canonical, "cron");
|
|
33
|
-
}
|
|
34
|
-
catch (cause) {
|
|
35
|
-
throw new WorkflowSourceSemanticError("invalid-cron", cause instanceof Error ? cause.message : "Invalid cron schedule.");
|
|
36
|
-
}
|
|
37
|
-
return canonical;
|
|
38
|
-
}
|
|
39
|
-
export function canonicalizeWorkflowRun(value) {
|
|
40
|
-
if (value.includes("${{")) {
|
|
41
|
-
throw new WorkflowSourceSemanticError("unsupported-github-expression", "GitHub expressions and contexts are not supported.");
|
|
42
|
-
}
|
|
43
|
-
if (value.includes("\0")) {
|
|
44
|
-
throw new WorkflowSourceSemanticError("invalid-exec-argv", "Local run may not contain NUL bytes.");
|
|
45
|
-
}
|
|
46
|
-
return value;
|
|
47
|
-
}
|
|
48
15
|
export function canonicalizeWorkflowWorkingDirectory(value, workspaceRoot) {
|
|
49
16
|
if (hasControlCharacter(value)) {
|
|
50
17
|
throw new WorkflowSourceSemanticError("working-directory-control-character", "working-directory may not contain NUL or control characters.");
|
|
@@ -74,65 +41,6 @@ function hasControlCharacter(value) {
|
|
|
74
41
|
}
|
|
75
42
|
return false;
|
|
76
43
|
}
|
|
77
|
-
export function classifyWorkflowStepUses(value) {
|
|
78
|
-
if (value.includes("${{")) {
|
|
79
|
-
throw new WorkflowSourceSemanticError("unsupported-github-expression", "GitHub expressions are unsupported in uses.");
|
|
80
|
-
}
|
|
81
|
-
if (value.length === 0 || value.trim() !== value || /\s/.test(value)) {
|
|
82
|
-
throw new WorkflowSourceSemanticError("unsupported-uses-target", "uses must be one exact, non-empty executable ref");
|
|
83
|
-
}
|
|
84
|
-
if (value === "akm/command")
|
|
85
|
-
return { kind: "builtin-command", ref: "akm/command" };
|
|
86
|
-
try {
|
|
87
|
-
return classifyTargetRef(value);
|
|
88
|
-
}
|
|
89
|
-
catch (cause) {
|
|
90
|
-
throw usesFailure(value, cause);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Validate AKM's built-in command action at the shared source/decoder boundary.
|
|
95
|
-
*
|
|
96
|
-
* Inline YAML actions are portable templates and therefore use WP4's one
|
|
97
|
-
* authoritative template validator. Markdown prose is explicitly `literal`,
|
|
98
|
-
* while a stored ref remains resolution-owned because its template bytes are
|
|
99
|
-
* not available until the later resolver loads the command asset.
|
|
100
|
-
*/
|
|
101
|
-
export function validateWorkflowBuiltinCommand(value, mode) {
|
|
102
|
-
let action;
|
|
103
|
-
try {
|
|
104
|
-
action = parseBuiltinCommandAction(value);
|
|
105
|
-
}
|
|
106
|
-
catch (cause) {
|
|
107
|
-
throw new WorkflowSourceSemanticError("builtin-command-inputs", cause instanceof Error ? cause.message : "Invalid akm/command inputs.");
|
|
108
|
-
}
|
|
109
|
-
const expectedMode = action.kind === "stored" ? "stored-ref" : "portable-template";
|
|
110
|
-
const effectiveMode = mode ?? expectedMode;
|
|
111
|
-
if (action.kind === "stored") {
|
|
112
|
-
if (effectiveMode !== "stored-ref") {
|
|
113
|
-
throw new WorkflowSourceSemanticError("builtin-command-inputs", "Stored akm/command refs require commandMode stored-ref.");
|
|
114
|
-
}
|
|
115
|
-
return action;
|
|
116
|
-
}
|
|
117
|
-
if (effectiveMode === "stored-ref") {
|
|
118
|
-
throw new WorkflowSourceSemanticError("builtin-command-inputs", "Inline akm/command content cannot use commandMode stored-ref.");
|
|
119
|
-
}
|
|
120
|
-
if (effectiveMode === "literal" && action.arguments !== undefined) {
|
|
121
|
-
throw new WorkflowSourceSemanticError("builtin-command-inputs", "Literal akm/command content cannot declare arguments because no substitution occurs.");
|
|
122
|
-
}
|
|
123
|
-
return action;
|
|
124
|
-
}
|
|
125
|
-
function usesFailure(value, cause) {
|
|
126
|
-
const message = cause instanceof Error ? cause.message : String(cause);
|
|
127
|
-
const code = value.startsWith("docker://")
|
|
128
|
-
? "docker-action-unsupported"
|
|
129
|
-
: value.startsWith("./") || value.startsWith("../") || value.startsWith("/")
|
|
130
|
-
? "local-action-path-unsupported"
|
|
131
|
-
: /^(?:[A-Za-z0-9][A-Za-z0-9._-]*\/\/)?agents\//.test(value)
|
|
132
|
-
? "non-executable-asset-ref"
|
|
133
|
-
: "unsupported-uses-target";
|
|
134
|
-
return new WorkflowSourceSemanticError(code, message);
|
|
135
|
-
}
|
|
136
44
|
function verifyPhysicalContainment(workspaceRoot, relative) {
|
|
137
45
|
let root;
|
|
138
46
|
try {
|
package/docs/README.md
CHANGED
|
@@ -17,7 +17,7 @@ Full per-directory indexes: [Guides](guides/README.md),
|
|
|
17
17
|
- [Getting Started](guides/getting-started.md) -- Install akm, connect a source, and pull a curated shortlist in five to seven minutes
|
|
18
18
|
- [Concepts](guides/concepts.md) -- Capabilities, bundles, adapters, asset types, and refs -- the mental model in one page
|
|
19
19
|
- [Agent Install Guide](agents/agent-install.md) -- Step-by-step automated (non-interactive) install for agents
|
|
20
|
-
- `akm
|
|
20
|
+
- `akm hints` (complete guide by default; `akm hints --detail brief` for the short one) -- The CLI reference agents load to use akm; always the embedded corpus at `src/assets/hints/cli-hints-{full,short}.md`
|
|
21
21
|
|
|
22
22
|
## Use
|
|
23
23
|
|
package/docs/agents/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Documentation for wiring AI agents into akm.
|
|
4
4
|
|
|
5
5
|
Run `akm hints` for the complete CLI reference agents should load into a
|
|
6
|
-
system prompt, or `akm
|
|
7
|
-
|
|
6
|
+
system prompt, or `akm hints --detail brief` for the compact guide.
|
|
7
|
+
It always prints the embedded
|
|
8
8
|
corpus at `src/assets/hints/cli-hints-full.md` / `cli-hints-short.md` --
|
|
9
9
|
browse those files directly if you want to read the reference without running
|
|
10
10
|
the CLI. There used to be a separate `docs/agents/AGENTS.md` /
|
|
@@ -12,4 +12,4 @@ the CLI. There used to be a separate `docs/agents/AGENTS.md` /
|
|
|
12
12
|
re-diverging from the embedded copy with no test to catch it, so it was
|
|
13
13
|
deleted and its still-true unique content was merged into the embedded files.
|
|
14
14
|
|
|
15
|
-
- [Agent Install Guide](agent-install.md) -- Short redirect covering the install shape (binary, `akm setup --yes`, a source, an index, `akm
|
|
15
|
+
- [Agent Install Guide](agent-install.md) -- Short redirect covering the install shape (binary, `akm setup --yes`, a source, an index, `akm hints`); for the exact no-prompts command sequence, see the [headless install recipe](../guides/recipes/headless-install.md)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`akm` is a portable capability library agents install and configure without
|
|
4
4
|
interactive prompts: install the binary, run `akm setup --yes`, add a source,
|
|
5
|
-
build the index, then expose `akm
|
|
5
|
+
build the index, then expose `akm hints` output to the agent so it
|
|
6
6
|
knows how to search and load bundle content. Configuration lives in
|
|
7
7
|
top-level keys validated against the config schema, and semantic search can
|
|
8
8
|
run on local embeddings or a remote endpoint depending on what the host
|