akm-cli 0.9.5 → 0.9.7

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.
Files changed (130) hide show
  1. package/CHANGELOG.md +295 -0
  2. package/dist/assets/hints/cli-hints-full.md +3 -3
  3. package/dist/assets/improve-strategies/catchup.json +40 -11
  4. package/dist/assets/improve-strategies/thorough.json +45 -7
  5. package/dist/assets/tasks/improve/akm-improve-frequent.yml +2 -2
  6. package/dist/commands/agent/contribute-cli.js +11 -0
  7. package/dist/commands/env/env-cli.js +1 -2
  8. package/dist/commands/env/secret-cli.js +1 -5
  9. package/dist/commands/feedback-cli.js +0 -4
  10. package/dist/commands/health/checks.js +0 -32
  11. package/dist/commands/health/surfaces.js +2 -2
  12. package/dist/commands/health.js +6 -15
  13. package/dist/commands/improve/autonomy-gate.js +1 -1
  14. package/dist/commands/improve/consolidate.js +25 -26
  15. package/dist/commands/improve/distill.js +2 -2
  16. package/dist/commands/improve/extract.js +8 -1
  17. package/dist/commands/improve/improve-cli.js +1 -1
  18. package/dist/commands/improve/improve-strategies.js +0 -4
  19. package/dist/commands/improve/improve.js +3 -5
  20. package/dist/commands/improve/locks.js +13 -5
  21. package/dist/commands/improve/loop-stages.js +8 -9
  22. package/dist/commands/improve/memory/memory-contradiction-detect.js +1 -19
  23. package/dist/commands/improve/memory/memory-improve.js +2 -1
  24. package/dist/commands/improve/outcome-loop.js +0 -6
  25. package/dist/commands/improve/preparation.js +1 -1
  26. package/dist/commands/improve/reflect.js +21 -10
  27. package/dist/commands/lint/base-linter.js +141 -18
  28. package/dist/commands/lint/index.js +21 -10
  29. package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -7
  30. package/dist/commands/read/curate.js +47 -0
  31. package/dist/commands/read/search-cli.js +24 -1
  32. package/dist/commands/sources/bundle-config-ops.js +9 -4
  33. package/dist/commands/sources/info.js +14 -10
  34. package/dist/commands/tasks/tasks.js +12 -16
  35. package/dist/commands/workflow-cli.js +2 -2
  36. package/dist/core/asset/asset-placement.js +13 -2
  37. package/dist/core/asset/frontmatter.js +116 -0
  38. package/dist/core/asset/memory-archive.js +97 -0
  39. package/dist/core/common.js +61 -24
  40. package/dist/core/config/config-io.js +2 -2
  41. package/dist/core/config/config-sources.js +32 -2
  42. package/dist/core/config/config.js +1 -1
  43. package/dist/core/config/engine-semantics.js +0 -2
  44. package/dist/core/config/schema/engines.js +9 -7
  45. package/dist/core/config/schema/primitives.js +0 -5
  46. package/dist/core/config/schema/search.js +2 -1
  47. package/dist/core/file-lock.js +2 -1
  48. package/dist/core/maintenance-barrier.js +2 -14
  49. package/dist/core/paths.js +0 -3
  50. package/dist/core/redaction.js +2 -2
  51. package/dist/core/spawn-env.js +8 -12
  52. package/dist/core/state/migrations.js +1 -12
  53. package/dist/core/state-db.js +9 -27
  54. package/dist/core/write-source.js +12 -19
  55. package/dist/execution/directory-identity.js +36 -10
  56. package/dist/indexer/graph/graph-boost.js +0 -4
  57. package/dist/indexer/index-writer-lock.js +43 -24
  58. package/dist/indexer/index-written-assets.js +5 -6
  59. package/dist/indexer/indexer.js +2 -39
  60. package/dist/indexer/materialize-embeddings.js +85 -41
  61. package/dist/indexer/search/db-search.js +15 -48
  62. package/dist/indexer/search/ranking-contributors.js +0 -25
  63. package/dist/indexer/search/ranking.js +3 -13
  64. package/dist/integrations/agent/builder-shared.js +0 -25
  65. package/dist/integrations/agent/model-map.js +2 -60
  66. package/dist/integrations/harnesses/aider/agent-builder.js +1 -3
  67. package/dist/integrations/harnesses/amazonq/agent-builder.js +2 -7
  68. package/dist/integrations/harnesses/claude/agent-builder.js +1 -4
  69. package/dist/integrations/harnesses/codex/agent-builder.js +1 -4
  70. package/dist/integrations/harnesses/copilot/agent-builder.js +2 -6
  71. package/dist/integrations/harnesses/gemini/agent-builder.js +2 -7
  72. package/dist/integrations/harnesses/opencode/agent-builder.js +1 -4
  73. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +2 -16
  74. package/dist/integrations/harnesses/openhands/agent-builder.js +1 -3
  75. package/dist/integrations/harnesses/pi/agent-builder.js +2 -4
  76. package/dist/integrations/session-logs/index.js +0 -9
  77. package/dist/llm/client.js +75 -42
  78. package/dist/llm/embedder.js +7 -3
  79. package/dist/llm/embedders/remote.js +141 -42
  80. package/dist/registry/network.js +5 -37
  81. package/dist/runtime.js +2 -10
  82. package/dist/scripts/akm-migrate-node.js +73 -133
  83. package/dist/scripts/akm-migrate.js +73 -133
  84. package/dist/setup/engine-config.js +2 -5
  85. package/dist/setup/registry-stash-loader.js +0 -8
  86. package/dist/setup/setup.js +9 -46
  87. package/dist/setup/steps/connection-shared.js +10 -13
  88. package/dist/sources/providers/git-install.js +1 -1
  89. package/dist/sources/snapshot-fetchers/website-ingest.js +126 -0
  90. package/dist/storage/engines/sqlite-migrations.js +20 -1
  91. package/dist/storage/repositories/index-connection.js +45 -3
  92. package/dist/storage/repositories/index-entries-repository.js +0 -15
  93. package/dist/tasks/backends/cron.js +49 -9
  94. package/dist/tasks/backends/launchd.js +15 -20
  95. package/dist/tasks/backends/schtasks.js +18 -8
  96. package/dist/tasks/resolve-akm-bin.js +17 -2
  97. package/dist/tasks/run/run-native-task.js +8 -6
  98. package/dist/tasks/scheduler-invocation.js +8 -1
  99. package/dist/tasks/source/bounded-document.js +2 -4
  100. package/dist/tasks/source/parse-task-source.js +23 -9
  101. package/dist/tasks/source/task-source-v3-frozen.js +5 -7
  102. package/dist/tasks/source/task-source-v4.js +5 -10
  103. package/dist/tasks/source/task-to-v3.js +5 -10
  104. package/dist/tasks/source/task-to-v4.js +1 -4
  105. package/dist/tasks/source-v3.js +6 -6
  106. package/dist/workflows/exec/native-executor.js +21 -31
  107. package/dist/workflows/exec/run-workflow.js +5 -6
  108. package/dist/workflows/exec/scheduler.js +3 -19
  109. package/dist/workflows/exec/step-work.js +1 -4
  110. package/dist/workflows/exec/unit-dispatch.js +2 -2
  111. package/dist/workflows/exec/worktree.js +1 -13
  112. package/dist/workflows/freeze/targets/child-workflow.js +2 -10
  113. package/dist/workflows/ir/plan-hash.js +4 -6
  114. package/dist/workflows/ir/schema-v4.js +0 -12
  115. package/dist/workflows/ir/schema.js +20 -31
  116. package/dist/workflows/parser.js +11 -52
  117. package/dist/workflows/renderer.js +2 -3
  118. package/dist/workflows/resource-limits.js +11 -41
  119. package/dist/workflows/runtime/runs.js +3 -4
  120. package/dist/workflows/source-ir/schema.js +14 -30
  121. package/dist/workflows/validator.js +1 -7
  122. package/docs/reference/cli.md +5 -1
  123. package/docs/reference/configuration.md +1 -1
  124. package/package.json +1 -1
  125. package/schemas/akm-config.json +4 -23
  126. package/schemas/akm-task.json +1 -2
  127. package/schemas/akm-workflow.json +1 -13
  128. package/dist/assets/improve-strategies/frequent.json +0 -15
  129. package/dist/assets/improve-strategies/memory-focus.json +0 -15
  130. package/dist/indexer/search/semantic-status.js +0 -142
@@ -14,7 +14,7 @@ import { validateExtraParams } from "../../core/extra-params.js";
14
14
  import { checkJsonSchemaDefinition } from "../../core/json-schema.js";
15
15
  import { parseReference } from "../program/expressions.js";
16
16
  import { PROGRAM_RETRY_REASONS } from "../program/schema.js";
17
- import { jsonBytes, utf8Bytes, WORKFLOW_ENGINE_NAME_PATTERN, WORKFLOW_ENV_VAR_NAME_PATTERN, WORKFLOW_MAX_CONCURRENCY, WORKFLOW_MAX_ENGINE_NAME_LENGTH, WORKFLOW_MAX_EXEC_ARG_BYTES, WORKFLOW_MAX_EXEC_ARGV, WORKFLOW_MAX_EXEC_CWD_LENGTH, WORKFLOW_MAX_EXEC_PASS_ENV, WORKFLOW_MAX_EXTRA_PARAMS_BYTES, WORKFLOW_MAX_GATE_LOOPS, WORKFLOW_MAX_INPUTS, WORKFLOW_MAX_MAP_EXPANSION, WORKFLOW_MAX_OUTPUTS, WORKFLOW_MAX_PARAMS, WORKFLOW_MAX_RETRIES, WORKFLOW_MAX_ROUTE_BRANCHES, WORKFLOW_MAX_SCHEMA_BYTES, WORKFLOW_MAX_TIMEOUT_MS, } from "../resource-limits.js";
17
+ import { jsonBytes, WORKFLOW_ENGINE_NAME_PATTERN, WORKFLOW_ENV_VAR_NAME_PATTERN, WORKFLOW_MAX_CONCURRENCY, WORKFLOW_MAX_ENGINE_NAME_LENGTH, WORKFLOW_MAX_EXTRA_PARAMS_BYTES, WORKFLOW_MAX_SCHEMA_BYTES, WORKFLOW_MAX_TIMEOUT_MS, } from "../resource-limits.js";
18
18
  import { compareWorkflowSourceCodePoints } from "./compare.js";
19
19
  import { canonicalizeWorkflowCron, canonicalizeWorkflowRun, canonicalizeWorkflowWorkingDirectory, classifyWorkflowStepUses, rejectNulInArgv, validateWorkflowBuiltinCommand, WorkflowSourceSemanticError, } from "./semantics.js";
20
20
  export const WORKFLOW_SOURCE_IR_VERSION = 1;
@@ -255,7 +255,7 @@ function validateStep(value, jobId, index, stepIds, options) {
255
255
  }
256
256
  validateMap(step.map, `step ${id} map`);
257
257
  validateRoute(step.route, `step ${id} route`);
258
- optionalStringList(step.inputs, `step ${id} inputs`, WORKFLOW_MAX_INPUTS);
258
+ optionalStringList(step.inputs, `step ${id} inputs`, Infinity);
259
259
  if (Array.isArray(step.inputs)) {
260
260
  for (const [inputIndex, input] of step.inputs.entries())
261
261
  validateReference(input, `step ${id} inputs[${inputIndex}]`);
@@ -277,12 +277,7 @@ function validateExec(value, location, options) {
277
277
  return;
278
278
  const exec = record(value, location);
279
279
  keys(exec, ["command", "cwd", "passEnv"], location);
280
- stringList(exec.command, `${location}.command`, WORKFLOW_MAX_EXEC_ARGV, false);
281
- for (const [index, argument] of exec.command.entries()) {
282
- if (utf8Bytes(argument) > WORKFLOW_MAX_EXEC_ARG_BYTES) {
283
- fail(`${location}.command[${index}] exceeds ${WORKFLOW_MAX_EXEC_ARG_BYTES} bytes`);
284
- }
285
- }
280
+ stringList(exec.command, `${location}.command`, Infinity, false);
286
281
  try {
287
282
  rejectNulInArgv(exec.command);
288
283
  }
@@ -291,9 +286,6 @@ function validateExec(value, location, options) {
291
286
  }
292
287
  optionalString(exec.cwd, `${location}.cwd`);
293
288
  if (exec.cwd !== undefined) {
294
- if (exec.cwd.length > WORKFLOW_MAX_EXEC_CWD_LENGTH) {
295
- fail(`${location}.cwd exceeds ${WORKFLOW_MAX_EXEC_CWD_LENGTH} characters`);
296
- }
297
289
  try {
298
290
  exec.cwd = canonicalizeWorkflowWorkingDirectory(exec.cwd, options.workspaceRoot);
299
291
  }
@@ -302,7 +294,7 @@ function validateExec(value, location, options) {
302
294
  }
303
295
  }
304
296
  if (exec.passEnv !== undefined) {
305
- stringList(exec.passEnv, `${location}.passEnv`, WORKFLOW_MAX_EXEC_PASS_ENV, false);
297
+ stringList(exec.passEnv, `${location}.passEnv`, Infinity, false);
306
298
  }
307
299
  if (Array.isArray(exec.passEnv)) {
308
300
  for (const name of exec.passEnv) {
@@ -359,8 +351,8 @@ function validateRetry(value, location) {
359
351
  return;
360
352
  const retry = record(value, location);
361
353
  keys(retry, ["max", "on"], location);
362
- if (!Number.isSafeInteger(retry.max) || retry.max < 0 || retry.max > WORKFLOW_MAX_RETRIES) {
363
- fail(`${location}.max must be an integer from 0 through ${WORKFLOW_MAX_RETRIES}`);
354
+ if (!Number.isSafeInteger(retry.max) || retry.max < 0) {
355
+ fail(`${location}.max must be a non-negative integer`);
364
356
  }
365
357
  stringList(retry.on, `${location}.on`, PROGRAM_RETRY_REASONS.length, false);
366
358
  for (const reason of retry.on) {
@@ -393,10 +385,8 @@ function validateRoute(value, location) {
393
385
  keys(route, ["input", "branches", "defaultStepId"], location);
394
386
  nonEmptyString(route.input, `${location}.input`);
395
387
  validateReference(route.input, `${location}.input`);
396
- if (!Array.isArray(route.branches) ||
397
- route.branches.length === 0 ||
398
- route.branches.length > WORKFLOW_MAX_ROUTE_BRANCHES) {
399
- fail(`${location}.branches must contain 1 through ${WORKFLOW_MAX_ROUTE_BRANCHES} entries`);
388
+ if (!Array.isArray(route.branches) || route.branches.length === 0) {
389
+ fail(`${location}.branches must be a non-empty array`);
400
390
  }
401
391
  const matches = new Set();
402
392
  for (const [index, value] of route.branches.entries()) {
@@ -416,11 +406,8 @@ function validateGate(value, location) {
416
406
  return;
417
407
  const gate = record(value, location);
418
408
  keys(gate, ["maxLoops", "rubric"], location);
419
- if (gate.maxLoops !== undefined &&
420
- (!Number.isSafeInteger(gate.maxLoops) ||
421
- gate.maxLoops < 1 ||
422
- gate.maxLoops > WORKFLOW_MAX_GATE_LOOPS)) {
423
- fail(`${location}.maxLoops must be an integer from 1 through ${WORKFLOW_MAX_GATE_LOOPS}`);
409
+ if (gate.maxLoops !== undefined && (!Number.isSafeInteger(gate.maxLoops) || gate.maxLoops < 1)) {
410
+ fail(`${location}.maxLoops must be an integer of at least 1`);
424
411
  }
425
412
  optionalString(gate.rubric, `${location}.rubric`);
426
413
  }
@@ -453,8 +440,8 @@ function validateParams(value) {
453
440
  if (value === undefined)
454
441
  return;
455
442
  const params = record(value, "params");
456
- if (Object.keys(params).length === 0 || Object.keys(params).length > WORKFLOW_MAX_PARAMS) {
457
- fail(`params must contain 1 through ${WORKFLOW_MAX_PARAMS} entries`);
443
+ if (Object.keys(params).length === 0) {
444
+ fail(`params must contain at least one entry`);
458
445
  }
459
446
  for (const [name, schema] of Object.entries(params)) {
460
447
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
@@ -472,8 +459,8 @@ function validateOutputs(value) {
472
459
  if (value === undefined)
473
460
  return;
474
461
  const outputs = record(value, "outputs");
475
- if (Object.keys(outputs).length === 0 || Object.keys(outputs).length > WORKFLOW_MAX_OUTPUTS) {
476
- fail(`outputs must contain 1 through ${WORKFLOW_MAX_OUTPUTS} entries`);
462
+ if (Object.keys(outputs).length === 0) {
463
+ fail(`outputs must contain at least one entry`);
477
464
  }
478
465
  for (const [name, declaration] of Object.entries(outputs)) {
479
466
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
@@ -496,9 +483,6 @@ function validateBudget(value) {
496
483
  fail(`budget.${key} must be a positive integer`);
497
484
  }
498
485
  }
499
- if (typeof budget.maxUnits === "number" && budget.maxUnits > WORKFLOW_MAX_MAP_EXPANSION) {
500
- fail(`budget.maxUnits must be at most ${WORKFLOW_MAX_MAP_EXPANSION}`);
501
- }
502
486
  }
503
487
  function validateLlm(value, location) {
504
488
  if (value === undefined)
@@ -16,7 +16,7 @@
16
16
  * resource limits).
17
17
  */
18
18
  import { bundleRefToString, parseBundleRef } from "../core/asset/asset-ref.js";
19
- import { utf8Bytes, WORKFLOW_MAX_INSTRUCTION_BYTES, WORKFLOW_MAX_PARAMS, WORKFLOW_MAX_STEPS } from "./resource-limits.js";
19
+ import { utf8Bytes, WORKFLOW_MAX_INSTRUCTION_BYTES } from "./resource-limits.js";
20
20
  export function runSemanticChecks(draft, frontmatterData, frontmatterEndLine, errors) {
21
21
  checkXrefs(frontmatterData.xrefs, frontmatterEndLine, errors);
22
22
  checkResourceLimits(draft, errors);
@@ -43,12 +43,6 @@ function checkXrefs(value, line, errors) {
43
43
  }
44
44
  }
45
45
  function checkResourceLimits(draft, errors) {
46
- if (draft.steps.length > WORKFLOW_MAX_STEPS) {
47
- errors.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_STEPS} steps.` });
48
- }
49
- if (Object.keys(draft.params ?? {}).length > WORKFLOW_MAX_PARAMS) {
50
- errors.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_PARAMS} parameters.` });
51
- }
52
46
  for (const step of draft.steps) {
53
47
  if (step.instructions && utf8Bytes(step.instructions.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
54
48
  errors.push({
@@ -2032,7 +2032,9 @@ when one exists.
2032
2032
  Scan bundle markdown files for structural issues: unquoted colons, missing
2033
2033
  `updated` field, orphaned stubs, placeholder stubs, missing `name`/`type`,
2034
2034
  stale paths, and broken refs — in body text and in
2035
- `refs`/`xrefs`/`supersededBy`/`contradictedBy` frontmatter. Also reports
2035
+ `refs`/`xrefs`/`supersededBy`/`contradictedBy` frontmatter. A belief edge
2036
+ pointing at a memory that `akm improve` pruned resolves through the archive
2037
+ tombstone under `.akm/memory-cleanup/archive/` and is not reported (#884). Also reports
2036
2038
  `dangerous-env-key` findings for env files (the same key set `akm bundle add`
2037
2039
  enforces — see [Dangerous env key audit](#dangerous-env-key-audit) — but
2038
2040
  non-blocking here; `lint` only warns). `--type workflows` structurally parses
@@ -2046,6 +2048,7 @@ akm lint --fix # Auto-fix Tier-1 issues in place
2046
2048
  akm lint --type workflows # Only lint one asset type
2047
2049
  akm lint --dir ~/other-bundle # Override the bundle root (default: from config)
2048
2050
  akm lint --fail-on-flagged # CI-friendly: exit non-zero when summary.flagged > 0
2051
+ akm lint --prune-dangling-edges # Opt-in: drop belief edges whose target is gone
2049
2052
  ```
2050
2053
 
2051
2054
  | Flag | Description |
@@ -2054,6 +2057,7 @@ akm lint --fail-on-flagged # CI-friendly: exit non-zero when summary.flagge
2054
2057
  | `--dir` | Override the bundle root directory (default: from config) |
2055
2058
  | `--type` | Only lint assets of this type (e.g. `workflows`, `tasks`, `memories`). **akm bundles only** — every other adapter validates the whole bundle and warns on stderr that the flag had no effect. |
2056
2059
  | `--fail-on-flagged` | Exit non-zero when `summary.flagged > 0`. Default: exit 0 regardless of findings. |
2060
+ | `--prune-dangling-edges` | Opt-in repair (#884): drop `supersededBy`/`contradictedBy` entries whose target has neither a file nor a prune tombstone. **Not** implied by `--fix` — it edits well-formed files to delete a belief-graph claim, so review a plain `akm lint` report first. Clears the same `writable: false` gate `--fix` does. |
2057
2061
 
2058
2062
  Returns `fixed[]` and `flagged[]` arrays plus a `summary: { fixed, flagged }`
2059
2063
  count. Each entry carries `file`, `issue`, `detail`, and whether it was
@@ -366,7 +366,7 @@ reference, same rules as engine `apiKey`), `dimension`, `localModel`,
366
366
 
367
367
  | Key | Purpose |
368
368
  | --- | --- |
369
- | `search.graphBoost.*` | Entity-graph relevance boost: `directBoostPerEntity`/`directBoostCap` (directly related entities), `hopBoostPerEntity`/`hopBoostCap` (multi-hop, capped at `maxHops` ≤ 3), `confidenceMode` (`off`\|`blend`\|`multiply`, default `blend`), `confidenceWeight` (0–1, default `0.2`) |
369
+ | `search.graphBoost.*` | Entity-graph relevance boost: `directBoostPerEntity`/`directBoostCap` (directly related entities), `hopBoostPerEntity`/`hopBoostCap` (multi-hop, capped at `maxHops` ≤ 3), `confidenceMode` (`blend`, the only supported value), `confidenceWeight` (0–1, default `0.2`) |
370
370
 
371
371
  ## Feedback
372
372
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akm-cli",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "type": "module",
5
5
  "description": "akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cursor.",
6
6
  "keywords": [
@@ -57,9 +57,6 @@
57
57
  "type": "integer",
58
58
  "exclusiveMinimum": 0
59
59
  },
60
- "supportsJsonSchema": {
61
- "type": "boolean"
62
- },
63
60
  "extraParams": {
64
61
  "type": "object",
65
62
  "additionalProperties": {}
@@ -572,9 +569,7 @@
572
569
  "confidenceMode": {
573
570
  "type": "string",
574
571
  "enum": [
575
- "off",
576
- "blend",
577
- "multiply"
572
+ "blend"
578
573
  ],
579
574
  "default": "blend"
580
575
  },
@@ -1747,9 +1742,6 @@
1747
1742
  "type": "integer",
1748
1743
  "exclusiveMinimum": 0
1749
1744
  },
1750
- "supportsJsonSchema": {
1751
- "type": "boolean"
1752
- },
1753
1745
  "extraParams": {
1754
1746
  "type": "object",
1755
1747
  "additionalProperties": {}
@@ -2262,9 +2254,7 @@
2262
2254
  "confidenceMode": {
2263
2255
  "type": "string",
2264
2256
  "enum": [
2265
- "off",
2266
- "blend",
2267
- "multiply"
2257
+ "blend"
2268
2258
  ],
2269
2259
  "default": "blend"
2270
2260
  },
@@ -3420,14 +3410,8 @@
3420
3410
  "type": "integer",
3421
3411
  "exclusiveMinimum": 0
3422
3412
  },
3423
- "capabilities": {
3424
- "type": "object",
3425
- "properties": {
3426
- "structuredOutput": {
3427
- "type": "boolean"
3428
- }
3429
- },
3430
- "additionalProperties": true
3413
+ "supportsJsonSchema": {
3414
+ "type": "boolean"
3431
3415
  },
3432
3416
  "extraParams": {
3433
3417
  "type": "object",
@@ -3443,9 +3427,6 @@
3443
3427
  "reasoningEffort": {
3444
3428
  "type": "string",
3445
3429
  "minLength": 1
3446
- },
3447
- "supportsJsonSchema": {
3448
- "type": "boolean"
3449
3430
  }
3450
3431
  },
3451
3432
  "required": [
@@ -27,7 +27,6 @@
27
27
  },
28
28
  "inputs": {
29
29
  "type": "object",
30
- "maxProperties": 128,
31
30
  "propertyNames": { "$ref": "#/definitions/taskInputName" },
32
31
  "additionalProperties": { "$ref": "#/definitions/inputDeclaration" }
33
32
  },
@@ -105,7 +104,7 @@
105
104
  "items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }
106
105
  },
107
106
  "maxSteps": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
108
- "maxRetries": { "type": "integer", "minimum": 0, "maximum": 100 }
107
+ "maxRetries": { "type": "integer", "minimum": 0 }
109
108
  },
110
109
  "oneOf": [
111
110
  {
@@ -22,7 +22,6 @@
22
22
  "params": {
23
23
  "type": "object",
24
24
  "minProperties": 1,
25
- "maxProperties": 128,
26
25
  "description": "Run parameters: param name -> JSON Schema declaration. Names must be params.<name>-addressable identifiers.",
27
26
  "propertyNames": {
28
27
  "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
@@ -34,7 +33,6 @@
34
33
  "outputs": {
35
34
  "type": "object",
36
35
  "minProperties": 1,
37
- "maxProperties": 64,
38
36
  "description": "Named, optionally schema-validated projections of step artifacts, exported when the run completes. Names must be steps.<child>.output.<name>-addressable identifiers. Each entry: { from: steps.<id>.output(.<seg>)*, schema?: <bounded JSON Schema> }. Markdown-frontmatter only.",
39
37
  "propertyNames": {
40
38
  "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
@@ -52,7 +50,6 @@
52
50
  "steps": {
53
51
  "type": "array",
54
52
  "minItems": 1,
55
- "maxItems": 256,
56
53
  "items": {
57
54
  "$ref": "#/definitions/step"
58
55
  }
@@ -188,7 +185,6 @@
188
185
  "max": {
189
186
  "type": "integer",
190
187
  "minimum": 0,
191
- "maximum": 100,
192
188
  "description": "Maximum retry attempts per unit."
193
189
  },
194
190
  "on": {
@@ -213,7 +209,6 @@
213
209
  "max_units": {
214
210
  "type": "integer",
215
211
  "minimum": 1,
216
- "maximum": 10000,
217
212
  "description": "Ceiling on total dispatched units across the run (seeded from journaled unit rows)."
218
213
  }
219
214
  }
@@ -252,25 +247,21 @@
252
247
  "type": "array",
253
248
  "description": "argv; command[0] is the program, resolved through PATH. Never shell-parsed.",
254
249
  "minItems": 1,
255
- "maxItems": 64,
256
250
  "items": {
257
251
  "type": "string",
258
- "minLength": 1,
259
- "maxLength": 4096
252
+ "minLength": 1
260
253
  }
261
254
  },
262
255
  "cwd": {
263
256
  "type": "string",
264
257
  "description": "Optional RELATIVE working directory inside the unit's working directory (its fresh worktree under `isolation: worktree`). Absolute paths, Windows drive letters, \"~\", and \"..\" segments are rejected here, and containment is re-checked against the resolved base — symlinks included — before the command is spawned.",
265
258
  "minLength": 1,
266
- "maxLength": 1024,
267
259
  "pattern": "^(?!/|\\\\|~|[A-Za-z]:)(?!.*(?:^|[/\\\\])\\.\\.(?:[/\\\\]|$)).+$"
268
260
  },
269
261
  "pass_env": {
270
262
  "type": "array",
271
263
  "description": "Extra environment variable NAMES copied through from akm's own environment on top of the default allowlist — for a per-machine toolchain variable (e.g. CARGO_HOME) that no committed `env:` asset could carry. NAMES ONLY: values never appear in a workflow, and unlike `env:` bindings these values are NOT redacted from the command's output, so never list a credential here.",
272
264
  "minItems": 1,
273
- "maxItems": 32,
274
265
  "uniqueItems": true,
275
266
  "items": {
276
267
  "type": "string",
@@ -398,7 +389,6 @@
398
389
  "when": {
399
390
  "type": "array",
400
391
  "minItems": 1,
401
- "maxItems": 256,
402
392
  "items": {
403
393
  "$ref": "#/definitions/routeBranch"
404
394
  }
@@ -416,7 +406,6 @@
416
406
  "max_loops": {
417
407
  "type": "integer",
418
408
  "minimum": 1,
419
- "maximum": 100,
420
409
  "description": "Evaluator-optimizer loop bound."
421
410
  }
422
411
  }
@@ -424,7 +413,6 @@
424
413
  "inputs": {
425
414
  "type": "array",
426
415
  "minItems": 1,
427
- "maxItems": 64,
428
416
  "uniqueItems": true,
429
417
  "items": {
430
418
  "$ref": "#/definitions/reference"
@@ -1,15 +0,0 @@
1
- {
2
- "description": "Frequent inference pass — memory inference, graph extraction, and reflect; improve-stage extract off.",
3
- "processes": {
4
- "reflect": { "enabled": true },
5
- "distill": { "enabled": false },
6
- "consolidate": { "enabled": false },
7
- "memoryInference": { "enabled": true },
8
- "graphExtraction": { "enabled": true },
9
- "extract": { "enabled": false, "minNewSessions": 3, "triage": { "enabled": true, "minScore": 2 } },
10
- "triage": { "enabled": false },
11
- "validation": { "enabled": false },
12
- "proactiveMaintenance": { "enabled": false }
13
- },
14
- "sync": { "enabled": true, "push": true }
15
- }
@@ -1,15 +0,0 @@
1
- {
2
- "description": "Memory and lesson improvement only — no distill, consolidate, or graphExtraction.",
3
- "processes": {
4
- "reflect": { "enabled": true, "allowedTypes": ["memory", "lesson"] },
5
- "distill": { "enabled": false },
6
- "consolidate": { "enabled": false },
7
- "memoryInference": { "enabled": true },
8
- "graphExtraction": { "enabled": false },
9
- "extract": { "enabled": false },
10
- "triage": { "enabled": false },
11
- "validation": { "enabled": false },
12
- "proactiveMaintenance": { "enabled": false }
13
- },
14
- "sync": { "enabled": true, "push": true }
15
- }
@@ -1,142 +0,0 @@
1
- // This Source Code Form is subject to the terms of the Mozilla Public
2
- // License, v. 2.0. If a copy of the MPL was not distributed with this
3
- // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import fs from "node:fs";
5
- import { writeFileAtomic } from "../../core/common.js";
6
- import { getCacheDir, getSemanticStatusPath } from "../../core/paths.js";
7
- import { DETERMINISTIC_EMBED_MODEL_ID, isDeterministicEmbedEnabled } from "../../llm/embedders/deterministic.js";
8
- import { DEFAULT_LOCAL_MODEL } from "../../llm/embedders/local.js";
9
- let semanticStatusMutationForTests;
10
- /** TEST-ONLY. Inject a semantic-status filesystem publication fault. */
11
- export function _setSemanticStatusMutationForTests(mutation) {
12
- semanticStatusMutationForTests = mutation;
13
- }
14
- export function deriveSemanticProviderFingerprint(embedding) {
15
- if (isDeterministicEmbedEnabled()) {
16
- return `deterministic:${DETERMINISTIC_EMBED_MODEL_ID}`;
17
- }
18
- if (embedding?.endpoint) {
19
- // Fingerprint keys on vector identity only (model + dimension). The endpoint
20
- // is transport/routing and has no bearing on vector compatibility, so moving
21
- // the same model+dimension to a different host must not force a full re-embed.
22
- return `remote:${embedding.model}|${embedding.dimension ?? "default"}`;
23
- }
24
- return `local:${embedding?.localModel ?? DEFAULT_LOCAL_MODEL}`;
25
- }
26
- export function readSemanticStatus() {
27
- try {
28
- const raw = JSON.parse(fs.readFileSync(getSemanticStatusPath(), "utf8"));
29
- if ((raw.status === "pending" ||
30
- raw.status === "ready-js" ||
31
- raw.status === "ready-vec" ||
32
- raw.status === "blocked") &&
33
- typeof raw.providerFingerprint === "string" &&
34
- typeof raw.lastCheckedAt === "string") {
35
- const status = {
36
- status: raw.status,
37
- providerFingerprint: raw.providerFingerprint,
38
- lastCheckedAt: raw.lastCheckedAt,
39
- };
40
- if (typeof raw.reason === "string")
41
- status.reason = raw.reason;
42
- if (typeof raw.message === "string")
43
- status.message = raw.message;
44
- if (typeof raw.entryCount === "number")
45
- status.entryCount = raw.entryCount;
46
- if (typeof raw.embeddingCount === "number")
47
- status.embeddingCount = raw.embeddingCount;
48
- return status;
49
- }
50
- }
51
- catch {
52
- // ignore corrupt or missing semantic status
53
- }
54
- return undefined;
55
- }
56
- export function writeSemanticStatus(status) {
57
- semanticStatusMutationForTests?.("write");
58
- const dir = getCacheDir();
59
- fs.mkdirSync(dir, { recursive: true });
60
- writeFileAtomic(getSemanticStatusPath(), `${JSON.stringify(status, null, 2)}\n`);
61
- }
62
- export function clearSemanticStatus() {
63
- semanticStatusMutationForTests?.("clear");
64
- try {
65
- fs.unlinkSync(getSemanticStatusPath());
66
- }
67
- catch {
68
- // ignore missing file
69
- }
70
- }
71
- /** How long a "blocked" status is retained before the system retries. 24 hours. */
72
- export const BLOCKED_TTL_MS = 24 * 60 * 60 * 1000;
73
- export function getEffectiveSemanticStatus(config, status = readSemanticStatus()) {
74
- if (config.semanticSearchMode === "off")
75
- return "disabled";
76
- if (!status)
77
- return "pending";
78
- const fingerprint = deriveSemanticProviderFingerprint(config.embedding);
79
- if (status.providerFingerprint !== fingerprint)
80
- return "pending";
81
- // Auto-recovery: if blocked status is older than BLOCKED_TTL_MS, treat as pending
82
- // so the next index run will re-attempt semantic setup.
83
- if (status.status === "blocked") {
84
- const checkedAt = new Date(status.lastCheckedAt).getTime();
85
- if (Number.isNaN(checkedAt) || Date.now() - checkedAt > BLOCKED_TTL_MS) {
86
- return "pending";
87
- }
88
- }
89
- return status.status;
90
- }
91
- export function isSemanticRuntimeReady(status) {
92
- return status === "ready-js" || status === "ready-vec";
93
- }
94
- export function classifySemanticFailure(message) {
95
- const lower = message.toLowerCase();
96
- if (lower.includes("401") || lower.includes("403") || lower.includes("auth") || lower.includes("unauthorized")) {
97
- return "remote-auth";
98
- }
99
- if (lower.includes("429") || lower.includes("rate limit") || lower.includes("quota")) {
100
- return "remote-rate-limit";
101
- }
102
- if (lower.includes("eacces") || lower.includes("permission denied")) {
103
- return "permission-denied";
104
- }
105
- // Native library / linker errors must be checked before the generic ONNX
106
- // match because Alpine/musl linker errors often contain "onnxruntime" in
107
- // the library path (e.g. onnxruntime_binding.node).
108
- if (lower.includes("shared library") ||
109
- lower.includes("glibc") ||
110
- lower.includes("musl") ||
111
- lower.includes("libc.so")) {
112
- return "native-lib-missing";
113
- }
114
- if (lower.includes("onnx") || lower.includes("onnxruntime")) {
115
- return "onnx-runtime-failed";
116
- }
117
- if (lower.includes("404") || lower.includes("model not found") || lower.includes("bad request")) {
118
- return "remote-model";
119
- }
120
- if (lower.includes("transformers") ||
121
- lower.includes("missing-package") ||
122
- lower.includes("local embedding dependency is unavailable")) {
123
- return "missing-package";
124
- }
125
- if (lower.includes("download")) {
126
- return "local-model-download";
127
- }
128
- if (lower.includes("dimension mismatch")) {
129
- return "dimension-mismatch";
130
- }
131
- if (lower.includes("db") || lower.includes("sqlite") || lower.includes("cache dir")) {
132
- return "db-open";
133
- }
134
- if (lower.includes("timeout") ||
135
- lower.includes("unreachable") ||
136
- lower.includes("refused") ||
137
- lower.includes("network") ||
138
- lower.includes("fetch")) {
139
- return "remote-network";
140
- }
141
- return "unknown";
142
- }