akm-cli 0.8.7 → 0.8.14
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 +428 -0
- package/dist/assets/help/help-proposals.md +1 -2
- package/dist/assets/hints/cli-hints-full.md +34 -19
- package/dist/assets/hints/cli-hints-short.md +1 -1
- package/dist/assets/profiles/catchup.json +13 -0
- package/dist/assets/profiles/consolidate.json +13 -0
- package/dist/assets/profiles/frequent.json +13 -0
- package/dist/assets/tasks/core/backup.yml +4 -0
- package/dist/assets/tasks/core/extract.yml +4 -0
- package/dist/assets/tasks/core/improve.yml +4 -0
- package/dist/assets/tasks/core/index-refresh.yml +4 -0
- package/dist/assets/tasks/core/sync.yml +4 -0
- package/dist/assets/tasks/core/update-stashes.yml +4 -0
- package/dist/assets/tasks/core/version-check.yml +4 -0
- package/dist/assets/templates/html/default.html +78 -0
- package/dist/assets/templates/html/health.html +560 -0
- package/dist/assets/templates/html/vendor/echarts.min.js +45 -0
- package/dist/cli/config-migrate.js +6 -6
- package/dist/cli/config-validate.js +4 -4
- package/dist/cli/confirm.js +3 -3
- package/dist/cli/parse-args.js +1 -1
- package/dist/cli/shared.js +72 -19
- package/dist/cli-node.mjs +26 -0
- package/dist/cli.js +206 -3866
- package/dist/commands/{agent-dispatch.js → agent/agent-dispatch.js} +6 -6
- package/dist/commands/{agent-support.js → agent/agent-support.js} +2 -2
- package/dist/commands/agent/contribute-cli.js +200 -0
- package/dist/commands/completions.js +1 -1
- package/dist/commands/config-cli.js +230 -3
- package/dist/commands/db-cli.js +2 -2
- package/dist/commands/env/env-cli.js +529 -0
- package/dist/commands/env/env.js +410 -0
- package/dist/commands/env/secret-cli.js +259 -0
- package/dist/commands/{secret.js → env/secret.js} +6 -47
- package/dist/commands/events.js +4 -4
- package/dist/commands/feedback-cli.js +18 -34
- package/dist/commands/graph/graph-cli.js +132 -0
- package/dist/commands/{graph.js → graph/graph.js} +22 -16
- package/dist/commands/health/checks.js +279 -0
- package/dist/commands/health/html-report.js +448 -0
- package/dist/commands/health.js +189 -266
- package/dist/commands/{consolidate.js → improve/consolidate.js} +48 -36
- package/dist/commands/{distill-promotion-policy.js → improve/distill-promotion-policy.js} +3 -3
- package/dist/commands/{distill.js → improve/distill.js} +39 -18
- package/dist/commands/{eval-cases.js → improve/eval-cases.js} +1 -1
- package/dist/commands/{extract-cli.js → improve/extract-cli.js} +4 -4
- package/dist/commands/{extract-prompt.js → improve/extract-prompt.js} +2 -2
- package/dist/commands/{extract.js → improve/extract.js} +221 -26
- package/dist/commands/{improve-auto-accept.js → improve/improve-auto-accept.js} +30 -4
- package/dist/commands/{improve-cli.js → improve/improve-cli.js} +44 -22
- package/dist/commands/{improve-profiles.js → improve/improve-profiles.js} +13 -7
- package/dist/commands/{improve-result-file.js → improve/improve-result-file.js} +1 -1
- package/dist/commands/{improve.js → improve/improve.js} +672 -292
- package/dist/{core → commands/improve/memory}/memory-belief.js +2 -2
- package/dist/{core → commands/improve/memory}/memory-contradiction-detect.js +5 -5
- package/dist/{core → commands/improve/memory}/memory-improve.js +4 -4
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/{reflect.js → improve/reflect.js} +58 -28
- package/dist/commands/improve/session-asset.js +248 -0
- package/dist/commands/lint/agent-linter.js +1 -1
- package/dist/commands/lint/base-linter.js +55 -37
- package/dist/commands/lint/command-linter.js +1 -1
- package/dist/commands/lint/default-linter.js +1 -1
- package/dist/commands/lint/env-key-rules.js +1 -1
- package/dist/commands/lint/index.js +19 -25
- package/dist/commands/lint/knowledge-linter.js +1 -1
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +8 -8
- package/dist/commands/lint/skill-linter.js +1 -1
- package/dist/commands/lint/task-linter.js +1 -1
- package/dist/commands/lint/workflow-linter.js +1 -1
- package/dist/commands/lint.js +1 -1
- package/dist/commands/observability-cli.js +244 -0
- package/dist/commands/proposal/drain-policies.js +3 -3
- package/dist/commands/proposal/drain.js +87 -15
- package/dist/commands/proposal/proposal-cli.js +490 -0
- package/dist/commands/{proposal.js → proposal/proposal.js} +17 -6
- package/dist/commands/{propose.js → proposal/propose.js} +11 -11
- package/dist/{core → commands/proposal/validators}/proposal-quality-validators.js +8 -3
- package/dist/{core → commands/proposal/validators}/proposal-validators.js +5 -5
- package/dist/{core → commands/proposal/validators}/proposals.js +374 -345
- package/dist/commands/{curate.js → read/curate.js} +7 -7
- package/dist/commands/{knowledge.js → read/knowledge.js} +22 -9
- package/dist/commands/{registry-search.js → read/registry-search.js} +5 -5
- package/dist/commands/{remember-cli.js → read/remember-cli.js} +15 -7
- package/dist/commands/read/search-cli.js +207 -0
- package/dist/commands/{search.js → read/search.js} +22 -27
- package/dist/commands/{show.js → read/show.js} +31 -45
- package/dist/commands/registry-cli.js +8 -8
- package/dist/commands/remember.js +14 -10
- package/dist/commands/sources/add-cli.js +293 -0
- package/dist/commands/{history.js → sources/history.js} +27 -25
- package/dist/commands/{info.js → sources/info.js} +6 -6
- package/dist/commands/{init.js → sources/init.js} +6 -6
- package/dist/commands/{installed-stashes.js → sources/installed-stashes.js} +12 -12
- package/dist/commands/{migration-help.js → sources/migration-help.js} +3 -2
- package/dist/commands/{schema-repair.js → sources/schema-repair.js} +8 -8
- package/dist/commands/{self-update.js → sources/self-update.js} +10 -9
- package/dist/commands/{source-add.js → sources/source-add.js} +10 -10
- package/dist/commands/{source-clone.js → sources/source-clone.js} +7 -7
- package/dist/commands/{source-manage.js → sources/source-manage.js} +4 -4
- package/dist/commands/sources/sources-cli.js +305 -0
- package/dist/commands/sources/stash-cli.js +219 -0
- package/dist/commands/{stash-skeleton.js → sources/stash-skeleton.js} +2 -1
- package/dist/commands/tasks/default-tasks.js +173 -0
- package/dist/commands/tasks/tasks-cli.js +210 -0
- package/dist/commands/{tasks.js → tasks/tasks.js} +14 -14
- package/dist/commands/wiki-cli.js +307 -0
- package/dist/commands/workflow-cli.js +329 -0
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/assert.js +40 -0
- package/dist/core/asset/asset-create.js +54 -0
- package/dist/core/{asset-ref.js → asset/asset-ref.js} +21 -4
- package/dist/core/{asset-registry.js → asset/asset-registry.js} +3 -3
- package/dist/core/{asset-spec.js → asset/asset-spec.js} +17 -31
- package/dist/core/{markdown.js → asset/markdown.js} +1 -1
- package/dist/core/{stash-meta.js → asset/stash-meta.js} +1 -1
- package/dist/core/best-effort.js +64 -0
- package/dist/core/common.js +32 -18
- package/dist/core/{config-io.js → config/config-io.js} +29 -19
- package/dist/core/{config-migration.js → config/config-migration.js} +11 -9
- package/dist/core/{config-schema.js → config/config-schema.js} +50 -7
- package/dist/core/config/config-types.js +16 -0
- package/dist/core/{config-walker.js → config/config-walker.js} +2 -2
- package/dist/core/{config.js → config/config.js} +10 -8
- package/dist/core/env-secret-ref.js +90 -0
- package/dist/core/errors.js +13 -3
- package/dist/core/events.js +27 -4
- package/dist/core/file-lock.js +1 -1
- package/dist/core/improve-types.js +48 -0
- package/dist/core/lesson-lint.js +2 -2
- package/dist/core/logs-db.js +304 -0
- package/dist/core/paths.js +2 -2
- package/dist/core/ripgrep/install.js +2 -2
- package/dist/core/ripgrep/resolve.js +2 -2
- package/dist/core/state-db.js +195 -60
- package/dist/core/text-truncation.js +148 -0
- package/dist/core/time.js +1 -1
- package/dist/core/write-source.js +98 -85
- package/dist/indexer/{db-backup.js → db/db-backup.js} +9 -24
- package/dist/indexer/{db.js → db/db.js} +128 -118
- package/dist/indexer/{graph-db.js → db/graph-db.js} +9 -4
- package/dist/indexer/{llm-cache.js → db/llm-cache.js} +15 -12
- package/dist/indexer/ensure-index.js +4 -4
- package/dist/indexer/{graph-boost.js → graph/graph-boost.js} +1 -1
- package/dist/indexer/{graph-extraction.js → graph/graph-extraction.js} +55 -13
- package/dist/indexer/indexer.js +37 -30
- package/dist/indexer/init.js +54 -0
- package/dist/indexer/manifest.js +10 -10
- package/dist/indexer/{memory-inference.js → passes/memory-inference.js} +141 -33
- package/dist/indexer/{metadata-contributors.js → passes/metadata-contributors.js} +10 -8
- package/dist/indexer/{metadata.js → passes/metadata.js} +15 -19
- package/dist/indexer/{staleness-detect.js → passes/staleness-detect.js} +53 -12
- package/dist/indexer/{db-search.js → search/db-search.js} +28 -16
- package/dist/indexer/{ranking-contributors.js → search/ranking-contributors.js} +1 -1
- package/dist/indexer/{ranking.js → search/ranking.js} +2 -2
- package/dist/indexer/{search-hit-enrichers.js → search/search-hit-enrichers.js} +3 -3
- package/dist/indexer/{search-source.js → search/search-source.js} +8 -8
- package/dist/indexer/{semantic-status.js → search/semantic-status.js} +3 -3
- package/dist/indexer/usage/unmigrated-vaults-guard.js +94 -0
- package/dist/indexer/{usage-events.js → usage/usage-events.js} +32 -0
- package/dist/indexer/{file-context.js → walk/file-context.js} +10 -15
- package/dist/indexer/{matchers.js → walk/matchers.js} +13 -9
- package/dist/indexer/{path-resolver.js → walk/path-resolver.js} +6 -6
- package/dist/indexer/{project-context.js → walk/project-context.js} +1 -1
- package/dist/indexer/{walker.js → walk/walker.js} +4 -3
- package/dist/integrations/agent/builder-shared.js +39 -0
- package/dist/integrations/agent/builders.js +14 -81
- package/dist/integrations/agent/config.js +6 -4
- package/dist/integrations/agent/detect.js +1 -1
- package/dist/integrations/agent/index.js +23 -8
- package/dist/integrations/agent/prompts.js +2 -3
- package/dist/integrations/agent/runner.js +22 -3
- package/dist/integrations/agent/spawn.js +9 -10
- package/dist/integrations/harnesses/claude/agent-builder.js +48 -0
- package/dist/integrations/harnesses/claude/config-import.js +70 -0
- package/dist/integrations/harnesses/claude/index.js +64 -0
- package/dist/integrations/{session-logs/providers/claude-code.js → harnesses/claude/session-log.js} +32 -5
- package/dist/integrations/harnesses/index.js +144 -0
- package/dist/integrations/harnesses/opencode/agent-builder.js +43 -0
- package/dist/integrations/harnesses/opencode/config-import.js +82 -0
- package/dist/integrations/harnesses/opencode/index.js +59 -0
- package/dist/integrations/{session-logs/providers/opencode.js → harnesses/opencode/session-log.js} +1 -1
- package/dist/integrations/harnesses/opencode-sdk/index.js +49 -0
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +234 -0
- package/dist/integrations/harnesses/types.js +43 -0
- package/dist/integrations/lockfile.js +7 -16
- package/dist/integrations/session-logs/index.js +82 -9
- package/dist/llm/call-ai.js +4 -4
- package/dist/llm/client.js +146 -6
- package/dist/llm/embedder.js +6 -6
- package/dist/llm/embedders/local.js +9 -22
- package/dist/llm/embedders/remote.js +2 -2
- package/dist/llm/embedders/types.js +1 -1
- package/dist/llm/graph-extract.js +31 -12
- package/dist/llm/index-passes.js +1 -1
- package/dist/llm/memory-infer.js +12 -5
- package/dist/llm/metadata-enhance.js +2 -2
- package/dist/llm/usage-persist.js +77 -0
- package/dist/llm/usage-telemetry.js +103 -0
- package/dist/output/context.js +9 -46
- package/dist/output/html-render.js +73 -0
- package/dist/output/renderers.js +88 -58
- package/dist/output/shapes/curate.js +7 -3
- package/dist/output/shapes/distill.js +7 -3
- package/dist/output/shapes/env-list.js +18 -16
- package/dist/output/shapes/events.js +5 -4
- package/dist/output/shapes/helpers.js +19 -5
- package/dist/output/shapes/history.js +7 -3
- package/dist/output/shapes/passthrough.js +8 -11
- package/dist/output/shapes/{proposal-accept.js → proposal/accept.js} +7 -3
- package/dist/output/shapes/{proposal-diff.js → proposal/diff.js} +7 -3
- package/dist/output/shapes/{proposal-list.js → proposal/list.js} +7 -3
- package/dist/output/shapes/{proposal-producer.js → proposal/producer.js} +5 -4
- package/dist/output/shapes/{proposal-reject.js → proposal/reject.js} +7 -3
- package/dist/output/shapes/{proposal-show.js → proposal/show.js} +7 -3
- package/dist/output/shapes/registry-search.js +7 -3
- package/dist/output/shapes/registry.js +12 -0
- package/dist/output/shapes/search.js +7 -3
- package/dist/output/shapes/secret-list.js +18 -16
- package/dist/output/shapes/show.js +7 -3
- package/dist/output/shapes.js +55 -30
- package/dist/output/text/add.js +2 -3
- package/dist/output/text/clone.js +2 -3
- package/dist/output/text/config.js +2 -3
- package/dist/output/text/curate.js +4 -3
- package/dist/output/text/distill.js +2 -3
- package/dist/output/text/enable-disable.js +5 -4
- package/dist/output/text/env.js +13 -0
- package/dist/output/text/events.js +5 -4
- package/dist/output/text/feedback.js +4 -3
- package/dist/output/text/helpers.js +123 -40
- package/dist/output/text/history.js +2 -3
- package/dist/output/text/import.js +2 -3
- package/dist/output/text/index.js +2 -3
- package/dist/output/text/info.js +2 -3
- package/dist/output/text/init.js +2 -3
- package/dist/output/text/list.js +2 -3
- package/dist/output/text/proposal/producer.js +9 -0
- package/dist/output/text/proposal/proposal.js +13 -0
- package/dist/output/text/registry-commands.js +8 -7
- package/dist/output/text/registry.js +12 -0
- package/dist/output/text/remember.js +4 -3
- package/dist/output/text/remove.js +2 -3
- package/dist/output/text/save.js +2 -3
- package/dist/output/text/search.js +4 -3
- package/dist/output/text/show.js +4 -3
- package/dist/output/text/update.js +2 -3
- package/dist/output/text/upgrade.js +2 -3
- package/dist/output/text/wiki.js +12 -11
- package/dist/output/text/workflow.js +12 -10
- package/dist/output/text.js +66 -32
- package/dist/registry/build-index.js +11 -10
- package/dist/registry/factory.js +1 -1
- package/dist/registry/origin-resolve.js +1 -1
- package/dist/registry/providers/index.js +2 -2
- package/dist/registry/providers/skills-sh.js +91 -72
- package/dist/registry/providers/static-index.js +75 -52
- package/dist/registry/resolve.js +3 -3
- package/dist/runtime.js +242 -0
- package/dist/scripts/migrate-storage.js +1654 -683
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +254 -168
- package/dist/setup/detect.js +311 -9
- package/dist/setup/harness-config-import.js +6 -120
- package/dist/setup/setup.js +454 -43
- package/dist/sources/include.js +1 -1
- package/dist/sources/provider-factory.js +2 -2
- package/dist/sources/providers/filesystem.js +3 -3
- package/dist/sources/providers/git.js +9 -9
- package/dist/sources/providers/index.js +4 -4
- package/dist/sources/providers/npm.js +6 -6
- package/dist/sources/providers/provider-utils.js +13 -20
- package/dist/sources/providers/sync-from-ref.js +5 -5
- package/dist/sources/providers/tar-utils.js +2 -2
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +5 -5
- package/dist/sources/website-ingest.js +5 -5
- package/dist/storage/database.js +102 -0
- package/dist/storage/engines/sqlite-migrations.js +42 -0
- package/dist/storage/locations.js +25 -0
- package/dist/storage/repositories/index-db.js +43 -0
- package/dist/storage/repositories/workflow-runs-repository.js +141 -0
- package/dist/tasks/backends/cron.js +4 -4
- package/dist/tasks/backends/exec-utils.js +32 -0
- package/dist/tasks/backends/index.js +3 -3
- package/dist/tasks/backends/launchd.js +7 -14
- package/dist/tasks/backends/schtasks.js +7 -16
- package/dist/tasks/embedded.js +71 -0
- package/dist/tasks/parser.js +2 -2
- package/dist/tasks/resolveAkmBin.js +1 -1
- package/dist/tasks/runner.js +127 -31
- package/dist/tasks/schedule.js +1 -1
- package/dist/tasks/validator.js +7 -7
- package/dist/text-import-hook.mjs +51 -0
- package/dist/version.js +2 -1
- package/dist/wiki/wiki.js +7 -7
- package/dist/workflows/{authoring.js → authoring/authoring.js} +6 -6
- package/dist/workflows/{scope-key.js → authoring/scope-key.js} +1 -1
- package/dist/workflows/cli.js +1 -1
- package/dist/workflows/db.js +54 -32
- package/dist/workflows/parser.js +4 -4
- package/dist/workflows/renderer.js +5 -5
- package/dist/workflows/runtime/agent-identity.js +56 -0
- package/dist/workflows/runtime/checkin.js +57 -0
- package/dist/workflows/{runs.js → runtime/runs.js} +197 -101
- package/dist/workflows/validate-summary.js +82 -0
- package/docs/README.md +1 -1
- package/docs/data-and-telemetry.md +6 -6
- package/package.json +17 -8
- package/dist/commands/add-cli.js +0 -279
- package/dist/commands/env.js +0 -213
- package/dist/integrations/agent/sdk-runner.js +0 -126
- package/dist/output/shapes/vault-list.js +0 -19
- package/dist/output/text/proposal-producer.js +0 -8
- package/dist/output/text/proposal.js +0 -12
- package/dist/output/text/vault.js +0 -16
- /package/dist/core/{asset-serialize.js → asset/asset-serialize.js} +0 -0
- /package/dist/core/{frontmatter.js → asset/frontmatter.js} +0 -0
- /package/dist/core/{config-sources.js → config/config-sources.js} +0 -0
- /package/dist/indexer/{graph-dedup.js → graph/graph-dedup.js} +0 -0
- /package/dist/{core/config-types.js → indexer/passes/pass-context.js} +0 -0
- /package/dist/indexer/{search-fields.js → search/search-fields.js} +0 -0
- /package/dist/indexer/{index-context.js → walk/index-context.js} +0 -0
- /package/dist/workflows/{document-cache.js → runtime/document-cache.js} +0 -0
|
@@ -12,88 +12,21 @@
|
|
|
12
12
|
* Adding a new platform: implement `AgentCommandBuilder`, add to
|
|
13
13
|
* `BUILTIN_BUILDERS`. Nothing else changes.
|
|
14
14
|
*/
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
function assertNotFlag(value, field) {
|
|
26
|
-
if (value?.trimStart().startsWith("--")) {
|
|
27
|
-
throw new UsageError(`${field} must not start with "--": ${JSON.stringify(value.slice(0, 60))}`, "INVALID_FLAG_VALUE");
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
// ── Tool normalization ────────────────────────────────────────────────────────
|
|
31
|
-
/**
|
|
32
|
-
* Normalize a toolPolicy value to a comma-separated string suitable for a
|
|
33
|
-
* CLI flag. Structured policy objects are JSON-serialized.
|
|
34
|
-
*/
|
|
35
|
-
function normalizeTools(tools) {
|
|
36
|
-
if (typeof tools === "string")
|
|
37
|
-
return tools;
|
|
38
|
-
if (Array.isArray(tools))
|
|
39
|
-
return tools.join(",");
|
|
40
|
-
return JSON.stringify(tools);
|
|
41
|
-
}
|
|
15
|
+
import { claudeBuilder } from "../harnesses/claude/agent-builder.js";
|
|
16
|
+
import { opencodeBuilder } from "../harnesses/opencode/agent-builder.js";
|
|
17
|
+
// Types + shared validation helpers live in the leaf module `builder-shared.ts`
|
|
18
|
+
// so per-harness builders (harnesses/claude/agent-builder.ts) can depend on them
|
|
19
|
+
// without importing this file back — avoiding an init-order cycle through
|
|
20
|
+
// BUILTIN_BUILDERS (#563). Re-exported here so existing `agent/builders` import
|
|
21
|
+
// sites keep working.
|
|
22
|
+
import { assertNotFlag } from "./builder-shared.js";
|
|
23
|
+
import { resolveModel } from "./model-aliases.js";
|
|
24
|
+
export { assertNotFlag, normalizeTools } from "./builder-shared.js";
|
|
42
25
|
// ── Platform builders ─────────────────────────────────────────────────────────
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
* Tool policy is omitted — opencode manages tool access through its own agent
|
|
48
|
-
* config files, not via CLI flags.
|
|
49
|
-
*/
|
|
50
|
-
const opencodeBuilder = {
|
|
51
|
-
platform: "opencode",
|
|
52
|
-
build(profile, req) {
|
|
53
|
-
assertNotFlag(req.systemPrompt, "systemPrompt");
|
|
54
|
-
assertNotFlag(req.model, "model");
|
|
55
|
-
const args = [...profile.args]; // starts with ["run"]
|
|
56
|
-
if (req.systemPrompt) {
|
|
57
|
-
args.push("--system-prompt", req.systemPrompt);
|
|
58
|
-
}
|
|
59
|
-
if (req.model) {
|
|
60
|
-
const resolved = resolveModel(req.model, "opencode", profile.modelAliases);
|
|
61
|
-
args.push("--model", resolved);
|
|
62
|
-
}
|
|
63
|
-
args.push("--");
|
|
64
|
-
args.push(req.prompt);
|
|
65
|
-
return { argv: [profile.bin, ...args] };
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
/**
|
|
69
|
-
* Claude Code builder.
|
|
70
|
-
* Command shape: claude [--system-prompt "..."] [--model <m>] [--allowedTools <t>] --print "<prompt>"
|
|
71
|
-
*
|
|
72
|
-
* --print switches Claude Code to non-interactive captured output mode.
|
|
73
|
-
*/
|
|
74
|
-
const claudeBuilder = {
|
|
75
|
-
platform: "claude",
|
|
76
|
-
build(profile, req) {
|
|
77
|
-
assertNotFlag(req.systemPrompt, "systemPrompt");
|
|
78
|
-
assertNotFlag(req.model, "model");
|
|
79
|
-
const args = [...profile.args];
|
|
80
|
-
if (req.systemPrompt) {
|
|
81
|
-
args.push("--system-prompt", req.systemPrompt);
|
|
82
|
-
}
|
|
83
|
-
if (req.model) {
|
|
84
|
-
const resolved = resolveModel(req.model, "claude", profile.modelAliases);
|
|
85
|
-
args.push("--model", resolved);
|
|
86
|
-
}
|
|
87
|
-
if (req.tools) {
|
|
88
|
-
args.push("--allowedTools", normalizeTools(req.tools));
|
|
89
|
-
}
|
|
90
|
-
// --print = non-interactive, outputs to stdout — required for captured mode
|
|
91
|
-
args.push("--print");
|
|
92
|
-
args.push("--");
|
|
93
|
-
args.push(req.prompt);
|
|
94
|
-
return { argv: [profile.bin, ...args] };
|
|
95
|
-
},
|
|
96
|
-
};
|
|
26
|
+
// The OpenCode builder was migrated to its harness directory in #564
|
|
27
|
+
// (`harnesses/opencode/agent-builder.ts`) and the Claude Code builder in #563
|
|
28
|
+
// (`harnesses/claude/agent-builder.ts`). Both are imported back into
|
|
29
|
+
// BUILTIN_BUILDERS below so platform routing is unchanged.
|
|
97
30
|
/**
|
|
98
31
|
* Default builder — used for custom profiles and any platform without a
|
|
99
32
|
* dedicated builder. Passes systemPrompt and model via the same flags as
|
|
@@ -1,9 +1,10 @@
|
|
|
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 {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { VALID_HARNESS_IDS } from "../../core/config/config.js";
|
|
5
|
+
import { ConfigError } from "../../core/errors.js";
|
|
6
|
+
import { warn } from "../../core/warn.js";
|
|
7
|
+
import { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles.js";
|
|
7
8
|
/**
|
|
8
9
|
* Default hard timeout for an agent CLI (60s — matches the value used in
|
|
9
10
|
* `docs/configuration.md`).
|
|
@@ -141,7 +142,8 @@ export function parseAgentProfilesMapV2(value) {
|
|
|
141
142
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
142
143
|
return undefined;
|
|
143
144
|
const out = {};
|
|
144
|
-
|
|
145
|
+
// Derives from the canonical harness-id source of truth (#565).
|
|
146
|
+
const VALID_PLATFORMS = VALID_HARNESS_IDS;
|
|
145
147
|
for (const [name, raw] of Object.entries(value)) {
|
|
146
148
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
147
149
|
warn(`[akm] Ignoring profiles.agent["${name}"]: expected an object.`);
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import fs from "node:fs";
|
|
17
17
|
import path from "node:path";
|
|
18
|
-
import { listResolvedAgentProfiles } from "./config";
|
|
18
|
+
import { listResolvedAgentProfiles } from "./config.js";
|
|
19
19
|
/**
|
|
20
20
|
* Default PATH lookup. Walks `process.env.PATH` and returns the first
|
|
21
21
|
* existing executable file. Returns `undefined` when the bin is not on
|
|
@@ -1,11 +1,26 @@
|
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Internal entry point for the `agent` integration. CLI-only project — no
|
|
6
|
+
* public exports map. Other akm modules import from this barrel for the
|
|
7
|
+
* sake of grouping imports.
|
|
8
|
+
*
|
|
9
|
+
* Surface:
|
|
10
|
+
* • Types: AgentProfile, AgentConfig, AgentRunResult, AgentFailureReason.
|
|
11
|
+
* • Profiles: getBuiltinAgentProfile, listBuiltinAgentProfiles, BUILTIN_AGENT_PROFILE_NAMES.
|
|
12
|
+
* • Config: parseAgentConfig, resolveProfileFromConfig, requireAgentProfile, listResolvedAgentProfiles, listAgentProfileNames.
|
|
13
|
+
* • Spawn: runAgent. Builders: getCommandBuilder, AgentCommandBuilder, AgentDispatchRequest — platform-specific argv construction.
|
|
14
|
+
* • Detection: detectAgentCliProfiles, pickDefaultAgentProfile, defaultWhich.
|
|
15
|
+
*/
|
|
16
|
+
// The OpenCode SDK runner moved to its harness directory in #564
|
|
17
|
+
// (`harnesses/opencode-sdk/`). Re-exported here so existing `agent/index`
|
|
18
|
+
// import sites keep working.
|
|
19
|
+
export { runAgentSdk } from "../harnesses/opencode-sdk/index.js";
|
|
20
|
+
export { getCommandBuilder } from "./builders.js";
|
|
21
|
+
export { DEFAULT_AGENT_TIMEOUT_MS, listAgentProfileNames, listResolvedAgentProfiles, parseAgentConfig, requireAgentProfile, resolveAgentProfile, resolveDefaultProfileName, resolveProfileFromConfig, } from "./config.js";
|
|
22
|
+
export { defaultWhich, detectAgentCliProfiles, pickDefaultAgentProfile } from "./detect.js";
|
|
23
|
+
export { listBuiltinModelAliases, resolveModel } from "./model-aliases.js";
|
|
24
|
+
export { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles.js";
|
|
25
|
+
export { buildProposePrompt, buildReflectPrompt, buildSchemaRepairPrompt, extractDraftConfidence, parseAgentProposalPayload, stripJsonFences, } from "./prompts.js";
|
|
26
|
+
export { runAgent } from "./spawn.js";
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
* `frontmatter` is optional — the proposal queue parses it from `content`
|
|
26
26
|
* during validation. We carry it through if the agent supplies it.
|
|
27
27
|
*/
|
|
28
|
-
import { TYPE_DIRS } from "../../core/asset-spec";
|
|
29
|
-
import { parseEmbeddedJsonResponse, stripCodeFences, stripThinkBlocks } from "../../core/parse";
|
|
28
|
+
import { TYPE_DIRS } from "../../core/asset/asset-spec.js";
|
|
29
|
+
import { parseEmbeddedJsonResponse, stripCodeFences, stripThinkBlocks } from "../../core/parse.js";
|
|
30
30
|
/**
|
|
31
31
|
* Per-asset-type frontmatter / authoring hints surfaced in the prompt so
|
|
32
32
|
* the agent can produce content that passes proposal validation. Kept tiny:
|
|
@@ -42,7 +42,6 @@ const TYPE_HINTS = {
|
|
|
42
42
|
workflow: "workflow assets are markdown describing a multi-step process. Include `# <Title>` and ordered `## Step N` sections.",
|
|
43
43
|
script: "script assets are executable text files. Include a shebang and minimal usage comment.",
|
|
44
44
|
env: "env assets are `.env` files holding a group of related CONFIGURATION for an app/service (KEY=VALUE pairs, `#` comments) — URLs, flags, and any credentials it needs. Values may or may not be sensitive; all are protected (key names discoverable, values stay on disk). Inject with `akm env run env:<name> -- <cmd>` (the safe path — values never reach stdout/your context); do NOT run `akm env export` and read its output, as that prints values. For a single sensitive value used on its own for authentication (token, key, cert) use a `secret` instead. Never echo values back to the user.",
|
|
45
|
-
vault: "vault assets are DEPRECATED (use env). They store environment variables (KEY=VALUE pairs); comments use `#`. Never echo secret values back to the user.",
|
|
46
45
|
wiki: "wiki assets are markdown reference pages with `# Title` and structured headings.",
|
|
47
46
|
};
|
|
48
47
|
function hintForType(type) {
|
|
@@ -1,8 +1,27 @@
|
|
|
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 { ConfigError } from "../../core/errors";
|
|
5
|
-
import { warn } from "../../core/warn";
|
|
4
|
+
import { ConfigError } from "../../core/errors.js";
|
|
5
|
+
import { warn } from "../../core/warn.js";
|
|
6
|
+
// ── RunnerSpec capability predicates (H1) ───────────────────────────────────
|
|
7
|
+
// The `RunnerSpec` union is dispatched ad-hoc across the improve slice. These
|
|
8
|
+
// predicates co-locate the capability questions with the union definition so
|
|
9
|
+
// callers stop hand-inlining `kind !== "llm"` (which couples the call site to
|
|
10
|
+
// the exact shape of the union). They are typed as TypeScript type guards so
|
|
11
|
+
// narrowing flows through to the `connection` / `profile` accessors.
|
|
12
|
+
/** The in-tree LLM HTTP runner (`chatCompletion`); has no filesystem access. */
|
|
13
|
+
export function runnerIsLlm(runner) {
|
|
14
|
+
return runner.kind === "llm";
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Whether this runner can honour the file-write contract. Agent CLI + OpenCode
|
|
18
|
+
* SDK runners both have filesystem access; the direct LLM HTTP runner does NOT
|
|
19
|
+
* (see `src/llm/call-ai.ts`). Equivalent to `!runnerIsLlm(runner)` but names
|
|
20
|
+
* the capability the callers actually care about.
|
|
21
|
+
*/
|
|
22
|
+
export function runnerSupportsFileWrite(runner) {
|
|
23
|
+
return runner.kind !== "llm";
|
|
24
|
+
}
|
|
6
25
|
function resolveEffectiveMode(entry, profileName, config) {
|
|
7
26
|
if (entry.mode)
|
|
8
27
|
return entry.mode;
|
|
@@ -205,4 +224,4 @@ export function getStalenessDetectionThresholdDays(config) {
|
|
|
205
224
|
}
|
|
206
225
|
// Re-export `isProcessEnabled` from feature-gate.ts so callers that previously
|
|
207
226
|
// imported it from runner.ts continue to work.
|
|
208
|
-
export { isProcessEnabled } from "../../llm/feature-gate";
|
|
227
|
+
export { isProcessEnabled } from "../../llm/feature-gate.js";
|
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
import fs from "node:fs";
|
|
18
18
|
import os from "node:os";
|
|
19
19
|
import path from "node:path";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
20
|
+
import { spawn as runtimeSpawn } from "../../runtime.js";
|
|
21
|
+
import { getCommandBuilder } from "./builders.js";
|
|
22
|
+
import { DEFAULT_AGENT_TIMEOUT_MS } from "./config.js";
|
|
22
23
|
/**
|
|
23
24
|
* Kill the process group of `proc` with `signal`, falling back to
|
|
24
25
|
* `proc.kill(signal)` when `proc.pid` is unavailable (e.g. test fakes).
|
|
@@ -103,12 +104,10 @@ function pathCandidatesForCurrentPlatform(home) {
|
|
|
103
104
|
function resolveSpawnFn(options) {
|
|
104
105
|
if (options.spawn)
|
|
105
106
|
return options.spawn;
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
return bun.spawn.bind(bun);
|
|
107
|
+
// Default to the runtime-boundary spawn, which delegates to the native
|
|
108
|
+
// subprocess API on each runtime. Tests inject `options.spawn` to avoid
|
|
109
|
+
// poking real binaries.
|
|
110
|
+
return runtimeSpawn;
|
|
112
111
|
}
|
|
113
112
|
/**
|
|
114
113
|
* Build the child env. Starts empty and copies through:
|
|
@@ -169,7 +168,7 @@ async function readStream(stream, opts) {
|
|
|
169
168
|
*
|
|
170
169
|
* Failure modes (see {@link AgentFailureReason}):
|
|
171
170
|
*
|
|
172
|
-
* • `spawn_failed` —
|
|
171
|
+
* • `spawn_failed` — the spawn call threw synchronously.
|
|
173
172
|
* • `timeout` — exceeded the resolved timeout.
|
|
174
173
|
* • `non_zero_exit` — child exited with a non-zero code.
|
|
175
174
|
* • `parse_error` — `parseOutput === "json"` and stdout was not JSON.
|
|
@@ -233,7 +232,7 @@ export async function runAgent(profile, prompt, options = {}) {
|
|
|
233
232
|
};
|
|
234
233
|
}
|
|
235
234
|
// Hard timeout. We prefer SIGTERM, then SIGKILL if SIGTERM is ignored,
|
|
236
|
-
// but
|
|
235
|
+
// but the subprocess only exposes a single .kill() — one signal is enough
|
|
237
236
|
// for the structured-failure contract.
|
|
238
237
|
//
|
|
239
238
|
// BUG-M3: only flag `timedOut` when the child has not already exited. A
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
* Claude Code agent command builder (migrated from `agent/builders.ts`, #563).
|
|
6
|
+
*
|
|
7
|
+
* Translates a platform-agnostic {@link AgentDispatchRequest} into the exact
|
|
8
|
+
* argv the `claude` CLI expects. This is the Claude-specific slice of the
|
|
9
|
+
* builder strategy; the shared infrastructure (`AgentCommandBuilder`,
|
|
10
|
+
* `getCommandBuilder`, the OpenCode/default builders, flag/tool helpers) stays
|
|
11
|
+
* in `agent/builders.ts`, which imports this builder back into
|
|
12
|
+
* `BUILTIN_BUILDERS`.
|
|
13
|
+
*
|
|
14
|
+
* Behaviour-preserving relocation: the produced argv is byte-identical to the
|
|
15
|
+
* pre-migration `claudeBuilder`. The builder's `platform` stays `'claude'` (the
|
|
16
|
+
* canonical harness id).
|
|
17
|
+
*/
|
|
18
|
+
import { assertNotFlag, normalizeTools } from "../../agent/builder-shared.js";
|
|
19
|
+
import { resolveModel } from "../../agent/model-aliases.js";
|
|
20
|
+
/**
|
|
21
|
+
* Claude Code builder.
|
|
22
|
+
* Command shape: claude [--system-prompt "..."] [--model <m>] [--allowedTools <t>] --print "<prompt>"
|
|
23
|
+
*
|
|
24
|
+
* --print switches Claude Code to non-interactive captured output mode.
|
|
25
|
+
*/
|
|
26
|
+
export const claudeBuilder = {
|
|
27
|
+
platform: "claude",
|
|
28
|
+
build(profile, req) {
|
|
29
|
+
assertNotFlag(req.systemPrompt, "systemPrompt");
|
|
30
|
+
assertNotFlag(req.model, "model");
|
|
31
|
+
const args = [...profile.args];
|
|
32
|
+
if (req.systemPrompt) {
|
|
33
|
+
args.push("--system-prompt", req.systemPrompt);
|
|
34
|
+
}
|
|
35
|
+
if (req.model) {
|
|
36
|
+
const resolved = resolveModel(req.model, "claude", profile.modelAliases);
|
|
37
|
+
args.push("--model", resolved);
|
|
38
|
+
}
|
|
39
|
+
if (req.tools) {
|
|
40
|
+
args.push("--allowedTools", normalizeTools(req.tools));
|
|
41
|
+
}
|
|
42
|
+
// --print = non-interactive, outputs to stdout — required for captured mode
|
|
43
|
+
args.push("--print");
|
|
44
|
+
args.push("--");
|
|
45
|
+
args.push(req.prompt);
|
|
46
|
+
return { argv: [profile.bin, ...args] };
|
|
47
|
+
},
|
|
48
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
+
* Claude Code LLM-config importer (migrated from `setup/harness-config-import.ts`,
|
|
6
|
+
* #563).
|
|
7
|
+
*
|
|
8
|
+
* Detects a Claude Code installation (filesystem only, no network) and reads
|
|
9
|
+
* its config to extract LLM connection details. API key VALUES are never
|
|
10
|
+
* stored — only the env var name that holds them. The pluggable registry
|
|
11
|
+
* (`HARNESS_CONFIG_IMPORTERS`) and the OpenCode importer stay in
|
|
12
|
+
* `setup/harness-config-import.ts`, which imports this importer back.
|
|
13
|
+
*
|
|
14
|
+
* Behaviour-preserving relocation.
|
|
15
|
+
*/
|
|
16
|
+
import fs from "node:fs";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
function homeDir() {
|
|
19
|
+
return process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Imports LLM config from a Claude Code installation.
|
|
23
|
+
*
|
|
24
|
+
* Claude Code stores settings in `~/.claude/settings.json` or `~/.claude.json`.
|
|
25
|
+
* The model field may appear at the root or under `env.ANTHROPIC_MODEL`.
|
|
26
|
+
* The API key is always `ANTHROPIC_API_KEY`.
|
|
27
|
+
*/
|
|
28
|
+
export const claudeCodeImporter = {
|
|
29
|
+
harnessName: "Claude Code",
|
|
30
|
+
detect() {
|
|
31
|
+
const home = homeDir();
|
|
32
|
+
// Claude Code is installed if the ~/.claude/ directory exists
|
|
33
|
+
return fs.existsSync(path.join(home, ".claude"));
|
|
34
|
+
},
|
|
35
|
+
importConfig() {
|
|
36
|
+
const home = homeDir();
|
|
37
|
+
// Try ~/.claude/settings.json, then ~/.claude.json
|
|
38
|
+
const candidates = [path.join(home, ".claude", "settings.json"), path.join(home, ".claude.json")];
|
|
39
|
+
for (const filePath of candidates) {
|
|
40
|
+
try {
|
|
41
|
+
if (!fs.existsSync(filePath))
|
|
42
|
+
continue;
|
|
43
|
+
const raw = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
44
|
+
// Claude Code settings: model may be at root or nested under env
|
|
45
|
+
const envBlock = raw.env;
|
|
46
|
+
const model = typeof raw.model === "string"
|
|
47
|
+
? raw.model
|
|
48
|
+
: typeof envBlock?.ANTHROPIC_MODEL === "string"
|
|
49
|
+
? String(envBlock.ANTHROPIC_MODEL)
|
|
50
|
+
: undefined;
|
|
51
|
+
return {
|
|
52
|
+
harnessName: "Claude Code",
|
|
53
|
+
provider: "anthropic",
|
|
54
|
+
model: model ?? "claude-sonnet-4-5",
|
|
55
|
+
apiKeyEnvVar: "ANTHROPIC_API_KEY",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// try next candidate
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// ~/.claude exists but no readable settings — still return basic Anthropic config
|
|
63
|
+
return {
|
|
64
|
+
harnessName: "Claude Code",
|
|
65
|
+
provider: "anthropic",
|
|
66
|
+
model: "claude-sonnet-4-5",
|
|
67
|
+
apiKeyEnvVar: "ANTHROPIC_API_KEY",
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
* Claude Code harness (#563).
|
|
6
|
+
*
|
|
7
|
+
* This is the per-harness barrel that gathers the Claude Code integration
|
|
8
|
+
* surfaces that were previously scattered across the codebase:
|
|
9
|
+
* - session-log reader → ./session-log.ts (ClaudeCodeProvider)
|
|
10
|
+
* - agent command builder → ./agent-builder.ts (claudeBuilder)
|
|
11
|
+
* - config importer → ./config-import.ts (claudeCodeImporter)
|
|
12
|
+
*
|
|
13
|
+
* It also defines {@link ClaudeHarness}, the {@link AkmHarness} descriptor that
|
|
14
|
+
* `HARNESS_REGISTRY` registers.
|
|
15
|
+
*
|
|
16
|
+
* ## id normalization bridge ('claude' vs 'claude-code')
|
|
17
|
+
*
|
|
18
|
+
* The canonical, persisted id is `'claude'` (used by the agent runner, agent
|
|
19
|
+
* profiles, the Zod config schema and `--type` resolution after normalization).
|
|
20
|
+
* `'claude-code'` is the historical RUNTIME identity — the string stamped on
|
|
21
|
+
* session-log events/refs, the extracted-session dedup key, and the value
|
|
22
|
+
* `resolveAgentIdentity` reports. It is registered as an `alias` and exposed as
|
|
23
|
+
* `runtimeId` so BOTH directions round-trip via `normalizeHarnessId()` /
|
|
24
|
+
* `denormalizeRuntimeIdentity()`. Existing persisted configs and session logs
|
|
25
|
+
* that say `'claude-code'` keep working unchanged.
|
|
26
|
+
*/
|
|
27
|
+
import { BaseHarness } from "../types.js";
|
|
28
|
+
export { claudeBuilder } from "./agent-builder.js";
|
|
29
|
+
export { claudeCodeImporter } from "./config-import.js";
|
|
30
|
+
export { ClaudeCodeProvider } from "./session-log.js";
|
|
31
|
+
function caps(c) {
|
|
32
|
+
return {
|
|
33
|
+
sessionLogs: false,
|
|
34
|
+
agentDispatch: false,
|
|
35
|
+
detection: false,
|
|
36
|
+
configImport: false,
|
|
37
|
+
runtimeIdentity: false,
|
|
38
|
+
v1Migration: false,
|
|
39
|
+
...c,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Claude Code.
|
|
44
|
+
*
|
|
45
|
+
* Canonical id is `'claude'`; `'claude-code'` is the runtime/session-log
|
|
46
|
+
* identity and is registered as an alias so both directions round-trip.
|
|
47
|
+
*/
|
|
48
|
+
export class ClaudeHarness extends BaseHarness {
|
|
49
|
+
id = "claude";
|
|
50
|
+
displayName = "Claude Code";
|
|
51
|
+
aliases = ["claude-code"];
|
|
52
|
+
runtimeId = "claude-code";
|
|
53
|
+
// Home-relative config dir scanned by `akm setup` (#567). Claude Code has a
|
|
54
|
+
// session-log provider, so offering it as a stash source is functional.
|
|
55
|
+
setupDetectionDir = ".claude";
|
|
56
|
+
capabilities = caps({
|
|
57
|
+
sessionLogs: true,
|
|
58
|
+
agentDispatch: true,
|
|
59
|
+
detection: true,
|
|
60
|
+
configImport: true,
|
|
61
|
+
runtimeIdentity: true,
|
|
62
|
+
v1Migration: true,
|
|
63
|
+
});
|
|
64
|
+
}
|
package/dist/integrations/{session-logs/providers/claude-code.js → harnesses/claude/session-log.js}
RENAMED
|
@@ -4,8 +4,20 @@
|
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import os from "node:os";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import { extractInlineRefMentions } from "
|
|
8
|
-
|
|
7
|
+
import { extractInlineRefMentions } from "../../session-logs/inline-refs.js";
|
|
8
|
+
/**
|
|
9
|
+
* Root directory holding Claude Code's per-project JSONL session logs.
|
|
10
|
+
*
|
|
11
|
+
* Resolved per call (not memoized at module load) so the `AKM_CLAUDE_PROJECTS_DIR`
|
|
12
|
+
* override can be set after import. The override exists so tests — and the
|
|
13
|
+
* isolated-storage sandbox — can point the scan at an empty fixture directory
|
|
14
|
+
* instead of the real `~/.claude/projects`, which on an actively-used machine
|
|
15
|
+
* holds many large session files and would make `akm health` (which scans it
|
|
16
|
+
* synchronously) slow and non-hermetic.
|
|
17
|
+
*/
|
|
18
|
+
function claudeProjectsDir() {
|
|
19
|
+
return process.env.AKM_CLAUDE_PROJECTS_DIR ?? path.join(os.homedir(), ".claude", "projects");
|
|
20
|
+
}
|
|
9
21
|
/**
|
|
10
22
|
* Parse a single Claude Code JSONL event into a normalized {@link SessionEvent}.
|
|
11
23
|
* Returns `undefined` for events that don't carry textual content (file
|
|
@@ -75,14 +87,29 @@ function parseClaudeEvent(entry, sessionId, filePath, fallbackTsMs) {
|
|
|
75
87
|
filePath,
|
|
76
88
|
};
|
|
77
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Claude Code native session-log reader.
|
|
92
|
+
*
|
|
93
|
+
* id-normalization note (#563): the canonical harness id is `'claude'`, but
|
|
94
|
+
* the provider's `name` — which is STAMPED onto every {@link SessionEvent} /
|
|
95
|
+
* {@link SessionRef} (`harness: this.name`), used as the extracted-session
|
|
96
|
+
* dedup key, and embedded in `session:<harness>:<id>` proposal refs — stays
|
|
97
|
+
* `'claude-code'` (the harness runtimeId). Changing it would silently break
|
|
98
|
+
* round-tripping of already-persisted session-tracking rows and refs. Registry
|
|
99
|
+
* lookups normalize `'claude-code'` → `'claude'` via the #562 bridge
|
|
100
|
+
* (`getHarness`), and the `--type` flag accepts both, so the canonical id and
|
|
101
|
+
* the persisted runtime string coexist without drift.
|
|
102
|
+
*/
|
|
78
103
|
export class ClaudeCodeProvider {
|
|
104
|
+
// Runtime identity (NOT the canonical id) — see class doc. Equals
|
|
105
|
+
// HARNESS_BY_ID.get("claude").runtimeId.
|
|
79
106
|
name = "claude-code";
|
|
80
107
|
isAvailable() {
|
|
81
|
-
return fs.existsSync(
|
|
108
|
+
return fs.existsSync(claudeProjectsDir());
|
|
82
109
|
}
|
|
83
110
|
*readEvents(input) {
|
|
84
111
|
try {
|
|
85
|
-
for (const jsonlPath of this.#walkJsonl(
|
|
112
|
+
for (const jsonlPath of this.#walkJsonl(claudeProjectsDir())) {
|
|
86
113
|
const stat = fs.statSync(jsonlPath);
|
|
87
114
|
if (stat.mtimeMs < input.sinceMs)
|
|
88
115
|
continue;
|
|
@@ -113,7 +140,7 @@ export class ClaudeCodeProvider {
|
|
|
113
140
|
}
|
|
114
141
|
}
|
|
115
142
|
listSessions(input = {}) {
|
|
116
|
-
const root = input.location ??
|
|
143
|
+
const root = input.location ?? claudeProjectsDir();
|
|
117
144
|
const sinceMs = input.sinceMs ?? 0;
|
|
118
145
|
const summaries = [];
|
|
119
146
|
try {
|