akm-cli 0.7.4 → 0.8.0-rc.10
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 +224 -1
- package/README.md +22 -6
- package/SECURITY.md +93 -0
- package/dist/cli/config-migrate.js +144 -0
- package/dist/cli/config-validate.js +39 -0
- package/dist/cli/confirm.js +73 -0
- package/dist/cli/parse-args.js +133 -0
- package/dist/cli/shared.js +129 -0
- package/dist/cli.js +2631 -1440
- package/dist/commands/add-cli.js +279 -0
- package/dist/commands/agent-dispatch.js +110 -0
- package/dist/commands/agent-support.js +68 -0
- package/dist/commands/completions.js +3 -0
- package/dist/commands/config-cli.js +130 -534
- package/dist/commands/consolidate.js +2122 -0
- package/dist/commands/curate.js +45 -3
- package/dist/commands/db-cli.js +23 -0
- package/dist/commands/distill-promotion-policy.js +660 -0
- package/dist/commands/distill.js +1081 -73
- package/dist/commands/env.js +213 -0
- package/dist/commands/eval-cases.js +43 -0
- package/dist/commands/events.js +15 -24
- package/dist/commands/extract-cli.js +127 -0
- package/dist/commands/extract-prompt.js +204 -0
- package/dist/commands/extract.js +477 -0
- package/dist/commands/feedback-cli.js +331 -0
- package/dist/commands/graph.js +477 -0
- package/dist/commands/health.js +1302 -0
- package/dist/commands/help/help-accept.md +12 -0
- package/dist/commands/help/help-improve.md +69 -0
- package/dist/commands/help/help-proposals.md +18 -0
- package/dist/commands/help/help-propose.md +17 -0
- package/dist/commands/help/help-reject.md +11 -0
- package/dist/commands/history.js +54 -46
- package/dist/commands/improve-auto-accept.js +97 -0
- package/dist/commands/improve-cli.js +217 -0
- package/dist/commands/improve-profiles.js +166 -0
- package/dist/commands/improve-result-file.js +167 -0
- package/dist/commands/improve.js +2373 -0
- package/dist/commands/info.js +5 -2
- package/dist/commands/init.js +50 -2
- package/dist/commands/installed-stashes.js +102 -139
- package/dist/commands/knowledge.js +136 -0
- package/dist/commands/lint/agent-linter.js +49 -0
- package/dist/commands/lint/base-linter.js +479 -0
- package/dist/commands/lint/command-linter.js +49 -0
- package/dist/commands/lint/default-linter.js +16 -0
- package/dist/commands/lint/env-key-rules.js +154 -0
- package/dist/commands/lint/index.js +196 -0
- package/dist/commands/lint/knowledge-linter.js +16 -0
- package/dist/commands/lint/markdown-insertion.js +343 -0
- package/dist/commands/lint/memory-linter.js +61 -0
- package/dist/commands/lint/registry.js +36 -0
- package/dist/commands/lint/skill-linter.js +45 -0
- package/dist/commands/lint/task-linter.js +50 -0
- package/dist/commands/lint/types.js +4 -0
- package/dist/commands/lint/workflow-linter.js +56 -0
- package/dist/commands/lint.js +4 -0
- package/dist/commands/migration-help.js +3 -0
- package/dist/commands/proposal.js +67 -12
- package/dist/commands/propose.js +120 -45
- package/dist/commands/reflect.js +1104 -60
- package/dist/commands/registry-cli.js +150 -0
- package/dist/commands/registry-search.js +5 -2
- package/dist/commands/remember-cli.js +257 -0
- package/dist/commands/remember.js +70 -7
- package/dist/commands/schema-repair.js +203 -0
- package/dist/commands/search.js +115 -14
- package/dist/commands/secret.js +173 -0
- package/dist/commands/self-update.js +3 -0
- package/dist/commands/show.js +158 -60
- package/dist/commands/source-add.js +17 -45
- package/dist/commands/source-clone.js +3 -0
- package/dist/commands/source-manage.js +14 -19
- package/dist/commands/tasks.js +437 -0
- package/dist/commands/url-checker.js +42 -0
- package/dist/core/action-contributors.js +28 -0
- package/dist/core/asset-ref.js +17 -2
- package/dist/core/asset-registry.js +12 -17
- package/dist/core/asset-serialize.js +88 -0
- package/dist/core/asset-spec.js +67 -1
- package/dist/core/common.js +182 -0
- package/dist/core/concurrent.js +25 -0
- package/dist/core/config-io.js +347 -0
- package/dist/core/config-migration.js +622 -0
- package/dist/core/config-schema.js +534 -0
- package/dist/core/config-sources.js +108 -0
- package/dist/core/config-types.js +4 -0
- package/dist/core/config-walker.js +337 -0
- package/dist/core/config.js +364 -968
- package/dist/core/errors.js +42 -20
- package/dist/core/events.js +105 -135
- package/dist/core/file-lock.js +104 -0
- package/dist/core/frontmatter.js +75 -8
- package/dist/core/lesson-lint.js +3 -0
- package/dist/core/markdown.js +20 -0
- package/dist/core/memory-belief.js +62 -0
- package/dist/core/memory-contradiction-detect.js +274 -0
- package/dist/core/memory-improve.js +806 -0
- package/dist/core/parse.js +158 -0
- package/dist/core/paths.js +280 -14
- package/dist/core/proposal-quality-validators.js +380 -0
- package/dist/core/proposal-validators.js +69 -0
- package/dist/core/proposals.js +512 -42
- package/dist/core/state-db.js +1068 -0
- package/dist/core/text-truncation.js +107 -0
- package/dist/core/time.js +54 -0
- package/dist/core/tty.js +59 -0
- package/dist/core/warn.js +64 -1
- package/dist/core/write-source.js +3 -0
- package/dist/indexer/db-backup.js +391 -0
- package/dist/indexer/db-search.js +198 -489
- package/dist/indexer/db.js +990 -108
- package/dist/indexer/ensure-index.js +136 -0
- package/dist/indexer/file-context.js +3 -0
- package/dist/indexer/graph-boost.js +376 -101
- package/dist/indexer/graph-db.js +391 -0
- package/dist/indexer/graph-dedup.js +95 -0
- package/dist/indexer/graph-extraction.js +550 -114
- package/dist/indexer/index-context.js +4 -0
- package/dist/indexer/indexer.js +547 -309
- package/dist/indexer/llm-cache.js +52 -0
- package/dist/indexer/manifest.js +3 -0
- package/dist/indexer/matchers.js +167 -160
- package/dist/indexer/memory-inference.js +152 -74
- package/dist/indexer/metadata-contributors.js +29 -0
- package/dist/indexer/metadata.js +275 -196
- package/dist/indexer/path-resolver.js +92 -0
- package/dist/indexer/project-context.js +192 -0
- package/dist/indexer/ranking-contributors.js +331 -0
- package/dist/indexer/ranking.js +81 -0
- package/dist/indexer/search-fields.js +5 -9
- package/dist/indexer/search-hit-enrichers.js +111 -0
- package/dist/indexer/search-source.js +44 -10
- package/dist/indexer/semantic-status.js +6 -17
- package/dist/indexer/staleness-detect.js +447 -0
- package/dist/indexer/usage-events.js +12 -9
- package/dist/indexer/walker.js +28 -0
- package/dist/integrations/agent/builders.js +135 -0
- package/dist/integrations/agent/config.js +122 -230
- package/dist/integrations/agent/detect.js +3 -0
- package/dist/integrations/agent/index.js +7 -13
- package/dist/integrations/agent/model-aliases.js +55 -0
- package/dist/integrations/agent/profiles.js +70 -5
- package/dist/integrations/agent/prompts.js +250 -36
- package/dist/integrations/agent/runner.js +151 -0
- package/dist/integrations/agent/sdk-runner.js +126 -0
- package/dist/integrations/agent/spawn.js +183 -35
- package/dist/integrations/github.js +3 -0
- package/dist/integrations/lockfile.js +32 -69
- package/dist/integrations/session-logs/index.js +69 -0
- package/dist/integrations/session-logs/inline-refs.js +35 -0
- package/dist/integrations/session-logs/pre-filter.js +152 -0
- package/dist/integrations/session-logs/providers/claude-code.js +282 -0
- package/dist/integrations/session-logs/providers/opencode.js +258 -0
- package/dist/integrations/session-logs/types.js +4 -0
- package/dist/llm/call-ai.js +62 -0
- package/dist/llm/client.js +79 -88
- package/dist/llm/embedder.js +20 -29
- package/dist/llm/embedders/cache.js +3 -7
- package/dist/llm/embedders/local.js +42 -1
- package/dist/llm/embedders/remote.js +20 -8
- package/dist/llm/embedders/types.js +3 -7
- package/dist/llm/feature-gate.js +95 -48
- package/dist/llm/graph-extract.js +676 -72
- package/dist/llm/index-passes.js +44 -29
- package/dist/llm/memory-infer.js +80 -71
- package/dist/llm/metadata-enhance.js +42 -29
- package/dist/llm/prompts/extract-session.md +80 -0
- package/dist/llm/prompts/graph-extract-user-prompt.md +35 -0
- package/dist/output/cli-hints-full.md +292 -0
- package/dist/output/cli-hints-short.md +66 -0
- package/dist/output/cli-hints.js +7 -311
- package/dist/output/context.js +60 -8
- package/dist/output/renderers.js +306 -258
- package/dist/output/shapes/curate.js +56 -0
- package/dist/output/shapes/distill.js +10 -0
- package/dist/output/shapes/env-list.js +19 -0
- package/dist/output/shapes/events.js +11 -0
- package/dist/output/shapes/helpers.js +424 -0
- package/dist/output/shapes/history.js +7 -0
- package/dist/output/shapes/passthrough.js +102 -0
- package/dist/output/shapes/proposal-accept.js +7 -0
- package/dist/output/shapes/proposal-diff.js +7 -0
- package/dist/output/shapes/proposal-list.js +7 -0
- package/dist/output/shapes/proposal-producer.js +11 -0
- package/dist/output/shapes/proposal-reject.js +7 -0
- package/dist/output/shapes/proposal-show.js +7 -0
- package/dist/output/shapes/registry-search.js +6 -0
- package/dist/output/shapes/registry.js +30 -0
- package/dist/output/shapes/search.js +6 -0
- package/dist/output/shapes/secret-list.js +19 -0
- package/dist/output/shapes/show.js +6 -0
- package/dist/output/shapes/vault-list.js +19 -0
- package/dist/output/shapes.js +51 -511
- package/dist/output/text/add.js +6 -0
- package/dist/output/text/clone.js +6 -0
- package/dist/output/text/config.js +6 -0
- package/dist/output/text/curate.js +6 -0
- package/dist/output/text/distill.js +7 -0
- package/dist/output/text/enable-disable.js +7 -0
- package/dist/output/text/events.js +10 -0
- package/dist/output/text/feedback.js +6 -0
- package/dist/output/text/helpers.js +1039 -0
- package/dist/output/text/history.js +7 -0
- package/dist/output/text/import.js +6 -0
- package/dist/output/text/index.js +6 -0
- package/dist/output/text/info.js +6 -0
- package/dist/output/text/init.js +6 -0
- package/dist/output/text/list.js +6 -0
- package/dist/output/text/proposal-producer.js +8 -0
- package/dist/output/text/proposal.js +11 -0
- package/dist/output/text/registry-commands.js +11 -0
- package/dist/output/text/registry.js +30 -0
- package/dist/output/text/remember.js +6 -0
- package/dist/output/text/remove.js +6 -0
- package/dist/output/text/save.js +6 -0
- package/dist/output/text/search.js +6 -0
- package/dist/output/text/show.js +6 -0
- package/dist/output/text/update.js +6 -0
- package/dist/output/text/upgrade.js +6 -0
- package/dist/output/text/vault.js +16 -0
- package/dist/output/text/wiki.js +15 -0
- package/dist/output/text/workflow.js +14 -0
- package/dist/output/text.js +44 -1093
- package/dist/registry/build-index.js +3 -0
- package/dist/registry/create-provider-registry.js +3 -0
- package/dist/registry/factory.js +4 -1
- package/dist/registry/origin-resolve.js +3 -0
- package/dist/registry/providers/index.js +3 -0
- package/dist/registry/providers/skills-sh.js +71 -50
- package/dist/registry/providers/static-index.js +53 -48
- package/dist/registry/providers/types.js +3 -24
- package/dist/registry/resolve.js +11 -16
- package/dist/registry/types.js +3 -0
- package/dist/scripts/migrate-storage.js +17750 -0
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +9031 -0
- package/dist/scripts/migrations/v16-to-v17.js +141 -0
- package/dist/setup/detect.js +3 -0
- package/dist/setup/ripgrep-install.js +3 -0
- package/dist/setup/ripgrep-resolve.js +3 -0
- package/dist/setup/setup.js +775 -37
- package/dist/setup/steps.js +3 -15
- package/dist/sources/include.js +3 -0
- package/dist/sources/provider-factory.js +5 -12
- package/dist/sources/provider.js +3 -20
- package/dist/sources/providers/filesystem.js +19 -23
- package/dist/sources/providers/git.js +179 -20
- package/dist/sources/providers/index.js +3 -0
- package/dist/sources/providers/install-types.js +3 -13
- package/dist/sources/providers/npm.js +3 -4
- package/dist/sources/providers/provider-utils.js +3 -0
- package/dist/sources/providers/sync-from-ref.js +3 -11
- package/dist/sources/providers/tar-utils.js +3 -0
- package/dist/sources/providers/website.js +18 -22
- package/dist/sources/resolve.js +3 -0
- package/dist/sources/types.js +3 -0
- package/dist/sources/website-ingest.js +7 -0
- package/dist/tasks/backends/cron.js +203 -0
- package/dist/tasks/backends/exec-utils.js +28 -0
- package/dist/tasks/backends/index.js +24 -0
- package/dist/tasks/backends/launchd-template.xml +19 -0
- package/dist/tasks/backends/launchd.js +187 -0
- package/dist/tasks/backends/schtasks-template.xml +29 -0
- package/dist/tasks/backends/schtasks.js +215 -0
- package/dist/tasks/parser.js +211 -0
- package/dist/tasks/resolveAkmBin.js +87 -0
- package/dist/tasks/runner.js +458 -0
- package/dist/tasks/schedule.js +227 -0
- package/dist/tasks/schema.js +15 -0
- package/dist/tasks/validator.js +62 -0
- package/dist/version.js +3 -0
- package/dist/wiki/index-template.md +12 -0
- package/dist/wiki/ingest-workflow-template.md +54 -0
- package/dist/wiki/log-template.md +8 -0
- package/dist/wiki/schema-template.md +61 -0
- package/dist/wiki/wiki-templates.js +15 -0
- package/dist/wiki/wiki.js +13 -61
- package/dist/workflows/authoring.js +8 -25
- package/dist/workflows/cli.js +3 -0
- package/dist/workflows/db.js +141 -2
- package/dist/workflows/document-cache.js +3 -10
- package/dist/workflows/parser.js +3 -0
- package/dist/workflows/renderer.js +11 -3
- package/dist/workflows/runs.js +91 -89
- package/dist/workflows/schema.js +3 -0
- package/dist/workflows/scope-key.js +79 -0
- package/dist/workflows/validator.js +4 -8
- package/dist/workflows/workflow-template.md +24 -0
- package/docs/README.md +10 -2
- package/docs/data-and-telemetry.md +225 -0
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.7.4.md +1 -1
- package/docs/migration/release-notes/0.7.5.md +20 -0
- package/docs/migration/release-notes/0.8.0.md +48 -0
- package/docs/migration/v0.7-to-v0.8.md +1307 -0
- package/package.json +29 -11
- package/dist/commands/install-audit.js +0 -381
- package/dist/commands/vault.js +0 -333
- package/dist/templates/wiki-templates.js +0 -100
|
@@ -1,190 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* The on-disk shape is:
|
|
5
|
-
*
|
|
6
|
-
* ```jsonc
|
|
7
|
-
* {
|
|
8
|
-
* "agent": {
|
|
9
|
-
* "default": "opencode",
|
|
10
|
-
* "timeoutMs": 60000,
|
|
11
|
-
* "profiles": {
|
|
12
|
-
* "opencode": { "bin": "opencode", "args": ["--non-interactive"], ... }
|
|
13
|
-
* }
|
|
14
|
-
* }
|
|
15
|
-
* }
|
|
16
|
-
* ```
|
|
17
|
-
*
|
|
18
|
-
* Unknown keys at any level under `agent` are warn-and-ignored — this is the
|
|
19
|
-
* v1 §9.2 contract. Missing `agent` block disables agent commands; callers
|
|
20
|
-
* should reach for {@link requireAgentConfig} to surface a stable
|
|
21
|
-
* `ConfigError` with a hint pointing at setup.
|
|
22
|
-
*
|
|
23
|
-
* No LLM SDK is imported here. The runtime path is shell-out only (see
|
|
24
|
-
* `./spawn.ts`).
|
|
25
|
-
*/
|
|
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/.
|
|
26
4
|
import { ConfigError } from "../../core/errors";
|
|
27
5
|
import { warn } from "../../core/warn";
|
|
28
6
|
import { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles";
|
|
29
|
-
/** Keys recognised at the top level of an `agent` config block. */
|
|
30
|
-
const KNOWN_AGENT_KEYS = new Set(["default", "timeoutMs", "profiles"]);
|
|
31
|
-
/** Keys recognised on a profile entry. */
|
|
32
|
-
const KNOWN_PROFILE_KEYS = new Set(["bin", "args", "stdio", "env", "envPassthrough", "timeoutMs", "parseOutput"]);
|
|
33
7
|
/**
|
|
34
|
-
* Default hard timeout for an agent CLI
|
|
35
|
-
*
|
|
8
|
+
* Default hard timeout for an agent CLI (60s — matches the value used in
|
|
9
|
+
* `docs/configuration.md`).
|
|
36
10
|
*/
|
|
37
11
|
export const DEFAULT_AGENT_TIMEOUT_MS = 60_000;
|
|
38
12
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* malformed roots we emit a warning).
|
|
43
|
-
*
|
|
44
|
-
* Unknown keys (top-level and per-profile) are warn-and-ignore. Type errors
|
|
45
|
-
* on individual fields are warn-and-ignore so a bad `timeoutMs` does not
|
|
46
|
-
* break the rest of the block.
|
|
47
|
-
*/
|
|
48
|
-
export function parseAgentConfig(value) {
|
|
49
|
-
if (value === undefined)
|
|
50
|
-
return undefined;
|
|
51
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
52
|
-
warn('[akm] Ignoring "agent" config: expected an object.');
|
|
53
|
-
return undefined;
|
|
54
|
-
}
|
|
55
|
-
const raw = value;
|
|
56
|
-
const out = {};
|
|
57
|
-
for (const key of Object.keys(raw)) {
|
|
58
|
-
if (!KNOWN_AGENT_KEYS.has(key)) {
|
|
59
|
-
warn(`[akm] Ignoring unknown agent config key: "${key}"`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if ("default" in raw) {
|
|
63
|
-
if (typeof raw.default === "string" && raw.default.trim()) {
|
|
64
|
-
out.default = raw.default.trim();
|
|
65
|
-
}
|
|
66
|
-
else if (raw.default !== undefined) {
|
|
67
|
-
warn("[akm] Ignoring agent.default: expected a non-empty string.");
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
if ("timeoutMs" in raw) {
|
|
71
|
-
if (typeof raw.timeoutMs === "number" &&
|
|
72
|
-
Number.isFinite(raw.timeoutMs) &&
|
|
73
|
-
Number.isInteger(raw.timeoutMs) &&
|
|
74
|
-
raw.timeoutMs > 0) {
|
|
75
|
-
out.timeoutMs = raw.timeoutMs;
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
warn("[akm] Ignoring agent.timeoutMs: expected a positive integer (milliseconds).");
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if ("profiles" in raw) {
|
|
82
|
-
const profiles = parseAgentProfilesMap(raw.profiles);
|
|
83
|
-
if (profiles)
|
|
84
|
-
out.profiles = profiles;
|
|
85
|
-
}
|
|
86
|
-
return out;
|
|
87
|
-
}
|
|
88
|
-
function parseAgentProfilesMap(value) {
|
|
89
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
90
|
-
warn("[akm] Ignoring agent.profiles: expected an object.");
|
|
91
|
-
return undefined;
|
|
92
|
-
}
|
|
93
|
-
const out = {};
|
|
94
|
-
for (const [name, raw] of Object.entries(value)) {
|
|
95
|
-
const parsed = parseAgentProfileConfig(name, raw);
|
|
96
|
-
if (parsed)
|
|
97
|
-
out[name] = parsed;
|
|
98
|
-
}
|
|
99
|
-
return Object.keys(out).length > 0 ? out : undefined;
|
|
100
|
-
}
|
|
101
|
-
function parseAgentProfileConfig(name, value) {
|
|
102
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
103
|
-
warn(`[akm] Ignoring agent.profiles."${name}": expected an object.`);
|
|
104
|
-
return undefined;
|
|
105
|
-
}
|
|
106
|
-
const raw = value;
|
|
107
|
-
const out = {};
|
|
108
|
-
for (const key of Object.keys(raw)) {
|
|
109
|
-
if (!KNOWN_PROFILE_KEYS.has(key)) {
|
|
110
|
-
warn(`[akm] Ignoring unknown agent.profiles."${name}" key: "${key}"`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (typeof raw.bin === "string" && raw.bin.trim()) {
|
|
114
|
-
out.bin = raw.bin.trim();
|
|
115
|
-
}
|
|
116
|
-
else if (raw.bin !== undefined) {
|
|
117
|
-
warn(`[akm] Ignoring agent.profiles."${name}".bin: expected a non-empty string.`);
|
|
118
|
-
}
|
|
119
|
-
if (Array.isArray(raw.args)) {
|
|
120
|
-
const args = raw.args.filter((a) => typeof a === "string");
|
|
121
|
-
if (args.length === raw.args.length) {
|
|
122
|
-
out.args = args;
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
warn(`[akm] Ignoring non-string entries in agent.profiles."${name}".args.`);
|
|
126
|
-
if (args.length > 0)
|
|
127
|
-
out.args = args;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else if (raw.args !== undefined) {
|
|
131
|
-
warn(`[akm] Ignoring agent.profiles."${name}".args: expected an array of strings.`);
|
|
132
|
-
}
|
|
133
|
-
if (raw.stdio === "captured" || raw.stdio === "interactive") {
|
|
134
|
-
out.stdio = raw.stdio;
|
|
135
|
-
}
|
|
136
|
-
else if (raw.stdio !== undefined) {
|
|
137
|
-
warn(`[akm] Ignoring agent.profiles."${name}".stdio: expected "captured" or "interactive".`);
|
|
138
|
-
}
|
|
139
|
-
if (typeof raw.env === "object" && raw.env !== null && !Array.isArray(raw.env)) {
|
|
140
|
-
const env = {};
|
|
141
|
-
for (const [k, v] of Object.entries(raw.env)) {
|
|
142
|
-
if (typeof v === "string")
|
|
143
|
-
env[k] = v;
|
|
144
|
-
}
|
|
145
|
-
if (Object.keys(env).length > 0)
|
|
146
|
-
out.env = env;
|
|
147
|
-
}
|
|
148
|
-
else if (raw.env !== undefined) {
|
|
149
|
-
warn(`[akm] Ignoring agent.profiles."${name}".env: expected a string-valued object.`);
|
|
150
|
-
}
|
|
151
|
-
if (Array.isArray(raw.envPassthrough)) {
|
|
152
|
-
const list = raw.envPassthrough.filter((s) => typeof s === "string" && s.length > 0);
|
|
153
|
-
if (list.length > 0)
|
|
154
|
-
out.envPassthrough = list;
|
|
155
|
-
}
|
|
156
|
-
else if (raw.envPassthrough !== undefined) {
|
|
157
|
-
warn(`[akm] Ignoring agent.profiles."${name}".envPassthrough: expected an array of strings.`);
|
|
158
|
-
}
|
|
159
|
-
if (typeof raw.timeoutMs === "number" &&
|
|
160
|
-
Number.isFinite(raw.timeoutMs) &&
|
|
161
|
-
Number.isInteger(raw.timeoutMs) &&
|
|
162
|
-
raw.timeoutMs > 0) {
|
|
163
|
-
out.timeoutMs = raw.timeoutMs;
|
|
164
|
-
}
|
|
165
|
-
else if (raw.timeoutMs !== undefined) {
|
|
166
|
-
warn(`[akm] Ignoring agent.profiles."${name}".timeoutMs: expected a positive integer.`);
|
|
167
|
-
}
|
|
168
|
-
if (raw.parseOutput === "text" || raw.parseOutput === "json") {
|
|
169
|
-
out.parseOutput = raw.parseOutput;
|
|
170
|
-
}
|
|
171
|
-
else if (raw.parseOutput !== undefined) {
|
|
172
|
-
warn(`[akm] Ignoring agent.profiles."${name}".parseOutput: expected "text" or "json".`);
|
|
173
|
-
}
|
|
174
|
-
return out;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Merge a user override (from `agent.profiles[<name>]`) on top of the
|
|
178
|
-
* built-in profile (if any) and return the resolved profile. If `name`
|
|
179
|
-
* matches no built-in and the user override has no `bin`, returns
|
|
180
|
-
* `undefined` — the profile is unusable.
|
|
181
|
-
*
|
|
182
|
-
* Used at the spawn site, never at config-load time. Keeping merge logic
|
|
183
|
-
* here means the parser stays a pure shape-checker.
|
|
13
|
+
* Resolve the effective `AgentProfile` for `name` by merging the optional
|
|
14
|
+
* user override (`profiles.agent[name]`) on top of the built-in profile (if
|
|
15
|
+
* any). Returns `undefined` when neither yields a usable profile.
|
|
184
16
|
*/
|
|
185
17
|
export function resolveAgentProfile(name, overrides) {
|
|
186
18
|
const builtin = getBuiltinAgentProfile(name);
|
|
187
|
-
|
|
19
|
+
const platform = overrides?.platform;
|
|
20
|
+
// For opencode-sdk profiles, allow synthesizing without a built-in.
|
|
21
|
+
const sdkMode = platform === "opencode-sdk";
|
|
22
|
+
if (!builtin && !overrides?.bin && !sdkMode)
|
|
188
23
|
return undefined;
|
|
189
24
|
const base = builtin ??
|
|
190
25
|
{
|
|
@@ -194,99 +29,156 @@ export function resolveAgentProfile(name, overrides) {
|
|
|
194
29
|
stdio: "captured",
|
|
195
30
|
envPassthrough: [],
|
|
196
31
|
parseOutput: "text",
|
|
32
|
+
...(sdkMode ? { sdkMode: true } : {}),
|
|
197
33
|
};
|
|
198
34
|
if (!overrides)
|
|
199
35
|
return base;
|
|
200
|
-
|
|
36
|
+
return {
|
|
201
37
|
name,
|
|
202
38
|
bin: overrides.bin ?? base.bin,
|
|
203
39
|
args: overrides.args ?? base.args,
|
|
204
|
-
stdio:
|
|
205
|
-
env:
|
|
206
|
-
envPassthrough:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
40
|
+
stdio: base.stdio,
|
|
41
|
+
env: base.env,
|
|
42
|
+
envPassthrough: base.envPassthrough,
|
|
43
|
+
timeoutMs: base.timeoutMs,
|
|
44
|
+
parseOutput: base.parseOutput,
|
|
45
|
+
...(sdkMode ? { sdkMode: true } : {}),
|
|
46
|
+
model: overrides.model ?? base.model,
|
|
47
|
+
endpoint: base.endpoint,
|
|
48
|
+
apiKey: base.apiKey,
|
|
49
|
+
commandBuilder: base.commandBuilder,
|
|
50
|
+
modelAliases: base.modelAliases,
|
|
211
51
|
};
|
|
212
|
-
return merged;
|
|
213
|
-
}
|
|
214
|
-
function mergePassthrough(base, extra) {
|
|
215
|
-
const seen = new Set();
|
|
216
|
-
const out = [];
|
|
217
|
-
for (const k of [...base, ...extra]) {
|
|
218
|
-
if (!seen.has(k)) {
|
|
219
|
-
seen.add(k);
|
|
220
|
-
out.push(k);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return out;
|
|
224
52
|
}
|
|
225
53
|
/**
|
|
226
54
|
* Resolve the runnable profile for `name`, or `undefined` if none is
|
|
227
|
-
* available (no built-in and no user override
|
|
55
|
+
* available (no built-in and no user override).
|
|
228
56
|
*/
|
|
229
|
-
export function resolveProfileFromConfig(name,
|
|
230
|
-
return resolveAgentProfile(name,
|
|
57
|
+
export function resolveProfileFromConfig(name, config) {
|
|
58
|
+
return resolveAgentProfile(name, config?.profiles?.agent?.[name]);
|
|
231
59
|
}
|
|
232
60
|
/**
|
|
233
|
-
* Return the names of every profile available in `
|
|
234
|
-
*
|
|
61
|
+
* Return the names of every agent profile available in `config` — built-ins
|
|
62
|
+
* plus any user-defined entries under `profiles.agent`. Sorted, deduplicated.
|
|
235
63
|
*/
|
|
236
|
-
export function listAgentProfileNames(
|
|
64
|
+
export function listAgentProfileNames(config) {
|
|
237
65
|
const seen = new Set(BUILTIN_AGENT_PROFILE_NAMES);
|
|
238
|
-
for (const name of Object.keys(
|
|
66
|
+
for (const name of Object.keys(config?.profiles?.agent ?? {}))
|
|
239
67
|
seen.add(name);
|
|
240
68
|
return [...seen].sort();
|
|
241
69
|
}
|
|
242
70
|
/**
|
|
243
|
-
* Resolve the default profile name. Order: explicit `
|
|
244
|
-
* `agent
|
|
71
|
+
* Resolve the default agent profile name. Order: explicit `requested` arg →
|
|
72
|
+
* `config.defaults.agent` → undefined.
|
|
245
73
|
*/
|
|
246
|
-
export function resolveDefaultProfileName(
|
|
74
|
+
export function resolveDefaultProfileName(config, requested) {
|
|
247
75
|
if (requested?.trim())
|
|
248
76
|
return requested.trim();
|
|
249
|
-
|
|
250
|
-
|
|
77
|
+
const def = config?.defaults?.agent;
|
|
78
|
+
if (typeof def === "string" && def.trim())
|
|
79
|
+
return def.trim();
|
|
251
80
|
return undefined;
|
|
252
81
|
}
|
|
253
82
|
/**
|
|
254
|
-
* Throw a
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
* Covers two cases per acceptance criteria:
|
|
258
|
-
*
|
|
259
|
-
* 1. The `agent` block is absent — agent commands are disabled.
|
|
260
|
-
* 2. The block exists but no usable profile (no `default`, no requested
|
|
261
|
-
* name, or the named profile cannot be resolved).
|
|
262
|
-
*
|
|
263
|
-
* Use as `const profile = requireAgentProfile(config.agent, requestedName)`.
|
|
83
|
+
* Throw a stable `ConfigError` when the caller needs an agent profile but
|
|
84
|
+
* none can be resolved.
|
|
264
85
|
*/
|
|
265
|
-
export function requireAgentProfile(
|
|
266
|
-
if (!
|
|
267
|
-
throw new ConfigError("agent commands are disabled: no
|
|
86
|
+
export function requireAgentProfile(config, requested) {
|
|
87
|
+
if (!config) {
|
|
88
|
+
throw new ConfigError("agent commands are disabled: no agent configuration in config.json.", "INVALID_CONFIG_FILE", "Run `akm setup` to detect and configure an agent CLI, or add an entry under `profiles.agent` and set `defaults.agent`.");
|
|
268
89
|
}
|
|
269
|
-
const name = resolveDefaultProfileName(
|
|
90
|
+
const name = resolveDefaultProfileName(config, requested);
|
|
270
91
|
if (!name) {
|
|
271
|
-
throw new ConfigError("agent commands require a profile: pass --profile or set `agent
|
|
92
|
+
throw new ConfigError("agent commands require a profile: pass --profile or set `defaults.agent` in config.json.", "INVALID_CONFIG_FILE", `Available profiles: ${listAgentProfileNames(config).join(", ")}.`);
|
|
272
93
|
}
|
|
273
|
-
const profile = resolveProfileFromConfig(name,
|
|
94
|
+
const profile = resolveProfileFromConfig(name, config);
|
|
274
95
|
if (!profile) {
|
|
275
|
-
throw new ConfigError(`agent profile "${name}" is not built-in and has no \`bin\` override.`, "INVALID_CONFIG_FILE", `Define agent.
|
|
96
|
+
throw new ConfigError(`agent profile "${name}" is not built-in and has no \`bin\` override.`, "INVALID_CONFIG_FILE", `Define profiles.agent."${name}".bin in config.json, or pick one of: ${listAgentProfileNames(config).join(", ")}.`);
|
|
276
97
|
}
|
|
277
98
|
return profile;
|
|
278
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolve the agent profile bound to a named improve process. Reads from
|
|
102
|
+
* `profiles.improve.default.processes.<processName>` for the profile binding,
|
|
103
|
+
* then falls back to `defaults.agent`.
|
|
104
|
+
*/
|
|
105
|
+
export function resolveProcessAgentProfile(processName, config) {
|
|
106
|
+
const processEntry = config?.profiles?.improve?.default?.processes;
|
|
107
|
+
const entry = processEntry?.[processName];
|
|
108
|
+
const profileName = entry?.profile;
|
|
109
|
+
const profile = requireAgentProfile(config, profileName);
|
|
110
|
+
let resolvedTimeoutMs;
|
|
111
|
+
if (entry?.timeoutMs === null) {
|
|
112
|
+
resolvedTimeoutMs = null;
|
|
113
|
+
}
|
|
114
|
+
else if (typeof entry?.timeoutMs === "number") {
|
|
115
|
+
resolvedTimeoutMs = entry.timeoutMs;
|
|
116
|
+
}
|
|
117
|
+
else if (profile.timeoutMs !== undefined) {
|
|
118
|
+
resolvedTimeoutMs = profile.timeoutMs;
|
|
119
|
+
}
|
|
120
|
+
return { profile, timeoutMs: resolvedTimeoutMs };
|
|
121
|
+
}
|
|
279
122
|
/**
|
|
280
123
|
* Convenience: list every fully-resolved profile (built-ins merged with
|
|
281
|
-
*
|
|
124
|
+
* user overrides). Used by setup detection to enumerate candidates.
|
|
282
125
|
*/
|
|
283
|
-
export function listResolvedAgentProfiles(
|
|
126
|
+
export function listResolvedAgentProfiles(config) {
|
|
284
127
|
const resolved = [];
|
|
285
128
|
const builtins = listBuiltinAgentProfiles();
|
|
286
|
-
for (const name of listAgentProfileNames(
|
|
287
|
-
const profile = resolveProfileFromConfig(name,
|
|
129
|
+
for (const name of listAgentProfileNames(config)) {
|
|
130
|
+
const profile = resolveProfileFromConfig(name, config) ?? builtins[name];
|
|
288
131
|
if (profile)
|
|
289
132
|
resolved.push(profile);
|
|
290
133
|
}
|
|
291
134
|
return resolved;
|
|
292
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Parse the v2 `profiles.agent` map (AgentProfileConfigV2 shape with required
|
|
138
|
+
* `platform` field). Returns a map of profile name → AgentProfileConfigV2.
|
|
139
|
+
*/
|
|
140
|
+
export function parseAgentProfilesMapV2(value) {
|
|
141
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
142
|
+
return undefined;
|
|
143
|
+
const out = {};
|
|
144
|
+
const VALID_PLATFORMS = ["opencode", "claude", "opencode-sdk"];
|
|
145
|
+
for (const [name, raw] of Object.entries(value)) {
|
|
146
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
147
|
+
warn(`[akm] Ignoring profiles.agent["${name}"]: expected an object.`);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const obj = raw;
|
|
151
|
+
if (!VALID_PLATFORMS.includes(obj.platform)) {
|
|
152
|
+
warn(`[akm] Ignoring profiles.agent["${name}"]: missing or invalid "platform" (must be one of: ${VALID_PLATFORMS.join(", ")}).`);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const profile = {
|
|
156
|
+
platform: obj.platform,
|
|
157
|
+
};
|
|
158
|
+
if (typeof obj.bin === "string" && obj.bin.trim())
|
|
159
|
+
profile.bin = obj.bin.trim();
|
|
160
|
+
if (Array.isArray(obj.args) && obj.args.every((a) => typeof a === "string")) {
|
|
161
|
+
profile.args = obj.args;
|
|
162
|
+
}
|
|
163
|
+
if (typeof obj.workspace === "string" && obj.workspace.trim())
|
|
164
|
+
profile.workspace = obj.workspace.trim();
|
|
165
|
+
if (typeof obj.model === "string" && obj.model.trim())
|
|
166
|
+
profile.model = obj.model.trim();
|
|
167
|
+
out[name] = profile;
|
|
168
|
+
}
|
|
169
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Stub kept for source-compat with callers that previously used the v1 agent
|
|
173
|
+
* config parser. After 0.8.0 there is no separate `agent` block to parse — the
|
|
174
|
+
* loaded `AkmConfig` already carries the agent data on `profiles.agent` and
|
|
175
|
+
* `defaults.agent`. This function is a no-op alias for those callers.
|
|
176
|
+
*
|
|
177
|
+
* @deprecated v0.8.0 — the unified `AkmConfig` IS the agent config. Use the
|
|
178
|
+
* profile/defaults accessors above instead.
|
|
179
|
+
*/
|
|
180
|
+
export function parseAgentConfig(_value) {
|
|
181
|
+
// No-op: there is no separate agent block in 0.8.0. Callers should pass
|
|
182
|
+
// their loaded `AkmConfig` directly to `requireAgentProfile` etc.
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
* Surface:
|
|
7
|
-
* • Types: AgentProfile, AgentConfig, AgentRunResult, AgentFailureReason.
|
|
8
|
-
* • Profiles: getBuiltinAgentProfile, listBuiltinAgentProfiles, BUILTIN_AGENT_PROFILE_NAMES.
|
|
9
|
-
* • Config: parseAgentConfig, resolveProfileFromConfig, requireAgentProfile, listResolvedAgentProfiles, listAgentProfileNames.
|
|
10
|
-
* • Spawn: runAgent.
|
|
11
|
-
* • Detection: detectAgentCliProfiles, pickDefaultAgentProfile, defaultWhich.
|
|
12
|
-
*/
|
|
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 { getCommandBuilder } from "./builders";
|
|
13
5
|
export { DEFAULT_AGENT_TIMEOUT_MS, listAgentProfileNames, listResolvedAgentProfiles, parseAgentConfig, requireAgentProfile, resolveAgentProfile, resolveDefaultProfileName, resolveProfileFromConfig, } from "./config";
|
|
14
6
|
export { defaultWhich, detectAgentCliProfiles, pickDefaultAgentProfile } from "./detect";
|
|
7
|
+
export { listBuiltinModelAliases, resolveModel } from "./model-aliases";
|
|
15
8
|
export { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles";
|
|
16
|
-
export { buildProposePrompt, buildReflectPrompt, parseAgentProposalPayload, stripJsonFences } from "./prompts";
|
|
9
|
+
export { buildProposePrompt, buildReflectPrompt, buildSchemaRepairPrompt, extractDraftConfidence, parseAgentProposalPayload, stripJsonFences, } from "./prompts";
|
|
10
|
+
export { runAgentSdk } from "./sdk-runner";
|
|
17
11
|
export { runAgent } from "./spawn";
|
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
* Built-in alias table. Alias keys are lowercase.
|
|
6
|
+
*
|
|
7
|
+
* Platform model string conventions:
|
|
8
|
+
* opencode — "<provider>/<model>" e.g. "opencode/claude-opus-4-7"
|
|
9
|
+
* claude — bare model name e.g. "claude-opus-4-7"
|
|
10
|
+
* (Claude Code also accepts its own built-in shorthands, but we
|
|
11
|
+
* always resolve to the full name for determinism)
|
|
12
|
+
*/
|
|
13
|
+
const BUILTIN_ALIASES = [
|
|
14
|
+
{
|
|
15
|
+
alias: "opus",
|
|
16
|
+
platforms: {
|
|
17
|
+
claude: "claude-opus-4-7",
|
|
18
|
+
opencode: "opencode/claude-opus-4-7",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
alias: "sonnet",
|
|
23
|
+
platforms: {
|
|
24
|
+
claude: "claude-sonnet-4-6",
|
|
25
|
+
opencode: "opencode/claude-sonnet-4-6",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
alias: "haiku",
|
|
30
|
+
platforms: {
|
|
31
|
+
claude: "claude-haiku-4-5-20251001",
|
|
32
|
+
opencode: "opencode/claude-haiku-4-5",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a model alias or exact model ID to the string the target platform
|
|
38
|
+
* CLI expects for its --model flag.
|
|
39
|
+
*
|
|
40
|
+
* @param model Raw alias ("opus") or exact model ID ("claude-opus-4-7").
|
|
41
|
+
* @param platform Builder platform name ("claude", "opencode", ...).
|
|
42
|
+
* @param custom Profile-level aliases from config.json — take priority over builtins.
|
|
43
|
+
* @returns Resolved model string, or `model` verbatim when no alias matches.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveModel(model, platform, custom) {
|
|
46
|
+
const key = model.toLowerCase();
|
|
47
|
+
if (custom?.[key])
|
|
48
|
+
return custom[key];
|
|
49
|
+
const entry = BUILTIN_ALIASES.find((a) => a.alias === key);
|
|
50
|
+
return entry?.platforms[platform] ?? model;
|
|
51
|
+
}
|
|
52
|
+
/** Return all built-in alias entries (for tests and documentation). */
|
|
53
|
+
export function listBuiltinModelAliases() {
|
|
54
|
+
return BUILTIN_ALIASES;
|
|
55
|
+
}
|
|
@@ -1,8 +1,13 @@
|
|
|
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/.
|
|
1
4
|
const COMMON_PASSTHROUGH = ["HOME", "PATH", "USER", "LANG", "LC_ALL", "TERM", "TMPDIR"];
|
|
2
5
|
/**
|
|
3
6
|
* Built-in profiles for the five agent CLIs the v1 spec calls out
|
|
4
7
|
* explicitly. The fields here are conservative defaults — every value is
|
|
5
8
|
* overridable from user config.
|
|
9
|
+
*
|
|
10
|
+
* For headless/automation use (propose, reflect, tasks), use the '-headless' variant.
|
|
6
11
|
*/
|
|
7
12
|
const BUILTINS = {
|
|
8
13
|
opencode: {
|
|
@@ -46,15 +51,75 @@ const BUILTINS = {
|
|
|
46
51
|
parseOutput: "text",
|
|
47
52
|
},
|
|
48
53
|
};
|
|
49
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Headless variants of the five base profiles for automation use (propose, reflect, tasks).
|
|
56
|
+
*
|
|
57
|
+
* These profiles use `stdio: "captured"` and `parseOutput: "json"` so the
|
|
58
|
+
* agent's response can be read from stdout. They share the same `bin` and
|
|
59
|
+
* `envPassthrough` as the corresponding base profile but are intentionally
|
|
60
|
+
* kept out of `BUILTIN_AGENT_PROFILE_NAMES` (and therefore out of CLI
|
|
61
|
+
* detection/enumeration) to avoid showing up as separate installable profiles.
|
|
62
|
+
*
|
|
63
|
+
* Users may reference them by name via `--profile opencode-headless` or by
|
|
64
|
+
* setting `agent.default: "opencode-headless"` in config.json.
|
|
65
|
+
*/
|
|
66
|
+
const HEADLESS_BUILTINS = {
|
|
67
|
+
"opencode-headless": {
|
|
68
|
+
name: "opencode-headless",
|
|
69
|
+
bin: "opencode",
|
|
70
|
+
args: ["run"],
|
|
71
|
+
stdio: "captured",
|
|
72
|
+
envPassthrough: [...COMMON_PASSTHROUGH, "OPENCODE_API_KEY", "OPENCODE_CONFIG"],
|
|
73
|
+
parseOutput: "json",
|
|
74
|
+
},
|
|
75
|
+
"claude-headless": {
|
|
76
|
+
name: "claude-headless",
|
|
77
|
+
bin: "claude",
|
|
78
|
+
args: [],
|
|
79
|
+
stdio: "captured",
|
|
80
|
+
envPassthrough: [...COMMON_PASSTHROUGH, "ANTHROPIC_API_KEY", "CLAUDE_CONFIG"],
|
|
81
|
+
parseOutput: "json",
|
|
82
|
+
},
|
|
83
|
+
"codex-headless": {
|
|
84
|
+
name: "codex-headless",
|
|
85
|
+
bin: "codex",
|
|
86
|
+
args: [],
|
|
87
|
+
stdio: "captured",
|
|
88
|
+
envPassthrough: [...COMMON_PASSTHROUGH, "OPENAI_API_KEY", "CODEX_CONFIG"],
|
|
89
|
+
parseOutput: "json",
|
|
90
|
+
},
|
|
91
|
+
"gemini-headless": {
|
|
92
|
+
name: "gemini-headless",
|
|
93
|
+
bin: "gemini",
|
|
94
|
+
args: [],
|
|
95
|
+
stdio: "captured",
|
|
96
|
+
envPassthrough: [...COMMON_PASSTHROUGH, "GEMINI_API_KEY", "GOOGLE_API_KEY"],
|
|
97
|
+
parseOutput: "json",
|
|
98
|
+
},
|
|
99
|
+
"aider-headless": {
|
|
100
|
+
name: "aider-headless",
|
|
101
|
+
bin: "aider",
|
|
102
|
+
args: ["--no-auto-commits"],
|
|
103
|
+
stdio: "captured",
|
|
104
|
+
envPassthrough: [...COMMON_PASSTHROUGH, "OPENAI_API_KEY", "ANTHROPIC_API_KEY"],
|
|
105
|
+
parseOutput: "json",
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Names of the five primary built-in profiles. Stable, sorted. Does NOT
|
|
110
|
+
* include the `-headless` variants (those are resolvable by name but are
|
|
111
|
+
* excluded from detection/enumeration flows).
|
|
112
|
+
*/
|
|
50
113
|
export const BUILTIN_AGENT_PROFILE_NAMES = Object.freeze(Object.keys(BUILTINS).sort());
|
|
51
|
-
/** Returns the built-in profile by name, or `undefined` if not
|
|
114
|
+
/** Returns the built-in profile by name (including headless variants), or `undefined` if not found. */
|
|
52
115
|
export function getBuiltinAgentProfile(name) {
|
|
53
|
-
return BUILTINS[name];
|
|
116
|
+
return BUILTINS[name] ?? HEADLESS_BUILTINS[name];
|
|
54
117
|
}
|
|
55
118
|
/**
|
|
56
|
-
* Return a deep copy of every built-in profile keyed by name.
|
|
57
|
-
*
|
|
119
|
+
* Return a deep copy of every primary built-in profile keyed by name.
|
|
120
|
+
* Headless variants are NOT included — use `getBuiltinAgentProfile(name)`
|
|
121
|
+
* to look them up by name. Callers should not assume reference equality with
|
|
122
|
+
* subsequent calls.
|
|
58
123
|
*/
|
|
59
124
|
export function listBuiltinAgentProfiles() {
|
|
60
125
|
const out = {};
|