akm-cli 0.9.31 → 0.10.26101002-alpha
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 +265 -0
- package/STABILITY.md +79 -53
- package/dist/api-node.mjs +20 -0
- package/dist/api.d.ts +23 -0
- package/dist/api.js +45 -0
- package/dist/assets/hints/cli-hints-full.md +13 -27
- package/dist/assets/hints/cli-hints-short.md +1 -1
- package/dist/assets/improve-strategies/default.json +3 -3
- package/dist/assets/prompts/consolidate-pair.md +9 -7
- package/dist/cli/shared.js +31 -48
- package/dist/cli/unknown-flags.js +6 -43
- package/dist/cli.js +8 -34
- package/dist/commands/agent/contribute-cli.js +1 -1
- package/dist/commands/completions.js +1 -2
- package/dist/commands/config-cli.js +5 -28
- package/dist/commands/env/env-cli.js +5 -5
- package/dist/commands/env/secret-cli.js +2 -2
- package/dist/commands/health/checks.js +41 -16
- package/dist/commands/health/plugin-staleness.js +52 -22
- package/dist/commands/improve/autonomy-gate.js +5 -3
- package/dist/commands/improve/consolidate/pair-pass.js +7 -1
- package/dist/commands/improve/consolidate.js +6 -35
- package/dist/commands/improve/distill/lesson-update.js +91 -0
- package/dist/commands/improve/distill-guards.js +1 -43
- package/dist/commands/improve/distill.js +140 -20
- package/dist/commands/improve/eligibility.js +14 -1
- package/dist/commands/improve/extract-cli.js +1 -1
- package/dist/commands/improve/improve-cli.js +87 -102
- package/dist/commands/improve/improve-strategies.js +8 -12
- package/dist/commands/improve/improve.js +2 -2
- package/dist/commands/improve/loop-stages.js +0 -1
- package/dist/commands/improve/planner.js +0 -1
- package/dist/commands/improve/preparation.js +40 -99
- package/dist/commands/improve/proactive-maintenance.js +2 -2
- package/dist/commands/improve/reflect-noise.js +3 -55
- package/dist/commands/improve/reflect.js +3 -8
- package/dist/commands/improve/retrieval-scope.js +2 -2
- package/dist/commands/improve/salience.js +2 -9
- package/dist/commands/improve/stage.js +14 -9
- package/dist/commands/lint/index.js +5 -20
- package/dist/commands/observability-cli.js +3 -9
- package/dist/commands/proposal/drain.js +39 -6
- package/dist/commands/proposal/proposal-cli.js +11 -31
- package/dist/commands/proposal/repository.js +3 -3
- package/dist/commands/read/knowledge.js +3 -3
- package/dist/commands/read/remember-cli.js +0 -13
- package/dist/commands/read/search-cli.js +29 -97
- package/dist/commands/read/search.js +0 -11
- package/dist/commands/read/show.js +0 -19
- package/dist/commands/sources/plugin-upgrade.js +164 -101
- package/dist/commands/sources/sources-cli.js +1 -15
- package/dist/commands/sources/stash-cli.js +4 -12
- package/dist/commands/tasks/tasks-cli.js +4 -115
- package/dist/commands/workflow/plan.js +11 -33
- package/dist/commands/workflow-cli.js +2 -7
- package/dist/core/adapter/adapter-ids.js +1 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
- package/dist/core/adapter/adapters/akm-adapter.js +9 -48
- package/dist/core/adapter/adapters/akm-lint.js +10 -26
- package/dist/core/adapter/adapters/akm-metadata.js +2 -72
- package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
- package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
- package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
- package/dist/core/adapter/recognize-match.js +3 -4
- package/dist/core/common.js +18 -2
- package/dist/core/config/config-schema.js +12 -15
- package/dist/core/config/config-types.js +6 -15
- package/dist/core/config/config-walker.js +6 -23
- package/dist/core/config/config.js +17 -80
- package/dist/core/config/engine-semantics.js +7 -3
- package/dist/core/config/schema/engines.js +7 -7
- package/dist/core/config/schema/improve-processes.js +8 -61
- package/dist/core/config/schema/improve.js +2 -21
- package/dist/core/config/schema/index-config.js +6 -39
- package/dist/core/env-secret-ref.js +2 -45
- package/dist/core/errors.js +1 -2
- package/dist/core/extra-params.js +2 -86
- package/dist/core/improve-result.js +11 -1
- package/dist/core/mutation-target.js +2 -2
- package/dist/core/recognition-util.js +4 -5
- package/dist/core/warn.js +21 -4
- package/dist/core/write-source.js +3 -3
- package/dist/execution/target-ref.js +1 -2
- package/dist/indexer/search/db-search.js +4 -19
- package/dist/indexer/search/fts-query.js +0 -19
- package/dist/integrations/agent/engine-resolution.js +5 -2
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +41 -98
- package/dist/integrations/agent/request-lowering.js +3 -3
- package/dist/integrations/harnesses/aider/index.js +5 -0
- package/dist/integrations/harnesses/amazonq/index.js +1 -0
- package/dist/integrations/harnesses/claude/config-import.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +5 -0
- package/dist/integrations/harnesses/codex/index.js +1 -0
- package/dist/integrations/harnesses/copilot/index.js +1 -0
- package/dist/integrations/harnesses/gemini/index.js +1 -0
- package/dist/integrations/harnesses/index.js +18 -39
- package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
- package/dist/integrations/harnesses/opencode/config-import.js +121 -52
- package/dist/integrations/harnesses/opencode/index.js +22 -0
- package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
- package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
- package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
- package/dist/integrations/harnesses/opencode/session-log.js +104 -115
- package/dist/integrations/harnesses/opencode/version.js +98 -0
- package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +228 -0
- package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
- package/dist/integrations/harnesses/openhands/index.js +1 -0
- package/dist/integrations/harnesses/pi/index.js +1 -0
- package/dist/integrations/harnesses/shared.js +2 -0
- package/dist/integrations/harnesses/types.js +2 -0
- package/dist/llm/client.js +41 -11
- package/dist/output/cli-hints.js +1 -1
- package/dist/output/context.js +10 -19
- package/dist/output/format-exempt.js +5 -8
- package/dist/output/shapes/helpers.js +1 -22
- package/dist/output/shapes/passthrough.js +0 -1
- package/dist/output/shapes.js +3 -31
- package/dist/output/stdout.js +5 -1
- package/dist/output/text/command-format.js +6 -1
- package/dist/output/text/workflow-format.js +4 -22
- package/dist/scripts/akm-migrate-node.js +13049 -14013
- package/dist/scripts/akm-migrate.js +16316 -17276
- package/dist/setup/detect.js +10 -4
- package/dist/setup/harness-config-import.js +5 -14
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +12 -13
- package/dist/storage/repositories/task-history-repository.js +0 -5
- package/dist/storage/repositories/workflow-runs-repository.js +5 -15
- package/dist/tasks/embedded.js +2 -1
- package/dist/tasks/run/task-history.js +0 -2
- package/dist/tasks/schedule-gates.js +39 -0
- package/dist/tasks/scheduler-binding.js +0 -16
- package/dist/tasks/scheduler-sync.js +3 -97
- package/dist/tasks/source/bounded-document.js +1 -1
- package/dist/tasks/source/task-source-v4.js +2 -12
- package/dist/tasks/task-run-reserved-flags.js +2 -31
- package/dist/workflows/authoring/authoring.js +6 -6
- package/dist/workflows/compile.js +8 -65
- package/dist/workflows/exec/child-workflow.js +22 -3
- package/dist/workflows/exec/native-executor.js +12 -147
- package/dist/workflows/exec/run-workflow.js +31 -103
- package/dist/workflows/exec/step-work.js +9 -178
- package/dist/workflows/exec/unit-dispatch.js +0 -10
- package/dist/workflows/freeze/environment.js +3 -44
- package/dist/workflows/freeze/freeze.js +8 -41
- package/dist/workflows/freeze/targets/child-workflow.js +27 -63
- package/dist/workflows/freeze/targets/command.js +2 -16
- package/dist/workflows/freeze/targets/shell.js +0 -2
- package/dist/workflows/freeze/task-bindings.js +2 -28
- package/dist/workflows/ir/params.js +12 -2
- package/dist/workflows/parser.js +82 -232
- package/dist/workflows/plan.js +1 -1
- package/dist/workflows/renderer.js +10 -19
- package/dist/workflows/runtime/run-plan.js +11 -53
- package/dist/workflows/runtime/runs.js +4 -27
- package/dist/workflows/source-files.js +12 -16
- package/dist/workflows/source-semantics.js +1 -93
- package/docs/README.md +1 -1
- package/docs/agents/README.md +3 -3
- package/docs/agents/agent-install.md +1 -1
- package/docs/architecture/adapters.md +17 -31
- package/docs/architecture/architecture.md +4 -5
- package/docs/architecture/improvement.md +52 -21
- package/docs/architecture/internals/improve-workflow.md +15 -8
- package/docs/architecture/internals/indexing.md +1 -1
- package/docs/architecture/internals/search.md +1 -2
- package/docs/architecture/internals/storage-locations.md +5 -5
- package/docs/architecture/persisted-data-compat.md +13 -4
- package/docs/architecture/specs/0.9.0-decisions.md +6 -2
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +2 -2
- package/docs/architecture/specs/workflow-format-unification.md +1 -6
- package/docs/architecture/testing/manual-testing-checklist.md +20 -29
- package/docs/architecture/testing/task-workflow-manual-tests.md +106 -203
- package/docs/architecture/testing/testing-workflow.md +1 -1
- package/docs/architecture/workflow-engine.md +5 -56
- package/docs/guides/author-workflows.md +39 -69
- package/docs/guides/capture-knowledge.md +1 -1
- package/docs/guides/claude-code-vs-akm-workflows.md +1 -2
- package/docs/guides/discover-and-load.md +4 -4
- package/docs/guides/getting-started.md +1 -1
- package/docs/guides/improve-the-library.md +7 -7
- package/docs/guides/recipes/headless-install.md +2 -2
- package/docs/guides/run-workflows.md +1 -1
- package/docs/guides/use-with-any-agent.md +49 -4
- package/docs/integration/bundling-akm.md +7 -6
- package/docs/maintainers/curate-workmap.md +1 -2
- package/docs/maintainers/release-checklist.md +30 -1
- package/docs/posts/akm-command-tour.md +3 -3
- package/docs/product-surface.md +1 -1
- package/docs/reference/README.md +1 -0
- package/docs/reference/api.md +65 -0
- package/docs/reference/asset-types.md +3 -5
- package/docs/reference/bundle-types.md +2 -4
- package/docs/reference/cli.md +129 -171
- package/docs/reference/configuration.md +84 -19
- package/docs/reference/data-and-telemetry.md +1 -1
- package/docs/reference/env-and-secrets.md +2 -2
- package/docs/reference/supported-formats.md +3 -4
- package/docs/reference/tasks.md +12 -19
- package/docs/reference/website-sources.md +1 -1
- package/docs/reference/workflow-schema.md +89 -317
- package/docs/reference/workflows.md +20 -48
- package/package.json +12 -2
- package/schemas/akm-config.json +2 -243
- package/schemas/akm-task.json +2 -3
- package/schemas/akm-workflow.json +47 -84
- package/dist/assets/improve-strategies/catchup.json +0 -41
- package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
- package/dist/assets/improve-strategies/quick.json +0 -17
- package/dist/assets/improve-strategies/reflect-distill.json +0 -29
- package/dist/assets/improve-strategies/thorough.json +0 -49
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
- package/dist/cli/retired-commands.js +0 -118
- package/dist/commands/tasks/validate.js +0 -176
- package/dist/core/config/legacy-source-shape-shim.js +0 -117
- package/dist/integrations/harnesses/ids.js +0 -28
- package/dist/tasks/source/task-source-v3-frozen.js +0 -424
- package/dist/tasks/source/task-to-v4.js +0 -863
- package/dist/workflows/exec/worktree.js +0 -372
- package/dist/workflows/freeze/child-output-references.js +0 -83
- package/dist/workflows/freeze/identity.js +0 -22
- package/dist/workflows/freeze/targets/script.js +0 -50
- package/dist/workflows/freeze/targets/task.js +0 -124
- package/dist/workflows/github-yaml.js +0 -506
- package/dist/workflows/runtime/run-outputs.js +0 -80
|
@@ -54,8 +54,7 @@ const allowedTypesField = z.array(z.string().min(1)).optional();
|
|
|
54
54
|
const excludeRefPrefixesField = z.array(z.string().min(1)).optional();
|
|
55
55
|
/**
|
|
56
56
|
* Consolidate process: hard cap on memories processed per pass.
|
|
57
|
-
* Reflect
|
|
58
|
-
* proactiveMaintenance: fallback when `maxPerRun` is absent.
|
|
57
|
+
* Reflect: max refs processed (same as profile-level `limit`).
|
|
59
58
|
*/
|
|
60
59
|
const processLimitField = positiveInt.optional();
|
|
61
60
|
/**
|
|
@@ -90,19 +89,6 @@ const clsField = z
|
|
|
90
89
|
})
|
|
91
90
|
.passthrough()
|
|
92
91
|
.optional();
|
|
93
|
-
/**
|
|
94
|
-
* WS-3b: Distill→source fidelity check (step 10). After a distill proposal,
|
|
95
|
-
* check it against its cited source memories; a contradiction flag forces
|
|
96
|
-
* human review. Default OFF. Distill process only.
|
|
97
|
-
*/
|
|
98
|
-
const fidelityCheckField = z.object({ enabled: z.boolean().optional() }).passthrough().optional();
|
|
99
|
-
/**
|
|
100
|
-
* #639 — semantic value-floor filter for the `reflect` process. When
|
|
101
|
-
* enabled, proposals classified as "low-value" by the deterministic noise
|
|
102
|
-
* gate are deferred. DEFAULT OFF (absent / { enabled: false } = pre-#639
|
|
103
|
-
* byte-identical behaviour). Reflect process only.
|
|
104
|
-
*/
|
|
105
|
-
const lowValueFilterField = z.object({ enabled: z.boolean().optional() }).passthrough().optional();
|
|
106
92
|
/**
|
|
107
93
|
* The wording lists of reflect's pre-judge defect filter (`findReflectDefect`).
|
|
108
94
|
* Each list is optional: one that is set replaces that rule's default list, and
|
|
@@ -152,57 +138,28 @@ const triageJudgmentField = z
|
|
|
152
138
|
.union([z.boolean(), triageJudgmentObjectField])
|
|
153
139
|
.transform((value) => typeof value === "boolean" ? { enabled: value } : { ...value, enabled: value.enabled ?? true })
|
|
154
140
|
.optional();
|
|
155
|
-
/**
|
|
156
|
-
* WS-3b: Anti-collapse guard (step 8), consolidate process only: a small
|
|
157
|
-
* random (non-similarity-driven) fraction of the pool is mixed into the
|
|
158
|
-
* clustered order so consolidation is not purely rich-get-richer. Default ON
|
|
159
|
-
* (opt out via `enabled: false`); `randomClusterFraction` defaults to 0.05.
|
|
160
|
-
* The retired merge guards (`maxGeneration`, `lexicalDiversityCheck`,
|
|
161
|
-
* `mergeInformationFloor`, `minSpecificityRetention`) never refused a merge
|
|
162
|
-
* and are tolerated as unknown keys.
|
|
163
|
-
*/
|
|
164
|
-
const antiCollapseField = z
|
|
165
|
-
.object({
|
|
166
|
-
enabled: z.boolean().optional(),
|
|
167
|
-
randomClusterFraction: z.number().min(0).max(1).optional(),
|
|
168
|
-
})
|
|
169
|
-
.passthrough()
|
|
170
|
-
.optional();
|
|
171
141
|
const REFLECT_PROCESS_FIELDS = {
|
|
172
142
|
allowedTypes: allowedTypesField,
|
|
173
143
|
excludeRefPrefixes: excludeRefPrefixesField,
|
|
174
144
|
limit: processLimitField,
|
|
175
145
|
qualityGate: qualityGateField,
|
|
176
|
-
lowValueFilter: lowValueFilterField,
|
|
177
146
|
defectFilter: defectFilterField,
|
|
178
147
|
};
|
|
179
148
|
const DISTILL_PROCESS_FIELDS = {
|
|
180
149
|
allowedTypes: allowedTypesField,
|
|
181
|
-
limit: processLimitField,
|
|
182
150
|
qualityGate: qualityGateField,
|
|
183
151
|
// Skip distill entirely when reflect produced zero planned refs.
|
|
184
152
|
requirePlannedRefs: z.boolean().optional(),
|
|
185
153
|
cls: clsField,
|
|
186
|
-
fidelityCheck: fidelityCheckField,
|
|
187
154
|
};
|
|
188
155
|
const CONSOLIDATE_PROCESS_FIELDS = {
|
|
189
156
|
allowedTypes: allowedTypesField,
|
|
190
157
|
limit: processLimitField,
|
|
191
|
-
// Minimum eligible-memory pool size below which the consolidation pass skips
|
|
192
|
-
// entirely (emits `pool_below_min_size`). 0 disables the guard. Default 500.
|
|
193
|
-
minPoolSize: z.number().int().min(0).optional(),
|
|
194
158
|
maxChunkSize: z.number().int().min(1).max(50).optional(),
|
|
195
|
-
// Fallback p90 wall-clock time per consolidation chunk in seconds, used for
|
|
196
|
-
// cold-start budget estimation when no telemetry history exists. The actual
|
|
197
|
-
// p90 is derived from observed run durations once sufficient history
|
|
198
|
-
// accumulates; this value is only used on the very first run. Default 30s.
|
|
199
|
-
p90ChunkSecondsDefault: z.number().finite().positive().optional(),
|
|
200
|
-
antiCollapse: antiCollapseField,
|
|
201
159
|
};
|
|
202
160
|
const MEMORY_INFERENCE_PROCESS_FIELDS = {
|
|
203
161
|
// Minimum pending memory count to run the pass.
|
|
204
162
|
minPendingCount: z.number().int().min(0).optional(),
|
|
205
|
-
cls: clsField,
|
|
206
163
|
};
|
|
207
164
|
const EXTRACT_PROCESS_FIELDS = {
|
|
208
165
|
defaultSince: z.string().min(1).optional(),
|
|
@@ -241,10 +198,8 @@ const TRIAGE_PROCESS_FIELDS = {
|
|
|
241
198
|
const PROACTIVE_MAINTENANCE_PROCESS_FIELDS = {
|
|
242
199
|
// Staleness gate + rotation cooldown in days (default 30).
|
|
243
200
|
dueDays: z.number().int().min(0).optional(),
|
|
244
|
-
// Top-N bound per run (default
|
|
245
|
-
// when both are set.
|
|
201
|
+
// Top-N bound per run (default 15).
|
|
246
202
|
maxPerRun: positiveInt.optional(),
|
|
247
|
-
limit: processLimitField,
|
|
248
203
|
};
|
|
249
204
|
/** distill/consolidate are memory-only and never read `excludeRefPrefixes` (reflect only, R12). */
|
|
250
205
|
function rejectExcludeRefPrefixesOutsideReflect(value, ctx) {
|
|
@@ -306,8 +261,10 @@ export const ProactiveMaintenanceProcessConfigSchema = z
|
|
|
306
261
|
* "unknown enabled process" check below — an old config must keep loading
|
|
307
262
|
* (AGENTS.md "Reading persisted data"). `graphExtraction`: the LLM
|
|
308
263
|
* entity-graph extraction it ran was retired in 0.9.17-alpha.9.
|
|
264
|
+
* `feedbackDistillation`: a wrapper of `processes.distill.enabled`, removed in
|
|
265
|
+
* 0.8.0.
|
|
309
266
|
*/
|
|
310
|
-
const RETIRED_PROCESS_NAMES = new Set(["graphExtraction"]);
|
|
267
|
+
const RETIRED_PROCESS_NAMES = new Set(["graphExtraction", "feedbackDistillation"]);
|
|
311
268
|
const ImproveProfileProcessesSchema = z
|
|
312
269
|
.object({
|
|
313
270
|
reflect: ReflectProcessConfigSchema.optional(),
|
|
@@ -321,19 +278,9 @@ const ImproveProfileProcessesSchema = z
|
|
|
321
278
|
})
|
|
322
279
|
.passthrough()
|
|
323
280
|
.superRefine((val, ctx) => {
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
// doing nothing. Other unknown process keys remain preserved for
|
|
328
|
-
// cross-version compatibility, but an enabled one is rejected below because
|
|
329
|
-
// this version cannot execute it.
|
|
330
|
-
if ("feedbackDistillation" in val) {
|
|
331
|
-
ctx.addIssue({
|
|
332
|
-
code: z.ZodIssueCode.custom,
|
|
333
|
-
message: "feedbackDistillation was removed in 0.8.0 — use processes.distill.enabled instead. " +
|
|
334
|
-
"It now controls both the orchestration gate and the LLM-call gate.",
|
|
335
|
-
});
|
|
336
|
-
}
|
|
281
|
+
// Unknown process keys remain preserved for cross-version compatibility,
|
|
282
|
+
// but an enabled one is rejected below because this version cannot
|
|
283
|
+
// execute it.
|
|
337
284
|
for (const [name, process] of Object.entries(val)) {
|
|
338
285
|
if (!IMPROVE_PROCESS_NAMES.includes(name) &&
|
|
339
286
|
!RETIRED_PROCESS_NAMES.has(name) &&
|
|
@@ -3,33 +3,14 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
5
|
* Top-level `improve` config section (salience, state GC, strategies). Retired
|
|
6
|
-
* keys (`salience.replayBudget`, `collapseDetector`, `utilityDecay`) are
|
|
6
|
+
* keys (`salience.replayBudget`, `salienceThreshold`, `collapseDetector`, `utilityDecay`) are
|
|
7
7
|
* tolerated as unknown keys.
|
|
8
8
|
*/
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { ImproveProfileConfigSchema } from "./improve-processes.js";
|
|
11
11
|
import { engineName, nonNegativeNumber } from "./primitives.js";
|
|
12
12
|
// ── Improve top-level (event retention, salience, state GC) ────────────────
|
|
13
|
-
const ImproveSalienceSchema = z
|
|
14
|
-
.object({
|
|
15
|
-
/**
|
|
16
|
-
* WS-2 Part-V gate: enable the outcome-weight term in the salience projection.
|
|
17
|
-
* Default TRUE/absent (DEFAULT ON since the G2 saturation cap landed — see
|
|
18
|
-
* salience.ts): uses the WS-2 weights (w_e=0.25, w_o=0.15, w_r=0.60) so the
|
|
19
|
-
* prediction-error outcome signal shapes rankScore (the R1 loop-closure).
|
|
20
|
-
* Set to `false` to opt out and restore the WS-1 parity weights
|
|
21
|
-
* (w_e=0.30, w_r=0.70, w_o=0); the `outcome` sub-score is still computed
|
|
22
|
-
* and stored for observability in that mode.
|
|
23
|
-
*/
|
|
24
|
-
outcomeWeightEnabled: z.boolean().optional(),
|
|
25
|
-
/**
|
|
26
|
-
* Minimum encoding salience score [0, 1] for a zero-feedback asset to be
|
|
27
|
-
* admitted to the high-salience improve lane (#608).
|
|
28
|
-
* Default 0.75. Set to 1.0 to disable the lane entirely.
|
|
29
|
-
*/
|
|
30
|
-
salienceThreshold: z.number().min(0).max(1).optional(),
|
|
31
|
-
})
|
|
32
|
-
.passthrough();
|
|
13
|
+
const ImproveSalienceSchema = z.object({}).passthrough();
|
|
33
14
|
// #733 — orphan-GC pass (Workstream C, lean by design: one config gate).
|
|
34
15
|
// The pass ALWAYS runs and ALWAYS reports counts (via the `asset_state_gc`
|
|
35
16
|
// event); this gate controls ONLY whether it actually deletes rows whose
|
|
@@ -7,40 +7,14 @@
|
|
|
7
7
|
* change.
|
|
8
8
|
*/
|
|
9
9
|
import { z } from "zod";
|
|
10
|
-
import { warnOnce } from "../../warn.js";
|
|
11
10
|
import { engineName, LlmInvocationOverridesSchema, nonEmptyString, positiveInt } from "./primitives.js";
|
|
12
11
|
// ── Index / per-pass ────────────────────────────────────────────────────────
|
|
13
|
-
const INDEX_PASS_RETIRED_KEYS = new Set([
|
|
14
|
-
"endpoint",
|
|
15
|
-
"provider",
|
|
16
|
-
"apiKey",
|
|
17
|
-
"baseUrl",
|
|
18
|
-
"temperature",
|
|
19
|
-
"maxTokens",
|
|
20
|
-
"capabilities",
|
|
21
|
-
]);
|
|
22
12
|
/**
|
|
23
|
-
* Per-pass `index.<pass>` entry.
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* anywhere else in config.
|
|
13
|
+
* Per-pass `index.<pass>` entry. Unknown keys (including inline engine
|
|
14
|
+
* settings an earlier release carried) are kept and named by the config
|
|
15
|
+
* loader's schema walk like any other unknown key.
|
|
27
16
|
*/
|
|
28
|
-
export const IndexPassConfigSchema = z
|
|
29
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
30
|
-
return raw; // let z.object below produce the type error
|
|
31
|
-
}
|
|
32
|
-
const obj = raw;
|
|
33
|
-
let cleaned;
|
|
34
|
-
for (const key of Object.keys(obj)) {
|
|
35
|
-
const dotted = [...(ctx.path ?? []), key].join(".");
|
|
36
|
-
if (INDEX_PASS_RETIRED_KEYS.has(key)) {
|
|
37
|
-
warnOnce(`index-pass:retired:${dotted}`, `\`${dotted}\` is a retired engine setting and is ignored; select a named engine and use typed invocation fields instead.`);
|
|
38
|
-
cleaned ??= { ...obj };
|
|
39
|
-
delete cleaned[key];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return cleaned ?? raw;
|
|
43
|
-
}, z
|
|
17
|
+
export const IndexPassConfigSchema = z
|
|
44
18
|
.object({
|
|
45
19
|
engine: engineName.optional(),
|
|
46
20
|
model: nonEmptyString.optional(),
|
|
@@ -48,7 +22,7 @@ export const IndexPassConfigSchema = z.preprocess((raw, ctx) => {
|
|
|
48
22
|
enabled: z.boolean().optional(),
|
|
49
23
|
llm: LlmInvocationOverridesSchema.optional(),
|
|
50
24
|
})
|
|
51
|
-
.passthrough()
|
|
25
|
+
.passthrough();
|
|
52
26
|
const IndexDefaultsSchema = z
|
|
53
27
|
.object({
|
|
54
28
|
engine: engineName.optional(),
|
|
@@ -80,14 +54,7 @@ const IndexConfigRuntimeSchema = z.preprocess((raw, ctx) => {
|
|
|
80
54
|
}
|
|
81
55
|
if (typeof raw !== "object")
|
|
82
56
|
return raw;
|
|
83
|
-
let cleaned;
|
|
84
57
|
for (const [passName, value] of Object.entries(raw)) {
|
|
85
|
-
if (passName === "stalenessDetection") {
|
|
86
|
-
warnOnce("index:stalenessDetection", "`index.stalenessDetection` is a retired pass and is ignored.");
|
|
87
|
-
cleaned ??= { ...raw };
|
|
88
|
-
delete cleaned.stalenessDetection;
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
58
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
92
59
|
ctx.addIssue({
|
|
93
60
|
code: z.ZodIssueCode.custom,
|
|
@@ -96,7 +63,7 @@ const IndexConfigRuntimeSchema = z.preprocess((raw, ctx) => {
|
|
|
96
63
|
return raw;
|
|
97
64
|
}
|
|
98
65
|
}
|
|
99
|
-
return
|
|
66
|
+
return raw;
|
|
100
67
|
}, z
|
|
101
68
|
.object({
|
|
102
69
|
defaults: IndexDefaultsSchema.optional(),
|
|
@@ -70,50 +70,11 @@ export function listEnvsRecursive(listKeysFn, config = loadConfig()) {
|
|
|
70
70
|
}
|
|
71
71
|
return result;
|
|
72
72
|
}
|
|
73
|
-
/**
|
|
74
|
-
* The `vault` asset type was removed in 0.9.0. The env/secret input path no
|
|
75
|
-
* longer routes through the legacy stored-ref parser (which carries the removal
|
|
76
|
-
* signpost), so a `vault:`/`vault/` leading token would otherwise be silently
|
|
77
|
-
* qualified into an `env/vault:…` not-found. Detect it here and re-emit the
|
|
78
|
-
* migration signpost so 0.8→0.9 muscle memory still gets pointed at env/secret.
|
|
79
|
-
*/
|
|
80
|
-
function assertNotRemovedVaultRef(ref) {
|
|
81
|
-
const boundary = ref.indexOf("//");
|
|
82
|
-
const bare = boundary >= 0 ? ref.slice(boundary + 2) : ref;
|
|
83
|
-
if (/^vault[:/]/.test(bare.trim())) {
|
|
84
|
-
throw new UsageError("The `vault` asset type was removed in 0.9.0 — use `env/` (whole .env config) or `secrets/` (a single value).", "INVALID_FLAG_VALUE");
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Q-08 ruling: the pre-0.9.0 `type:name` ref grammar taught `env:<name>` /
|
|
89
|
-
* `secret:<name>` (help text and docs also implied `environment:`/`secrets:`
|
|
90
|
-
* variants) as the way to address a single env/secret. That grammar is GONE —
|
|
91
|
-
* NO alias, no re-acceptance (same rule as the retired `vault:` prefix above).
|
|
92
|
-
* Left unchecked, a colon-prefixed ref does not error here at all: it falls
|
|
93
|
-
* through to the "bare name" convenience below and gets silently qualified
|
|
94
|
-
* into a literal `env/env:name` (or `secrets/secret:name`) file that can never
|
|
95
|
-
* exist — a confusing not-found that hides the real mistake instead of naming
|
|
96
|
-
* it. Reject it here, loudly, before that happens.
|
|
97
|
-
*/
|
|
98
|
-
function assertNotColonRef(ref, aliases, replacement) {
|
|
99
|
-
const boundary = ref.indexOf("//");
|
|
100
|
-
const bare = (boundary >= 0 ? ref.slice(boundary + 2) : ref).trim();
|
|
101
|
-
const colon = bare.indexOf(":");
|
|
102
|
-
if (colon <= 0)
|
|
103
|
-
return;
|
|
104
|
-
const head = bare.slice(0, colon).toLowerCase();
|
|
105
|
-
if (!aliases.includes(head))
|
|
106
|
-
return;
|
|
107
|
-
const name = bare.slice(colon + 1);
|
|
108
|
-
throw new UsageError(`The \`${head}:\` ref spelling was removed in 0.9.0 — use the slash form instead: \`${replacement}${name}\`.`, "INVALID_FLAG_VALUE");
|
|
109
|
-
}
|
|
110
73
|
export function parseEnvRef(ref) {
|
|
111
74
|
// Accept a bare env name (`prod`, `sub/prod`) or the new-grammar
|
|
112
75
|
// `[bundle//]env/name` conceptId. A bare name's leading segment maps to no
|
|
113
76
|
// asset type, so it is qualified with the `env/` conceptId prefix; anything
|
|
114
77
|
// already a full new-grammar ref is parsed as-is.
|
|
115
|
-
assertNotRemovedVaultRef(ref);
|
|
116
|
-
assertNotColonRef(ref, ["env", "environment"], "env/");
|
|
117
78
|
return parseRefInput(isFullRefInput(ref) ? ref : `env/${ref}`);
|
|
118
79
|
}
|
|
119
80
|
export function findEnvSource(origin, type, name) {
|
|
@@ -152,10 +113,8 @@ export function makeEnvRef(name, source, config = loadConfig()) {
|
|
|
152
113
|
}
|
|
153
114
|
/**
|
|
154
115
|
* Resolve an env ref to an absolute `.env` path. Accepts the `env/<name>`
|
|
155
|
-
* conceptId (or a bare name, auto-qualified into it)
|
|
156
|
-
*
|
|
157
|
-
* silently resolved. The path is returned even when the file does not yet
|
|
158
|
-
* exist (so `create` writes under `env/`).
|
|
116
|
+
* conceptId (or a bare name, auto-qualified into it). The path is returned
|
|
117
|
+
* even when the file does not yet exist (so `create` writes under `env/`).
|
|
159
118
|
*/
|
|
160
119
|
export function resolveEnvPath(ref) {
|
|
161
120
|
const parsed = parseEnvRef(ref);
|
|
@@ -177,8 +136,6 @@ export function resolveEnvPath(ref) {
|
|
|
177
136
|
export function parseSecretRef(ref) {
|
|
178
137
|
// Same bare-name-vs-full-ref rule as parseEnvRef; a bare name is qualified
|
|
179
138
|
// with the `secrets/` conceptId prefix (secret's stash subdir).
|
|
180
|
-
assertNotRemovedVaultRef(ref);
|
|
181
|
-
assertNotColonRef(ref, ["secret", "secrets"], "secrets/");
|
|
182
139
|
return parseRefInput(isFullRefInput(ref) ? ref : `secrets/${ref}`);
|
|
183
140
|
}
|
|
184
141
|
export function makeSecretRef(name, source) {
|
package/dist/core/errors.js
CHANGED
|
@@ -38,8 +38,7 @@ const USAGE_HINTS = {
|
|
|
38
38
|
INVALID_FLAG_VALUE: "Run `akm <command> --help` to see accepted values.",
|
|
39
39
|
INVALID_SOURCE_VALUE: "Pick one of: local, registry, all, or a configured source name.",
|
|
40
40
|
INVALID_FORMAT_VALUE: "Pick one of: json, jsonl, yaml, text, md, html.",
|
|
41
|
-
INVALID_DETAIL_VALUE: "Pick one of: brief, normal, full
|
|
42
|
-
INVALID_SHAPE_VALUE: "Pick one of: human, agent, summary (summary falls back to agent, with a warning, on commands with no summary projection).",
|
|
41
|
+
INVALID_DETAIL_VALUE: "Pick one of: brief, normal, full, agent.",
|
|
43
42
|
INVALID_JSON_CONFIG_VALUE: 'Quote JSON values in your shell, for example: akm config set embedding \'{"endpoint":"http://localhost:11434/v1/embeddings","model":"nomic-embed-text"}\'.',
|
|
44
43
|
MISSING_OR_AMBIGUOUS_TARGET: "Use `akm bundle update --all` or pass a target like `akm bundle update npm:@scope/pkg` (not both).",
|
|
45
44
|
TARGET_NOT_UPDATABLE: "Run `akm bundle list` to view your sources, then retry with one of those values.",
|
|
@@ -1,7 +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 { isRecord } from "./common.js";
|
|
5
4
|
export const EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS = [
|
|
6
5
|
"model",
|
|
7
6
|
"messages",
|
|
@@ -31,8 +30,7 @@ const CREDENTIAL_KEYS = new Set(EXTRA_PARAMS_CREDENTIAL_KEYS);
|
|
|
31
30
|
// `EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS` rightly stops a provider extra from
|
|
32
31
|
// shadowing an AKM-managed field, but naming the rule without naming the fix
|
|
33
32
|
// leaves the reader stuck (#852). Every protected key gets a one-line remedy
|
|
34
|
-
// baked into its issue message
|
|
35
|
-
// are also eligible for the automatic config-load lift below.
|
|
33
|
+
// baked into its issue message.
|
|
36
34
|
/** normalizeExtraParamKey(key) -> the first-class engine field it shadows. */
|
|
37
35
|
const LEGACY_EXTRA_PARAMS_FIELD = {
|
|
38
36
|
model: "model",
|
|
@@ -41,16 +39,7 @@ const LEGACY_EXTRA_PARAMS_FIELD = {
|
|
|
41
39
|
enablethinking: "enableThinking",
|
|
42
40
|
reasoningeffort: "reasoningEffort",
|
|
43
41
|
};
|
|
44
|
-
/**
|
|
45
|
-
* Subset of {@link LEGACY_EXTRA_PARAMS_FIELD} that {@link liftLegacyEngineExtraParams}
|
|
46
|
-
* will move onto the first-class field automatically. `model` is deliberately
|
|
47
|
-
* excluded: unlike the others it was never a "no first-class field yet"
|
|
48
|
-
* workaround (`model` has always been required on an LLM engine), so a
|
|
49
|
-
* mismatch is far more likely a genuine mistake than a stale 0.9.1 config —
|
|
50
|
-
* it stays a hard rejection rather than being silently reinterpreted.
|
|
51
|
-
*/
|
|
52
|
-
const LIFTABLE_EXTRA_PARAMS_KEYS = new Set(["temperature", "maxtokens", "enablethinking", "reasoningeffort"]);
|
|
53
|
-
/** Remedies for protected keys with no scalar first-class field to lift onto. */
|
|
42
|
+
/** Remedies for protected keys with no scalar first-class field. */
|
|
54
43
|
const EXTRA_PARAMS_NO_FIELD_REMEDY = {
|
|
55
44
|
messages: "AKM builds the request messages internally — remove it from extraParams",
|
|
56
45
|
responseformat: "AKM controls the response format internally — remove it from extraParams",
|
|
@@ -117,76 +106,3 @@ export function formatExtraParamsIssue(label, issue) {
|
|
|
117
106
|
const suffix = issue.path.map((part) => (typeof part === "number" ? `[${part}]` : `.${part}`)).join("");
|
|
118
107
|
return `${label}${suffix} ${issue.message}`;
|
|
119
108
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Compute the legacy `extraParams` -> first-class-field lift for a raw
|
|
122
|
-
* parsed config object: a 0.9.1-shaped config using (e.g.)
|
|
123
|
-
* `extraParams.reasoning_effort` now needs `reasoningEffort` set instead,
|
|
124
|
-
* since that field became first-class — and therefore protected — in 0.9.2
|
|
125
|
-
* (#852, following #815).
|
|
126
|
-
*
|
|
127
|
-
* Pure: never touches the filesystem. Two callers use this differently:
|
|
128
|
-
* `akm migrate apply` (scripts/akm-migrate/migrate/config-extra-params.ts) uses the
|
|
129
|
-
* returned `config` to persist the rewrite to disk, once; `parseAndValidateConfigText`
|
|
130
|
-
* (src/core/config/config.ts) calls this only to detect whether a lift is
|
|
131
|
-
* needed and discards `config` — an unmigrated config fails closed there
|
|
132
|
-
* with a pointer to `akm migrate apply` rather than silently drifting from
|
|
133
|
-
* what's on disk. `conflicts` (an extraParams key and its first-class field
|
|
134
|
-
* set to different values) is a genuine authoring error in both callers and
|
|
135
|
-
* is never auto-resolved.
|
|
136
|
-
*/
|
|
137
|
-
export function liftLegacyEngineExtraParams(raw) {
|
|
138
|
-
const lifted = [];
|
|
139
|
-
const conflicts = [];
|
|
140
|
-
const rawEngines = raw.engines;
|
|
141
|
-
if (!isRecord(rawEngines)) {
|
|
142
|
-
return { config: raw, lifted, conflicts };
|
|
143
|
-
}
|
|
144
|
-
const engines = {};
|
|
145
|
-
let anyEngineChanged = false;
|
|
146
|
-
for (const [name, engineValue] of Object.entries(rawEngines)) {
|
|
147
|
-
if (!isRecord(engineValue) || !isRecord(engineValue.extraParams)) {
|
|
148
|
-
engines[name] = engineValue;
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
const engine = { ...engineValue };
|
|
152
|
-
const extraParams = { ...engineValue.extraParams };
|
|
153
|
-
let engineChanged = false;
|
|
154
|
-
for (const [rawKey, value] of Object.entries(engineValue.extraParams)) {
|
|
155
|
-
const normalized = normalizeExtraParamKey(rawKey);
|
|
156
|
-
if (!LIFTABLE_EXTRA_PARAMS_KEYS.has(normalized))
|
|
157
|
-
continue;
|
|
158
|
-
const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
|
|
159
|
-
if (!field)
|
|
160
|
-
continue;
|
|
161
|
-
const existing = engine[field];
|
|
162
|
-
if (existing !== undefined && existing !== value) {
|
|
163
|
-
conflicts.push({ engine: name, key: rawKey, field, extraParamsValue: value, fieldValue: existing });
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
delete extraParams[rawKey];
|
|
167
|
-
engineChanged = true;
|
|
168
|
-
if (existing === value) {
|
|
169
|
-
lifted.push(`engines.${name}.extraParams.${rawKey} is redundant — engines.${name}.${field} is already set to the same value; dropped the extraParams entry`);
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
engine[field] = value;
|
|
173
|
-
lifted.push(`engines.${name}.extraParams.${rawKey} -> engines.${name}.${field}`);
|
|
174
|
-
}
|
|
175
|
-
if (!engineChanged) {
|
|
176
|
-
engines[name] = engineValue;
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
anyEngineChanged = true;
|
|
180
|
-
if (Object.keys(extraParams).length > 0) {
|
|
181
|
-
engine.extraParams = extraParams;
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
delete engine.extraParams;
|
|
185
|
-
}
|
|
186
|
-
engines[name] = engine;
|
|
187
|
-
}
|
|
188
|
-
if (!anyEngineChanged) {
|
|
189
|
-
return { config: raw, lifted, conflicts };
|
|
190
|
-
}
|
|
191
|
-
return { config: { ...raw, engines }, lifted, conflicts };
|
|
192
|
-
}
|
|
@@ -126,6 +126,8 @@ function validateConsolidationPlan(value) {
|
|
|
126
126
|
]));
|
|
127
127
|
if (!isRecord(value.configured))
|
|
128
128
|
fail("plan.consolidation.configured must be an object");
|
|
129
|
+
// `minPoolSize` is no longer written (the minimum-pool guard was removed in 0.10, #1131); runs an
|
|
130
|
+
// older release persisted still carry it, ignored — AGENTS.md "Reading persisted data".
|
|
129
131
|
requireExactFields(value.configured, new Set(["enabled", "minPoolSize", "limit", "maxChunkSize"]));
|
|
130
132
|
if (value.configured.enabled !== undefined && typeof value.configured.enabled !== "boolean") {
|
|
131
133
|
fail("plan.consolidation.configured.enabled must be a boolean");
|
|
@@ -140,7 +142,8 @@ function validateConsolidationPlan(value) {
|
|
|
140
142
|
requireExactFields(value.effective, new Set(["enabled", "minPoolSize", "limit", "chunkSize"]));
|
|
141
143
|
if (typeof value.effective.enabled !== "boolean")
|
|
142
144
|
fail("plan.consolidation.effective.enabled must be a boolean");
|
|
143
|
-
|
|
145
|
+
if (value.effective.minPoolSize !== undefined)
|
|
146
|
+
requireCount(value.effective, "minPoolSize", "plan.consolidation.effective");
|
|
144
147
|
requireCount(value.effective, "chunkSize", "plan.consolidation.effective");
|
|
145
148
|
if (value.effective.limit !== undefined && typeof value.effective.limit !== "number") {
|
|
146
149
|
fail("plan.consolidation.effective.limit must be a number");
|
|
@@ -157,6 +160,9 @@ function validateConsolidationPlan(value) {
|
|
|
157
160
|
requireExactFields(value.gates, new Set(["profile", "minimumPool", "delta"]));
|
|
158
161
|
for (const gateName of ["profile", "minimumPool", "delta"]) {
|
|
159
162
|
const gate = value.gates[gateName];
|
|
163
|
+
// `minimumPool` is no longer written; only an older release's persisted plan has it.
|
|
164
|
+
if (gate === undefined && gateName === "minimumPool")
|
|
165
|
+
continue;
|
|
160
166
|
if (!isRecord(gate))
|
|
161
167
|
fail(`plan.consolidation.gates.${gateName} must be an object`);
|
|
162
168
|
requireExactFields(gate, new Set(["passed", "reason"]));
|
|
@@ -171,6 +177,8 @@ function validateProactivePlan(value) {
|
|
|
171
177
|
requireExactFields(value, new Set(["configured", "effective", "candidatePool", "dueTotal", "neverReflected", "selected", "selectedRefs"]));
|
|
172
178
|
if (!isRecord(value.configured))
|
|
173
179
|
fail("plan.proactive.configured must be an object");
|
|
180
|
+
// `limit` is no longer written (the `proactiveMaintenance.limit` alias of `maxPerRun` was removed in 0.10, #1091);
|
|
181
|
+
// runs an older release stored may carry it.
|
|
174
182
|
requireExactFields(value.configured, new Set(["dueDays", "maxPerRun", "limit"]));
|
|
175
183
|
for (const field of ["dueDays", "maxPerRun", "limit"]) {
|
|
176
184
|
if (value.configured[field] !== undefined && typeof value.configured[field] !== "number") {
|
|
@@ -424,6 +432,8 @@ function validateImprovePlan(value, dryRun, plannedRefNames) {
|
|
|
424
432
|
}
|
|
425
433
|
if (!isRecord(value.triage))
|
|
426
434
|
fail("plan.triage must be an object");
|
|
435
|
+
// `maxDiffLines` is no longer written (the triage config key was dropped before 0.10, #1091); runs an older
|
|
436
|
+
// release stored may carry it.
|
|
427
437
|
requireExactFields(value.triage, new Set(["enabled", "configuredMode", "mode", "maxAcceptsPerRun", "maxDiffLines"]));
|
|
428
438
|
if (typeof value.triage.enabled !== "boolean")
|
|
429
439
|
fail("plan.triage.enabled must be a boolean");
|
|
@@ -51,12 +51,12 @@ function resolveExplicitMutationTarget(config, explicitTarget, options) {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
-
* Reconcile a qualified mutation ref with the explicit target (`--
|
|
54
|
+
* Reconcile a qualified mutation ref with the explicit target (`--bundle`, or
|
|
55
55
|
* the `options.flag` the caller's command spells), then resolve the write
|
|
56
56
|
* destination.
|
|
57
57
|
*/
|
|
58
58
|
export function resolveMutationTarget(config, ref, explicitTarget, options = {}) {
|
|
59
|
-
const flag = options.flag ?? "--
|
|
59
|
+
const flag = options.flag ?? "--bundle";
|
|
60
60
|
const writeOptions = { requireWritable: options.requireWritable, flag };
|
|
61
61
|
const qualifiedTarget = ref.origin ? resolveBundleWriteTarget(config, ref.origin, writeOptions) : undefined;
|
|
62
62
|
const explicitResolved = explicitTarget
|
|
@@ -34,13 +34,12 @@ export const SCRIPT_EXTENSIONS = new Set([
|
|
|
34
34
|
".kts",
|
|
35
35
|
]);
|
|
36
36
|
/**
|
|
37
|
-
* Recognized workflow asset extensions.
|
|
38
|
-
*
|
|
39
|
-
* `workflows/<name>` refs resolve against this list.
|
|
37
|
+
* Recognized workflow asset extensions. `workflows/<name>` refs resolve against
|
|
38
|
+
* this list.
|
|
40
39
|
*/
|
|
41
|
-
export const WORKFLOW_EXTENSIONS = [".md"
|
|
40
|
+
export const WORKFLOW_EXTENSIONS = [".md"];
|
|
42
41
|
/**
|
|
43
|
-
* Strip
|
|
42
|
+
* Strip the recognized workflow extension (`.md`) from a workflow asset
|
|
44
43
|
* *name* so `foo` and `foo.md` collapse to one canonical identity — the same
|
|
45
44
|
* collapse `workflowSpec.toCanonicalName` performs on a resolved file path.
|
|
46
45
|
* Callers that turn a `workflows/<name>` ref into run identity (the
|
package/dist/core/warn.js
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
import fs from "node:fs";
|
|
16
16
|
import path from "node:path";
|
|
17
17
|
let quiet = false;
|
|
18
|
+
/** Calls inside {@link withQuiet}; counted so overlapping calls cannot leave the flag flipped. */
|
|
19
|
+
let quietScopes = 0;
|
|
18
20
|
let verbose = false;
|
|
19
21
|
let logFilePath;
|
|
20
22
|
let sinkOverride;
|
|
@@ -33,7 +35,22 @@ export function resetQuiet() {
|
|
|
33
35
|
quiet = false;
|
|
34
36
|
}
|
|
35
37
|
export function isQuiet() {
|
|
36
|
-
return quiet;
|
|
38
|
+
return quiet || quietScopes > 0;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Run `fn` with stderr diagnostics suppressed (the log file sink still
|
|
42
|
+
* receives them), then restore. For in-process callers (`src/api.ts`) that
|
|
43
|
+
* must stay silent without touching the host's `--quiet` state: a depth count
|
|
44
|
+
* rather than save/restore of the flag keeps overlapping async calls correct.
|
|
45
|
+
*/
|
|
46
|
+
export async function withQuiet(fn) {
|
|
47
|
+
quietScopes++;
|
|
48
|
+
try {
|
|
49
|
+
return await fn();
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
quietScopes--;
|
|
53
|
+
}
|
|
37
54
|
}
|
|
38
55
|
/**
|
|
39
56
|
* Set the verbose flag from a CLI flag. The `AKM_VERBOSE` env var, when set,
|
|
@@ -103,7 +120,7 @@ export function info(...args) {
|
|
|
103
120
|
return;
|
|
104
121
|
}
|
|
105
122
|
appendToLogFile("INFO", args);
|
|
106
|
-
if (!
|
|
123
|
+
if (!isQuiet()) {
|
|
107
124
|
console.warn(...args);
|
|
108
125
|
}
|
|
109
126
|
}
|
|
@@ -118,7 +135,7 @@ export function warn(...args) {
|
|
|
118
135
|
return;
|
|
119
136
|
}
|
|
120
137
|
appendToLogFile("WARN", args);
|
|
121
|
-
if (!
|
|
138
|
+
if (!isQuiet()) {
|
|
122
139
|
console.warn(...args);
|
|
123
140
|
}
|
|
124
141
|
}
|
|
@@ -148,7 +165,7 @@ export function error(...args) {
|
|
|
148
165
|
return;
|
|
149
166
|
}
|
|
150
167
|
appendToLogFile("ERROR", args);
|
|
151
|
-
if (!
|
|
168
|
+
if (!isQuiet()) {
|
|
152
169
|
console.error(...args);
|
|
153
170
|
}
|
|
154
171
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* The only module that branches on `source.kind` for writes. It does two
|
|
8
8
|
* things:
|
|
9
9
|
*
|
|
10
|
-
* 1. Resolve the destination: `--
|
|
10
|
+
* 1. Resolve the destination: `--bundle` → `defaultWriteTarget` → working
|
|
11
11
|
* stash (`defaultBundle`). `writable` defaults to true on `filesystem` and
|
|
12
12
|
* false on `git`; `website` / `npm` are never writable (the config loader
|
|
13
13
|
* rejects `writable: true` on them).
|
|
@@ -53,7 +53,7 @@ export function isWriteCapableSourceKind(kind) {
|
|
|
53
53
|
return kind === "filesystem" || kind === "git";
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
|
-
* Resolve the destination for a write: explicit `--
|
|
56
|
+
* Resolve the destination for a write: explicit `--bundle`, then
|
|
57
57
|
* `defaultWriteTarget`, then the working stash (`defaultBundle`). There is no
|
|
58
58
|
* fallback to the first writable source.
|
|
59
59
|
*/
|
|
@@ -61,7 +61,7 @@ export function resolveWriteTarget(akmConfig, explicitTarget, options = {}) {
|
|
|
61
61
|
const allConfiguredSources = resolveConfiguredSources(akmConfig);
|
|
62
62
|
const configuredSources = resolveActiveConfiguredSources(akmConfig);
|
|
63
63
|
const requireWritable = options.requireWritable !== false;
|
|
64
|
-
const flag = options.flag ?? "--
|
|
64
|
+
const flag = options.flag ?? "--bundle";
|
|
65
65
|
if (explicitTarget) {
|
|
66
66
|
const match = configuredSources.find((s) => s.name === explicitTarget);
|
|
67
67
|
if (!match) {
|
|
@@ -22,8 +22,7 @@
|
|
|
22
22
|
*
|
|
23
23
|
* Explicit non-goals (binding, spec §4.1): no GitHub locator grammar, no
|
|
24
24
|
* `akm/command` builtin special case, no resolution, no filesystem access, no
|
|
25
|
-
* guessing.
|
|
26
|
-
* `classifyWorkflowStepUses` in src/workflows/source-semantics.ts).
|
|
25
|
+
* guessing.
|
|
27
26
|
*/
|
|
28
27
|
import { bundleRefToString, parseBundleRef } from "../core/asset/asset-ref.js";
|
|
29
28
|
import { UsageError } from "../core/errors.js";
|