@plumpslabs/kuma 2.3.17 → 2.3.19

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 (31) hide show
  1. package/dist/{chunk-3TX6Q37T.js → chunk-3BRBJZ7P.js} +3 -3
  2. package/dist/{chunk-SPHI2BOO.js → chunk-3OHYYXYN.js} +1 -1
  3. package/dist/{chunk-AJ7HHUDW.js → chunk-ABKE45T4.js} +138 -68
  4. package/dist/{chunk-Q2444HWO.js → chunk-FKRSI5U5.js} +1 -1
  5. package/dist/{chunk-RI3DKY62.js → chunk-GFLSAXAH.js} +1 -1
  6. package/dist/{chunk-OJALFQ4H.js → chunk-L7F67KUP.js} +2 -2
  7. package/dist/{chunk-R6B3VUSB.js → chunk-LVKOGXLC.js} +2 -2
  8. package/dist/{chunk-ZKDYTYMS.js → chunk-PRUTTZBS.js} +143 -4
  9. package/dist/{contextDigest-5JXLH56Z.js → contextDigest-QB5XHPXE.js} +3 -3
  10. package/dist/{domainRules-ED6EOFVY.js → domainRules-QLPAQASB.js} +2 -2
  11. package/dist/index.js +141 -51
  12. package/dist/{init-BC7FG4C2.js → init-PL4XL662.js} +1 -1
  13. package/dist/{kumaCheckpoint-XIQWRMGV.js → kumaCheckpoint-J2LDQMEO.js} +2 -2
  14. package/dist/{kumaCodeScanner-QYQUL4W6.js → kumaCodeScanner-J6B2EHGI.js} +7 -10
  15. package/dist/{kumaDb-IC7UX7PU.js → kumaDb-4XZ5S2LH.js} +1 -1
  16. package/dist/{kumaDriftDetector-QBY6OJOO.js → kumaDriftDetector-TOORILSZ.js} +1 -1
  17. package/dist/{kumaGotchas-5HODT5RI.js → kumaGotchas-XRGFFBTA.js} +3 -3
  18. package/dist/{kumaGraph-GUQM75WL.js → kumaGraph-UMXZNGYF.js} +4 -2
  19. package/dist/{kumaMemory-FMOWIODH.js → kumaMemory-FBJMV77G.js} +2 -2
  20. package/dist/{kumaMiner-3RXEOCBP.js → kumaMiner-XJETL7TL.js} +3 -3
  21. package/dist/{kumaPolicyEngine-ORBWL5PT.js → kumaPolicyEngine-2QDJDLM7.js} +2 -2
  22. package/dist/{kumaProgressiveContext-CVSNPY3W.js → kumaProgressiveContext-MWEDRXOH.js} +4 -4
  23. package/dist/{kumaSearch-B5WVYHHD.js → kumaSearch-PV4QTKE7.js} +1 -1
  24. package/dist/{kumaTrajectory-T6DXGOG4.js → kumaTrajectory-7NOAVNG2.js} +2 -2
  25. package/dist/{kumaVerifier-6NTJQU7B.js → kumaVerifier-6YEGC77M.js} +2 -2
  26. package/dist/{kumaVisualize-AFL7STLL.js → kumaVisualize-264OEBGJ.js} +17 -1
  27. package/dist/{safetyAudit-32WSA4Z5.js → safetyAudit-O45SPNTS.js} +2 -2
  28. package/dist/{safetyScore-WU27EOG4.js → safetyScore-TMMRD2MV.js} +5 -5
  29. package/dist/{sessionMemory-4UWA3E5J.js → sessionMemory-YPKVIOMV.js} +1 -1
  30. package/dist/{skillGenerator-GYEDLFZP.js → skillGenerator-PWEJKZNX.js} +7 -5
  31. package/package.json +1 -1
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getActiveGotchas
3
- } from "./chunk-Q2444HWO.js";
3
+ } from "./chunk-FKRSI5U5.js";
4
4
  import {
5
5
  sessionMemory
6
- } from "./chunk-R6B3VUSB.js";
6
+ } from "./chunk-LVKOGXLC.js";
7
7
  import {
8
8
  getDb
9
- } from "./chunk-3TX6Q37T.js";
9
+ } from "./chunk-3BRBJZ7P.js";
10
10
  import {
11
11
  getProjectRoot
12
12
  } from "./chunk-E2KFPEBT.js";
@@ -6,8 +6,8 @@ import {
6
6
  getLayersSummary,
7
7
  readLayer,
8
8
  writeLayer
9
- } from "./chunk-Q2444HWO.js";
10
- import "./chunk-R6B3VUSB.js";
9
+ } from "./chunk-FKRSI5U5.js";
10
+ import "./chunk-LVKOGXLC.js";
11
11
  import "./chunk-E2KFPEBT.js";
12
12
  export {
13
13
  appendToLayer,
package/dist/index.js CHANGED
@@ -3,27 +3,27 @@ import {
3
3
  auditStats,
4
4
  queryAudit,
5
5
  recordAudit
6
- } from "./chunk-RI3DKY62.js";
6
+ } from "./chunk-GFLSAXAH.js";
7
7
  import {
8
8
  ALL_CONFIG_TYPES,
9
9
  formatInitResults,
10
10
  runInit
11
- } from "./chunk-AJ7HHUDW.js";
11
+ } from "./chunk-ABKE45T4.js";
12
12
  import {
13
13
  formatDecisionTemplate,
14
14
  getProactiveMemories,
15
15
  recordDecision,
16
16
  scoreMemoryRelevance
17
- } from "./chunk-OJALFQ4H.js";
17
+ } from "./chunk-L7F67KUP.js";
18
18
  import {
19
19
  buildDriftMessages,
20
20
  getGitDiffStat,
21
21
  getSessionStats,
22
22
  getUnresolvedCount
23
- } from "./chunk-SPHI2BOO.js";
23
+ } from "./chunk-3OHYYXYN.js";
24
24
  import {
25
25
  sessionMemory
26
- } from "./chunk-R6B3VUSB.js";
26
+ } from "./chunk-LVKOGXLC.js";
27
27
  import {
28
28
  analyzeImpact,
29
29
  autoHeal,
@@ -34,7 +34,7 @@ import {
34
34
  getGraphStats,
35
35
  searchGraph,
36
36
  traceFlow
37
- } from "./chunk-ZKDYTYMS.js";
37
+ } from "./chunk-PRUTTZBS.js";
38
38
  import {
39
39
  addContextNote,
40
40
  addSecurityFinding,
@@ -59,7 +59,7 @@ import {
59
59
  saveResearchCache,
60
60
  updateDecisionStatus,
61
61
  updateTodoStatus
62
- } from "./chunk-3TX6Q37T.js";
62
+ } from "./chunk-3BRBJZ7P.js";
63
63
  import {
64
64
  getProjectRoot,
65
65
  validateFilePath
@@ -240,8 +240,8 @@ async function handleInit(_params) {
240
240
  lines.push(` \u{1F4DD} Modified: ${summary.modifiedFiles?.length || 0} file(s)`);
241
241
  lines.push(` \u{1F6E0}\uFE0F Tool calls: ${summary.toolCallCount}`);
242
242
  try {
243
- const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-WU27EOG4.js");
244
- const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-IC7UX7PU.js");
243
+ const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-TMMRD2MV.js");
244
+ const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-4XZ5S2LH.js");
245
245
  const score = await computeSafetyScore(_params.goal);
246
246
  const checksStr = JSON.stringify(score.checks);
247
247
  await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
@@ -336,7 +336,7 @@ async function handleResearch(params) {
336
336
  lines.push(" \u26A0\uFE0F Graph query failed");
337
337
  }
338
338
  try {
339
- const { scanCodebase } = await import("./kumaCodeScanner-QYQUL4W6.js");
339
+ const { scanCodebase } = await import("./kumaCodeScanner-J6B2EHGI.js");
340
340
  const scanResult = await scanCodebase({ scope, maxFiles: 100 });
341
341
  if (scanResult.nodeCount > 0 || scanResult.edgeCount > 0) {
342
342
  lines.push(` \u{1F52C} Auto-scanned ${scanResult.filesScanned} files \u2192 ${scanResult.nodeCount} nodes, ${scanResult.edgeCount} edges`);
@@ -422,8 +422,8 @@ async function handleResearches(_params) {
422
422
  async function handleHealth(_params) {
423
423
  sessionMemory.recordToolCall("kuma_context_health", {});
424
424
  try {
425
- const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-WU27EOG4.js");
426
- const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-IC7UX7PU.js");
425
+ const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-TMMRD2MV.js");
426
+ const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-4XZ5S2LH.js");
427
427
  const score = await computeSafetyScore();
428
428
  const checksStr = JSON.stringify(score.checks);
429
429
  await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
@@ -450,8 +450,8 @@ async function handleSync(params) {
450
450
  lines.push(` \u{1F6E0}\uFE0F Tool calls: ${summary.toolCallCount}`);
451
451
  lines.push("");
452
452
  try {
453
- const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-WU27EOG4.js");
454
- const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-IC7UX7PU.js");
453
+ const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-TMMRD2MV.js");
454
+ const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-4XZ5S2LH.js");
455
455
  const score = await computeSafetyScore(params.goal);
456
456
  const checksStr = JSON.stringify(score.checks);
457
457
  await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
@@ -462,14 +462,14 @@ async function handleSync(params) {
462
462
  }
463
463
  lines.push("");
464
464
  try {
465
- const { getGraphStats: getGraphStats2 } = await import("./kumaGraph-GUQM75WL.js");
465
+ const { getGraphStats: getGraphStats2 } = await import("./kumaGraph-UMXZNGYF.js");
466
466
  lines.push("**Knowledge Graph**");
467
467
  lines.push(await getGraphStats2());
468
468
  } catch {
469
469
  }
470
470
  lines.push("");
471
471
  try {
472
- const { getProactiveMemories: getProactiveMemories2 } = await import("./kumaMemory-FMOWIODH.js");
472
+ const { getProactiveMemories: getProactiveMemories2 } = await import("./kumaMemory-FBJMV77G.js");
473
473
  const memories = getProactiveMemories2();
474
474
  if (memories) {
475
475
  lines.push("**Relevant Memories**");
@@ -483,7 +483,7 @@ async function handleSync(params) {
483
483
  }
484
484
  async function handleVisualize(params) {
485
485
  const scope = params.scope;
486
- const { generateVisualizeReport } = await import("./kumaVisualize-AFL7STLL.js");
486
+ const { generateVisualizeReport } = await import("./kumaVisualize-264OEBGJ.js");
487
487
  return await generateVisualizeReport({
488
488
  scope,
489
489
  type: "flowchart",
@@ -493,11 +493,11 @@ async function handleVisualize(params) {
493
493
  async function handleDigest(_params) {
494
494
  sessionMemory.recordToolCall("kuma_context_digest", {});
495
495
  try {
496
- const { generateContextDigest } = await import("./contextDigest-5JXLH56Z.js");
496
+ const { generateContextDigest } = await import("./contextDigest-QB5XHPXE.js");
497
497
  return await generateContextDigest();
498
498
  } catch (err) {
499
499
  try {
500
- const { generateDigest } = await import("./domainRules-ED6EOFVY.js");
500
+ const { generateDigest } = await import("./domainRules-QLPAQASB.js");
501
501
  return generateDigest();
502
502
  } catch {
503
503
  return `Error generating digest: ${err}`;
@@ -507,7 +507,7 @@ async function handleDigest(_params) {
507
507
  async function handleDrift(_params) {
508
508
  sessionMemory.recordToolCall("kuma_context_drift", {});
509
509
  try {
510
- const { detectDrift, formatDriftReport, flagStaleRecords } = await import("./kumaDriftDetector-QBY6OJOO.js");
510
+ const { detectDrift, formatDriftReport, flagStaleRecords } = await import("./kumaDriftDetector-TOORILSZ.js");
511
511
  await flagStaleRecords();
512
512
  const records = await detectDrift();
513
513
  return formatDriftReport(records);
@@ -518,7 +518,7 @@ async function handleDrift(_params) {
518
518
  async function handleProgressive(params) {
519
519
  sessionMemory.recordToolCall("kuma_context_progressive", { scope: params.scope, section: params.section });
520
520
  try {
521
- const { getProgressiveContext, loadSection } = await import("./kumaProgressiveContext-CVSNPY3W.js");
521
+ const { getProgressiveContext, loadSection } = await import("./kumaProgressiveContext-MWEDRXOH.js");
522
522
  if (params.section) {
523
523
  const validSections = ["domain_rules", "architecture", "gotchas", "decisions", "graph", "changes", "health"];
524
524
  if (!validSections.includes(params.section)) {
@@ -670,7 +670,13 @@ var MEMORY_ALIASES = {
670
670
  // Skills synonyms
671
671
  "skills": "skills",
672
672
  "distilled-skills": "skills",
673
- "skill-list": "skills"
673
+ "skill-list": "skills",
674
+ // Add node synonyms
675
+ "add_node": "add_node",
676
+ "add-node": "add_node",
677
+ "node": "add_node",
678
+ "create-node": "add_node",
679
+ "record-node": "add_node"
674
680
  };
675
681
  async function handleMemory(params) {
676
682
  const rawAction = params.action || "session";
@@ -716,6 +722,8 @@ async function handleMemory(params) {
716
722
  return handleTrajectoryList(params);
717
723
  case "skills":
718
724
  return handleSkillsList(params);
725
+ case "add_node":
726
+ return handleAddNode(params);
719
727
  default:
720
728
  return `Unknown action "${action}".`;
721
729
  }
@@ -726,7 +734,7 @@ async function handleDecision(params) {
726
734
  case "template":
727
735
  return formatDecisionTemplate();
728
736
  case "suggest": {
729
- const { shouldRecordDecision } = await import("./kumaMemory-FMOWIODH.js");
737
+ const { shouldRecordDecision } = await import("./kumaMemory-FBJMV77G.js");
730
738
  const check = shouldRecordDecision();
731
739
  return check.worth ? `\u{1F4A1} Decision suggested: "${check.title}"
732
740
  Use kuma_memory({ action: 'decision', title: '...', context: '...', rationale: '...', outcome: '...' }) to record.` : "\u2705 No decision needed at this time.";
@@ -754,6 +762,17 @@ async function handleResearchSave(params) {
754
762
  validatedAt: (/* @__PURE__ */ new Date()).toISOString()
755
763
  });
756
764
  await saveResearchCache(scope, record, void 0, params.confidence);
765
+ try {
766
+ const { upsertNode, nodeId } = await import("./kumaGraph-UMXZNGYF.js");
767
+ await upsertNode({ id: nodeId("file", scope), type: "file", name: scope });
768
+ await upsertNode({
769
+ id: `research::${scope}`,
770
+ type: "variable",
771
+ name: `research:${scope}`,
772
+ metadata: { confidence: params.confidence || 0.8 }
773
+ });
774
+ } catch {
775
+ }
757
776
  try {
758
777
  const researchDir = path2.join(getProjectRoot(), ".kuma", "research");
759
778
  if (!fs2.existsSync(researchDir)) fs2.mkdirSync(researchDir, { recursive: true });
@@ -804,11 +823,11 @@ async function handleSearch(params) {
804
823
  if (!query) return "\u26A0\uFE0F query or scope parameter required.";
805
824
  const limit = params.limit || 20;
806
825
  const memResults = sessionMemory.searchMemory(query, limit);
807
- const { searchGraph: searchGraph2 } = await import("./kumaGraph-GUQM75WL.js");
826
+ const { searchGraph: searchGraph2 } = await import("./kumaGraph-UMXZNGYF.js");
808
827
  const graphResults = await searchGraph2(query, Math.min(limit, 10));
809
828
  let hybridResults = "";
810
829
  try {
811
- const { hybridSearch, formatHybridResults } = await import("./kumaSearch-B5WVYHHD.js");
830
+ const { hybridSearch, formatHybridResults } = await import("./kumaSearch-PV4QTKE7.js");
812
831
  const semanticResults = await hybridSearch(query, 8);
813
832
  if (semanticResults.length > 0) {
814
833
  hybridResults = "\n" + formatHybridResults(query, semanticResults);
@@ -892,7 +911,7 @@ async function handleDecisionLog(params) {
892
911
  }
893
912
  async function handleMine(params) {
894
913
  sessionMemory.recordToolCall("kuma_memory_mine", { scope: params.scope });
895
- const { mineHistoricalDecisions } = await import("./kumaMiner-3RXEOCBP.js");
914
+ const { mineHistoricalDecisions } = await import("./kumaMiner-XJETL7TL.js");
896
915
  return await mineHistoricalDecisions({
897
916
  scope: params.scope,
898
917
  since: typeof params.since === "string" ? params.since : void 0,
@@ -901,7 +920,45 @@ async function handleMine(params) {
901
920
  });
902
921
  }
903
922
  async function handleLayerAction(layer, params) {
904
- const { readLayer, writeLayer } = await import("./domainRules-ED6EOFVY.js");
923
+ const { readLayer, writeLayer } = await import("./domainRules-QLPAQASB.js");
924
+ if (layer === "arch_flow" && params.content) {
925
+ const content = params.content;
926
+ const domainMatch = content.match(/domain\s*[:]\s*([^|\n]+)/i);
927
+ const hopsMatch = content.match(/hops\s*[:]\s*([^|\n]+)/i);
928
+ const gotchasMatch = content.match(/gotchas?\s*[:]\s*([^|\n]+)/i);
929
+ const decisionsMatch = content.match(/decisions?\s*[:]\s*([^|\n]+)/i);
930
+ const filesMatch = content.match(/files?\s*[:]\s*([^|\n]+)/i);
931
+ if (domainMatch) {
932
+ const domain = domainMatch[1].trim();
933
+ const hopsStr = hopsMatch ? hopsMatch[1].trim() : "";
934
+ const gotchasStr = gotchasMatch ? gotchasMatch[1].trim() : "";
935
+ const decisionsStr = decisionsMatch ? decisionsMatch[1].trim() : "";
936
+ const filesStr = filesMatch ? filesMatch[1].trim() : "";
937
+ const hops = hopsStr ? hopsStr.split("\u2192").map((h) => h.trim()).filter(Boolean).map((h, i, arr) => ({
938
+ from: i === 0 ? domain : arr[i - 1],
939
+ to: h,
940
+ relation: "flows",
941
+ description: h
942
+ })) : [];
943
+ const gotchas = gotchasStr ? gotchasStr.split(",").map((g) => g.trim()).filter(Boolean) : [];
944
+ const decisions = decisionsStr ? decisionsStr.split(",").map((d) => d.trim()).filter(Boolean) : [];
945
+ const filePaths = filesStr ? filesStr.split(",").map((f) => f.trim()).filter(Boolean) : [];
946
+ try {
947
+ const { recordDomainFlow } = await import("./kumaGraph-UMXZNGYF.js");
948
+ const flow = await recordDomainFlow({ domain, hops, gotchas, decisions, filePaths });
949
+ await writeLayer("arch_flow", content);
950
+ return `\u2705 Domain flow "${domain}" recorded \u2014 ${flow.nodeCount} nodes, ${flow.edgeCount} edges created.
951
+ \u{1F3DB}\uFE0F **Domain Anchor:** ${domain}
952
+ \u{1F504} **Hops:** ${hops.length}
953
+ \u26A0\uFE0F **Gotchas:** ${gotchas.length}
954
+ \u{1F4C1} **Files:** ${filePaths.length}`;
955
+ } catch (err) {
956
+ await writeLayer("arch_flow", content);
957
+ return `\u2705 Architecture flow saved (text only). Graph recording failed: ${err}`;
958
+ }
959
+ }
960
+ return writeLayer("arch_flow", content);
961
+ }
905
962
  if (params.content) {
906
963
  return writeLayer(layer, params.content);
907
964
  }
@@ -909,7 +966,7 @@ async function handleLayerAction(layer, params) {
909
966
  }
910
967
  async function handleGotchaAction(params) {
911
968
  if (params.content && params.scope) {
912
- const { addGotcha } = await import("./kumaGotchas-5HODT5RI.js");
969
+ const { addGotcha } = await import("./kumaGotchas-XRGFFBTA.js");
913
970
  return await addGotcha({
914
971
  filePath: params.scope,
915
972
  description: params.content,
@@ -917,7 +974,7 @@ async function handleGotchaAction(params) {
917
974
  workaround: params.description
918
975
  });
919
976
  }
920
- const { listGotchas, syncGotchasToDb } = await import("./kumaGotchas-5HODT5RI.js");
977
+ const { listGotchas, syncGotchasToDb } = await import("./kumaGotchas-XRGFFBTA.js");
921
978
  await syncGotchasToDb();
922
979
  return await listGotchas({
923
980
  filePath: params.scope,
@@ -927,10 +984,10 @@ async function handleGotchaAction(params) {
927
984
  async function handleFederated(params) {
928
985
  sessionMemory.recordToolCall("kuma_memory_federated", { scope: params.scope, uri: params.uri });
929
986
  if (params.uri) {
930
- const { resolveFederatedNode } = await import("./kumaGraph-GUQM75WL.js");
987
+ const { resolveFederatedNode } = await import("./kumaGraph-UMXZNGYF.js");
931
988
  return await resolveFederatedNode(params.uri);
932
989
  }
933
- const { listFederatedReferences } = await import("./kumaGraph-GUQM75WL.js");
990
+ const { listFederatedReferences } = await import("./kumaGraph-UMXZNGYF.js");
934
991
  return await listFederatedReferences();
935
992
  }
936
993
  async function handleGenTest(params) {
@@ -938,25 +995,58 @@ async function handleGenTest(params) {
938
995
  if (params.target) {
939
996
  const id = parseInt(params.target, 10);
940
997
  if (!isNaN(id)) {
941
- const { generateTestFromTrajectoryId } = await import("./kumaTrajectory-T6DXGOG4.js");
998
+ const { generateTestFromTrajectoryId } = await import("./kumaTrajectory-7NOAVNG2.js");
942
999
  return await generateTestFromTrajectoryId(id);
943
1000
  }
944
1001
  }
945
- const { listGeneratedTests } = await import("./kumaTrajectory-T6DXGOG4.js");
1002
+ const { listGeneratedTests } = await import("./kumaTrajectory-7NOAVNG2.js");
946
1003
  return await listGeneratedTests();
947
1004
  }
948
1005
  async function handleTrajectoryList(params) {
949
1006
  sessionMemory.recordToolCall("kuma_memory_trajectory", {});
950
- const { listTrajectories } = await import("./kumaTrajectory-T6DXGOG4.js");
1007
+ const { listTrajectories } = await import("./kumaTrajectory-7NOAVNG2.js");
951
1008
  return await listTrajectories(params.limit || 10);
952
1009
  }
953
1010
  async function handleSkillsList(_params) {
954
1011
  sessionMemory.recordToolCall("kuma_memory_skills", {});
955
- const { listDistilledSkills } = await import("./kumaTrajectory-T6DXGOG4.js");
1012
+ const { listDistilledSkills } = await import("./kumaTrajectory-7NOAVNG2.js");
956
1013
  return await listDistilledSkills();
957
1014
  }
1015
+ async function handleAddNode(params) {
1016
+ const type = params.title;
1017
+ const name = params.content;
1018
+ const filePath = params.scope;
1019
+ if (!type || !name) {
1020
+ return "\u26A0\uFE0F `title` (node type: function/class/component/file/api_route/test) and `content` (node name) required.\nExample: kuma_memory({ action: 'add_node', title: 'function', content: 'sendMessage', scope: 'ChatService.ts' })";
1021
+ }
1022
+ const validTypes = ["function", "class", "component", "file", "api_route", "test"];
1023
+ if (!validTypes.includes(type)) {
1024
+ return `\u26A0\uFE0F Invalid type "${type}". Valid types: ${validTypes.join(", ")}`;
1025
+ }
1026
+ try {
1027
+ const { upsertNode, nodeId, addEdge } = await import("./kumaGraph-UMXZNGYF.js");
1028
+ const nodeIdStr = filePath ? `${type}::${filePath}::${name}` : nodeId(type, name);
1029
+ await upsertNode({
1030
+ id: nodeIdStr,
1031
+ type,
1032
+ name,
1033
+ filePath
1034
+ });
1035
+ if (filePath) {
1036
+ const fileNodeId = nodeId("file", filePath);
1037
+ await upsertNode({ id: fileNodeId, type: "file", name: filePath });
1038
+ try {
1039
+ await addEdge({ sourceId: fileNodeId, targetId: nodeIdStr, type: "contains" });
1040
+ } catch {
1041
+ }
1042
+ }
1043
+ return `\u2705 Node created: **${name}** (${type})${filePath ? ` \u2014 ${filePath}` : ""}`;
1044
+ } catch (err) {
1045
+ return `\u274C Failed to create node: ${err}`;
1046
+ }
1047
+ }
958
1048
  async function handleLayersSummary(_params) {
959
- const { getLayersSummary } = await import("./domainRules-ED6EOFVY.js");
1049
+ const { getLayersSummary } = await import("./domainRules-QLPAQASB.js");
960
1050
  return getLayersSummary();
961
1051
  }
962
1052
 
@@ -1956,7 +2046,7 @@ async function handleLock(params) {
1956
2046
  }
1957
2047
  async function handleHealth2(_params) {
1958
2048
  try {
1959
- const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-WU27EOG4.js");
2049
+ const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-TMMRD2MV.js");
1960
2050
  const score = await computeSafetyScore();
1961
2051
  await saveHealthSnapshot(score.score, score.risk, JSON.stringify(score.checks), score.summary);
1962
2052
  return formatSafetyScore(score);
@@ -2063,7 +2153,7 @@ async function handleClean(_params) {
2063
2153
  async function handlePolicy(params) {
2064
2154
  sessionMemory.recordToolCall("kuma_safety_policy", {});
2065
2155
  if (params.command) {
2066
- const { evaluateCommand, evaluateFilePath } = await import("./kumaPolicyEngine-ORBWL5PT.js");
2156
+ const { evaluateCommand, evaluateFilePath } = await import("./kumaPolicyEngine-2QDJDLM7.js");
2067
2157
  const commandVerdict = evaluateCommand(params.command);
2068
2158
  const lines = [];
2069
2159
  lines.push(`\u{1F4DC} **Policy Check**: ${commandVerdict.allowed ? "\u2705 Allowed" : "\u26D4 Blocked"}`);
@@ -2090,7 +2180,7 @@ async function handlePolicy(params) {
2090
2180
  }
2091
2181
  return lines.join("\n");
2092
2182
  }
2093
- const { formatPolicyStatus } = await import("./kumaPolicyEngine-ORBWL5PT.js");
2183
+ const { formatPolicyStatus } = await import("./kumaPolicyEngine-2QDJDLM7.js");
2094
2184
  return formatPolicyStatus();
2095
2185
  }
2096
2186
  async function handleAstValidation(params) {
@@ -2109,18 +2199,18 @@ async function handleAstValidation(params) {
2109
2199
  async function handleCheckpoint(params) {
2110
2200
  sessionMemory.recordToolCall("kuma_safety_checkpoint", { label: params.label });
2111
2201
  if (!params.label) return "\u26A0\uFE0F label parameter required. Example: kuma_safety({ action: 'checkpoint', label: 'pre-feature-x' })";
2112
- const { createCheckpoint } = await import("./kumaCheckpoint-XIQWRMGV.js");
2202
+ const { createCheckpoint } = await import("./kumaCheckpoint-J2LDQMEO.js");
2113
2203
  return await createCheckpoint(params.label, params.description);
2114
2204
  }
2115
2205
  async function handleRollbackLabel(params) {
2116
2206
  sessionMemory.recordToolCall("kuma_safety_rollback_label", { label: params.label });
2117
2207
  if (!params.label) return "\u26A0\uFE0F label parameter required. Example: kuma_safety({ action: 'rollback_label', label: 'pre-feature-x' })";
2118
- const { rollbackToCheckpoint } = await import("./kumaCheckpoint-XIQWRMGV.js");
2208
+ const { rollbackToCheckpoint } = await import("./kumaCheckpoint-J2LDQMEO.js");
2119
2209
  return await rollbackToCheckpoint(params.label);
2120
2210
  }
2121
2211
  async function handleCheckpointList(_params) {
2122
2212
  sessionMemory.recordToolCall("kuma_safety_checkpoint_list", {});
2123
- const { listCheckpoints } = await import("./kumaCheckpoint-XIQWRMGV.js");
2213
+ const { listCheckpoints } = await import("./kumaCheckpoint-J2LDQMEO.js");
2124
2214
  return listCheckpoints();
2125
2215
  }
2126
2216
  async function handleContract(params) {
@@ -2149,7 +2239,7 @@ async function handleVerify(params) {
2149
2239
  }
2150
2240
  _lastVerifyCall = now;
2151
2241
  sessionMemory.recordToolCall("kuma_safety_verify", { scope: params.scope || params.filePath });
2152
- const { runAutoVerification } = await import("./kumaVerifier-6NTJQU7B.js");
2242
+ const { runAutoVerification } = await import("./kumaVerifier-6YEGC77M.js");
2153
2243
  return await runAutoVerification({
2154
2244
  scope: params.scope || params.filePath,
2155
2245
  force: params.force,
@@ -2190,9 +2280,9 @@ function registerAllTools(server) {
2190
2280
  );
2191
2281
  server.tool(
2192
2282
  "kuma_memory",
2193
- "**Call AFTER research/editing every session** (including research-only). Record INLINE as you work.\n\nRECORD INLINE (call IMMEDIATELY during research):\n\u2022 STEP 5: `research_save` \u2014 every read/grep that finds new files/functions. Don't wait!\n\u2022 STEP 6: `gotcha` \u2014 IMMEDIATELY when you discover bugs/quirks. Record INLINE, not at the end.\n\u2022 STEP 7: `arch_flow` \u2014 IMMEDIATELY after EACH flow hop trace. Record before next task.\n\u2022 STEP 8: `decision` \u2014 IMMEDIATELY when choosing between options or finding architecture patterns.\n\nON DISCOVERY (when you encounter something):\n\u2022 `domain_rules` \u2014 uncovered business rules? Save them!\n\u2022 `context` \u2014 need to inject extra notes? Use this!\n\u2022 `todo` \u2014 create persistent task items\n\u2022 `mine` \u2014 extract historical context from git log\n\nOther actions: session, heal, search, changes, benchmark, layers.",
2283
+ "**Call after research/editing** (including research-only). Record what matters, skip what doesn't.\n\n\u{1F534} MUST RECORD \u2014 High Impact (saves agent time next session):\n\u2022 STEP 5: `research_save` \u2014 every read/grep that finds new files. Creates searchable cache.\n\u2022 STEP 6: `gotcha` \u2014 IMMEDIATELY when you discover bugs/quirks. No re-research.\n\u2022 STEP 7: `arch_flow` \u2014 IMMEDIATELY after EACH flow hop. Saves reading 5-10 files.\n\u2022 STEP 8: `decision` \u2014 IMMEDIATELY when choosing between options. Preserves rationale.\n\n\u{1F7E2} SKIP using MCP (agent native tools are faster):\n\u2022 Function/class nodes \u2192 grep\n\u2022 Component/route nodes \u2192 glob or check directly\n\u2022 Import edges \u2192 read imports directly\n\u2022 Visual graph \u2192 for humans, not AI agents\n\nOther actions: session, heal, search, changes, benchmark, layers.",
2194
2284
  {
2195
- action: z.enum(["decision", "mine", "research_save", "session", "heal", "search", "changes", "todo", "context", "benchmark", "decision_log", "domain_rules", "arch_flow", "gotcha", "layers", "federated", "gen_test", "trajectory", "skills"]).describe("Memory action: decision=ADR, mine=mine git log & comments, research_save=save, session=summary, heal=repair, search=search, changes=log, todo=manage todos, context=inject notes, benchmark=capture/diff, decision_log=manage decisions, domain_rules=Layer 1 business rules (Issue #17), arch_flow=Layer 2 architecture flow (Issue #17), gotcha=Layer 3 known gotchas (Issue #17/#21), layers=all 3 layers summary, federated=resolve federated kuma:// URI (Issue #27), gen_test=generate test from trajectory (Issue #28), trajectory=list trajectories, skills=list distilled skills"),
2285
+ action: z.enum(["decision", "mine", "research_save", "session", "heal", "search", "changes", "todo", "context", "benchmark", "decision_log", "domain_rules", "arch_flow", "gotcha", "layers", "federated", "gen_test", "trajectory", "skills", "add_node"]).describe("Memory action: decision=ADR, mine=mine git log & comments, research_save=save (creates file + graph node), session=summary, heal=repair, search=search, changes=log, todo=manage todos, context=inject notes, benchmark=capture/diff, decision_log=manage decisions, domain_rules=Layer 1 business rules (Issue #17), arch_flow=Layer 2 architecture flow (Issue #17), gotcha=Layer 3 known gotchas (Issue #17/#21), layers=all 3 layers summary, federated=resolve federated kuma:// URI (Issue #27), gen_test=generate test from trajectory (Issue #28), trajectory=list trajectories, skills=list distilled skills, add_node=manually create function/class/component structural nodes"),
2196
2286
  scope: z.string().optional().describe("Scope for research_save/search/todo/context/mine/federated"),
2197
2287
  query: z.string().optional().describe("Search query for search action"),
2198
2288
  content: z.string().optional().describe("Content/notes for research_save / context"),
@@ -2362,7 +2452,7 @@ async function main() {
2362
2452
  console.error("");
2363
2453
  let killedCount = 0;
2364
2454
  try {
2365
- const { getRunningVerificationPid } = await import("./kumaVerifier-6NTJQU7B.js");
2455
+ const { getRunningVerificationPid } = await import("./kumaVerifier-6YEGC77M.js");
2366
2456
  const pid = getRunningVerificationPid();
2367
2457
  if (pid) {
2368
2458
  try {
@@ -2571,7 +2661,7 @@ async function main() {
2571
2661
  });
2572
2662
  (async () => {
2573
2663
  try {
2574
- const { generateInitMdContent } = await import("./init-BC7FG4C2.js");
2664
+ const { generateInitMdContent } = await import("./init-PL4XL662.js");
2575
2665
  const fs7 = await import("fs");
2576
2666
  const path7 = await import("path");
2577
2667
  const initMdPath = path7.resolve(process.cwd(), ".kuma/init.md");
@@ -2588,7 +2678,7 @@ async function main() {
2588
2678
  (async () => {
2589
2679
  try {
2590
2680
  const { detectAgent, getSkillPath, getAgentLabel } = await import("./agentDetector-YOWQVJFR.js");
2591
- const { generateSkill, getSecondaryFiles } = await import("./skillGenerator-GYEDLFZP.js");
2681
+ const { generateSkill, getSecondaryFiles } = await import("./skillGenerator-PWEJKZNX.js");
2592
2682
  const fs7 = await import("fs");
2593
2683
  const path7 = await import("path");
2594
2684
  const detection = detectAgent();
@@ -2629,7 +2719,7 @@ async function main() {
2629
2719
  console.error(`[${SERVER_NAME}] \u2705 Restored session (${sessionInfo.toolCallCount} previous tool calls)`);
2630
2720
  }
2631
2721
  try {
2632
- const { buildFromSessionMemory } = await import("./kumaGraph-GUQM75WL.js");
2722
+ const { buildFromSessionMemory } = await import("./kumaGraph-UMXZNGYF.js");
2633
2723
  const edgeCount = await buildFromSessionMemory();
2634
2724
  if (edgeCount > 0) {
2635
2725
  console.error(`[${SERVER_NAME}] \u2705 Graph auto-populated with ${edgeCount} entries from session memory`);
@@ -2649,7 +2739,7 @@ async function main() {
2649
2739
  console.error(`[${SERVER_NAME}] \u26A0\uFE0F Scratch directory setup: ${err}`);
2650
2740
  }
2651
2741
  try {
2652
- const { getDb: getDb2, saveDb } = await import("./kumaDb-IC7UX7PU.js");
2742
+ const { getDb: getDb2, saveDb } = await import("./kumaDb-4XZ5S2LH.js");
2653
2743
  const db = await getDb2();
2654
2744
  db.run(
2655
2745
  `INSERT INTO sessions (started_at, goal, tool_calls) VALUES (?, ?, ?)`,
@@ -2689,7 +2779,7 @@ fi
2689
2779
  console.error(`[${SERVER_NAME}] \u26A0\uFE0F Auto-capture hook setup: ${err}`);
2690
2780
  }
2691
2781
  try {
2692
- const { buildSearchVectors } = await import("./kumaSearch-B5WVYHHD.js");
2782
+ const { buildSearchVectors } = await import("./kumaSearch-PV4QTKE7.js");
2693
2783
  const vectors = await buildSearchVectors();
2694
2784
  if (vectors.length > 0) {
2695
2785
  console.error(`[${SERVER_NAME}] \u2705 Search vector cache pre-warmed (${vectors.length} documents)`);
@@ -4,7 +4,7 @@ import {
4
4
  formatInitResults,
5
5
  generateInitMdContent,
6
6
  runInit
7
- } from "./chunk-AJ7HHUDW.js";
7
+ } from "./chunk-ABKE45T4.js";
8
8
  import "./chunk-E2KFPEBT.js";
9
9
  export {
10
10
  ALL_CONFIG_TYPES,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  sessionMemory
3
- } from "./chunk-R6B3VUSB.js";
3
+ } from "./chunk-LVKOGXLC.js";
4
4
  import {
5
5
  getDb,
6
6
  resetDbInstance
7
- } from "./chunk-3TX6Q37T.js";
7
+ } from "./chunk-3BRBJZ7P.js";
8
8
  import {
9
9
  getProjectRoot
10
10
  } from "./chunk-E2KFPEBT.js";
@@ -2,8 +2,8 @@ import {
2
2
  addEdge,
3
3
  nodeId,
4
4
  upsertNode
5
- } from "./chunk-ZKDYTYMS.js";
6
- import "./chunk-3TX6Q37T.js";
5
+ } from "./chunk-PRUTTZBS.js";
6
+ import "./chunk-3BRBJZ7P.js";
7
7
  import {
8
8
  getProjectRoot
9
9
  } from "./chunk-E2KFPEBT.js";
@@ -27,11 +27,12 @@ var CLASS_RE = /(?:export\s+)?(?:abstract\s+)?class\s+(\w+)(?:\s+extends\s+(\w+)
27
27
  var IMPORT_RE = /import\s+(?:\{([^}]*)\}\s+from\s+)?(?:\w+\s+from\s+)?(?:\*\s+as\s+\w+\s+from\s+)?['"]([^'"]+)['"]/g;
28
28
  var JSX_RETURN_RE = /return\s*\(?\s*</;
29
29
  var JSX_ELEMENT_RE = /<([A-Z]\w+)[\s/>]/g;
30
+ var JSX_IMPLICIT_RE = /=>\s*(?:\(\s*)?</;
30
31
  var EXPRESS_ROUTE_RE = /\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]\s*,\s*(\w+)/g;
31
32
  var HONO_ROUTE_RE = /c\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]/g;
32
- var TEST_PATTERNS = [".test.", ".spec.", "__tests__", "/test/"];
33
33
  var EXPORT_RE = /export\s+(?:default\s+)?(\w+)/g;
34
34
  var CALL_RE = /(\w+)\s*\(/g;
35
+ var TEST_PATTERNS = [".test.", ".spec.", "__tests__", "/test/"];
35
36
  var knownComponents = /* @__PURE__ */ new Set();
36
37
  var knownFunctions = /* @__PURE__ */ new Set();
37
38
  var symbolLocations = /* @__PURE__ */ new Map();
@@ -236,11 +237,9 @@ function parseFile(filePath, content) {
236
237
  }
237
238
  }
238
239
  }
239
- const JSX_IMPLICIT_RE = /=>\s*(?:\(\s*)?</;
240
240
  if (hasJSX) {
241
241
  for (const fn of [...result.functions]) {
242
242
  const fnStartLine = fn.line - 1;
243
- const fnLine = lines[fnStartLine];
244
243
  const endLine = Math.min(fnStartLine + 50, lines.length);
245
244
  let isComponent = false;
246
245
  for (let i = fnStartLine; i < endLine; i++) {
@@ -249,12 +248,10 @@ function parseFile(filePath, content) {
249
248
  break;
250
249
  }
251
250
  }
252
- if (!isComponent && JSX_IMPLICIT_RE.test(fnLine)) isComponent = true;
253
- if (!isComponent && fnLine.includes("=>") && fnStartLine + 1 < endLine) {
251
+ if (!isComponent && JSX_IMPLICIT_RE.test(lines[fnStartLine])) isComponent = true;
252
+ if (!isComponent && fnStartLine + 1 < endLine) {
254
253
  const nextLine = lines[fnStartLine + 1].trim();
255
- if (nextLine.startsWith("<") || nextLine.startsWith("(") || nextLine.startsWith("<>")) {
256
- isComponent = true;
257
- }
254
+ if (nextLine.startsWith("<") || nextLine.startsWith("(") || nextLine.startsWith("<>")) isComponent = true;
258
255
  }
259
256
  if (isComponent) {
260
257
  result.components.push({ name: fn.name, line: fn.line });
@@ -29,7 +29,7 @@ import {
29
29
  saveVerification,
30
30
  updateDecisionStatus,
31
31
  updateTodoStatus
32
- } from "./chunk-3TX6Q37T.js";
32
+ } from "./chunk-3BRBJZ7P.js";
33
33
  import "./chunk-E2KFPEBT.js";
34
34
  export {
35
35
  addContextNote,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getDb,
3
3
  saveDb
4
- } from "./chunk-3TX6Q37T.js";
4
+ } from "./chunk-3BRBJZ7P.js";
5
5
  import {
6
6
  getProjectRoot
7
7
  } from "./chunk-E2KFPEBT.js";
@@ -2,14 +2,14 @@ import {
2
2
  appendToLayer,
3
3
  checkFileGotchas,
4
4
  getActiveGotchas
5
- } from "./chunk-Q2444HWO.js";
5
+ } from "./chunk-FKRSI5U5.js";
6
6
  import {
7
7
  sessionMemory
8
- } from "./chunk-R6B3VUSB.js";
8
+ } from "./chunk-LVKOGXLC.js";
9
9
  import {
10
10
  getDb,
11
11
  saveDb
12
- } from "./chunk-3TX6Q37T.js";
12
+ } from "./chunk-3BRBJZ7P.js";
13
13
  import "./chunk-E2KFPEBT.js";
14
14
 
15
15
  // src/engine/kumaGotchas.ts
@@ -9,6 +9,7 @@ import {
9
9
  nodeId,
10
10
  queryGraph,
11
11
  recordApiRoute,
12
+ recordDomainFlow,
12
13
  recordFileDefinition,
13
14
  recordFunctionCall,
14
15
  recordImport,
@@ -17,8 +18,8 @@ import {
17
18
  searchGraph,
18
19
  traceFlow,
19
20
  upsertNode
20
- } from "./chunk-ZKDYTYMS.js";
21
- import "./chunk-3TX6Q37T.js";
21
+ } from "./chunk-PRUTTZBS.js";
22
+ import "./chunk-3BRBJZ7P.js";
22
23
  import "./chunk-E2KFPEBT.js";
23
24
  export {
24
25
  addEdge,
@@ -31,6 +32,7 @@ export {
31
32
  nodeId,
32
33
  queryGraph,
33
34
  recordApiRoute,
35
+ recordDomainFlow,
34
36
  recordFileDefinition,
35
37
  recordFunctionCall,
36
38
  recordImport,