akm-cli 0.7.4 → 0.8.0-rc1
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 → .github/CHANGELOG.md} +34 -1
- package/.github/LICENSE +374 -0
- package/dist/cli/parse-args.js +43 -0
- package/dist/cli.js +1007 -593
- package/dist/commands/agent-dispatch.js +102 -0
- package/dist/commands/agent-support.js +62 -0
- package/dist/commands/config-cli.js +68 -84
- package/dist/commands/consolidate.js +823 -0
- package/dist/commands/curate.js +1 -0
- package/dist/commands/distill-promotion-policy.js +658 -0
- package/dist/commands/distill.js +250 -48
- package/dist/commands/eval-cases.js +40 -0
- package/dist/commands/events.js +12 -24
- package/dist/commands/graph.js +222 -0
- package/dist/commands/health.js +376 -0
- package/dist/commands/help/help-accept.md +9 -0
- package/dist/commands/help/help-improve.md +53 -0
- package/dist/commands/help/help-proposals.md +15 -0
- package/dist/commands/help/help-propose.md +17 -0
- package/dist/commands/help/help-reject.md +8 -0
- package/dist/commands/history.js +3 -30
- package/dist/commands/improve.js +1170 -0
- package/dist/commands/info.js +2 -2
- package/dist/commands/init.js +2 -2
- package/dist/commands/install-audit.js +5 -1
- package/dist/commands/installed-stashes.js +118 -138
- package/dist/commands/knowledge.js +133 -0
- package/dist/commands/lint/agent-linter.js +46 -0
- package/dist/commands/lint/base-linter.js +251 -0
- package/dist/commands/lint/command-linter.js +46 -0
- package/dist/commands/lint/default-linter.js +13 -0
- package/dist/commands/lint/index.js +107 -0
- package/dist/commands/lint/knowledge-linter.js +13 -0
- package/dist/commands/lint/memory-linter.js +58 -0
- package/dist/commands/lint/registry.js +33 -0
- package/dist/commands/lint/skill-linter.js +42 -0
- package/dist/commands/lint/task-linter.js +47 -0
- package/dist/commands/lint/types.js +1 -0
- package/dist/commands/lint/workflow-linter.js +53 -0
- package/dist/commands/lint.js +1 -0
- package/dist/commands/migration-help.js +2 -2
- package/dist/commands/proposal.js +8 -7
- package/dist/commands/propose.js +113 -43
- package/dist/commands/reflect.js +175 -41
- package/dist/commands/registry-search.js +2 -2
- package/dist/commands/remember.js +55 -1
- package/dist/commands/schema-repair.js +130 -0
- package/dist/commands/search.js +21 -5
- package/dist/commands/show.js +131 -52
- package/dist/commands/source-add.js +10 -10
- package/dist/commands/source-manage.js +11 -19
- package/dist/commands/tasks.js +385 -0
- package/dist/commands/url-checker.js +39 -0
- package/dist/commands/vault.js +7 -33
- package/dist/core/action-contributors.js +25 -0
- package/dist/core/asset-registry.js +5 -17
- package/dist/core/asset-spec.js +11 -1
- package/dist/core/common.js +94 -0
- package/dist/core/concurrent.js +22 -0
- package/dist/core/config.js +229 -122
- package/dist/core/events.js +87 -123
- package/dist/core/frontmatter.js +3 -1
- package/dist/core/markdown.js +17 -0
- package/dist/core/memory-improve.js +678 -0
- package/dist/core/parse.js +155 -0
- package/dist/core/paths.js +101 -3
- package/dist/core/proposal-validators.js +61 -0
- package/dist/core/proposals.js +49 -38
- package/dist/core/state-db.js +775 -0
- package/dist/core/time.js +51 -0
- package/dist/core/warn.js +59 -1
- package/dist/indexer/db-search.js +86 -472
- package/dist/indexer/db.js +392 -6
- package/dist/indexer/ensure-index.js +133 -0
- package/dist/indexer/graph-boost.js +247 -94
- package/dist/indexer/graph-db.js +201 -0
- package/dist/indexer/graph-dedup.js +99 -0
- package/dist/indexer/graph-extraction.js +417 -74
- package/dist/indexer/index-context.js +10 -0
- package/dist/indexer/indexer.js +466 -298
- package/dist/indexer/llm-cache.js +47 -0
- package/dist/indexer/match-contributors.js +141 -0
- package/dist/indexer/matchers.js +24 -190
- package/dist/indexer/memory-inference.js +63 -29
- package/dist/indexer/metadata-contributors.js +26 -0
- package/dist/indexer/metadata.js +188 -175
- package/dist/indexer/path-resolver.js +89 -0
- package/dist/indexer/ranking-contributors.js +204 -0
- package/dist/indexer/ranking.js +74 -0
- package/dist/indexer/search-hit-enrichers.js +22 -0
- package/dist/indexer/search-source.js +24 -9
- package/dist/indexer/semantic-status.js +2 -16
- package/dist/indexer/walker.js +25 -0
- package/dist/integrations/agent/config.js +175 -3
- package/dist/integrations/agent/index.js +3 -1
- package/dist/integrations/agent/pipeline.js +39 -0
- package/dist/integrations/agent/profiles.js +67 -5
- package/dist/integrations/agent/prompts.js +114 -29
- package/dist/integrations/agent/runners.js +31 -0
- package/dist/integrations/agent/sdk-runner.js +120 -0
- package/dist/integrations/agent/spawn.js +136 -28
- package/dist/integrations/lockfile.js +10 -18
- package/dist/integrations/session-logs/index.js +65 -0
- package/dist/integrations/session-logs/providers/claude-code.js +56 -0
- package/dist/integrations/session-logs/providers/opencode.js +52 -0
- package/dist/integrations/session-logs/types.js +1 -0
- package/dist/llm/call-ai.js +74 -0
- package/dist/llm/client.js +63 -86
- package/dist/llm/feature-gate.js +27 -16
- package/dist/llm/graph-extract.js +297 -64
- package/dist/llm/memory-infer.js +52 -71
- package/dist/llm/metadata-enhance.js +39 -22
- package/dist/llm/prompts/graph-extract-user-prompt.md +12 -0
- package/dist/output/cli-hints-full.md +277 -0
- package/dist/output/cli-hints-short.md +65 -0
- package/dist/output/cli-hints.js +2 -309
- package/dist/output/renderers.js +196 -124
- package/dist/output/shapes.js +41 -3
- package/dist/output/text.js +257 -21
- package/dist/registry/providers/skills-sh.js +61 -49
- package/dist/registry/providers/static-index.js +44 -48
- package/dist/setup/setup.js +510 -11
- package/dist/sources/provider-factory.js +2 -1
- package/dist/sources/providers/git.js +44 -2
- package/dist/sources/website-ingest.js +4 -0
- package/dist/tasks/backends/cron.js +200 -0
- package/dist/tasks/backends/exec-utils.js +25 -0
- package/dist/tasks/backends/index.js +32 -0
- package/dist/tasks/backends/launchd-template.xml +19 -0
- package/dist/tasks/backends/launchd.js +184 -0
- package/dist/tasks/backends/schtasks-template.xml +29 -0
- package/dist/tasks/backends/schtasks.js +212 -0
- package/dist/tasks/parser.js +198 -0
- package/dist/tasks/resolveAkmBin.js +84 -0
- package/dist/tasks/runner.js +432 -0
- package/dist/tasks/schedule.js +208 -0
- package/dist/tasks/schema.js +13 -0
- package/dist/tasks/validator.js +59 -0
- package/dist/wiki/index-template.md +12 -0
- package/dist/wiki/ingest-workflow-template.md +54 -0
- package/dist/wiki/log-template.md +8 -0
- package/dist/wiki/schema-template.md +61 -0
- package/dist/wiki/wiki-templates.js +12 -0
- package/dist/wiki/wiki.js +10 -61
- package/dist/workflows/authoring.js +5 -25
- package/dist/workflows/db.js +9 -0
- package/dist/workflows/renderer.js +8 -3
- package/dist/workflows/runs.js +73 -88
- package/dist/workflows/scope-key.js +76 -0
- package/dist/workflows/validator.js +1 -1
- package/dist/workflows/workflow-template.md +24 -0
- package/docs/README.md +3 -0
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.7.4.md +1 -1
- package/docs/migration/release-notes/0.7.5.md +20 -0
- package/docs/migration/release-notes/0.8.0.md +43 -0
- package/package.json +4 -3
- package/dist/templates/wiki-templates.js +0 -100
package/dist/output/renderers.js
CHANGED
|
@@ -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
|
/**
|
|
@@ -563,28 +455,207 @@ const vaultEnvRenderer = {
|
|
|
563
455
|
type: "vault",
|
|
564
456
|
name,
|
|
565
457
|
path: ctx.absPath,
|
|
566
|
-
action: 'Vault — keys + comments only. Use `
|
|
458
|
+
action: 'Vault — keys + comments only. Use `source "$(akm vault path <ref>)"` to load values into the current shell, or `akm vault run <ref[/KEY]> -- <command>` to run with injected env. Values stay on disk and are never written to akm\'s stdout.',
|
|
567
459
|
description: comments.length > 0 ? comments.join("\n") : undefined,
|
|
568
460
|
keys,
|
|
569
461
|
comments,
|
|
570
462
|
};
|
|
571
463
|
},
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
464
|
+
enrichSearchHit(hit, _stashDir) {
|
|
465
|
+
const { keys } = listVaultKeys(hit.path);
|
|
466
|
+
if (keys.length > 0)
|
|
467
|
+
hit.keys = keys;
|
|
468
|
+
},
|
|
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
|
+
};
|
|
586
483
|
},
|
|
587
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
|
+
});
|
|
588
659
|
// ── Registration ─────────────────────────────────────────────────────────────
|
|
589
660
|
/** All built-in renderers. */
|
|
590
661
|
const builtinRenderers = [
|
|
@@ -598,6 +669,7 @@ const builtinRenderers = [
|
|
|
598
669
|
workflowMdRenderer,
|
|
599
670
|
scriptSourceRenderer,
|
|
600
671
|
vaultEnvRenderer,
|
|
672
|
+
taskMdRenderer,
|
|
601
673
|
];
|
|
602
674
|
/**
|
|
603
675
|
* Register all built-in renderers with the file-context registry.
|
package/dist/output/shapes.js
CHANGED
|
@@ -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
|
|
@@ -407,19 +437,22 @@ export function shapeSearchHit(hit, detail) {
|
|
|
407
437
|
// `ref` is included at `brief` so agents can run `akm show <ref>` without
|
|
408
438
|
// needing --detail full or --for-agent (REC-03).
|
|
409
439
|
if (detail === "brief")
|
|
410
|
-
return pickFields(hit, ["type", "name", "ref", "action", "estimatedTokens"]);
|
|
440
|
+
return pickFields(hit, ["type", "name", "ref", "action", "estimatedTokens", "keys"]);
|
|
411
441
|
if (detail === "normal") {
|
|
412
442
|
// `warnings` is projected at `normal` so non-fatal hit-level issues are
|
|
413
443
|
// visible without forcing callers up to `--detail full`. Optional
|
|
414
444
|
// `quality` (v1 spec §4.2) is also surfaced when present so callers
|
|
415
445
|
// can see why a `proposed` entry showed up under `--include-proposed`.
|
|
416
|
-
|
|
446
|
+
const shaped = capDescription(pickFields(hit, ["type", "name", "description", "action", "score", "estimatedTokens", "warnings", "quality"]), NORMAL_DESCRIPTION_LIMIT);
|
|
447
|
+
if (Array.isArray(hit.keys) && hit.keys.length > 0)
|
|
448
|
+
shaped.keys = hit.keys;
|
|
449
|
+
return shaped;
|
|
417
450
|
}
|
|
418
451
|
return hit;
|
|
419
452
|
}
|
|
420
453
|
/** Agent-optimized search hit: only fields an LLM agent needs to decide and act */
|
|
421
454
|
export function shapeSearchHitForAgent(hit) {
|
|
422
|
-
const picked = pickFields(hit, ["name", "ref", "type", "description", "action", "score", "estimatedTokens"]);
|
|
455
|
+
const picked = pickFields(hit, ["name", "ref", "type", "description", "action", "score", "estimatedTokens", "keys"]);
|
|
423
456
|
return capDescription(picked, NORMAL_DESCRIPTION_LIMIT);
|
|
424
457
|
}
|
|
425
458
|
export function capDescription(hit, limit) {
|
|
@@ -449,6 +482,7 @@ export function shapeShowOutput(result, detail, forAgent = false) {
|
|
|
449
482
|
"run",
|
|
450
483
|
"setup",
|
|
451
484
|
"cwd",
|
|
485
|
+
"activeRun",
|
|
452
486
|
"toolPolicy",
|
|
453
487
|
"modelHint",
|
|
454
488
|
"agent",
|
|
@@ -458,6 +492,7 @@ export function shapeShowOutput(result, detail, forAgent = false) {
|
|
|
458
492
|
"steps",
|
|
459
493
|
"keys",
|
|
460
494
|
"comments",
|
|
495
|
+
"related",
|
|
461
496
|
]);
|
|
462
497
|
}
|
|
463
498
|
if (detail === "summary") {
|
|
@@ -473,6 +508,7 @@ export function shapeShowOutput(result, detail, forAgent = false) {
|
|
|
473
508
|
"origin",
|
|
474
509
|
"keys",
|
|
475
510
|
"comments",
|
|
511
|
+
"related",
|
|
476
512
|
]);
|
|
477
513
|
}
|
|
478
514
|
const base = pickFields(result, [
|
|
@@ -495,8 +531,10 @@ export function shapeShowOutput(result, detail, forAgent = false) {
|
|
|
495
531
|
"run",
|
|
496
532
|
"setup",
|
|
497
533
|
"cwd",
|
|
534
|
+
"activeRun",
|
|
498
535
|
"keys",
|
|
499
536
|
"comments",
|
|
537
|
+
"related",
|
|
500
538
|
// path and editable are always projected so JSON consumers can locate and
|
|
501
539
|
// edit the asset without needing --detail full (QA #7).
|
|
502
540
|
"path",
|