akm-cli 0.9.0 → 0.9.1-beta.1
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 +707 -0
- package/README.md +28 -63
- package/STABILITY.md +4 -2
- package/dist/commands/agent/contribute-cli.js +1 -1
- package/dist/commands/feedback-cli.js +7 -1
- package/dist/commands/health/llm-usage.js +2 -1
- package/dist/commands/health/surfaces.js +4 -77
- package/dist/commands/health.js +65 -11
- package/dist/commands/improve/distill/quality-gate.js +6 -1
- package/dist/commands/improve/eligibility.js +7 -1
- package/dist/commands/improve/improve.js +126 -10
- package/dist/commands/improve/locks.js +7 -0
- package/dist/commands/improve/memory/memory-improve.js +8 -0
- package/dist/commands/improve/run-context.js +5 -0
- package/dist/commands/improve/session-asset.js +4 -0
- package/dist/commands/lint/base-linter.js +31 -7
- package/dist/commands/lint/index.js +200 -50
- package/dist/commands/lint/types.js +22 -1
- package/dist/commands/proposal/repository.js +17 -1
- package/dist/commands/sources/info.js +12 -2
- package/dist/commands/sources/installed-stashes.js +6 -1
- package/dist/commands/tasks/tasks.js +8 -2
- package/dist/commands/workflow-cli.js +17 -11
- package/dist/core/abort-deadline.js +28 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +67 -5
- package/dist/core/adapter/adapters/akm-adapter.js +13 -10
- package/dist/core/adapter/adapters/akm-lint.js +72 -20
- package/dist/core/adapter/adapters/akm-task-adapter.js +40 -19
- package/dist/core/adapter/adapters/tool-dir-shared.js +5 -3
- package/dist/core/asset/frontmatter.js +4 -0
- package/dist/core/common.js +66 -6
- package/dist/core/concurrent.js +32 -0
- package/dist/core/config/schema/workflow.js +11 -0
- package/dist/core/errors.js +25 -0
- package/dist/core/events.js +30 -24
- package/dist/core/file-lock.js +7 -1
- package/dist/core/improve-result.js +5 -0
- package/dist/core/json-schema.js +327 -9
- package/dist/core/loopback.js +89 -0
- package/dist/core/migration-operation.js +17 -2
- package/dist/core/path-access.js +107 -0
- package/dist/core/redaction.js +64 -17
- package/dist/core/spawn-env.js +234 -0
- package/dist/core/state-db-scope.js +134 -0
- package/dist/core/subprocess.js +181 -37
- package/dist/core/write-provenance.js +85 -0
- package/dist/core/write-source.js +7 -0
- package/dist/indexer/db/graph-db.js +17 -6
- package/dist/indexer/ensure-index.js +10 -3
- package/dist/indexer/index-written-assets.js +17 -2
- package/dist/indexer/indexer.js +55 -15
- package/dist/indexer/passes/memory-inference.js +4 -0
- package/dist/indexer/search/db-search.js +8 -15
- package/dist/integrations/agent/engine-resolution.js +24 -11
- package/dist/integrations/agent/model-aliases.js +1 -1
- package/dist/integrations/agent/profiles.js +9 -1
- package/dist/integrations/agent/spawn.js +15 -87
- package/dist/integrations/lockfile.js +45 -2
- package/dist/output/text/lint-format.js +17 -4
- package/dist/scripts/akm-migrate-node.js +1435 -753
- package/dist/scripts/akm-migrate.js +1403 -721
- package/dist/sources/providers/git-stash.js +19 -0
- package/dist/sources/providers/git.js +1 -1
- package/dist/sources/snapshot-fetchers/website-ingest.js +126 -20
- package/dist/storage/database.js +6 -1
- package/dist/storage/managed-db.js +19 -0
- package/dist/storage/repositories/index-connection.js +28 -3
- package/dist/storage/repositories/index-entries-repository.js +6 -1
- package/dist/storage/repositories/workflow-runs-repository.js +66 -13
- package/dist/tasks/log-redaction.js +156 -0
- package/dist/tasks/parser.js +82 -5
- package/dist/tasks/runner.js +139 -11
- package/dist/tasks/schema.js +65 -0
- package/dist/workflows/concurrency-policy.js +95 -1
- package/dist/workflows/exec/dispatch-redaction.js +114 -0
- package/dist/workflows/exec/exec-unit.js +542 -0
- package/dist/workflows/exec/frozen-judge.js +114 -42
- package/dist/workflows/exec/native-executor.js +457 -238
- package/dist/workflows/exec/param-secrets.js +4 -3
- package/dist/workflows/exec/run-workflow.js +424 -219
- package/dist/workflows/exec/step-work.js +496 -165
- package/dist/workflows/exec/unit-dispatch.js +31 -1
- package/dist/workflows/exec/unit-writer.js +53 -13
- package/dist/workflows/exec/worktree.js +454 -41
- package/dist/workflows/ir/compile.js +26 -2
- package/dist/workflows/ir/freeze.js +82 -15
- package/dist/workflows/ir/schema.js +105 -20
- package/dist/workflows/parser.js +216 -18
- package/dist/workflows/program/schema.js +24 -0
- package/dist/workflows/renderer.js +32 -4
- package/dist/workflows/resource-limits.js +182 -0
- package/dist/workflows/runtime/runs.js +146 -6
- package/dist/workflows/validate-summary.js +17 -2
- package/docs/README.md +74 -32
- package/docs/migration/release-notes/0.9.0.md +2 -1
- package/docs/migration/v0.7-to-v0.8.md +2 -1
- package/docs/migration/v0.8-to-v0.9.md +3 -1
- package/docs/reference/README.md +11 -4
- package/docs/reference/bundle-types.md +19 -0
- package/docs/reference/cli.md +105 -16
- package/docs/reference/configuration.md +15 -2
- package/docs/reference/data-and-telemetry.md +30 -10
- package/docs/reference/supported-formats.md +50 -0
- package/docs/reference/workflow-schema.md +1014 -0
- package/docs/reference/workflows.md +37 -633
- package/package.json +13 -6
- package/schemas/akm-config.json +8 -0
- package/schemas/akm-task.json +27 -5
- package/schemas/akm-workflow.json +85 -10
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akm-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1-beta.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "akm (Agent Knowledge Manager) —
|
|
5
|
+
"description": "akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cursor.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"akm",
|
|
8
8
|
"agent-knowledge-management",
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
"mcp",
|
|
22
22
|
"ai-coding-assistant",
|
|
23
23
|
"agent-skills",
|
|
24
|
-
"skill-management"
|
|
24
|
+
"skill-management",
|
|
25
|
+
"capability-library",
|
|
26
|
+
"agent-capabilities"
|
|
25
27
|
],
|
|
26
28
|
"homepage": "https://github.com/itlackey/akm#readme",
|
|
27
29
|
"repository": {
|
|
@@ -33,7 +35,8 @@
|
|
|
33
35
|
},
|
|
34
36
|
"license": "MPL-2.0",
|
|
35
37
|
"pinNotes": {
|
|
36
|
-
"@opencode-ai/sdk@1.2.20": "Exact pin. The SDK surface we use (createOpencodeClient + session.create/prompt/delete in src/integrations/harnesses/opencode-sdk/sdk-runner.ts) is stable across 1.x, but the SDK has shipped 5+ minor versions of unrelated provider/registry churn. akm-cli is a global CLI install so the pin is isolated from user-project deps. Re-test sdk-runner before bumping. Note this package is an HTTP client only — it declares no dependencies and its own createOpencodeServer spawns `opencode serve` — so it does NOT make the opencode binary available; that install is separate and is what every SDK-path probe checks for."
|
|
38
|
+
"@opencode-ai/sdk@1.2.20": "Exact pin. The SDK surface we use (createOpencodeClient + session.create/prompt/delete in src/integrations/harnesses/opencode-sdk/sdk-runner.ts) is stable across 1.x, but the SDK has shipped 5+ minor versions of unrelated provider/registry churn. akm-cli is a global CLI install so the pin is isolated from user-project deps. Re-test sdk-runner before bumping. Note this package is an HTTP client only — it declares no dependencies and its own createOpencodeServer spawns `opencode serve` — so it does NOT make the opencode binary available; that install is separate and is what every SDK-path probe checks for.",
|
|
39
|
+
"better-sqlite3@12.11.1": "Exact pin (#790). This is the SQLite driver akm loads on Node (src/storage/database.ts); Bun never touches it. The pin is about PREBUILT BINARIES, not API surface. better-sqlite3 ships one prebuild per Node ABI as a GitHub release asset and its install script is `prebuild-install || node-gyp rebuild` — so any (version, Node ABI) pair with no prebuild silently COMPILES FROM SOURCE against the headers of whatever Node is on the machine that day. The 11.x line predates Node 24 and declares no `engines` at all: its newest release (11.10.0, 2025-05-08) publishes ABI 108/115/127/131 (Node 18/20/22/23) and nothing for ABI 137 (Node 24). Node 24.19.0 then changed the public `node_object_wrap.h` so `node::ObjectWrap`'s ctor/dtor register and unregister an environment cleanup hook; a from-source 11.x build against those headers aborts at teardown in `Statement::~Statement()` with `RemoveEnvironmentCleanupHook ... Assertion (env) != nullptr`, intermittently, depending on GC timing. 12.11.1 publishes ABI 127/137/141/147 (Node 22/24/25/26) and declares `engines: 20.x || 22.x || 23.x || 24.x || 25.x || 26.x`, so every Node akm supports installs a prebuilt binary and never compiles. Before bumping: confirm the target version publishes a prebuild for EVERY Node major in `engines` (probe https://github.com/WiseLibs/better-sqlite3/releases/download/vX.Y.Z/better-sqlite3-vX.Y.Z-node-vABI-linux-x64.tar.gz), not just that the version is newer. 13.x is the eventual destination — it moved to node-addon-api/N-API with prebuilds bundled in the npm tarball and no install script, which retires this failure mode entirely — but it is a fresh major rewrite of the binding, so it wants its own soak, not a patch release. The CI node-smoke job installs this exact string by reading it back out of this file (.github/workflows/ci.yml), so the two cannot drift."
|
|
37
40
|
},
|
|
38
41
|
"files": [
|
|
39
42
|
"dist",
|
|
@@ -46,9 +49,12 @@
|
|
|
46
49
|
"docs/migration/v0.7-to-v0.8.md",
|
|
47
50
|
"docs/migration/v0.8-to-v0.9.md",
|
|
48
51
|
"docs/migration/v0.9.0-troubleshooting.md",
|
|
52
|
+
"docs/reference/bundle-types.md",
|
|
49
53
|
"docs/reference/cli.md",
|
|
50
54
|
"docs/reference/configuration.md",
|
|
51
55
|
"docs/reference/data-and-telemetry.md",
|
|
56
|
+
"docs/reference/supported-formats.md",
|
|
57
|
+
"docs/reference/workflow-schema.md",
|
|
52
58
|
"docs/reference/workflows.md",
|
|
53
59
|
"schemas"
|
|
54
60
|
],
|
|
@@ -71,11 +77,12 @@
|
|
|
71
77
|
"test:time": "bun scripts/test-timing-report.ts",
|
|
72
78
|
"lint:isolation": "bun scripts/lint-tests-isolation.ts",
|
|
73
79
|
"lint:doc-examples": "bun scripts/lint-doc-examples.ts",
|
|
80
|
+
"lint:active-docs-terminology": "bun scripts/lint-active-docs-terminology.ts",
|
|
74
81
|
"lint:devto-posts": "bun scripts/lint-devto-posts.ts",
|
|
75
82
|
"lint:devto-posts:fix": "bun scripts/lint-devto-posts.ts --fix",
|
|
76
83
|
"publish:devto": "npx -y @sinedied/devto-cli push \"docs/posts/**/*.md\" --token \"$DEVTO_TOKEN\" --repo \"$GITHUB_REPOSITORY\" --branch \"${GITHUB_REF_NAME:-main}\" --reconcile",
|
|
77
84
|
"release:check": "./tests/release-check.sh",
|
|
78
|
-
"lint": "bunx biome check src/ tests/ scripts/ && bun scripts/lint-tests-isolation.ts && bun scripts/lint-license-headers.ts && bun scripts/lint-runtime-boundary.ts && bun scripts/lint-write-source-chokepoint.ts && bun scripts/lint-secret-resolver-boundary.ts && bun scripts/lint-process-argv.ts && bun scripts/lint-repository-sql.ts && bun scripts/lint-goldens-presence.ts && bun scripts/lint-golden-captured-at-head.ts && bun scripts/lint-test-ref-literals.ts && bun scripts/lint-shipped-assets.ts && bun scripts/lint-doc-examples.ts && bun scripts/gen-config-schema.ts --check",
|
|
85
|
+
"lint": "bunx biome check src/ tests/ scripts/ && bun scripts/lint-tests-isolation.ts && bun scripts/lint-license-headers.ts && bun scripts/lint-runtime-boundary.ts && bun scripts/lint-write-source-chokepoint.ts && bun scripts/lint-secret-resolver-boundary.ts && bun scripts/lint-process-argv.ts && bun scripts/lint-repository-sql.ts && bun scripts/lint-goldens-presence.ts && bun scripts/lint-golden-captured-at-head.ts && bun scripts/lint-test-ref-literals.ts && bun scripts/lint-shipped-assets.ts && bun scripts/lint-doc-examples.ts && bun scripts/gen-config-schema.ts --check && bun scripts/lint-active-docs-terminology.ts",
|
|
79
86
|
"lint:runtime-boundary": "bun scripts/lint-runtime-boundary.ts",
|
|
80
87
|
"lint:tests-isolation": "bun scripts/lint-tests-isolation.ts",
|
|
81
88
|
"lint:fix": "bunx biome check --write src/ tests/ scripts/",
|
|
@@ -100,7 +107,7 @@
|
|
|
100
107
|
},
|
|
101
108
|
"optionalDependencies": {
|
|
102
109
|
"@huggingface/transformers": "^4.2.0",
|
|
103
|
-
"better-sqlite3": "
|
|
110
|
+
"better-sqlite3": "12.11.1",
|
|
104
111
|
"sqlite-vec": "^0.1.9"
|
|
105
112
|
},
|
|
106
113
|
"engines": {
|
package/schemas/akm-config.json
CHANGED
|
@@ -1622,6 +1622,10 @@
|
|
|
1622
1622
|
"type": "integer",
|
|
1623
1623
|
"exclusiveMinimum": 0
|
|
1624
1624
|
},
|
|
1625
|
+
"defaultMapConcurrency": {
|
|
1626
|
+
"type": "integer",
|
|
1627
|
+
"exclusiveMinimum": 0
|
|
1628
|
+
},
|
|
1625
1629
|
"judgeEngine": {
|
|
1626
1630
|
"type": "string",
|
|
1627
1631
|
"maxLength": 63,
|
|
@@ -3270,6 +3274,10 @@
|
|
|
3270
3274
|
"type": "integer",
|
|
3271
3275
|
"exclusiveMinimum": 0
|
|
3272
3276
|
},
|
|
3277
|
+
"defaultMapConcurrency": {
|
|
3278
|
+
"type": "integer",
|
|
3279
|
+
"exclusiveMinimum": 0
|
|
3280
|
+
},
|
|
3273
3281
|
"judgeEngine": {
|
|
3274
3282
|
"type": "string",
|
|
3275
3283
|
"maxLength": 63,
|
package/schemas/akm-task.json
CHANGED
|
@@ -25,21 +25,43 @@
|
|
|
25
25
|
"params": { "type": "object" },
|
|
26
26
|
"engine": { "type": "string", "minLength": 1 },
|
|
27
27
|
"model": { "type": "string", "minLength": 1 },
|
|
28
|
-
"timeoutMs": {
|
|
29
|
-
|
|
28
|
+
"timeoutMs": {
|
|
29
|
+
"type": ["integer", "null"],
|
|
30
|
+
"minimum": 1,
|
|
31
|
+
"maximum": 2147483647,
|
|
32
|
+
"description": "Timeout in milliseconds, or null to disable it. Prompt tasks: the engine timeout. Command tasks: the subprocess timeout. Workflow tasks: the whole-run timeout — omit it to take the unattended default (DEFAULT_WORKFLOW_TASK_TIMEOUT_MS in src/tasks/runner.ts), null to run unbounded."
|
|
33
|
+
},
|
|
34
|
+
"maxSteps": {
|
|
35
|
+
"type": "integer",
|
|
36
|
+
"minimum": 1,
|
|
37
|
+
"description": "Workflow tasks only: stop after executing this many workflow steps (`akm workflow run --max-steps`)."
|
|
38
|
+
},
|
|
39
|
+
"maxRetries": {
|
|
40
|
+
"type": "integer",
|
|
41
|
+
"minimum": 0,
|
|
42
|
+
"maximum": 100,
|
|
43
|
+
"description": "Workflow tasks only: retry a failed workflow step this many additional times (`akm workflow run --max-retries`)."
|
|
44
|
+
},
|
|
45
|
+
"llm": { "$ref": "#/definitions/llm" },
|
|
46
|
+
"redact": {
|
|
47
|
+
"type": "array",
|
|
48
|
+
"maxItems": 32,
|
|
49
|
+
"items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
|
|
50
|
+
"description": "NAMES ONLY: environment variable names whose values are scrubbed from this task's persisted run log and logs.db rows. Values never appear in a task file — a task file is indexed, searchable, and printed verbatim by `akm show`, so a literal secret here would leak more widely than the redaction closes. akm already scrubs config-declared credentials and infers others from the variable name; this is the escape hatch for a secret exported under a name none of those rules recognise. A name unset at run time contributes nothing."
|
|
51
|
+
}
|
|
30
52
|
},
|
|
31
53
|
"oneOf": [
|
|
32
54
|
{
|
|
33
55
|
"required": ["workflow"],
|
|
34
|
-
"not": { "anyOf": [{ "required": ["prompt"] }, { "required": ["command"] }, { "required": ["engine"] }, { "required": ["model"] }, { "required": ["
|
|
56
|
+
"not": { "anyOf": [{ "required": ["prompt"] }, { "required": ["command"] }, { "required": ["engine"] }, { "required": ["model"] }, { "required": ["llm"] }] }
|
|
35
57
|
},
|
|
36
58
|
{
|
|
37
59
|
"required": ["prompt"],
|
|
38
|
-
"not": { "anyOf": [{ "required": ["workflow"] }, { "required": ["command"] }, { "required": ["params"] }] }
|
|
60
|
+
"not": { "anyOf": [{ "required": ["workflow"] }, { "required": ["command"] }, { "required": ["params"] }, { "required": ["maxSteps"] }, { "required": ["maxRetries"] }] }
|
|
39
61
|
},
|
|
40
62
|
{
|
|
41
63
|
"required": ["command"],
|
|
42
|
-
"not": { "anyOf": [{ "required": ["workflow"] }, { "required": ["prompt"] }, { "required": ["params"] }, { "required": ["engine"] }, { "required": ["model"] }, { "required": ["llm"] }] }
|
|
64
|
+
"not": { "anyOf": [{ "required": ["workflow"] }, { "required": ["prompt"] }, { "required": ["params"] }, { "required": ["engine"] }, { "required": ["model"] }, { "required": ["llm"] }, { "required": ["maxSteps"] }, { "required": ["maxRetries"] }] }
|
|
43
65
|
}
|
|
44
66
|
],
|
|
45
67
|
"definitions": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://itlackey.github.io/akm/schemas/akm-workflow.json",
|
|
4
4
|
"title": "AKM Workflow",
|
|
5
|
-
"description": "Unified akm workflow frontmatter (workflow-format-unification). One markdown asset: the standard AKM asset envelope (type/description/tags/when_to_use/xrefs/updated/timestamp + the OKF v0.2 machine-stamped families) plus the orchestration graph. Per-step prose instructions and gate rubrics live in the markdown body, joined to this graph by step id — see docs/reference/
|
|
5
|
+
"description": "Unified akm workflow frontmatter (workflow-format-unification). One markdown asset: the standard AKM asset envelope (type/description/tags/when_to_use/xrefs/updated/timestamp + the OKF v0.2 machine-stamped families) plus the orchestration graph. Per-step prose instructions and gate rubrics live in the markdown body, joined to this graph by step id — see docs/reference/workflow-schema.md. Hand-authored alongside src/workflows/program/schema.ts; the enum vocabularies and patterns here are pinned against the TypeScript constants by tests/integration/workflows/schema-drift.test.ts.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["steps"],
|
|
8
8
|
"additionalProperties": false,
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"description": "A bare reference string: params.<name> or steps.<id>.output(.<ident>|[<int>])*. No ${{ }} delimiters — every position this appears in is a whole-value frontmatter field. Full grammar validation happens at compile time, not here."
|
|
58
58
|
},
|
|
59
59
|
"timeout": {
|
|
60
|
-
"description": "Duration: \"<n>ms\" | \"<n>s\" | \"<n>m\" | \"none\" (bare integers are milliseconds).",
|
|
60
|
+
"description": "Duration: \"<n>ms\" | \"<n>s\" | \"<n>m\" | \"none\" (bare integers are milliseconds). Must resolve to at most 2147483647 ms (setTimeout's 32-bit signed ceiling) — the parser enforces the same ceiling on the string form.",
|
|
61
61
|
"oneOf": [
|
|
62
62
|
{
|
|
63
63
|
"type": "string",
|
|
@@ -65,10 +65,18 @@
|
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
"type": "integer",
|
|
68
|
-
"minimum": 1
|
|
68
|
+
"minimum": 1,
|
|
69
|
+
"maximum": 2147483647
|
|
69
70
|
}
|
|
70
71
|
]
|
|
71
72
|
},
|
|
73
|
+
"engineName": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"minLength": 1,
|
|
76
|
+
"maxLength": 63,
|
|
77
|
+
"pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$",
|
|
78
|
+
"description": "Named engine: lowercase dash-separated words of letters and digits, starting with a letter. Same grammar the frozen-plan decoder enforces (src/workflows/resource-limits.ts WORKFLOW_ENGINE_NAME_PATTERN)."
|
|
79
|
+
},
|
|
72
80
|
"onError": {
|
|
73
81
|
"description": "Failure policy: fail the step on the first unit failure (default), or record failures and let the gate decide.",
|
|
74
82
|
"enum": ["fail", "continue"]
|
|
@@ -140,7 +148,7 @@
|
|
|
140
148
|
},
|
|
141
149
|
"jsonSchemaObject": {
|
|
142
150
|
"type": "object",
|
|
143
|
-
"description": "A JSON Schema declaration
|
|
151
|
+
"description": "A JSON Schema declaration. The parser validates it as a schema definition against the runtime's enforced subset (src/core/json-schema.ts checkJsonSchemaDefinition): typo'd type names and keywords outside the subset (e.g. $ref, const, format, patternProperties) are authoring-time errors, not silent no-ops."
|
|
144
152
|
},
|
|
145
153
|
"retry": {
|
|
146
154
|
"type": "object",
|
|
@@ -151,6 +159,7 @@
|
|
|
151
159
|
"max": {
|
|
152
160
|
"type": "integer",
|
|
153
161
|
"minimum": 0,
|
|
162
|
+
"maximum": 100,
|
|
154
163
|
"description": "Maximum retry attempts per unit."
|
|
155
164
|
},
|
|
156
165
|
"on": {
|
|
@@ -186,8 +195,7 @@
|
|
|
186
195
|
"additionalProperties": false,
|
|
187
196
|
"properties": {
|
|
188
197
|
"engine": {
|
|
189
|
-
"
|
|
190
|
-
"minLength": 1
|
|
198
|
+
"$ref": "#/definitions/engineName"
|
|
191
199
|
},
|
|
192
200
|
"model": {
|
|
193
201
|
"type": "string",
|
|
@@ -205,14 +213,79 @@
|
|
|
205
213
|
}
|
|
206
214
|
}
|
|
207
215
|
},
|
|
208
|
-
"
|
|
216
|
+
"exec": {
|
|
209
217
|
"type": "object",
|
|
210
|
-
"description": "
|
|
218
|
+
"description": "Run a shell command as this unit instead of dispatching to an engine. `command` is an ARGV ARRAY and there is no shell-string form: the child is spawned directly, so shell metacharacters (`;` `|` `&&` `$(…)` `>` `*`) are inert literal argument bytes — the quoting/injection class simply does not exist. Write the interpreter explicitly (e.g. [\"bash\", \"-lc\", \"a | b\"]) when a pipeline is really wanted. stdout is the promoted step artifact with trailing newlines stripped (like shell `$(…)`); when the unit declares an `output` schema, stdout must instead be exactly one JSON value, which is validated against it. A non-zero exit fails the unit with failure reason `non_zero_exit`, honoring `retry:` and `on_error:` like any other unit. The child's environment is an ALLOWLIST by default (PATH, HOME, locale/temp vars, the Windows process-creation essentials) — widen it with `pass_env` or `inherit_env`.",
|
|
219
|
+
"required": ["command"],
|
|
211
220
|
"additionalProperties": false,
|
|
212
221
|
"properties": {
|
|
213
|
-
"
|
|
222
|
+
"command": {
|
|
223
|
+
"type": "array",
|
|
224
|
+
"description": "argv; command[0] is the program, resolved through PATH. Never shell-parsed.",
|
|
225
|
+
"minItems": 1,
|
|
226
|
+
"maxItems": 64,
|
|
227
|
+
"items": {
|
|
228
|
+
"type": "string",
|
|
229
|
+
"minLength": 1,
|
|
230
|
+
"maxLength": 4096
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"cwd": {
|
|
214
234
|
"type": "string",
|
|
235
|
+
"description": "Optional RELATIVE working directory inside the unit's working directory (its fresh worktree under `isolation: worktree`). Absolute paths, Windows drive letters, \"~\", and \"..\" segments are rejected here, and containment is re-checked against the resolved base — symlinks included — before the command is spawned.",
|
|
215
236
|
"minLength": 1,
|
|
237
|
+
"maxLength": 1024,
|
|
238
|
+
"pattern": "^(?!/|\\\\|~|[A-Za-z]:)(?!.*(?:^|[/\\\\])\\.\\.(?:[/\\\\]|$)).+$"
|
|
239
|
+
},
|
|
240
|
+
"pass_env": {
|
|
241
|
+
"type": "array",
|
|
242
|
+
"description": "Extra environment variable NAMES copied through from akm's own environment on top of the default allowlist — for a per-machine toolchain variable (e.g. CARGO_HOME) that no committed `env:` asset could carry. NAMES ONLY: values never appear in a workflow, and unlike `env:` bindings these values are NOT redacted from the command's output, so never list a credential here.",
|
|
243
|
+
"minItems": 1,
|
|
244
|
+
"maxItems": 32,
|
|
245
|
+
"uniqueItems": true,
|
|
246
|
+
"items": {
|
|
247
|
+
"type": "string",
|
|
248
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
"inherit_env": {
|
|
252
|
+
"type": "boolean",
|
|
253
|
+
"description": "Give the command akm's ENTIRE environment instead of the default allowlist. Opt in only when a command genuinely needs the caller's whole environment (a wrapper script, a toolchain with many ambient variables); prefer `pass_env` or `env:` bindings, which keep what the command can see explicit in the frontmatter diff. Dispatch-significant: toggling it changes the unit's input hash."
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"unit": {
|
|
258
|
+
"type": "object",
|
|
259
|
+
"description": "Optional dispatch-override bag for a unit/map step. A step with none of these carries the run's engine/model/timeout defaults verbatim. Declaring `exec` turns the step into a shell-command unit: it names no engine, so `engine`, `model`, and `llm` are rejected alongside it.",
|
|
260
|
+
"additionalProperties": false,
|
|
261
|
+
"allOf": [
|
|
262
|
+
{
|
|
263
|
+
"if": {
|
|
264
|
+
"required": ["exec"]
|
|
265
|
+
},
|
|
266
|
+
"then": {
|
|
267
|
+
"not": {
|
|
268
|
+
"anyOf": [
|
|
269
|
+
{
|
|
270
|
+
"required": ["engine"]
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"required": ["model"]
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"required": ["llm"]
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
"properties": {
|
|
284
|
+
"exec": {
|
|
285
|
+
"$ref": "#/definitions/exec"
|
|
286
|
+
},
|
|
287
|
+
"engine": {
|
|
288
|
+
"$ref": "#/definitions/engineName",
|
|
216
289
|
"description": "Named engine selected when the workflow run is created."
|
|
217
290
|
},
|
|
218
291
|
"model": {
|
|
@@ -260,7 +333,8 @@
|
|
|
260
333
|
"concurrency": {
|
|
261
334
|
"type": "integer",
|
|
262
335
|
"minimum": 1,
|
|
263
|
-
"
|
|
336
|
+
"maximum": 64,
|
|
337
|
+
"description": "Max concurrent units for this step. Defaults to workflow.defaultMapConcurrency (4 when unset) — a map step is parallel by default since 0.9.1; write 1 for serial execution. The effective width is the minimum of this, workflow.maxConcurrency, the selected engine's concurrency, and the host CPU cap."
|
|
264
338
|
},
|
|
265
339
|
"reducer": {
|
|
266
340
|
"$ref": "#/definitions/reducer"
|
|
@@ -314,6 +388,7 @@
|
|
|
314
388
|
"max_loops": {
|
|
315
389
|
"type": "integer",
|
|
316
390
|
"minimum": 1,
|
|
391
|
+
"maximum": 100,
|
|
317
392
|
"description": "Evaluator-optimizer loop bound."
|
|
318
393
|
}
|
|
319
394
|
}
|