akm-cli 0.9.1 → 0.9.2-alpha.2
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 +103 -28
- package/README.md +3 -1
- package/SECURITY.md +1 -1
- package/STABILITY.md +1 -1
- package/dist/akm +2 -2
- package/dist/akm-migrate +2 -2
- package/dist/assets/hints/cli-hints-full.md +14 -9
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/models.json +35 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +3 -4
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +1 -3
- package/dist/assets/tasks/core/extract.yml +6 -5
- package/dist/assets/tasks/core/improve.yml +6 -5
- package/dist/assets/tasks/core/index-refresh.yml +6 -5
- package/dist/assets/tasks/core/sync.yml +6 -5
- package/dist/assets/tasks/core/version-check.yml +6 -5
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
- package/dist/cli/confirm.js +2 -2
- package/dist/cli/parse-args.js +3 -24
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +2 -2
- package/dist/cli.js +11 -9
- package/dist/commands/agent/agent-dispatch.js +55 -89
- package/dist/commands/agent/contribute-cli.js +12 -45
- package/dist/commands/command/builtin-action.js +32 -0
- package/dist/commands/command/command-cli.js +99 -0
- package/dist/commands/command/command-execution.js +308 -0
- package/dist/commands/command/execution-source-loader.js +176 -0
- package/dist/commands/command/portable-template.js +60 -0
- package/dist/commands/config-cli.js +10 -4
- package/dist/commands/env/env.js +4 -2
- package/dist/commands/feedback-cli.js +1 -1
- package/dist/commands/health/checks.js +241 -29
- package/dist/commands/health/html-report.js +0 -14
- package/dist/commands/health/report-view-model.js +0 -1
- package/dist/commands/health/surfaces.js +6 -7
- package/dist/commands/health/types.js +0 -2
- package/dist/commands/health.js +63 -18
- package/dist/commands/improve/collapse-detector.js +5 -6
- package/dist/commands/improve/consolidate.js +251 -214
- package/dist/commands/improve/distill/promote-memory.js +71 -34
- package/dist/commands/improve/distill/quality-gate.js +17 -5
- package/dist/commands/improve/distill.js +232 -155
- package/dist/commands/improve/eligibility.js +112 -79
- package/dist/commands/improve/execution.js +57 -0
- package/dist/commands/improve/extract-cli.js +5 -5
- package/dist/commands/improve/extract-prompt.js +64 -22
- package/dist/commands/improve/extract.js +608 -360
- package/dist/commands/improve/improve-strategies.js +43 -14
- package/dist/commands/improve/improve.js +249 -29
- package/dist/commands/improve/loop-stages.js +11 -17
- package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
- package/dist/commands/improve/outcome-loop.js +22 -38
- package/dist/commands/improve/planner.js +134 -0
- package/dist/commands/improve/preparation.js +730 -409
- package/dist/commands/improve/reflect.js +386 -223
- package/dist/commands/improve/run-context.js +3 -4
- package/dist/commands/improve/salience.js +6 -58
- package/dist/commands/improve/session-asset.js +12 -12
- package/dist/commands/lint/index.js +101 -29
- package/dist/commands/migrate-cli.js +11 -69
- package/dist/commands/migration-tool.js +6 -9
- package/dist/commands/models-cli.js +27 -0
- package/dist/commands/proposal/drain.js +258 -186
- package/dist/commands/proposal/proposal-cli.js +32 -10
- package/dist/commands/proposal/proposal.js +2 -5
- package/dist/commands/proposal/propose.js +192 -172
- package/dist/commands/proposal/repository.js +54 -91
- package/dist/commands/proposal/validators/proposal-validators.js +9 -7
- package/dist/commands/read/curate.js +53 -22
- package/dist/commands/read/registry-search.js +25 -9
- package/dist/commands/read/remember-cli.js +14 -2
- package/dist/commands/read/search.js +10 -4
- package/dist/commands/read/show.js +139 -153
- package/dist/commands/registry-cli.js +16 -7
- package/dist/commands/remember.js +33 -18
- package/dist/commands/sources/add-cli.js +19 -178
- package/dist/commands/sources/bundle-cli.js +15 -3
- package/dist/commands/sources/dangerous-env-audit.js +135 -0
- package/dist/commands/sources/info.js +2 -1
- package/dist/commands/sources/installed-stashes.js +901 -177
- package/dist/commands/sources/schema-repair.js +174 -95
- package/dist/commands/sources/self-update.js +30 -74
- package/dist/commands/sources/source-add.js +3 -5
- package/dist/commands/sources/sources-cli.js +2 -15
- package/dist/commands/sources/update-transaction.js +220 -0
- package/dist/commands/tasks/tasks-cli.js +3 -3
- package/dist/commands/tasks/tasks.js +736 -317
- package/dist/commands/workflow-cli.js +2 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
- package/dist/core/adapter/adapters/akm-adapter.js +85 -35
- package/dist/core/adapter/adapters/akm-lint.js +54 -39
- package/dist/core/adapter/adapters/akm-metadata.js +45 -45
- package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
- package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
- package/dist/core/adapter/adapters/index.js +0 -9
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
- package/dist/core/adapter/adapters/okf-adapter.js +4 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
- package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
- package/dist/core/adapter/execution-source.js +308 -0
- package/dist/core/adapter/recognize-match.js +36 -13
- package/dist/core/adapter/registry.js +0 -9
- package/dist/core/asset/stash-meta.js +94 -4
- package/dist/core/common.js +6 -11
- package/dist/core/config/config-io.js +3 -3
- package/dist/core/config/config-schema.js +18 -40
- package/dist/core/config/config-sources.js +11 -21
- package/dist/core/config/config-walker.js +31 -13
- package/dist/core/config/config.js +23 -26
- package/dist/core/config/schema/engines.js +8 -7
- package/dist/core/config/schema/improve-processes.js +29 -5
- package/dist/core/config/schema/index-config.js +0 -27
- package/dist/core/config/schema/primitives.js +1 -23
- package/dist/core/config/schema/sources-bundles.js +13 -16
- package/dist/core/errors.js +2 -0
- package/dist/core/events.js +68 -32
- package/dist/core/extra-params.js +1 -0
- package/dist/core/improve-result.js +315 -0
- package/dist/core/lesson-lint.js +0 -6
- package/dist/core/maintenance-barrier.js +4 -4
- package/dist/core/network-policy.js +152 -0
- package/dist/core/paths.js +1 -1
- package/dist/core/recognition-util.js +4 -4
- package/dist/core/registry-url.js +456 -0
- package/dist/core/state/migrations.js +161 -47
- package/dist/core/state-db.js +453 -80
- package/dist/core/system-error.js +32 -0
- package/dist/core/time.js +2 -12
- package/dist/core/write-source.js +0 -18
- package/dist/execution/directory-identity.js +52 -0
- package/dist/execution/executable-identity.js +107 -0
- package/dist/execution/guarded-source.js +398 -0
- package/dist/execution/json.js +95 -0
- package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
- package/dist/execution/record.js +55 -0
- package/dist/execution/resolved-request.js +730 -0
- package/dist/execution/source.js +320 -0
- package/dist/indexer/bundle-identity-guard.js +5 -4
- package/dist/indexer/db/graph-db.js +33 -0
- package/dist/indexer/graph/graph-boost.js +3 -4
- package/dist/indexer/graph/graph-extraction.js +562 -373
- package/dist/indexer/index-written-assets.js +78 -39
- package/dist/indexer/indexer.js +471 -432
- package/dist/indexer/installations.js +6 -0
- package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
- package/dist/indexer/materialize-embeddings.js +155 -0
- package/dist/indexer/passes/memory-inference.js +227 -174
- package/dist/indexer/passes/metadata.js +263 -118
- package/dist/indexer/scan/doc-to-entry.js +7 -10
- package/dist/indexer/scan/drain-dir.js +51 -23
- package/dist/indexer/search/db-search.js +156 -50
- package/dist/indexer/search/fts-query.js +40 -40
- package/dist/indexer/search/ranking.js +36 -1
- package/dist/indexer/search/search-attribution.js +3 -1
- package/dist/indexer/search/search-fields.js +23 -14
- package/dist/indexer/search/search-hit-enrichers.js +1 -1
- package/dist/indexer/search/search-source.js +7 -16
- package/dist/indexer/search/semantic-status.js +10 -1
- package/dist/indexer/usage/show-usage.js +105 -0
- package/dist/indexer/usage/usage-events.js +7 -2
- package/dist/indexer/walk/matchers.js +40 -10
- package/dist/indexer/walk/path-resolver.js +5 -2
- package/dist/indexer/walk/walker.js +20 -2
- package/dist/integrations/agent/builder-shared.js +3 -6
- package/dist/integrations/agent/conversation-fallback.js +16 -0
- package/dist/integrations/agent/engine-resolution.js +87 -87
- package/dist/integrations/agent/execution-cascade.js +566 -0
- package/dist/integrations/agent/execution-definitions.js +211 -0
- package/dist/integrations/agent/execution-lowering.js +811 -0
- package/dist/integrations/agent/execution-preparation.js +67 -0
- package/dist/integrations/agent/index.js +0 -2
- package/dist/integrations/agent/inline-execution.js +74 -0
- package/dist/integrations/agent/model-map.js +515 -0
- package/dist/integrations/agent/persona-fallback.js +30 -0
- package/dist/integrations/agent/request-lowering.js +186 -0
- package/dist/integrations/agent/runner-dispatch.js +230 -37
- package/dist/integrations/agent/runner.js +12 -83
- package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
- package/dist/integrations/harnesses/aider/index.js +0 -1
- package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
- package/dist/integrations/harnesses/amazonq/index.js +0 -1
- package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
- package/dist/integrations/harnesses/claude/index.js +1 -5
- package/dist/integrations/harnesses/claude/session-log.js +3 -33
- package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
- package/dist/integrations/harnesses/codex/index.js +0 -1
- package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
- package/dist/integrations/harnesses/copilot/index.js +0 -1
- package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
- package/dist/integrations/harnesses/gemini/index.js +0 -1
- package/dist/integrations/harnesses/index.js +4 -44
- package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
- package/dist/integrations/harnesses/opencode/index.js +0 -2
- package/dist/integrations/harnesses/opencode/session-log.js +14 -204
- package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
- package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
- package/dist/integrations/harnesses/openhands/index.js +0 -1
- package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
- package/dist/integrations/harnesses/pi/index.js +0 -1
- package/dist/integrations/harnesses/shared.js +0 -1
- package/dist/integrations/harnesses/types.js +1 -3
- package/dist/integrations/lockfile.js +82 -79
- package/dist/integrations/session-logs/index.js +6 -17
- package/dist/integrations/session-logs/provider-base.js +1 -29
- package/dist/llm/client.js +10 -5
- package/dist/llm/embedder.js +6 -7
- package/dist/llm/embedders/local.js +37 -88
- package/dist/llm/embedders/types.js +1 -1
- package/dist/llm/graph-extract.js +75 -50
- package/dist/llm/index-passes.js +43 -5
- package/dist/llm/memory-infer.js +8 -6
- package/dist/llm/metadata-enhance.js +5 -3
- package/dist/llm/structured-call.js +122 -25
- package/dist/output/format-exempt.js +1 -1
- package/dist/output/render-registry.js +0 -16
- package/dist/output/renderers.js +12 -7
- package/dist/output/shapes/curate.js +1 -0
- package/dist/output/shapes/helpers.js +10 -2
- package/dist/output/shapes/passthrough.js +2 -0
- package/dist/output/text/command-format.js +31 -33
- package/dist/output/text/health-format.js +1 -29
- package/dist/output/text/migrate.js +6 -56
- package/dist/output/text/proposal-format.js +16 -1
- package/dist/output/text/workflow-format.js +16 -0
- package/dist/registry/network.js +279 -0
- package/dist/registry/pinned-request-helper.js +247 -0
- package/dist/registry/pinned-transport.js +717 -0
- package/dist/registry/providers/skills-sh.js +18 -6
- package/dist/registry/providers/static-index.js +20 -7
- package/dist/registry/resolve.js +53 -28
- package/dist/scripts/akm-migrate-node.js +19334 -52269
- package/dist/scripts/akm-migrate.js +19270 -51612
- package/dist/setup/registry-stash-loader.js +64 -20
- package/dist/setup/semantic-assets.js +9 -34
- package/dist/setup/setup.js +12 -30
- package/dist/setup/source-identity.js +17 -0
- package/dist/setup/steps/sources.js +36 -15
- package/dist/setup/steps/tasks.js +39 -11
- package/dist/sources/providers/git-provider.js +3 -3
- package/dist/sources/providers/npm.js +2 -2
- package/dist/sources/providers/provider-utils.js +4 -3
- package/dist/sources/providers/website.js +11 -7
- package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
- package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
- package/dist/sources/website-url.js +73 -0
- package/dist/storage/engines/sqlite-migrations.js +81 -26
- package/dist/storage/managed-db.js +27 -24
- package/dist/storage/repositories/events-repository.js +3 -0
- package/dist/storage/repositories/index-connection.js +42 -10
- package/dist/storage/repositories/index-entries-repository.js +203 -229
- package/dist/storage/repositories/index-entry-mapper.js +8 -12
- package/dist/storage/repositories/index-entry-schema.js +255 -0
- package/dist/storage/repositories/index-fts-repository.js +64 -71
- package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
- package/dist/storage/repositories/index-meta-repository.js +0 -11
- package/dist/storage/repositories/index-schema.js +74 -350
- package/dist/storage/repositories/index-utility-repository.js +12 -17
- package/dist/storage/repositories/index-vec-repository.js +56 -7
- package/dist/storage/repositories/proposals-repository.js +4 -127
- package/dist/storage/repositories/registry-cache.js +2 -1
- package/dist/storage/repositories/task-history-repository.js +20 -40
- package/dist/storage/repositories/workflow-runs-repository.js +228 -129
- package/dist/storage/sqlite-read-snapshot.js +148 -0
- package/dist/tasks/backends/cron.js +170 -42
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +787 -202
- package/dist/tasks/backends/schtasks.js +282 -83
- package/dist/tasks/embedded.js +7 -7
- package/dist/tasks/frozen-script.js +50 -0
- package/dist/tasks/resolve-akm-bin.js +5 -1
- package/dist/tasks/runner.js +239 -251
- package/dist/tasks/runtime-v3.js +281 -0
- package/dist/tasks/scheduler-binding.js +272 -0
- package/dist/tasks/scheduler-invocation.js +57 -43
- package/dist/tasks/scheduler-sync.js +654 -0
- package/dist/tasks/source-v3.js +752 -0
- package/dist/tasks/standalone-script-entry.js +5 -0
- package/dist/tasks/task-id.js +29 -0
- package/dist/workflows/authoring/authoring.js +15 -32
- package/dist/workflows/exec/dispatch-redaction.js +14 -8
- package/dist/workflows/exec/exec-unit.js +7 -28
- package/dist/workflows/exec/frozen-judge.js +57 -89
- package/dist/workflows/exec/lowering-notices.js +23 -0
- package/dist/workflows/exec/native-executor.js +301 -458
- package/dist/workflows/exec/param-secrets.js +4 -3
- package/dist/workflows/exec/run-workflow.js +26 -32
- package/dist/workflows/exec/step-work.js +105 -109
- package/dist/workflows/exec/unit-dispatch.js +103 -27
- package/dist/workflows/exec/unit-writer.js +3 -3
- package/dist/workflows/exec/worktree.js +2 -2
- package/dist/workflows/ir/compile.js +86 -72
- package/dist/workflows/ir/environment-v4.js +328 -0
- package/dist/workflows/ir/freeze-v4.js +122 -0
- package/dist/workflows/ir/plan-hash.js +13 -7
- package/dist/workflows/ir/schema-v4.js +525 -0
- package/dist/workflows/ir/schema.js +25 -284
- package/dist/workflows/ir/source-freeze-v4.js +506 -0
- package/dist/workflows/parser.js +27 -24
- package/dist/workflows/program/schema.js +1 -2
- package/dist/workflows/renderer.js +42 -29
- package/dist/workflows/resource-limits.js +4 -5
- package/dist/workflows/runtime/agent-identity.js +11 -13
- package/dist/workflows/runtime/plan-classifier.js +8 -8
- package/dist/workflows/runtime/runs.js +27 -43
- package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
- package/dist/workflows/source-files.js +373 -0
- package/dist/workflows/source-ir/compile.js +196 -0
- package/dist/workflows/source-ir/github-yaml.js +577 -0
- package/dist/workflows/source-ir/ordering.js +38 -0
- package/dist/workflows/source-ir/program.js +50 -0
- package/dist/workflows/source-ir/result.js +26 -0
- package/dist/workflows/source-ir/schema.js +772 -0
- package/dist/workflows/source-ir/semantics.js +242 -0
- package/dist/workflows/source-ir/uses.js +14 -0
- package/docs/README.md +2 -0
- package/docs/migration/README.md +3 -1
- package/docs/migration/release-notes/0.9.2.md +55 -0
- package/docs/migration/release-notes/README.md +5 -0
- package/docs/migration/v0.8-to-v0.9.md +76 -1077
- package/docs/migration/v0.9.0-troubleshooting.md +104 -516
- package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
- package/docs/reference/README.md +1 -0
- package/docs/reference/cli.md +230 -98
- package/docs/reference/configuration.md +159 -36
- package/docs/reference/data-and-telemetry.md +19 -1
- package/docs/reference/supported-formats.md +23 -3
- package/docs/reference/tasks.md +182 -0
- package/docs/reference/workflow-schema.md +91 -40
- package/docs/reference/workflows.md +33 -6
- package/package.json +10 -6
- package/schemas/akm-config.json +372 -224
- package/schemas/akm-task.json +324 -80
- package/schemas/akm-workflow.json +6 -9
- package/dist/core/migration-operation.js +0 -75
- package/dist/integrations/agent/model-aliases.js +0 -74
- package/dist/tasks/parser.js +0 -380
- package/dist/tasks/schema.js +0 -123
- package/dist/tasks/validator.js +0 -80
- package/dist/workflows/ir/freeze.js +0 -320
- package/dist/workflows/runtime/document-cache.js +0 -13
|
@@ -15,7 +15,7 @@ import { resolveStashDir } from "../../core/common.js";
|
|
|
15
15
|
import { loadConfig } from "../../core/config/config.js";
|
|
16
16
|
import { resolveWriteTarget } from "../../core/write-source.js";
|
|
17
17
|
import { withAssetMutationLease } from "../../indexer/index-writer-lock.js";
|
|
18
|
-
import { createProposal, diffProposal, isProposalSkipped, listProposals, preflightProposalPromotion, promoteProposal, proposalContent, recoverProposalTransactionsForStash, rejectProposalDurably, resolveProposalId,
|
|
18
|
+
import { createProposal, diffProposal, isProposalSkipped, listProposals, preflightProposalPromotion, promoteProposal, proposalContent, recoverProposalTransactionsForStash, rejectProposalDurably, resolveProposalId, revertProposal, } from "./repository.js";
|
|
19
19
|
import { validateProposal } from "./validators/proposals.js";
|
|
20
20
|
// ── Shared helpers ──────────────────────────────────────────────────────────
|
|
21
21
|
function resolveStash(stashDir) {
|
|
@@ -103,10 +103,7 @@ export async function akmProposalReject(options) {
|
|
|
103
103
|
return withAssetMutationLease("proposal-reject", async () => {
|
|
104
104
|
const config = options.config ?? loadConfig();
|
|
105
105
|
const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, config);
|
|
106
|
-
|
|
107
|
-
// strict decoding — resolveProposalId's exact-UUID match would otherwise
|
|
108
|
-
// throw here, before the terminal-status machinery even runs.
|
|
109
|
-
const proposalId = resolveProposalIdForReject(stash, options.id, options.ctx);
|
|
106
|
+
const proposalId = resolveProposalId(stash, options.id, options.ctx).id;
|
|
110
107
|
await recoverProposalTransactionsForStash(stash, config, options.ctx, proposalId);
|
|
111
108
|
const updated = rejectProposalDurably(stash, proposalId, options.reason, options.ctx, options.gateDecision);
|
|
112
109
|
return {
|
|
@@ -16,27 +16,81 @@ import fs from "node:fs";
|
|
|
16
16
|
import { placementTypes, stashDirFor } from "../../core/asset/asset-placement.js";
|
|
17
17
|
import { parseRefInput } from "../../core/asset/resolve-ref.js";
|
|
18
18
|
import { resolveStashDir } from "../../core/common.js";
|
|
19
|
-
import {
|
|
19
|
+
import { UsageError } from "../../core/errors.js";
|
|
20
20
|
import { appendEvent } from "../../core/events.js";
|
|
21
|
-
import { redactSensitiveText } from "../../core/redaction.js";
|
|
22
21
|
import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
|
|
23
22
|
import { warn } from "../../core/warn.js";
|
|
24
23
|
import { deriveEntryProvenance } from "../../indexer/installations.js";
|
|
25
|
-
import { fallbackAnnouncement
|
|
26
|
-
import {
|
|
24
|
+
import { fallbackAnnouncement } from "../../integrations/agent/engine-fallback.js";
|
|
25
|
+
import { acquireLoweredExecutionDispatchLease, dispatchLoweredExecutionRequest, disposeLoweredExecutionDispatchLease, lowerResolvedExecutionRequest, redactWithLoweredExecutionDispatchLease, } from "../../integrations/agent/execution-lowering.js";
|
|
26
|
+
import { prepareInlineExecution } from "../../integrations/agent/inline-execution.js";
|
|
27
27
|
import { buildProposePrompt, parseAgentProposalPayload } from "../../integrations/agent/prompts.js";
|
|
28
|
-
import { collectDispatchSensitiveValues, executeRunner } from "../../integrations/agent/runner-dispatch.js";
|
|
29
28
|
import { baseFailureFields, enoentHintMessage, isEnoentFailure } from "../agent/agent-support.js";
|
|
30
29
|
import { createProposal, isProposalSkipped, resolveProposalQueueTarget, } from "./repository.js";
|
|
31
|
-
function failureEnvelope(result, type, name, engine, fallbackReason = "non_zero_exit") {
|
|
30
|
+
function failureEnvelope(result, type, name, engine, notices, fallbackReason = "non_zero_exit") {
|
|
32
31
|
return {
|
|
33
32
|
...baseFailureFields(result, fallbackReason),
|
|
34
33
|
schemaVersion: 2,
|
|
35
34
|
type,
|
|
36
35
|
name,
|
|
37
36
|
engine,
|
|
37
|
+
...(notices.length > 0 ? { notices } : {}),
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
+
function noticeFields(notices) {
|
|
41
|
+
return notices.length > 0 ? { notices } : {};
|
|
42
|
+
}
|
|
43
|
+
/** Materialize required credentials through the real runner boundary, without provider I/O. */
|
|
44
|
+
async function preflightProposalDispatch(lowered, runOptions) {
|
|
45
|
+
return acquireLoweredExecutionDispatchLease(lowered, {
|
|
46
|
+
...(runOptions.envSource ? { envSource: runOptions.envSource } : {}),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Resolve, lower, and dispatch the already-rendered proposal prompt. */
|
|
50
|
+
async function dispatchProposalPrompt(prompt, config, options, onDispatchReady) {
|
|
51
|
+
const current = {
|
|
52
|
+
...(options.engine !== undefined ? { engine: options.engine } : {}),
|
|
53
|
+
...(options.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
|
|
54
|
+
};
|
|
55
|
+
const prepared = prepareInlineExecution({
|
|
56
|
+
content: prompt,
|
|
57
|
+
config,
|
|
58
|
+
invocationKind: "direct",
|
|
59
|
+
...(Object.keys(current).length > 0 ? { current } : {}),
|
|
60
|
+
});
|
|
61
|
+
const engineName = prepared.request.engine.name;
|
|
62
|
+
const announcement = fallbackAnnouncement(prepared.fallbackEngineName, engineName);
|
|
63
|
+
if (announcement)
|
|
64
|
+
warn(announcement);
|
|
65
|
+
const lowered = lowerResolvedExecutionRequest(prepared.request, prepared.config);
|
|
66
|
+
const interactive = !options.runAgentOptions?.spawn;
|
|
67
|
+
const runOptions = {
|
|
68
|
+
stdio: interactive ? "interactive" : "captured",
|
|
69
|
+
parseOutput: "text",
|
|
70
|
+
...(options.runAgentOptions ?? {}),
|
|
71
|
+
};
|
|
72
|
+
const lease = await preflightProposalDispatch(lowered, runOptions);
|
|
73
|
+
// Materialize/validate every required symbolic credential before the entry
|
|
74
|
+
// event opens durable state. Provider/runtime failures still occur after the
|
|
75
|
+
// event, preserving the command-attempt observability contract.
|
|
76
|
+
try {
|
|
77
|
+
onDispatchReady();
|
|
78
|
+
options.onDispatchReady?.();
|
|
79
|
+
const result = await dispatchLoweredExecutionRequest(lowered, { runOptions, lease });
|
|
80
|
+
return {
|
|
81
|
+
result,
|
|
82
|
+
engineName,
|
|
83
|
+
...(lowered.runner.kind === "llm" ? {} : { engineBin: lowered.runner.profile.bin }),
|
|
84
|
+
notices: lowered.notices,
|
|
85
|
+
lease,
|
|
86
|
+
interactive,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
disposeLoweredExecutionDispatchLease(lease);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
40
94
|
/**
|
|
41
95
|
* WI-8.5a — the fully-qualified `bundle//conceptId` item_ref for a proposal
|
|
42
96
|
* target in `stashDir`. The conceptId is BUILT from the D-R2 static table
|
|
@@ -80,23 +134,11 @@ export async function akmPropose(options) {
|
|
|
80
134
|
throw new UsageError(`propose: unknown asset type "${options.type}". Known types: ${[...placementTypes()].sort().join(", ")}.`, "INVALID_FLAG_VALUE");
|
|
81
135
|
}
|
|
82
136
|
const stash = options.stashDir ?? resolveStashDir();
|
|
83
|
-
// 1. Resolve the
|
|
84
|
-
//
|
|
137
|
+
// 1. Resolve the write target. Engine/model/inference resolution happens
|
|
138
|
+
// exactly once below through the shared execution cascade.
|
|
85
139
|
const config = options.agentConfig ?? (await import("../../core/config/config.js")).loadConfig();
|
|
86
140
|
const target = resolveProposalQueueTarget(stash, config);
|
|
87
|
-
|
|
88
|
-
const { config: engineConfig, fallbackEngineName } = withEngineFallback(config);
|
|
89
|
-
const engineName = options.engine ?? engineConfig.defaults?.engine;
|
|
90
|
-
// Announced, never silent: `options.engine` outranks the default, so the
|
|
91
|
-
// fallback is only reportable when it is the engine actually selected.
|
|
92
|
-
const engineAnnouncement = fallbackAnnouncement(fallbackEngineName, engineName);
|
|
93
|
-
if (engineAnnouncement)
|
|
94
|
-
warn(engineAnnouncement);
|
|
95
|
-
if (!engineName)
|
|
96
|
-
throw new ConfigError(`propose ${NO_ENGINE_MESSAGE_SUFFIX} ${NO_ENGINE_REMEDY}`, "INVALID_CONFIG_FILE");
|
|
97
|
-
const runner = resolveEngine(engineName, engineConfig);
|
|
98
|
-
const profile = runner.kind === "llm" ? undefined : runner.profile;
|
|
99
|
-
// 3. Build prompt.
|
|
141
|
+
// 2. Build terminal user content.
|
|
100
142
|
// Synthesize a temp draft path so opencode can write the asset content
|
|
101
143
|
// directly using its file tools rather than returning JSON via stdout.
|
|
102
144
|
const draftFilePath = import("node:os").then((os) => import("node:path").then((path) => path.join(os.tmpdir(), `akm-propose-${options.type}-${options.name.replace(/[^a-z0-9_-]/gi, "_")}-${Date.now()}.md`)));
|
|
@@ -111,166 +153,144 @@ export async function akmPropose(options) {
|
|
|
111
153
|
...(standardsContext.trim() ? { standardsContext } : {}),
|
|
112
154
|
draftFilePath: resolvedDraftPath,
|
|
113
155
|
});
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
|
|
124
|
-
...(options.runAgentOptions ?? {}),
|
|
125
|
-
};
|
|
126
|
-
const sensitiveValues = collectDispatchSensitiveValues(runner, runOptions);
|
|
127
|
-
result = await executeRunner(runner, prompt, runOptions, {
|
|
128
|
-
llm: async (spec, llmPrompt, opts) => {
|
|
129
|
-
const { chatCompletion } = await import("../../llm/client.js");
|
|
130
|
-
const started = Date.now();
|
|
131
|
-
try {
|
|
132
|
-
const stdout = await chatCompletion(spec.connection, [{ role: "user", content: llmPrompt }], {
|
|
133
|
-
...(Object.hasOwn(opts, "timeoutMs") ? { timeoutMs: opts.timeoutMs } : {}),
|
|
134
|
-
});
|
|
135
|
-
return { ok: true, exitCode: 0, stdout, stderr: "", durationMs: Date.now() - started };
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
156
|
+
// 3. Preserve the fully-authored prompt as the terminal user content;
|
|
157
|
+
// no synthetic persona, conversation turn, schema, or tool selection is
|
|
158
|
+
// introduced while it crosses the shared resolved/lowered boundary.
|
|
159
|
+
const dispatch = await dispatchProposalPrompt(prompt, config, options, () => emitProposeInvoked(target.source, options));
|
|
160
|
+
const { result, engineName, notices, lease } = dispatch;
|
|
161
|
+
try {
|
|
162
|
+
if (!result.ok) {
|
|
163
|
+
// B3: ENOENT / not-found gives an actionable hint.
|
|
164
|
+
if (isEnoentFailure(result)) {
|
|
138
165
|
return {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
stdout: "",
|
|
142
|
-
stderr: "",
|
|
143
|
-
durationMs: Date.now() - started,
|
|
144
|
-
error: String(error),
|
|
145
|
-
reason: "spawn_failed",
|
|
166
|
+
...failureEnvelope(result, options.type, options.name, engineName, notices),
|
|
167
|
+
error: enoentHintMessage(dispatch.engineBin ?? engineName),
|
|
146
168
|
};
|
|
147
169
|
}
|
|
148
|
-
|
|
149
|
-
});
|
|
150
|
-
if (!result.ok) {
|
|
151
|
-
// B3: ENOENT / not-found gives an actionable hint.
|
|
152
|
-
if (isEnoentFailure(result)) {
|
|
153
|
-
return {
|
|
154
|
-
...failureEnvelope(result, options.type, options.name, engineName),
|
|
155
|
-
error: enoentHintMessage(profile?.bin ?? engineName),
|
|
156
|
-
};
|
|
170
|
+
return failureEnvelope(result, options.type, options.name, engineName, notices);
|
|
157
171
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
ref: proposeItemRef(target.source, options.type, options.name),
|
|
169
|
-
content: draftContent,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
// B1: When interactive mode was used and stdout is empty, the agent did not
|
|
174
|
-
// write the draft file and stdout was not captured — surface an actionable error.
|
|
175
|
-
const stdioWasInteractive = !useCustomSpawn;
|
|
176
|
-
if (stdioWasInteractive && (result.stdout ?? "") === "") {
|
|
177
|
-
return {
|
|
178
|
-
schemaVersion: 2,
|
|
179
|
-
ok: false,
|
|
180
|
-
reason: "parse_error",
|
|
181
|
-
error: "Agent did not write draft file and stdout was not captured (interactive mode). Check that the agent CLI understood the file-write instruction, or configure a headless profile with stdio: 'captured'.",
|
|
182
|
-
type: options.type,
|
|
183
|
-
name: options.name,
|
|
184
|
-
engine: engineName,
|
|
185
|
-
exitCode: result.exitCode,
|
|
186
|
-
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
172
|
+
// 5. Resolve the proposal content.
|
|
173
|
+
// Path A: opencode wrote the draft file — read it directly (no stdout parse).
|
|
174
|
+
// Path B: fallback to stdout JSON parse for non-file-writing agents.
|
|
175
|
+
let payload;
|
|
176
|
+
if (fs.existsSync(resolvedDraftPath)) {
|
|
177
|
+
const draftContent = fs.readFileSync(resolvedDraftPath, "utf8");
|
|
178
|
+
fs.unlinkSync(resolvedDraftPath);
|
|
179
|
+
payload = {
|
|
180
|
+
ref: proposeItemRef(target.source, options.type, options.name),
|
|
181
|
+
content: draftContent,
|
|
187
182
|
};
|
|
188
183
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
184
|
+
else {
|
|
185
|
+
// B1: When interactive mode was used and stdout is empty, the agent did not
|
|
186
|
+
// write the draft file and stdout was not captured — surface an actionable error.
|
|
187
|
+
if (dispatch.interactive && (result.stdout ?? "") === "") {
|
|
188
|
+
return {
|
|
189
|
+
schemaVersion: 2,
|
|
190
|
+
ok: false,
|
|
191
|
+
reason: "parse_error",
|
|
192
|
+
error: "Agent did not write draft file and stdout was not captured (interactive mode). Check that the agent CLI understood the file-write instruction, or configure a headless profile with stdio: 'captured'.",
|
|
193
|
+
type: options.type,
|
|
194
|
+
name: options.name,
|
|
195
|
+
engine: engineName,
|
|
196
|
+
exitCode: result.exitCode,
|
|
197
|
+
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
198
|
+
...noticeFields(notices),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
payload = parseAgentProposalPayload(result.stdout ?? "");
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
return {
|
|
206
|
+
schemaVersion: 2,
|
|
207
|
+
ok: false,
|
|
208
|
+
reason: "parse_error",
|
|
209
|
+
error: err instanceof Error ? err.message : String(err),
|
|
210
|
+
type: options.type,
|
|
211
|
+
name: options.name,
|
|
212
|
+
engine: engineName,
|
|
213
|
+
exitCode: result.exitCode,
|
|
214
|
+
stdout: result.stdout,
|
|
215
|
+
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
216
|
+
...noticeFields(notices),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
217
219
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
220
|
+
payload = { ...payload, content: redactWithLoweredExecutionDispatchLease(lease, payload.content) };
|
|
221
|
+
// 6. Insert the proposal. Note: we allow the agent's `ref` to normalise the
|
|
222
|
+
// asset name (e.g. path-cleanup), but only after validating that the ref is
|
|
223
|
+
// well-formed and the type still matches the requested type.
|
|
224
|
+
const expectedRef = proposeItemRef(target.source, options.type, options.name);
|
|
225
|
+
let ref = expectedRef;
|
|
226
|
+
if (payload.ref) {
|
|
227
|
+
let parsedRef;
|
|
228
|
+
try {
|
|
229
|
+
parsedRef = parseRefInput(payload.ref);
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
return {
|
|
233
|
+
schemaVersion: 2,
|
|
234
|
+
ok: false,
|
|
235
|
+
reason: "parse_error",
|
|
236
|
+
error: err instanceof Error ? err.message : String(err),
|
|
237
|
+
type: options.type,
|
|
238
|
+
name: options.name,
|
|
239
|
+
engine: engineName,
|
|
240
|
+
exitCode: result.exitCode,
|
|
241
|
+
stdout: result.stdout,
|
|
242
|
+
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
243
|
+
...noticeFields(notices),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
if (parsedRef.type !== options.type) {
|
|
247
|
+
return {
|
|
248
|
+
schemaVersion: 2,
|
|
249
|
+
ok: false,
|
|
250
|
+
reason: "parse_error",
|
|
251
|
+
error: `Agent returned ref type ${parsedRef.type} but expected ${options.type}`,
|
|
252
|
+
type: options.type,
|
|
253
|
+
name: options.name,
|
|
254
|
+
engine: engineName,
|
|
255
|
+
exitCode: result.exitCode,
|
|
256
|
+
stdout: result.stdout,
|
|
257
|
+
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
258
|
+
...noticeFields(notices),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
ref = proposeItemRef(target.source, parsedRef.type, parsedRef.name);
|
|
231
262
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
263
|
+
const createInput = {
|
|
264
|
+
ref,
|
|
265
|
+
source: "propose",
|
|
266
|
+
sourceRun: `propose-${Date.now()}`,
|
|
267
|
+
target,
|
|
268
|
+
// User-initiated proposals always bypass dedup/cooldown guards — the
|
|
269
|
+
// operator is explicitly asking for a new proposal.
|
|
270
|
+
force: true,
|
|
271
|
+
payload: {
|
|
272
|
+
content: payload.content,
|
|
273
|
+
...(payload.frontmatter ? { frontmatter: payload.frontmatter } : {}),
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
const proposalResult = createProposal(stash, createInput, options.ctx);
|
|
277
|
+
// With force:true, the result is always a Proposal (never skipped).
|
|
278
|
+
if (isProposalSkipped(proposalResult)) {
|
|
279
|
+
// Should never happen when force:true, but be defensive.
|
|
280
|
+
throw new Error(`Unexpected skip in propose command: ${proposalResult.message}`);
|
|
245
281
|
}
|
|
246
|
-
|
|
282
|
+
const proposal = proposalResult;
|
|
283
|
+
return {
|
|
284
|
+
schemaVersion: 2,
|
|
285
|
+
ok: true,
|
|
286
|
+
proposal,
|
|
287
|
+
ref: proposal.ref,
|
|
288
|
+
engine: engineName,
|
|
289
|
+
durationMs: result.durationMs,
|
|
290
|
+
...noticeFields(notices),
|
|
291
|
+
};
|
|
247
292
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
source: "propose",
|
|
251
|
-
sourceRun: `propose-${Date.now()}`,
|
|
252
|
-
target,
|
|
253
|
-
// User-initiated proposals always bypass dedup/cooldown guards — the
|
|
254
|
-
// operator is explicitly asking for a new proposal.
|
|
255
|
-
force: true,
|
|
256
|
-
payload: {
|
|
257
|
-
content: payload.content,
|
|
258
|
-
...(payload.frontmatter ? { frontmatter: payload.frontmatter } : {}),
|
|
259
|
-
},
|
|
260
|
-
};
|
|
261
|
-
const proposalResult = createProposal(stash, createInput, options.ctx);
|
|
262
|
-
// With force:true, the result is always a Proposal (never skipped).
|
|
263
|
-
if (isProposalSkipped(proposalResult)) {
|
|
264
|
-
// Should never happen when force:true, but be defensive.
|
|
265
|
-
throw new Error(`Unexpected skip in propose command: ${proposalResult.message}`);
|
|
293
|
+
finally {
|
|
294
|
+
disposeLoweredExecutionDispatchLease(lease);
|
|
266
295
|
}
|
|
267
|
-
const proposal = proposalResult;
|
|
268
|
-
return {
|
|
269
|
-
schemaVersion: 2,
|
|
270
|
-
ok: true,
|
|
271
|
-
proposal,
|
|
272
|
-
ref: proposal.ref,
|
|
273
|
-
engine: engineName,
|
|
274
|
-
durationMs: result.durationMs,
|
|
275
|
-
};
|
|
276
296
|
}
|