akm-cli 0.9.0-beta.3 → 0.9.0-beta.30

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 (107) hide show
  1. package/CHANGELOG.md +600 -0
  2. package/dist/assets/prompts/consolidate-system.md +23 -0
  3. package/dist/assets/prompts/contradiction-judge.md +33 -0
  4. package/dist/assets/prompts/distill-knowledge-system.md +22 -0
  5. package/dist/assets/prompts/distill-lesson-system.md +36 -0
  6. package/dist/assets/prompts/extract-session.md +5 -1
  7. package/dist/assets/prompts/graph-extract-system.md +1 -0
  8. package/dist/assets/prompts/memory-infer-system.md +1 -0
  9. package/dist/assets/prompts/memory-infer-user.md +5 -0
  10. package/dist/assets/prompts/metadata-enhance-system.md +1 -0
  11. package/dist/assets/prompts/procedural-system.md +44 -0
  12. package/dist/assets/prompts/recombine-system.md +40 -0
  13. package/dist/assets/prompts/staleness-detect-system.md +6 -0
  14. package/dist/assets/prompts/validate-summary-judge.md +1 -0
  15. package/dist/assets/templates/html/health.html +281 -111
  16. package/dist/cli.js +14 -3
  17. package/dist/commands/agent/contribute-cli.js +16 -3
  18. package/dist/commands/feedback-cli.js +15 -6
  19. package/dist/commands/graph/graph.js +75 -71
  20. package/dist/commands/health/checks.js +48 -0
  21. package/dist/commands/health/html-report.js +422 -80
  22. package/dist/commands/health.js +381 -9
  23. package/dist/commands/improve/calibration.js +161 -0
  24. package/dist/commands/improve/consolidate.js +634 -111
  25. package/dist/commands/improve/dedup.js +482 -0
  26. package/dist/commands/improve/distill.js +145 -69
  27. package/dist/commands/improve/encoding-salience.js +205 -0
  28. package/dist/commands/improve/extract-cli.js +115 -1
  29. package/dist/commands/improve/extract-prompt.js +33 -2
  30. package/dist/commands/improve/extract-watch.js +140 -0
  31. package/dist/commands/improve/extract.js +244 -35
  32. package/dist/commands/improve/feedback-valence.js +54 -0
  33. package/dist/commands/improve/homeostatic.js +467 -0
  34. package/dist/commands/improve/improve-auto-accept.js +113 -6
  35. package/dist/commands/improve/improve-profiles.js +12 -0
  36. package/dist/commands/improve/improve.js +1974 -614
  37. package/dist/commands/improve/memory/memory-contradiction-detect.js +23 -28
  38. package/dist/commands/improve/outcome-loop.js +256 -0
  39. package/dist/commands/improve/proactive-maintenance.js +87 -0
  40. package/dist/commands/improve/procedural.js +409 -0
  41. package/dist/commands/improve/recombine.js +528 -0
  42. package/dist/commands/improve/reflect.js +26 -1
  43. package/dist/commands/improve/related-sessions.js +120 -0
  44. package/dist/commands/improve/salience.js +386 -0
  45. package/dist/commands/improve/triage.js +95 -0
  46. package/dist/commands/lint/agent-linter.js +19 -24
  47. package/dist/commands/lint/base-linter.js +173 -60
  48. package/dist/commands/lint/command-linter.js +19 -24
  49. package/dist/commands/lint/env-key-rules.js +34 -1
  50. package/dist/commands/lint/fact-linter.js +39 -0
  51. package/dist/commands/lint/index.js +31 -13
  52. package/dist/commands/lint/memory-linter.js +1 -1
  53. package/dist/commands/lint/registry.js +7 -2
  54. package/dist/commands/lint/task-linter.js +3 -3
  55. package/dist/commands/lint/workflow-linter.js +26 -1
  56. package/dist/commands/proposal/proposal.js +5 -0
  57. package/dist/commands/proposal/validators/proposals.js +71 -54
  58. package/dist/commands/read/curate.js +344 -80
  59. package/dist/commands/read/search-cli.js +7 -0
  60. package/dist/commands/read/search.js +1 -0
  61. package/dist/commands/read/show.js +67 -2
  62. package/dist/commands/sources/installed-stashes.js +5 -1
  63. package/dist/commands/sources/stash-cli.js +10 -2
  64. package/dist/core/asset/asset-registry.js +2 -0
  65. package/dist/core/asset/asset-spec.js +14 -0
  66. package/dist/core/asset/frontmatter.js +166 -167
  67. package/dist/core/asset/markdown.js +8 -0
  68. package/dist/core/config/config-schema.js +259 -2
  69. package/dist/core/config/config.js +2 -2
  70. package/dist/core/logs-db.js +4 -3
  71. package/dist/core/paths.js +3 -0
  72. package/dist/core/state-db.js +649 -30
  73. package/dist/indexer/db/db.js +364 -38
  74. package/dist/indexer/db/graph-db.js +129 -86
  75. package/dist/indexer/ensure-index.js +152 -17
  76. package/dist/indexer/graph/graph-boost.js +51 -41
  77. package/dist/indexer/graph/graph-extraction.js +203 -3
  78. package/dist/indexer/index-writer-lock.js +99 -0
  79. package/dist/indexer/indexer.js +114 -111
  80. package/dist/indexer/passes/memory-inference.js +10 -3
  81. package/dist/indexer/passes/staleness-detect.js +2 -5
  82. package/dist/indexer/search/db-search.js +15 -4
  83. package/dist/indexer/search/ranking-contributors.js +22 -0
  84. package/dist/indexer/search/ranking.js +4 -0
  85. package/dist/indexer/walk/matchers.js +9 -0
  86. package/dist/integrations/agent/prompts.js +1 -0
  87. package/dist/integrations/harnesses/claude/session-log.js +11 -1
  88. package/dist/integrations/harnesses/opencode/session-log.js +9 -0
  89. package/dist/integrations/session-logs/index.js +16 -0
  90. package/dist/llm/client.js +23 -4
  91. package/dist/llm/embedder.js +27 -3
  92. package/dist/llm/embedders/local.js +66 -2
  93. package/dist/llm/graph-extract.js +2 -1
  94. package/dist/llm/memory-infer.js +4 -8
  95. package/dist/llm/metadata-enhance.js +9 -1
  96. package/dist/output/renderers.js +73 -1
  97. package/dist/output/shapes/curate.js +14 -2
  98. package/dist/output/text/helpers.js +9 -0
  99. package/dist/runtime.js +25 -1
  100. package/dist/scripts/migrate-storage.js +1242 -594
  101. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +473 -270
  102. package/dist/sources/providers/tar-utils.js +16 -8
  103. package/dist/storage/sqlite-pragmas.js +146 -0
  104. package/dist/workflows/db.js +3 -4
  105. package/dist/workflows/validate-summary.js +2 -7
  106. package/docs/data-and-telemetry.md +1 -0
  107. package/package.json +9 -6
@@ -2,6 +2,7 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
+ import { parseWorkflow } from "../../workflows/parser.js";
5
6
  import { BaseLinter } from "./base-linter.js";
6
7
  const PLACEHOLDER_STRINGS = ["Describe what this workflow accomplishes", "Example Workflow"];
7
8
  /**
@@ -32,7 +33,7 @@ export class WorkflowLinter extends BaseLinter {
32
33
  file: ctx.relPath,
33
34
  issue: "placeholder-stub",
34
35
  detail: `could not delete: ${e instanceof Error ? e.message : String(e)}`,
35
- fixed: false,
36
+ fixed: "failed",
36
37
  });
37
38
  }
38
39
  return issues;
@@ -44,6 +45,30 @@ export class WorkflowLinter extends BaseLinter {
44
45
  fixed: false,
45
46
  });
46
47
  }
48
+ const isReadOnly = ctx.filePath.includes("/.cache/") || ctx.filePath.includes("/registry/");
49
+ if (!isReadOnly) {
50
+ try {
51
+ const result = parseWorkflow(ctx.raw, { path: ctx.filePath });
52
+ if (!result.ok) {
53
+ for (const err of result.errors ?? []) {
54
+ issues.push({
55
+ file: ctx.relPath,
56
+ issue: "invalid-workflow-structure",
57
+ detail: err.message ?? String(err),
58
+ fixed: false,
59
+ });
60
+ }
61
+ }
62
+ }
63
+ catch (e) {
64
+ issues.push({
65
+ file: ctx.relPath,
66
+ issue: "invalid-workflow-structure",
67
+ detail: `workflow parser error: ${e instanceof Error ? e.message : String(e)}`,
68
+ fixed: false,
69
+ });
70
+ }
71
+ }
47
72
  return issues;
48
73
  }
49
74
  #checkPlaceholderStub(body) {
@@ -75,6 +75,11 @@ export async function akmProposalAccept(options) {
75
75
  source: result.proposal.source,
76
76
  ...(result.proposal.sourceRun !== undefined ? { sourceRun: result.proposal.sourceRun } : {}),
77
77
  assetPath: result.assetPath,
78
+ // Attribution tagging: carry the eligibility lane from the proposal record
79
+ // onto the promoted event so accept outcomes can be sliced by lane.
80
+ ...(result.proposal.eligibilitySource !== undefined
81
+ ? { eligibilitySource: result.proposal.eligibilitySource }
82
+ : {}),
78
83
  },
79
84
  });
80
85
  return {
@@ -50,7 +50,7 @@ import { makeAssetRef, parseAssetRef } from "../../../core/asset/asset-ref.js";
50
50
  import { resolveAssetPathFromName, TYPE_DIRS } from "../../../core/asset/asset-spec.js";
51
51
  import { NotFoundError, UsageError } from "../../../core/errors.js";
52
52
  import { appendEvent } from "../../../core/events.js";
53
- import { getStateDbPath, getStateProposal, hasImportedFsProposals, insertProposalIfAbsent, listStateProposalIdsByPrefix, listStateProposals, openStateDatabase, recordFsProposalsImport, upsertProposal, } from "../../../core/state-db.js";
53
+ import { getStateDbPath, getStateProposal, hasImportedFsProposals, insertProposalIfAbsent, listStateProposalIdsByPrefix, listStateProposals, openStateDatabase, recordFsProposalsImport, upsertProposal, withImmediateTransaction, } from "../../../core/state-db.js";
54
54
  import { warn } from "../../../core/warn.js";
55
55
  import { commitWriteTargetBoundary, formatRefForMessage, resolveWriteTarget, writeAssetToSource, } from "../../../core/write-source.js";
56
56
  import { runProposalValidators } from "./proposal-validators.js";
@@ -74,6 +74,8 @@ export const PROPOSAL_SOURCES = [
74
74
  "consolidate",
75
75
  "extract",
76
76
  "improve",
77
+ "recombine",
78
+ "procedural",
77
79
  // Semi-automated / tool-driven.
78
80
  "feedback",
79
81
  // Human-initiated / CLI-driven.
@@ -91,6 +93,8 @@ export const AUTOMATED_PROPOSAL_SOURCES = [
91
93
  "consolidate",
92
94
  "extract",
93
95
  "improve",
96
+ "recombine",
97
+ "procedural",
94
98
  "schema-repair",
95
99
  ];
96
100
  /**
@@ -334,37 +338,42 @@ export function createProposal(stashDir, input, ctx) {
334
338
  }
335
339
  const normalizedRef = makeAssetRef(parsedRef.type, parsedRef.name, parsedRef.origin);
336
340
  return withProposalsDb(stashDir, ctx, (db) => {
337
- if (!input.force) {
338
- const skip = checkDedupAndCooldown(db, stashDir, normalizedRef, input, ctx);
339
- if (skip)
340
- return skip;
341
- }
342
- const created = nowIso(ctx);
343
- // Phase 6A: validate confidence is a finite number in [0, 1]. Anything else
344
- // is dropped silently we never store NaN, Infinity, or out-of-range values.
345
- // Callers that mis-report confidence should not poison the auto-accept gate.
346
- const sanitizedConfidence = typeof input.confidence === "number" &&
347
- Number.isFinite(input.confidence) &&
348
- input.confidence >= 0 &&
349
- input.confidence <= 1
350
- ? input.confidence
351
- : undefined;
352
- const proposal = {
353
- id: newId(ctx),
354
- ref: normalizedRef,
355
- status: "pending",
356
- source: input.source,
357
- ...(input.sourceRun !== undefined ? { sourceRun: input.sourceRun } : {}),
358
- createdAt: created,
359
- updatedAt: created,
360
- payload: {
361
- content: input.payload.content,
362
- ...(input.payload.frontmatter !== undefined ? { frontmatter: input.payload.frontmatter } : {}),
363
- },
364
- ...(sanitizedConfidence !== undefined ? { confidence: sanitizedConfidence } : {}),
365
- };
366
- upsertProposal(db, proposal, stashDir);
367
- return proposal;
341
+ return withImmediateTransaction(db, () => {
342
+ if (!input.force) {
343
+ const skip = checkDedupAndCooldown(db, stashDir, normalizedRef, input, ctx);
344
+ if (skip)
345
+ return skip;
346
+ }
347
+ const created = nowIso(ctx);
348
+ // Phase 6A: validate confidence is a finite number in [0, 1]. Anything else
349
+ // is dropped silently we never store NaN, Infinity, or out-of-range values.
350
+ // Callers that mis-report confidence should not poison the auto-accept gate.
351
+ const sanitizedConfidence = typeof input.confidence === "number" &&
352
+ Number.isFinite(input.confidence) &&
353
+ input.confidence >= 0 &&
354
+ input.confidence <= 1
355
+ ? input.confidence
356
+ : undefined;
357
+ const proposal = {
358
+ id: newId(ctx),
359
+ ref: normalizedRef,
360
+ status: "pending",
361
+ source: input.source,
362
+ ...(input.sourceRun !== undefined ? { sourceRun: input.sourceRun } : {}),
363
+ createdAt: created,
364
+ updatedAt: created,
365
+ payload: {
366
+ content: input.payload.content,
367
+ ...(input.payload.frontmatter !== undefined ? { frontmatter: input.payload.frontmatter } : {}),
368
+ },
369
+ ...(sanitizedConfidence !== undefined ? { confidence: sanitizedConfidence } : {}),
370
+ // Attribution tagging: persist the eligibility lane so it survives to
371
+ // accept/reject/revert time. See EligibilitySource.
372
+ ...(input.eligibilitySource !== undefined ? { eligibilitySource: input.eligibilitySource } : {}),
373
+ };
374
+ upsertProposal(db, proposal, stashDir);
375
+ return proposal;
376
+ });
368
377
  });
369
378
  }
370
379
  /**
@@ -517,19 +526,25 @@ export function resolveProposalId(stashDir, idOrRef, ctx) {
517
526
  */
518
527
  export function archiveProposal(stashDir, id, status, reason, ctx) {
519
528
  return withProposalsDb(stashDir, ctx, (db) => {
520
- const existing = requireProposal(db, stashDir, id);
521
- const updated = {
522
- ...existing,
523
- status,
524
- updatedAt: nowIso(ctx),
525
- review: {
526
- outcome: status,
527
- ...(reason !== undefined ? { reason } : {}),
528
- decidedAt: nowIso(ctx),
529
- },
530
- };
531
- upsertProposal(db, updated, stashDir);
532
- return updated;
529
+ return withImmediateTransaction(db, () => {
530
+ const existing = requireProposal(db, stashDir, id);
531
+ if (existing.status !== "pending") {
532
+ throw new UsageError(`Proposal ${id} is not pending (current status: ${existing.status}). Only pending proposals can be ${status}.`, "INVALID_FLAG_VALUE");
533
+ }
534
+ const decidedAt = nowIso(ctx);
535
+ const updated = {
536
+ ...existing,
537
+ status,
538
+ updatedAt: decidedAt,
539
+ review: {
540
+ outcome: status,
541
+ ...(reason !== undefined ? { reason } : {}),
542
+ decidedAt,
543
+ },
544
+ };
545
+ upsertProposal(db, updated, stashDir);
546
+ return updated;
547
+ });
533
548
  });
534
549
  }
535
550
  /**
@@ -548,15 +563,17 @@ export function archiveProposal(stashDir, id, status, reason, ctx) {
548
563
  */
549
564
  export function recordGateDecision(stashDir, id, decision, ctx) {
550
565
  return withProposalsDb(stashDir, ctx, (db) => {
551
- const existing = getStateProposal(db, id, stashDir);
552
- if (!existing)
553
- return undefined;
554
- const updated = {
555
- ...existing,
556
- gateDecision: { ...decision, decidedAt: decision.decidedAt ?? nowIso(ctx) },
557
- };
558
- upsertProposal(db, updated, stashDir);
559
- return updated;
566
+ return withImmediateTransaction(db, () => {
567
+ const existing = getStateProposal(db, id, stashDir);
568
+ if (!existing || existing.status !== "pending")
569
+ return undefined;
570
+ const updated = {
571
+ ...existing,
572
+ gateDecision: { ...decision, decidedAt: decision.decidedAt ?? nowIso(ctx) },
573
+ };
574
+ upsertProposal(db, updated, stashDir);
575
+ return updated;
576
+ });
560
577
  });
561
578
  }
562
579
  /**