akm-cli 0.9.0-rc.1 → 0.9.0-rc.3
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 +249 -9
- package/SECURITY.md +23 -24
- package/dist/assets/help/help-improve.md +10 -10
- package/dist/assets/hints/cli-hints-full.md +44 -10
- package/dist/assets/hints/cli-hints-short.md +6 -2
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +1 -0
- package/dist/assets/{profiles → improve-strategies}/frequent.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +3 -3
- package/dist/assets/{profiles → improve-strategies}/quick.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/recombine-only.json +2 -0
- package/dist/assets/{profiles → improve-strategies}/reflect-distill.json +4 -4
- package/dist/assets/{profiles → improve-strategies}/synthesize.json +2 -0
- package/dist/assets/stash-skeleton/README.md +28 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +12 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +11 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +7 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +7 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +98 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +63 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +127 -0
- package/dist/assets/tasks/core/backup.yml +3 -2
- package/dist/assets/tasks/core/extract.yml +1 -0
- package/dist/assets/tasks/core/improve.yml +1 -0
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +1 -0
- package/dist/assets/tasks/graph-refresh-weekly.yml +4 -4
- package/dist/assets/templates/html/health.html +5 -1
- package/dist/cli/config-migrate.js +547 -126
- package/dist/cli/config-validate.js +10 -8
- package/dist/cli.js +50 -14
- package/dist/commands/agent/agent-dispatch.js +17 -16
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +5 -15
- package/dist/commands/backup-cli.js +56 -0
- package/dist/commands/config-cli.js +48 -155
- package/dist/commands/env/secret.js +8 -5
- package/dist/commands/feedback-cli.js +24 -7
- package/dist/commands/health/checks.js +200 -74
- package/dist/commands/health/html-report.js +4 -0
- package/dist/commands/health/improve-metrics.js +30 -32
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +4 -0
- package/dist/commands/health/metrics.js +2 -1
- package/dist/commands/health/surfaces.js +7 -5
- package/dist/commands/health.js +1 -1
- package/dist/commands/improve/anti-collapse.js +3 -3
- package/dist/commands/improve/collapse-detector.js +5 -5
- package/dist/commands/improve/consolidate/chunking.js +2 -2
- package/dist/commands/improve/consolidate.js +148 -88
- package/dist/commands/improve/distill/promote-memory.js +13 -18
- package/dist/commands/improve/distill/quality-gate.js +6 -8
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +32 -26
- package/dist/commands/improve/distill.js +68 -41
- package/dist/commands/improve/eligibility.js +31 -20
- package/dist/commands/improve/extract-cli.js +47 -19
- package/dist/commands/improve/extract-prompt.js +2 -2
- package/dist/commands/improve/extract.js +153 -73
- package/dist/commands/improve/improve-auto-accept.js +14 -28
- package/dist/commands/improve/improve-cli.js +41 -17
- package/dist/commands/improve/improve-result-file.js +30 -24
- package/dist/commands/improve/improve-strategies.js +138 -0
- package/dist/commands/improve/improve.js +109 -38
- package/dist/commands/improve/locks.js +66 -45
- package/dist/commands/improve/loop-stages.js +86 -39
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +12 -4
- package/dist/commands/improve/preparation.js +122 -90
- package/dist/commands/improve/procedural.js +13 -8
- package/dist/commands/improve/recombine.js +33 -8
- package/dist/commands/improve/reflect.js +143 -228
- package/dist/commands/improve/salience.js +5 -1
- package/dist/commands/improve/shared.js +11 -5
- package/dist/commands/improve/source-identity.js +43 -0
- package/dist/commands/lint/base-linter.js +152 -42
- package/dist/commands/migrate-cli.js +36 -0
- package/dist/commands/mv-cli.js +1198 -0
- package/dist/commands/proposal/drain.js +16 -4
- package/dist/commands/proposal/proposal-cli.js +21 -10
- package/dist/commands/proposal/proposal.js +16 -55
- package/dist/commands/proposal/propose.js +64 -69
- package/dist/commands/proposal/repository.js +664 -58
- package/dist/commands/read/curate.js +4 -2
- package/dist/commands/read/knowledge.js +440 -5
- package/dist/commands/read/remember-cli.js +39 -2
- package/dist/commands/read/search-cli.js +6 -1
- package/dist/commands/read/search.js +6 -2
- package/dist/commands/read/show.js +8 -7
- package/dist/commands/registry-cli.js +29 -14
- package/dist/commands/remember.js +2 -0
- package/dist/commands/sources/init.js +13 -14
- package/dist/commands/sources/schema-repair.js +2 -4
- package/dist/commands/sources/self-update.js +156 -112
- package/dist/commands/sources/source-add.js +62 -73
- package/dist/commands/sources/source-manage.js +50 -46
- package/dist/commands/sources/sources-cli.js +7 -2
- package/dist/commands/sources/stash-cli.js +41 -4
- package/dist/commands/tasks/default-tasks.js +12 -12
- package/dist/commands/tasks/tasks-cli.js +7 -3
- package/dist/commands/tasks/tasks.js +113 -18
- package/dist/commands/wiki-cli.js +9 -10
- package/dist/core/asset/frontmatter.js +12 -2
- package/dist/core/common.js +41 -6
- package/dist/core/config/config-io.js +30 -19
- package/dist/core/config/config-schema.js +373 -69
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +98 -27
- package/dist/core/config/config.js +135 -268
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +32 -0
- package/dist/core/errors.js +2 -2
- package/dist/core/extra-params.js +61 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/improve-result.js +178 -0
- package/dist/core/maintenance-barrier.js +119 -0
- package/dist/core/migration-backup.js +1061 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/paths.js +3 -0
- package/dist/core/redaction.js +358 -0
- package/dist/core/state/migrations.js +15 -3
- package/dist/core/state-db.js +60 -2
- package/dist/core/write-source.js +86 -18
- package/dist/indexer/db/db.js +212 -41
- package/dist/indexer/graph/graph-extraction.js +28 -16
- package/dist/indexer/index-writer-lock.js +59 -51
- package/dist/indexer/index-written-assets.js +75 -49
- package/dist/indexer/indexer.js +52 -3
- package/dist/indexer/passes/memory-inference.js +10 -6
- package/dist/indexer/passes/metadata.js +250 -0
- package/dist/indexer/search/db-search.js +111 -44
- package/dist/indexer/search/fts-query.js +41 -0
- package/dist/indexer/search/ranking-contributors.js +48 -0
- package/dist/indexer/search/ranking.js +36 -23
- package/dist/indexer/search/search-fields.js +11 -1
- package/dist/indexer/search/search-source.js +2 -2
- package/dist/indexer/usage/usage-events.js +8 -2
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -52
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +209 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +7 -2
- package/dist/integrations/agent/profiles.js +6 -99
- package/dist/integrations/agent/runner-dispatch.js +76 -13
- package/dist/integrations/agent/runner.js +76 -207
- package/dist/integrations/agent/spawn.js +4 -6
- package/dist/integrations/harnesses/aider/agent-builder.js +2 -3
- package/dist/integrations/harnesses/aider/index.js +0 -1
- package/dist/integrations/harnesses/amazonq/agent-builder.js +2 -3
- package/dist/integrations/harnesses/amazonq/index.js +0 -1
- package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +0 -2
- package/dist/integrations/harnesses/codex/agent-builder.js +2 -3
- package/dist/integrations/harnesses/codex/index.js +0 -1
- package/dist/integrations/harnesses/copilot/agent-builder.js +2 -3
- package/dist/integrations/harnesses/copilot/index.js +0 -1
- package/dist/integrations/harnesses/gemini/agent-builder.js +2 -3
- package/dist/integrations/harnesses/gemini/index.js +0 -1
- package/dist/integrations/harnesses/index.js +1 -24
- package/dist/integrations/harnesses/opencode/agent-builder.js +2 -3
- package/dist/integrations/harnesses/opencode/index.js +0 -6
- package/dist/integrations/harnesses/opencode-sdk/harness.js +1 -6
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
- package/dist/integrations/harnesses/openhands/agent-builder.js +2 -3
- package/dist/integrations/harnesses/openhands/index.js +0 -1
- package/dist/integrations/harnesses/pi/agent-builder.js +2 -3
- package/dist/integrations/harnesses/pi/index.js +0 -1
- package/dist/integrations/harnesses/types.js +1 -32
- package/dist/integrations/lockfile.js +32 -21
- package/dist/llm/client.js +48 -14
- package/dist/llm/feature-gate.js +15 -47
- package/dist/llm/graph-extract.js +1 -1
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer-impl.js +1 -1
- package/dist/llm/usage-persist.js +4 -0
- package/dist/llm/usage-telemetry.js +35 -5
- package/dist/output/shapes/helpers.js +2 -1
- package/dist/output/shapes/passthrough.js +2 -0
- package/dist/output/text/helpers.js +3 -1
- package/dist/schemas/akm-config.json +11013 -8600
- package/dist/schemas/akm-task.json +87 -0
- package/dist/schemas/akm-workflow.json +57 -13
- package/dist/scripts/migrate-storage.js +8502 -543
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +8493 -515
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +99 -0
- package/dist/setup/setup.js +237 -133
- package/dist/setup/steps/connection.js +62 -33
- package/dist/setup/steps/platforms.js +4 -4
- package/dist/setup/steps/tasks.js +1 -1
- package/dist/setup/steps.js +3 -2
- package/dist/sources/providers/git-stash.js +58 -21
- package/dist/sources/providers/git.js +1 -1
- package/dist/storage/database.js +13 -1
- package/dist/storage/engines/sqlite-migrations.js +139 -3
- package/dist/storage/repositories/events-repository.js +24 -0
- package/dist/storage/repositories/improve-runs-repository.js +5 -5
- package/dist/storage/repositories/proposals-repository.js +14 -0
- package/dist/storage/repositories/task-history-repository.js +78 -0
- package/dist/storage/repositories/workflow-runs-repository.js +9 -8
- package/dist/tasks/embedded.js +2 -0
- package/dist/tasks/parser.js +138 -52
- package/dist/tasks/runner.js +71 -75
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/validator.js +11 -6
- package/dist/wiki/wiki.js +9 -8
- package/dist/workflows/authoring/workflow-program-template.yaml +3 -3
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/db.js +78 -15
- package/dist/workflows/exec/brief.js +18 -24
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +124 -65
- package/dist/workflows/exec/report.js +93 -33
- package/dist/workflows/exec/run-workflow.js +38 -25
- package/dist/workflows/exec/scheduler.js +12 -41
- package/dist/workflows/exec/step-work.js +91 -35
- package/dist/workflows/ir/compile.js +13 -26
- package/dist/workflows/ir/freeze.js +243 -0
- package/dist/workflows/ir/plan-hash.js +40 -5
- package/dist/workflows/ir/schema.js +542 -1
- package/dist/workflows/parser.js +7 -0
- package/dist/workflows/program/parser.js +132 -23
- package/dist/workflows/program/project.js +3 -4
- package/dist/workflows/program/schema.js +2 -2
- package/dist/workflows/resource-limits.js +20 -0
- package/dist/workflows/runtime/plan-classifier.js +187 -0
- package/dist/workflows/runtime/runs.js +54 -47
- package/dist/workflows/runtime/workflow-asset-loader.js +0 -22
- package/dist/workflows/validator.js +49 -2
- package/docs/data-and-telemetry.md +2 -2
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +5 -4
- package/docs/migration/release-notes/0.9.0.md +24 -7
- package/docs/migration/v0.8-to-v0.9.md +506 -0
- package/package.json +4 -2
- package/schemas/akm-config.json +16638 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +372 -0
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/llm/call-ai.js +0 -62
- package/dist/setup/legacy-config.js +0 -106
- package/docs/README.md +0 -104
- /package/dist/assets/{profiles → improve-strategies}/thorough.json +0 -0
|
@@ -8,27 +8,29 @@
|
|
|
8
8
|
* prints "All checks passed." or a list of structured errors (path + message).
|
|
9
9
|
* Exits non-zero on errors so it composes well in CI hooks.
|
|
10
10
|
*/
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import { validateConfigShape } from "../core/config/config-schema.js";
|
|
11
|
+
import { parseConfigText, readConfigText } from "../core/config/config-io.js";
|
|
12
|
+
import { CURRENT_CONFIG_VERSION, validateConfigShape } from "../core/config/config-schema.js";
|
|
14
13
|
import { ConfigError } from "../core/errors.js";
|
|
15
14
|
import { getConfigPath } from "../core/paths.js";
|
|
16
15
|
export async function runConfigValidate() {
|
|
17
16
|
const configPath = getConfigPath();
|
|
18
|
-
if (!fs.existsSync(configPath)) {
|
|
19
|
-
console.log(`No config file at ${configPath} — nothing to validate.`);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
17
|
let text;
|
|
23
18
|
try {
|
|
24
|
-
text =
|
|
19
|
+
text = readConfigText(configPath);
|
|
25
20
|
}
|
|
26
21
|
catch (err) {
|
|
27
22
|
const detail = err instanceof Error ? err.message : String(err);
|
|
28
23
|
throw new ConfigError(`Could not read config at ${configPath}: ${detail}`, "INVALID_CONFIG_FILE");
|
|
29
24
|
}
|
|
25
|
+
if (text === undefined) {
|
|
26
|
+
console.log(`No config file at ${configPath} — nothing to validate.`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
30
29
|
// parseConfigText throws ConfigError on malformed JSON (#458). Surface as-is.
|
|
31
30
|
const raw = parseConfigText(text, configPath);
|
|
31
|
+
if (raw.configVersion !== CURRENT_CONFIG_VERSION) {
|
|
32
|
+
throw new ConfigError(`Unsupported configVersion at ${configPath}: expected "${CURRENT_CONFIG_VERSION}".`, "UNSUPPORTED_CONFIG_VERSION", "Recreate engines and improve.strategies manually; AKM 0.9 never translates profile-based configuration.");
|
|
33
|
+
}
|
|
32
34
|
const result = validateConfigShape(raw);
|
|
33
35
|
if (result.ok) {
|
|
34
36
|
console.log(`All checks passed. (${configPath})`);
|
package/dist/cli.js
CHANGED
|
@@ -63,6 +63,7 @@ import { defineCommand, runMain } from "citty";
|
|
|
63
63
|
import { findCittyTopLevelCommand } from "./cli/parse-args.js";
|
|
64
64
|
import { EXIT_CODES, emitJsonError, output, parseAllFlagValues, runWithJsonErrors } from "./cli/shared.js";
|
|
65
65
|
import { agentCommand, lintCommand, proposeCommand } from "./commands/agent/contribute-cli.js";
|
|
66
|
+
import { backupCommand } from "./commands/backup-cli.js";
|
|
66
67
|
import { generateBashCompletions, installBashCompletions } from "./commands/completions.js";
|
|
67
68
|
import { configCommand } from "./commands/config-cli.js";
|
|
68
69
|
import { envCommand } from "./commands/env/env-cli.js";
|
|
@@ -74,6 +75,8 @@ import { renderRunsDetailMd, renderWindowCompareMd } from "./commands/health/md-
|
|
|
74
75
|
import { parseWindowSpec } from "./commands/health/windows.js";
|
|
75
76
|
import { extractCommand } from "./commands/improve/extract-cli.js";
|
|
76
77
|
import { improveCommand } from "./commands/improve/improve-cli.js";
|
|
78
|
+
import { migrateCommand } from "./commands/migrate-cli.js";
|
|
79
|
+
import { mvCommand } from "./commands/mv-cli.js";
|
|
77
80
|
import { hintsCommand, lessonsCommand, logCommand } from "./commands/observability-cli.js";
|
|
78
81
|
import { proposalCommand } from "./commands/proposal/proposal-cli.js";
|
|
79
82
|
import { rememberCommand } from "./commands/read/remember-cli.js";
|
|
@@ -88,11 +91,12 @@ import { tasksCommand } from "./commands/tasks/tasks-cli.js";
|
|
|
88
91
|
import { wikiCommand } from "./commands/wiki-cli.js";
|
|
89
92
|
import { workflowCommand } from "./commands/workflow-cli.js";
|
|
90
93
|
import { bestEffort } from "./core/best-effort.js";
|
|
91
|
-
import { loadConfig } from "./core/config/config.js";
|
|
94
|
+
import { DEFAULT_CONFIG, loadConfig } from "./core/config/config.js";
|
|
92
95
|
import { UsageError } from "./core/errors.js";
|
|
93
96
|
import { getCacheDir, getConfigPath, getDbPath } from "./core/paths.js";
|
|
94
97
|
import { plainize } from "./core/tty.js";
|
|
95
98
|
import { info, isQuiet, setQuiet, setVerbose, warn } from "./core/warn.js";
|
|
99
|
+
import { disposeDispatchResources } from "./integrations/agent/runner-dispatch.js";
|
|
96
100
|
import { getHyphenatedBoolean, getOutputMode, initOutputMode, parseFlagValue } from "./output/context.js";
|
|
97
101
|
import { deliverRendered, renderHtml, resolveTemplatePath } from "./output/html-render.js";
|
|
98
102
|
import { pkgVersion } from "./version.js";
|
|
@@ -195,10 +199,15 @@ const setupCommand = defineCommand({
|
|
|
195
199
|
type: "string",
|
|
196
200
|
description: "Stash directory path (overrides stashDir in config or --config JSON)",
|
|
197
201
|
},
|
|
202
|
+
"no-init": {
|
|
203
|
+
type: "boolean",
|
|
204
|
+
default: false,
|
|
205
|
+
description: "Write configuration without scaffolding the stash directory",
|
|
206
|
+
},
|
|
198
207
|
probe: {
|
|
199
208
|
type: "boolean",
|
|
200
209
|
default: false,
|
|
201
|
-
description: "Probe LLM/embedding endpoints
|
|
210
|
+
description: "Probe LLM/embedding endpoints before writing config to verify connectivity",
|
|
202
211
|
},
|
|
203
212
|
"detect-only": {
|
|
204
213
|
type: "boolean",
|
|
@@ -213,7 +222,9 @@ const setupCommand = defineCommand({
|
|
|
213
222
|
},
|
|
214
223
|
async run({ args }) {
|
|
215
224
|
await runWithJsonErrors(async () => {
|
|
216
|
-
|
|
225
|
+
// citty treats a leading `no-` as boolean negation on some parse paths,
|
|
226
|
+
// so retain the raw argv spelling as the authoritative compatibility form.
|
|
227
|
+
const noInit = getHyphenatedBoolean(args, "no-init") || process.argv.includes("--no-init");
|
|
217
228
|
const detectOnly = args["detect-only"];
|
|
218
229
|
const resetRecommended = args["reset-recommended"];
|
|
219
230
|
if (detectOnly) {
|
|
@@ -505,7 +516,10 @@ export const main = defineCommand({
|
|
|
505
516
|
import: importKnowledgeCommand,
|
|
506
517
|
sync: syncCommand,
|
|
507
518
|
clone: cloneCommand,
|
|
519
|
+
mv: mvCommand,
|
|
508
520
|
registry: registryCommand,
|
|
521
|
+
migrate: migrateCommand,
|
|
522
|
+
backup: backupCommand,
|
|
509
523
|
config: configCommand,
|
|
510
524
|
feedback: feedbackCommand,
|
|
511
525
|
history: historyCommand,
|
|
@@ -527,6 +541,20 @@ export const main = defineCommand({
|
|
|
527
541
|
},
|
|
528
542
|
});
|
|
529
543
|
const MAIN_TOP_LEVEL_ARGS = main.args;
|
|
544
|
+
/** Recovery/setup surfaces must remain reachable when config.json is invalid. */
|
|
545
|
+
export function shouldBypassConfigStartup(argv) {
|
|
546
|
+
const args = argv.slice(2);
|
|
547
|
+
if (args.includes("--help") || args.includes("-h") || args.includes("--version") || args.includes("-v"))
|
|
548
|
+
return true;
|
|
549
|
+
const command = findCittyTopLevelCommand([...args], MAIN_TOP_LEVEL_ARGS);
|
|
550
|
+
if (command === "setup" || command === "backup" || command === "migrate")
|
|
551
|
+
return true;
|
|
552
|
+
if (command !== "config")
|
|
553
|
+
return false;
|
|
554
|
+
const configIndex = args.indexOf("config");
|
|
555
|
+
const subcommand = args.slice(configIndex + 1).find((arg) => !arg.startsWith("-"));
|
|
556
|
+
return subcommand === "path" || subcommand === "validate" || subcommand === "migrate";
|
|
557
|
+
}
|
|
530
558
|
// ── Exit codes ──────────────────────────────────────────────────────────────
|
|
531
559
|
// Canonical table lives in `src/cli/shared.ts` (EXIT_CODES). These aliases keep
|
|
532
560
|
// the local call sites terse. EXIT_HEALTH_WARN (4) is the `akm health` "warn"
|
|
@@ -556,7 +584,8 @@ if (import.meta.main || process.env.AKM_NODE_ENTRY === "1") {
|
|
|
556
584
|
// rather than letting the raw exception escape with a stack trace.
|
|
557
585
|
try {
|
|
558
586
|
applyEarlyStderrFlags(process.argv);
|
|
559
|
-
|
|
587
|
+
const bypassConfig = shouldBypassConfigStartup(process.argv);
|
|
588
|
+
initOutputMode(process.argv, bypassConfig ? (DEFAULT_CONFIG.output ?? {}) : (loadConfig().output ?? {}));
|
|
560
589
|
}
|
|
561
590
|
catch (error) {
|
|
562
591
|
emitJsonError(error);
|
|
@@ -575,15 +604,17 @@ if (import.meta.main || process.env.AKM_NODE_ENTRY === "1") {
|
|
|
575
604
|
// 0.8.0 moved the index to $XDG_DATA_HOME/akm/index.db (getDataDir()).
|
|
576
605
|
// If the old file exists at $XDG_CACHE_HOME/akm/index.db, remove it so the
|
|
577
606
|
// user isn't confused by a phantom DB. Best-effort; never fatal.
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
fs.
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
607
|
+
if (!shouldBypassConfigStartup(process.argv)) {
|
|
608
|
+
bestEffort(() => {
|
|
609
|
+
const oldIndexPath = path.join(getCacheDir(), "index.db");
|
|
610
|
+
if (fs.existsSync(oldIndexPath)) {
|
|
611
|
+
fs.rmSync(oldIndexPath, { force: true });
|
|
612
|
+
fs.rmSync(`${oldIndexPath}-shm`, { force: true });
|
|
613
|
+
fs.rmSync(`${oldIndexPath}-wal`, { force: true });
|
|
614
|
+
warn(`Cleaned up stale 0.7.x index from ${oldIndexPath}. Canonical path is now ${getDbPath()}.`);
|
|
615
|
+
}
|
|
616
|
+
}, "stale 0.7.x index cleanup is non-fatal");
|
|
617
|
+
}
|
|
587
618
|
// First-time-user breadcrumb: when run with no subcommand AND no config
|
|
588
619
|
// exists yet AND stderr is a TTY, print a friendly pointer to `akm setup`
|
|
589
620
|
// above citty's auto-generated usage block. Triggers only when stdin/stderr
|
|
@@ -608,5 +639,10 @@ if (import.meta.main || process.env.AKM_NODE_ENTRY === "1") {
|
|
|
608
639
|
}
|
|
609
640
|
console.error(plainize("👋 First time with akm? Run `akm setup` to get started.\n Docs: https://github.com/itlackey/akm#readme\n"));
|
|
610
641
|
})();
|
|
611
|
-
|
|
642
|
+
try {
|
|
643
|
+
await runMain(main);
|
|
644
|
+
}
|
|
645
|
+
finally {
|
|
646
|
+
await disposeDispatchResources();
|
|
647
|
+
}
|
|
612
648
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
|
-
* `akm agent <
|
|
5
|
+
* `akm agent [--engine <name>] [--prompt <text>] [--command <ref>] [--workflow <ref>] [args...]`
|
|
6
6
|
*
|
|
7
|
-
* Dispatch an agent by named
|
|
7
|
+
* Dispatch an agent by named engine, optionally injecting a prompt from
|
|
8
8
|
* inline text, a stash command: asset, or a stash workflow: asset.
|
|
9
9
|
*
|
|
10
10
|
* When none of --prompt, --command, or --workflow are given, the agent is
|
|
@@ -16,9 +16,8 @@
|
|
|
16
16
|
import fs from "node:fs";
|
|
17
17
|
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
18
18
|
import { NotFoundError, UsageError } from "../../core/errors.js";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { runOpencodeSdk } from "../../integrations/harnesses/opencode-sdk/index.js";
|
|
19
|
+
import { resolveEngine } from "../../integrations/agent/engine-resolution.js";
|
|
20
|
+
import { executeRunner } from "../../integrations/agent/runner-dispatch.js";
|
|
22
21
|
/**
|
|
23
22
|
* Fill `{{0}}`, `{{1}}`, ... placeholders in `template` with the
|
|
24
23
|
* corresponding entries in `args`. Any placeholder index that exceeds the
|
|
@@ -59,12 +58,16 @@ async function resolveAssetBody(ref) {
|
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
60
|
export async function akmAgentDispatch(options) {
|
|
62
|
-
if (!options.
|
|
63
|
-
throw new UsageError("agent
|
|
61
|
+
if (!options.agentConfig)
|
|
62
|
+
throw new UsageError("agent requires a valid config with an agent engine.", "MISSING_REQUIRED_ARGUMENT");
|
|
63
|
+
const engineName = options.engine ?? options.agentConfig.defaults?.engine;
|
|
64
|
+
if (!engineName)
|
|
65
|
+
throw new UsageError("agent requires --engine or defaults.engine.", "MISSING_REQUIRED_ARGUMENT");
|
|
66
|
+
const runner = resolveEngine(engineName, options.agentConfig);
|
|
67
|
+
if (runner.kind === "llm") {
|
|
68
|
+
throw new UsageError(`Engine "${engineName}" is an LLM engine; akm agent requires an agent engine.`, "INVALID_FLAG_VALUE");
|
|
64
69
|
}
|
|
65
|
-
|
|
66
|
-
// agent config is absent or the profile is not found.
|
|
67
|
-
const profile = requireAgentProfile(options.agentConfig, options.profileName.trim());
|
|
70
|
+
const profile = runner.profile;
|
|
68
71
|
// Resolve the prompt text from whichever source was provided.
|
|
69
72
|
let prompt;
|
|
70
73
|
if (options.commandRef) {
|
|
@@ -79,7 +82,7 @@ export async function akmAgentDispatch(options) {
|
|
|
79
82
|
prompt = options.prompt;
|
|
80
83
|
}
|
|
81
84
|
// When prompt is undefined, the agent is launched interactively.
|
|
82
|
-
const stdio = prompt === undefined &&
|
|
85
|
+
const stdio = prompt === undefined && runner.kind !== "sdk" ? "interactive" : profile.stdio;
|
|
83
86
|
// Build the final dispatch request: merge the caller-supplied dispatch with
|
|
84
87
|
// the resolved prompt so the builder has all context in one place.
|
|
85
88
|
const dispatchRequest = options.dispatch
|
|
@@ -93,14 +96,12 @@ export async function akmAgentDispatch(options) {
|
|
|
93
96
|
...(options.cwd ? { cwd: options.cwd } : {}),
|
|
94
97
|
...(dispatchRequest !== undefined ? { dispatch: dispatchRequest } : {}),
|
|
95
98
|
};
|
|
96
|
-
const result =
|
|
97
|
-
? await runOpencodeSdk(profile, prompt ?? "", runOptions, options.llmConfig)
|
|
98
|
-
: await runAgent(profile, prompt, runOptions);
|
|
99
|
+
const result = await executeRunner(runner, prompt ?? "", runOptions);
|
|
99
100
|
return {
|
|
100
|
-
schemaVersion:
|
|
101
|
+
schemaVersion: 2,
|
|
101
102
|
ok: result.ok,
|
|
102
103
|
shape: "agent-result",
|
|
103
|
-
|
|
104
|
+
engine: engineName,
|
|
104
105
|
exitCode: result.exitCode,
|
|
105
106
|
stdout: result.stdout ?? "",
|
|
106
107
|
stderr: result.stderr ?? "",
|
|
@@ -1,30 +1,6 @@
|
|
|
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
|
-
import { loadConfig } from "../../core/config/config.js";
|
|
5
|
-
import { requireAgentProfile, } from "../../integrations/agent/index.js";
|
|
6
|
-
// ── Config helpers ───────────────────────────────────────────────────────────
|
|
7
|
-
/**
|
|
8
|
-
* Load the loaded AkmConfig from disk.
|
|
9
|
-
*
|
|
10
|
-
* After 0.8.0, the legacy `agent` top-level block was removed — the agent
|
|
11
|
-
* profile data now lives on the unified `AkmConfig` (via `profiles.agent` and
|
|
12
|
-
* `defaults.agent`). This helper remains for source-compat with callers that
|
|
13
|
-
* still expect an "AgentConfig"; it now returns the loaded `AkmConfig`.
|
|
14
|
-
*/
|
|
15
|
-
export function loadAgentConfigFromDisk() {
|
|
16
|
-
return loadConfig();
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Resolve the agent profile for a command's options.
|
|
20
|
-
* Prefers an injected `agentProfile` (test seam) over the on-disk config.
|
|
21
|
-
*/
|
|
22
|
-
export function resolveAgentProfile(options) {
|
|
23
|
-
if (options.agentProfile)
|
|
24
|
-
return options.agentProfile;
|
|
25
|
-
const agent = options.agentConfig ?? loadAgentConfigFromDisk();
|
|
26
|
-
return requireAgentProfile(agent, options.profile);
|
|
27
|
-
}
|
|
28
4
|
// ── Failure helpers ──────────────────────────────────────────────────────────
|
|
29
5
|
/**
|
|
30
6
|
* Base failure envelope shared by all agent command failures.
|
|
@@ -38,17 +38,13 @@ export const agentCommand = defineCommand({
|
|
|
38
38
|
description: "Dispatch an agent CLI (opencode, claude, …) with an optional agent asset that provides the system prompt, model, and tool policy. Use <agent-ref> to embody a stash agent, --model to override the model, and --prompt/--command/--workflow to provide the task.",
|
|
39
39
|
},
|
|
40
40
|
args: {
|
|
41
|
-
profile: {
|
|
42
|
-
type: "positional",
|
|
43
|
-
description: "Agent profile / platform to use (opencode, claude, …)",
|
|
44
|
-
required: false,
|
|
45
|
-
},
|
|
46
41
|
"agent-ref": {
|
|
47
42
|
type: "positional",
|
|
48
43
|
description: "Optional agent asset ref (e.g. agent:code-reviewer). Loads system prompt, model, and tool policy from the stash asset.",
|
|
49
44
|
required: false,
|
|
50
45
|
},
|
|
51
46
|
prompt: { type: "string", description: "Task prompt to pass to the agent" },
|
|
47
|
+
engine: { type: "string", description: "Agent engine to use (default: defaults.engine)" },
|
|
52
48
|
command: { type: "string", description: "Load prompt from a command: asset" },
|
|
53
49
|
workflow: { type: "string", description: "Load prompt from a workflow: asset" },
|
|
54
50
|
model: {
|
|
@@ -63,13 +59,8 @@ export const agentCommand = defineCommand({
|
|
|
63
59
|
},
|
|
64
60
|
async run({ args }) {
|
|
65
61
|
await runWithJsonErrors(async () => {
|
|
66
|
-
if (!args.profile) {
|
|
67
|
-
throw new UsageError("Usage: akm agent <profile> [<agent-ref>] [--prompt <text>] [--model <model>]", "MISSING_REQUIRED_ARGUMENT", "Provide the agent profile name. Available profiles are listed in profiles.agent.");
|
|
68
|
-
}
|
|
69
62
|
const timeoutMs = parsePositiveIntFlag(args["timeout-ms"], "--timeout-ms");
|
|
70
63
|
const config = loadConfig();
|
|
71
|
-
const { getDefaultLlmConfig } = await import("../../core/config/config.js");
|
|
72
|
-
// After 0.8.0 the agent block IS the loaded AkmConfig.
|
|
73
64
|
const agentConfig = config;
|
|
74
65
|
// Resolve agent asset ref → extract system prompt, model, and tool policy.
|
|
75
66
|
const agentRef = getStringArg(args, "agent-ref");
|
|
@@ -95,12 +86,11 @@ export const agentCommand = defineCommand({
|
|
|
95
86
|
// platform-specific flags beyond the profile's base args).
|
|
96
87
|
const hasDispatchContent = !!(promptText ?? commandRef ?? workflowRef ?? systemPrompt ?? model ?? assetTools);
|
|
97
88
|
const result = await akmAgentDispatch({
|
|
98
|
-
|
|
89
|
+
engine: getStringArg(args, "engine"),
|
|
99
90
|
prompt: promptText,
|
|
100
91
|
commandRef,
|
|
101
92
|
workflowRef,
|
|
102
93
|
agentConfig,
|
|
103
|
-
llmConfig: getDefaultLlmConfig(config),
|
|
104
94
|
...(hasDispatchContent
|
|
105
95
|
? {
|
|
106
96
|
dispatch: {
|
|
@@ -125,7 +115,7 @@ export const agentCommand = defineCommand({
|
|
|
125
115
|
export const lintCommand = defineCommand({
|
|
126
116
|
meta: {
|
|
127
117
|
name: "lint",
|
|
128
|
-
description: "Scan stash .md files for structural issues (unquoted colons, missing updated field, orphaned stubs, placeholder stubs, missing name/type, stale paths). Use --fix to auto-fix Tier 1 issues. Exits 0 on success regardless of findings; use --fail-on-flagged for CI fail-on-finding behavior.",
|
|
118
|
+
description: "Scan stash .md files for structural issues (unquoted colons, missing updated field, orphaned stubs, placeholder stubs, missing name/type, stale paths, broken refs in body text and in refs/xrefs/supersededBy/contradictedBy frontmatter). Use --fix to auto-fix Tier 1 issues. Exits 0 on success regardless of findings; use --fail-on-flagged for CI fail-on-finding behavior.",
|
|
129
119
|
},
|
|
130
120
|
args: {
|
|
131
121
|
fix: {
|
|
@@ -182,7 +172,7 @@ export const proposeCommand = defineCommand({
|
|
|
182
172
|
},
|
|
183
173
|
task: { type: "string", description: "Task description for the agent (what should the asset do?)" },
|
|
184
174
|
file: { type: "string", description: "Read the task or prompt text from a UTF-8 file" },
|
|
185
|
-
|
|
175
|
+
engine: { type: "string", description: "Engine to use (defaults to defaults.engine)" },
|
|
186
176
|
"timeout-ms": { type: "string", description: "Override the agent CLI timeout in milliseconds" },
|
|
187
177
|
},
|
|
188
178
|
async run({ args }) {
|
|
@@ -207,7 +197,7 @@ export const proposeCommand = defineCommand({
|
|
|
207
197
|
type: String(args.type),
|
|
208
198
|
name: proposedName,
|
|
209
199
|
task: taskText,
|
|
210
|
-
|
|
200
|
+
engine: getStringArg(args, "engine"),
|
|
211
201
|
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
212
202
|
});
|
|
213
203
|
output("propose", result);
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
import { defineGroupCommand, defineJsonCommand, output } from "../cli/shared.js";
|
|
5
|
+
import { UsageError } from "../core/errors.js";
|
|
6
|
+
import { createMigrationBackup, MIGRATION_BACKUP_VERSION, restoreMigrationBackup } from "../core/migration-backup.js";
|
|
7
|
+
function requireVersion(value) {
|
|
8
|
+
if (value !== MIGRATION_BACKUP_VERSION) {
|
|
9
|
+
throw new UsageError(`Unsupported migration backup target ${JSON.stringify(value)}; expected ${MIGRATION_BACKUP_VERSION}.`, "INVALID_FLAG_VALUE");
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export const backupCommand = defineGroupCommand({
|
|
13
|
+
meta: { name: "backup", description: "Create or restore a verified migration recovery run" },
|
|
14
|
+
subCommands: {
|
|
15
|
+
create: defineJsonCommand({
|
|
16
|
+
meta: { name: "create", description: "Create a unique installation-scoped migration recovery run" },
|
|
17
|
+
args: {
|
|
18
|
+
for: { type: "string", required: true, description: "Migration target version (0.9.0)" },
|
|
19
|
+
},
|
|
20
|
+
run({ args }) {
|
|
21
|
+
requireVersion(args.for);
|
|
22
|
+
const result = createMigrationBackup();
|
|
23
|
+
output("backup", {
|
|
24
|
+
action: "create",
|
|
25
|
+
for: MIGRATION_BACKUP_VERSION,
|
|
26
|
+
path: result.path,
|
|
27
|
+
created: result.created,
|
|
28
|
+
manifest: result.manifest,
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
}),
|
|
32
|
+
restore: defineJsonCommand({
|
|
33
|
+
meta: { name: "restore", description: "Restore a recovery run after preserving a rescue snapshot" },
|
|
34
|
+
args: {
|
|
35
|
+
for: { type: "string", required: true, description: "Migration target version (0.9.0)" },
|
|
36
|
+
run: { type: "string", description: "Backup run ID (defaults to the newest applicable run)" },
|
|
37
|
+
confirm: { type: "boolean", default: false, description: "Confirm destructive restoration" },
|
|
38
|
+
},
|
|
39
|
+
run({ args }) {
|
|
40
|
+
requireVersion(args.for);
|
|
41
|
+
const result = restoreMigrationBackup(args.confirm, args.run);
|
|
42
|
+
output("backup", {
|
|
43
|
+
action: "restore",
|
|
44
|
+
for: MIGRATION_BACKUP_VERSION,
|
|
45
|
+
path: result.path,
|
|
46
|
+
restored: true,
|
|
47
|
+
rescuePath: result.rescuePath,
|
|
48
|
+
manifest: result.manifest,
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
defaultRun() {
|
|
54
|
+
throw new UsageError("Choose `backup create` or `backup restore`.", "MISSING_REQUIRED_ARGUMENT");
|
|
55
|
+
},
|
|
56
|
+
});
|