akm-cli 0.7.5 → 0.8.0-rc2

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 (152) hide show
  1. package/.github/CHANGELOG.md +1 -1
  2. package/dist/cli/parse-args.js +43 -0
  3. package/dist/cli.js +853 -479
  4. package/dist/commands/agent-dispatch.js +102 -0
  5. package/dist/commands/agent-support.js +62 -0
  6. package/dist/commands/config-cli.js +68 -84
  7. package/dist/commands/consolidate.js +823 -0
  8. package/dist/commands/distill-promotion-policy.js +658 -0
  9. package/dist/commands/distill.js +244 -52
  10. package/dist/commands/eval-cases.js +40 -0
  11. package/dist/commands/events.js +2 -23
  12. package/dist/commands/graph.js +222 -0
  13. package/dist/commands/health.js +376 -0
  14. package/dist/commands/help/help-accept.md +9 -0
  15. package/dist/commands/help/help-improve.md +53 -0
  16. package/dist/commands/help/help-proposals.md +15 -0
  17. package/dist/commands/help/help-propose.md +17 -0
  18. package/dist/commands/help/help-reject.md +8 -0
  19. package/dist/commands/history.js +3 -30
  20. package/dist/commands/improve.js +1170 -0
  21. package/dist/commands/info.js +2 -2
  22. package/dist/commands/init.js +2 -2
  23. package/dist/commands/install-audit.js +5 -1
  24. package/dist/commands/installed-stashes.js +118 -138
  25. package/dist/commands/knowledge.js +133 -0
  26. package/dist/commands/lint/agent-linter.js +46 -0
  27. package/dist/commands/lint/base-linter.js +285 -0
  28. package/dist/commands/lint/command-linter.js +46 -0
  29. package/dist/commands/lint/default-linter.js +13 -0
  30. package/dist/commands/lint/index.js +107 -0
  31. package/dist/commands/lint/knowledge-linter.js +13 -0
  32. package/dist/commands/lint/memory-linter.js +58 -0
  33. package/dist/commands/lint/registry.js +33 -0
  34. package/dist/commands/lint/skill-linter.js +42 -0
  35. package/dist/commands/lint/task-linter.js +47 -0
  36. package/dist/commands/lint/types.js +1 -0
  37. package/dist/commands/lint/workflow-linter.js +53 -0
  38. package/dist/commands/lint.js +1 -0
  39. package/dist/commands/proposal.js +8 -7
  40. package/dist/commands/propose.js +78 -28
  41. package/dist/commands/reflect.js +143 -35
  42. package/dist/commands/registry-search.js +2 -2
  43. package/dist/commands/remember.js +54 -0
  44. package/dist/commands/schema-repair.js +130 -0
  45. package/dist/commands/search.js +21 -5
  46. package/dist/commands/show.js +121 -17
  47. package/dist/commands/source-add.js +10 -10
  48. package/dist/commands/source-manage.js +11 -19
  49. package/dist/commands/tasks.js +385 -0
  50. package/dist/commands/url-checker.js +39 -0
  51. package/dist/commands/vault.js +8 -26
  52. package/dist/core/action-contributors.js +25 -0
  53. package/dist/core/asset-ref.js +4 -0
  54. package/dist/core/asset-registry.js +4 -16
  55. package/dist/core/asset-spec.js +10 -0
  56. package/dist/core/common.js +94 -0
  57. package/dist/core/concurrent.js +22 -0
  58. package/dist/core/config.js +222 -128
  59. package/dist/core/events.js +73 -126
  60. package/dist/core/frontmatter.js +3 -1
  61. package/dist/core/markdown.js +17 -0
  62. package/dist/core/memory-improve.js +678 -0
  63. package/dist/core/parse.js +155 -0
  64. package/dist/core/paths.js +101 -3
  65. package/dist/core/proposal-validators.js +61 -0
  66. package/dist/core/proposals.js +49 -38
  67. package/dist/core/state-db.js +775 -0
  68. package/dist/core/time.js +51 -0
  69. package/dist/core/warn.js +59 -1
  70. package/dist/indexer/db-search.js +52 -238
  71. package/dist/indexer/db.js +378 -1
  72. package/dist/indexer/ensure-index.js +61 -0
  73. package/dist/indexer/graph-boost.js +247 -94
  74. package/dist/indexer/graph-db.js +201 -0
  75. package/dist/indexer/graph-dedup.js +99 -0
  76. package/dist/indexer/graph-extraction.js +409 -76
  77. package/dist/indexer/index-context.js +10 -0
  78. package/dist/indexer/indexer.js +442 -290
  79. package/dist/indexer/llm-cache.js +47 -0
  80. package/dist/indexer/match-contributors.js +141 -0
  81. package/dist/indexer/matchers.js +24 -190
  82. package/dist/indexer/memory-inference.js +63 -29
  83. package/dist/indexer/metadata-contributors.js +26 -0
  84. package/dist/indexer/metadata.js +194 -175
  85. package/dist/indexer/path-resolver.js +89 -0
  86. package/dist/indexer/ranking-contributors.js +204 -0
  87. package/dist/indexer/ranking.js +74 -0
  88. package/dist/indexer/search-hit-enrichers.js +22 -0
  89. package/dist/indexer/search-source.js +24 -9
  90. package/dist/indexer/semantic-status.js +2 -16
  91. package/dist/indexer/walker.js +25 -0
  92. package/dist/integrations/agent/config.js +175 -3
  93. package/dist/integrations/agent/index.js +3 -1
  94. package/dist/integrations/agent/pipeline.js +39 -0
  95. package/dist/integrations/agent/profiles.js +67 -5
  96. package/dist/integrations/agent/prompts.js +77 -72
  97. package/dist/integrations/agent/runners.js +31 -0
  98. package/dist/integrations/agent/sdk-runner.js +120 -0
  99. package/dist/integrations/agent/spawn.js +71 -16
  100. package/dist/integrations/lockfile.js +10 -18
  101. package/dist/integrations/session-logs/index.js +65 -0
  102. package/dist/integrations/session-logs/providers/claude-code.js +56 -0
  103. package/dist/integrations/session-logs/providers/opencode.js +52 -0
  104. package/dist/integrations/session-logs/types.js +1 -0
  105. package/dist/llm/call-ai.js +74 -0
  106. package/dist/llm/client.js +61 -122
  107. package/dist/llm/feature-gate.js +27 -16
  108. package/dist/llm/graph-extract.js +297 -62
  109. package/dist/llm/memory-infer.js +49 -71
  110. package/dist/llm/metadata-enhance.js +39 -22
  111. package/dist/llm/prompts/graph-extract-user-prompt.md +12 -0
  112. package/dist/output/cli-hints-full.md +277 -0
  113. package/dist/output/cli-hints-short.md +65 -0
  114. package/dist/output/cli-hints.js +2 -318
  115. package/dist/output/renderers.js +190 -123
  116. package/dist/output/shapes.js +33 -0
  117. package/dist/output/text.js +239 -2
  118. package/dist/registry/providers/skills-sh.js +61 -49
  119. package/dist/registry/providers/static-index.js +44 -48
  120. package/dist/setup/setup.js +510 -11
  121. package/dist/sources/provider-factory.js +2 -1
  122. package/dist/sources/providers/git.js +2 -2
  123. package/dist/sources/website-ingest.js +4 -0
  124. package/dist/tasks/backends/cron.js +200 -0
  125. package/dist/tasks/backends/exec-utils.js +25 -0
  126. package/dist/tasks/backends/index.js +32 -0
  127. package/dist/tasks/backends/launchd-template.xml +19 -0
  128. package/dist/tasks/backends/launchd.js +184 -0
  129. package/dist/tasks/backends/schtasks-template.xml +29 -0
  130. package/dist/tasks/backends/schtasks.js +212 -0
  131. package/dist/tasks/parser.js +198 -0
  132. package/dist/tasks/resolveAkmBin.js +84 -0
  133. package/dist/tasks/runner.js +432 -0
  134. package/dist/tasks/schedule.js +208 -0
  135. package/dist/tasks/schema.js +13 -0
  136. package/dist/tasks/validator.js +59 -0
  137. package/dist/wiki/index-template.md +12 -0
  138. package/dist/wiki/ingest-workflow-template.md +54 -0
  139. package/dist/wiki/log-template.md +8 -0
  140. package/dist/wiki/schema-template.md +61 -0
  141. package/dist/wiki/wiki-templates.js +12 -0
  142. package/dist/wiki/wiki.js +10 -61
  143. package/dist/workflows/authoring.js +5 -25
  144. package/dist/workflows/renderer.js +8 -3
  145. package/dist/workflows/runs.js +59 -91
  146. package/dist/workflows/validator.js +1 -1
  147. package/dist/workflows/workflow-template.md +24 -0
  148. package/docs/README.md +3 -0
  149. package/docs/migration/release-notes/0.7.0.md +1 -1
  150. package/docs/migration/release-notes/0.8.0.md +43 -0
  151. package/package.json +3 -2
  152. package/dist/templates/wiki-templates.js +0 -100
@@ -14,6 +14,7 @@ import { parseFrontmatter, toStringOrUndefined } from "../core/frontmatter";
14
14
  import { extractFrontmatterOnly, extractLineRange, extractSection, formatToc, parseMarkdownToc, } from "../core/markdown";
15
15
  import { registerRenderer } from "../indexer/file-context";
16
16
  import { extractCommentMetadata, extractDescriptionFromComments } from "../indexer/metadata";
17
+ import { registerMetadataContributor } from "../indexer/metadata-contributors";
17
18
  import { buildWorkflowAction, workflowMdRenderer } from "../workflows/renderer";
18
19
  // ── Interpreter auto-detection map ───────────────────────────────────────────
19
20
  const INTERPRETER_MAP = {
@@ -278,16 +279,6 @@ const knowledgeMdRenderer = {
278
279
  }
279
280
  }
280
281
  },
281
- extractMetadata(entry, ctx) {
282
- try {
283
- const toc = parseMarkdownToc(ctx.content());
284
- if (toc.headings.length > 0)
285
- entry.toc = toc.headings;
286
- }
287
- catch {
288
- // Non-fatal: skip TOC if file can't be read
289
- }
290
- },
291
282
  };
292
283
  // ── 4b. wiki-md ──────────────────────────────────────────────────────────────
293
284
  const WIKI_PAGE_ACTION = "Wiki page — read below. Use 'toc' to scan, 'section <heading>' for depth.";
@@ -357,16 +348,6 @@ const wikiMdRenderer = {
357
348
  }
358
349
  }
359
350
  },
360
- extractMetadata(entry, ctx) {
361
- try {
362
- const toc = parseMarkdownToc(ctx.content());
363
- if (toc.headings.length > 0)
364
- entry.toc = toc.headings;
365
- }
366
- catch {
367
- // Non-fatal: skip TOC if file can't be read
368
- }
369
- },
370
351
  };
371
352
  // ── 4c. lesson-md ────────────────────────────────────────────────────────────
372
353
  /**
@@ -398,33 +379,6 @@ const lessonMdRenderer = {
398
379
  content: parsed.content,
399
380
  };
400
381
  },
401
- extractMetadata(entry, ctx) {
402
- try {
403
- const parsed = parseFrontmatter(ctx.content());
404
- const fm = parsed.data;
405
- const desc = toStringOrUndefined(fm.description);
406
- if (desc && !entry.description) {
407
- entry.description = desc;
408
- entry.source = "frontmatter";
409
- entry.confidence = 0.9;
410
- }
411
- const whenToUse = toStringOrUndefined(fm.when_to_use);
412
- if (whenToUse) {
413
- const hints = new Set(entry.searchHints ?? []);
414
- hints.add(`when_to_use:${whenToUse}`);
415
- entry.searchHints = Array.from(hints).filter(Boolean);
416
- }
417
- if (Array.isArray(fm.tags) && fm.tags.length > 0) {
418
- const fmTags = fm.tags.filter((t) => typeof t === "string" && t.trim().length > 0);
419
- if (fmTags.length > 0) {
420
- entry.tags = Array.from(new Set([...(entry.tags ?? []), ...fmTags]));
421
- }
422
- }
423
- }
424
- catch {
425
- // Non-fatal: skip metadata extraction on parse error
426
- }
427
- },
428
382
  };
429
383
  // ── 5. memory-md ─────────────────────────────────────────────────────────────
430
384
  const memoryMdRenderer = {
@@ -439,58 +393,6 @@ const memoryMdRenderer = {
439
393
  content: ctx.content(),
440
394
  };
441
395
  },
442
- extractMetadata(entry, ctx) {
443
- try {
444
- const parsed = parseFrontmatter(ctx.content());
445
- const fm = parsed.data;
446
- // Description from frontmatter
447
- const desc = toStringOrUndefined(fm.description);
448
- if (desc && !entry.description) {
449
- entry.description = desc;
450
- entry.source = "frontmatter";
451
- entry.confidence = 0.9;
452
- }
453
- // Tags from frontmatter
454
- if (Array.isArray(fm.tags) && fm.tags.length > 0) {
455
- const fmTags = fm.tags.filter((t) => typeof t === "string" && t.trim().length > 0);
456
- if (fmTags.length > 0) {
457
- entry.tags = Array.from(new Set([...(entry.tags ?? []), ...fmTags]));
458
- }
459
- }
460
- // Build searchHints from structured memory metadata fields
461
- const hints = new Set(entry.searchHints ?? []);
462
- const source = toStringOrUndefined(fm.source);
463
- if (source)
464
- hints.add(source);
465
- // observed_at: prefer frontmatter value, fall back to file mtime
466
- const fmObservedAt = toStringOrUndefined(fm.observed_at);
467
- if (fmObservedAt) {
468
- hints.add(`observed_at:${fmObservedAt}`);
469
- }
470
- else {
471
- // mtime fallback: format as ISO date (YYYY-MM-DD)
472
- try {
473
- const mtime = ctx.stat().mtime;
474
- const isoDate = mtime.toISOString().slice(0, 10);
475
- hints.add(`observed_at:${isoDate}`);
476
- }
477
- catch {
478
- // Non-fatal: skip mtime fallback on stat error
479
- }
480
- }
481
- const expires = toStringOrUndefined(fm.expires);
482
- if (expires)
483
- hints.add(`expires:${expires}`);
484
- if (fm.subjective === true)
485
- hints.add("subjective");
486
- if (hints.size > 0) {
487
- entry.searchHints = Array.from(hints).filter(Boolean);
488
- }
489
- }
490
- catch {
491
- // Non-fatal: skip metadata extraction on error
492
- }
493
- },
494
396
  };
495
397
  // ── 6. workflow-md ───────────────────────────────────────────────────────────
496
398
  // Defined in src/workflows/renderer.ts and imported above.
@@ -537,16 +439,6 @@ const scriptSourceRenderer = {
537
439
  throw error;
538
440
  }
539
441
  },
540
- extractMetadata(entry, ctx) {
541
- if (ctx.ext !== ".md") {
542
- const commentDesc = extractDescriptionFromComments(ctx.absPath);
543
- if (commentDesc && !entry.description) {
544
- entry.description = commentDesc;
545
- entry.source = "comments";
546
- entry.confidence = 0.7;
547
- }
548
- }
549
- },
550
442
  };
551
443
  // ── 8. vault-env ─────────────────────────────────────────────────────────────
552
444
  /**
@@ -574,22 +466,196 @@ const vaultEnvRenderer = {
574
466
  if (keys.length > 0)
575
467
  hit.keys = keys;
576
468
  },
577
- extractMetadata(entry, ctx) {
578
- // Re-derive from the file directly to guarantee no value ever transits
579
- // through any other code path. Caller already short-circuits in
580
- // generateMetadata{,Flat}, but this is defense in depth.
581
- const { keys, comments } = listVaultKeys(ctx.absPath);
582
- if (comments.length > 0 && !entry.description) {
583
- entry.description = comments.join(" ").slice(0, 500);
584
- entry.source = "comments";
585
- entry.confidence = 0.7;
586
- }
587
- if (keys.length > 0) {
588
- entry.searchHints = keys;
589
- }
590
- entry.tags = Array.from(new Set([...(entry.tags ?? []), "vault", "secrets"]));
469
+ };
470
+ // ── 7. task-md ───────────────────────────────────────────────────────────────
471
+ const TASK_PAGE_ACTION = "Scheduled task `akm tasks show <id>` for parsed details, `akm tasks run <id>` to invoke now.";
472
+ const taskMdRenderer = {
473
+ name: "task-md",
474
+ buildShowResponse(ctx) {
475
+ const name = deriveName(ctx);
476
+ return {
477
+ type: "task",
478
+ name,
479
+ path: ctx.absPath,
480
+ action: TASK_PAGE_ACTION,
481
+ content: ctx.content(),
482
+ };
591
483
  },
592
484
  };
485
+ function applyTocMetadata(entry, ctx) {
486
+ try {
487
+ const toc = parseMarkdownToc(ctx.content());
488
+ if (toc.headings.length > 0)
489
+ entry.toc = toc.headings;
490
+ }
491
+ catch {
492
+ // Non-fatal: skip TOC if file can't be read
493
+ }
494
+ }
495
+ function applyLessonMetadata(entry, ctx) {
496
+ try {
497
+ const parsed = parseFrontmatter(ctx.content());
498
+ const fm = parsed.data;
499
+ const desc = toStringOrUndefined(fm.description);
500
+ if (desc && !entry.description) {
501
+ entry.description = desc;
502
+ entry.source = "frontmatter";
503
+ entry.confidence = 0.9;
504
+ }
505
+ const whenToUse = toStringOrUndefined(fm.when_to_use);
506
+ if (whenToUse) {
507
+ const hints = new Set(entry.searchHints ?? []);
508
+ hints.add(`when_to_use:${whenToUse}`);
509
+ entry.searchHints = Array.from(hints).filter(Boolean);
510
+ }
511
+ if (Array.isArray(fm.tags) && fm.tags.length > 0) {
512
+ const fmTags = fm.tags.filter((t) => typeof t === "string" && t.trim().length > 0);
513
+ if (fmTags.length > 0) {
514
+ entry.tags = Array.from(new Set([...(entry.tags ?? []), ...fmTags]));
515
+ }
516
+ }
517
+ }
518
+ catch {
519
+ // Non-fatal: skip metadata extraction on parse error
520
+ }
521
+ }
522
+ function applyMemoryMetadata(entry, ctx) {
523
+ try {
524
+ const parsed = parseFrontmatter(ctx.content());
525
+ const fm = parsed.data;
526
+ const desc = toStringOrUndefined(fm.description);
527
+ if (desc && !entry.description) {
528
+ entry.description = desc;
529
+ entry.source = "frontmatter";
530
+ entry.confidence = 0.9;
531
+ }
532
+ if (Array.isArray(fm.tags) && fm.tags.length > 0) {
533
+ const fmTags = fm.tags.filter((t) => typeof t === "string" && t.trim().length > 0);
534
+ if (fmTags.length > 0) {
535
+ entry.tags = Array.from(new Set([...(entry.tags ?? []), ...fmTags]));
536
+ }
537
+ }
538
+ const hints = new Set(entry.searchHints ?? []);
539
+ const source = toStringOrUndefined(fm.source);
540
+ if (source)
541
+ hints.add(source);
542
+ const fmObservedAt = toStringOrUndefined(fm.observed_at);
543
+ if (fmObservedAt) {
544
+ hints.add(`observed_at:${fmObservedAt}`);
545
+ }
546
+ else {
547
+ try {
548
+ const isoDate = ctx.stat().mtime.toISOString().slice(0, 10);
549
+ hints.add(`observed_at:${isoDate}`);
550
+ }
551
+ catch {
552
+ // Non-fatal: skip mtime fallback on stat error
553
+ }
554
+ }
555
+ const expires = toStringOrUndefined(fm.expires);
556
+ if (expires)
557
+ hints.add(`expires:${expires}`);
558
+ if (fm.subjective === true)
559
+ hints.add("subjective");
560
+ if (hints.size > 0) {
561
+ entry.searchHints = Array.from(hints).filter(Boolean);
562
+ }
563
+ }
564
+ catch {
565
+ // Non-fatal: skip metadata extraction on error
566
+ }
567
+ }
568
+ function applyScriptMetadata(entry, ctx) {
569
+ if (ctx.ext === ".md")
570
+ return;
571
+ const commentDesc = extractDescriptionFromComments(ctx.absPath);
572
+ if (commentDesc && !entry.description) {
573
+ entry.description = commentDesc;
574
+ entry.source = "comments";
575
+ entry.confidence = 0.7;
576
+ }
577
+ }
578
+ function applyVaultMetadata(entry, ctx) {
579
+ const { keys, comments } = listVaultKeys(ctx.absPath);
580
+ if (comments.length > 0 && !entry.description) {
581
+ entry.description = comments.join(" ").slice(0, 500);
582
+ entry.source = "comments";
583
+ entry.confidence = 0.7;
584
+ }
585
+ if (keys.length > 0) {
586
+ entry.searchHints = keys;
587
+ }
588
+ entry.tags = Array.from(new Set([...(entry.tags ?? []), "vault", "secrets"]));
589
+ }
590
+ function applyTaskMetadata(entry, ctx) {
591
+ try {
592
+ const parsed = parseFrontmatter(ctx.content());
593
+ const fm = parsed.data;
594
+ const desc = toStringOrUndefined(fm.description);
595
+ if (desc && !entry.description) {
596
+ entry.description = desc;
597
+ entry.source = "frontmatter";
598
+ entry.confidence = 0.9;
599
+ }
600
+ if (Array.isArray(fm.tags)) {
601
+ const fmTags = fm.tags.filter((t) => typeof t === "string" && t.trim().length > 0);
602
+ if (fmTags.length > 0) {
603
+ entry.tags = Array.from(new Set([...(entry.tags ?? []), ...fmTags]));
604
+ }
605
+ }
606
+ entry.tags = Array.from(new Set([...(entry.tags ?? []), "task", "scheduled"]));
607
+ const hints = new Set(entry.searchHints ?? []);
608
+ const schedule = toStringOrUndefined(fm.schedule);
609
+ if (schedule)
610
+ hints.add(`schedule:${schedule}`);
611
+ const workflow = toStringOrUndefined(fm.workflow);
612
+ if (workflow)
613
+ hints.add(`workflow:${workflow}`);
614
+ const prompt = toStringOrUndefined(fm.prompt);
615
+ if (prompt)
616
+ hints.add(`prompt:${prompt}`);
617
+ if (hints.size > 0)
618
+ entry.searchHints = Array.from(hints).filter(Boolean);
619
+ }
620
+ catch {
621
+ // Non-fatal: skip metadata extraction on error
622
+ }
623
+ }
624
+ registerMetadataContributor({
625
+ name: "knowledge-toc-metadata",
626
+ appliesTo: ({ rendererName }) => rendererName === "knowledge-md",
627
+ contribute: (entry, ctx) => applyTocMetadata(entry, ctx.renderContext),
628
+ });
629
+ registerMetadataContributor({
630
+ name: "wiki-toc-metadata",
631
+ appliesTo: ({ rendererName }) => rendererName === "wiki-md",
632
+ contribute: (entry, ctx) => applyTocMetadata(entry, ctx.renderContext),
633
+ });
634
+ registerMetadataContributor({
635
+ name: "lesson-frontmatter-metadata",
636
+ appliesTo: ({ rendererName }) => rendererName === "lesson-md",
637
+ contribute: (entry, ctx) => applyLessonMetadata(entry, ctx.renderContext),
638
+ });
639
+ registerMetadataContributor({
640
+ name: "memory-frontmatter-metadata",
641
+ appliesTo: ({ rendererName }) => rendererName === "memory-md",
642
+ contribute: (entry, ctx) => applyMemoryMetadata(entry, ctx.renderContext),
643
+ });
644
+ registerMetadataContributor({
645
+ name: "script-comment-metadata",
646
+ appliesTo: ({ rendererName }) => rendererName === "script-source",
647
+ contribute: (entry, ctx) => applyScriptMetadata(entry, ctx.renderContext),
648
+ });
649
+ registerMetadataContributor({
650
+ name: "vault-secret-metadata",
651
+ appliesTo: ({ rendererName }) => rendererName === "vault-env",
652
+ contribute: (entry, ctx) => applyVaultMetadata(entry, ctx.renderContext),
653
+ });
654
+ registerMetadataContributor({
655
+ name: "task-frontmatter-metadata",
656
+ appliesTo: ({ rendererName }) => rendererName === "task-md",
657
+ contribute: (entry, ctx) => applyTaskMetadata(entry, ctx.renderContext),
658
+ });
593
659
  // ── Registration ─────────────────────────────────────────────────────────────
594
660
  /** All built-in renderers. */
595
661
  const builtinRenderers = [
@@ -603,6 +669,7 @@ const builtinRenderers = [
603
669
  workflowMdRenderer,
604
670
  scriptSourceRenderer,
605
671
  vaultEnvRenderer,
672
+ taskMdRenderer,
606
673
  ];
607
674
  /**
608
675
  * Register all built-in renderers with the file-context registry.
@@ -45,12 +45,20 @@ export function shapeForCommand(command, result, detail, forAgent = false) {
45
45
  case "reflect":
46
46
  case "propose":
47
47
  return shapeProposalProducerOutput(result, detail);
48
+ case "improve":
49
+ return result;
48
50
  // Output shape registration for `akm distill <ref>` (#228). The shape is
49
51
  // simple — outcome + ids + optional payload — so `brief` strips the full
50
52
  // proposal blob, `normal` keeps the headline fields, and `full` projects
51
53
  // everything for downstream automation.
52
54
  case "distill":
53
55
  return shapeDistillOutput(result, detail);
56
+ case "graph-summary":
57
+ case "graph-entities":
58
+ case "graph-relations":
59
+ case "graph-related":
60
+ case "graph-export":
61
+ return result;
54
62
  // Identity-passthrough commands — registered here so the registry stays
55
63
  // exhaustive (v1 spec §9). Each result object is already shaped at the
56
64
  // command boundary; the registry just confirms there's no surprise
@@ -64,6 +72,7 @@ export function shapeForCommand(command, result, detail, forAgent = false) {
64
72
  case "feedback":
65
73
  case "import":
66
74
  case "index":
75
+ case "health":
67
76
  case "info":
68
77
  case "init":
69
78
  case "list":
@@ -97,6 +106,27 @@ export function shapeForCommand(command, result, detail, forAgent = false) {
97
106
  case "workflow-start":
98
107
  case "workflow-status":
99
108
  case "workflow-validate":
109
+ case "tasks-add":
110
+ case "tasks-list":
111
+ case "tasks-show":
112
+ case "tasks-remove":
113
+ case "tasks-enable":
114
+ case "tasks-disable":
115
+ case "tasks-run":
116
+ case "tasks-history":
117
+ case "tasks-sync":
118
+ case "tasks-doctor":
119
+ return result;
120
+ // Output shape registration for `akm lint`, `akm setup`, and `akm consolidate`.
121
+ // Each result is already fully shaped at the command boundary; pass through as-is.
122
+ case "lint":
123
+ case "setup":
124
+ case "consolidate":
125
+ return result;
126
+ // Output shape registration for `akm agent <profile>`. The result carries
127
+ // structured agent-run fields; the text renderer uses the interactive/
128
+ // captured distinction to decide what to print.
129
+ case "agent-result":
100
130
  return result;
101
131
  default:
102
132
  // v1 spec §9 (output-shape registry exhaustive): no silent JSON.stringify
@@ -462,6 +492,7 @@ export function shapeShowOutput(result, detail, forAgent = false) {
462
492
  "steps",
463
493
  "keys",
464
494
  "comments",
495
+ "related",
465
496
  ]);
466
497
  }
467
498
  if (detail === "summary") {
@@ -477,6 +508,7 @@ export function shapeShowOutput(result, detail, forAgent = false) {
477
508
  "origin",
478
509
  "keys",
479
510
  "comments",
511
+ "related",
480
512
  ]);
481
513
  }
482
514
  const base = pickFields(result, [
@@ -502,6 +534,7 @@ export function shapeShowOutput(result, detail, forAgent = false) {
502
534
  "activeRun",
503
535
  "keys",
504
536
  "comments",
537
+ "related",
505
538
  // path and editable are always projected so JSON consumers can locate and
506
539
  // edit the asset without needing --detail full (QA #7).
507
540
  "path",