@plumpslabs/kuma 2.3.17 → 2.3.18
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/dist/{chunk-AJ7HHUDW.js → chunk-ZIXY2COZ.js} +100 -65
- package/dist/index.js +59 -7
- package/dist/{init-BC7FG4C2.js → init-RUKOPMX6.js} +1 -1
- package/dist/{kumaCodeScanner-QYQUL4W6.js → kumaCodeScanner-2RDHZ5F4.js} +5 -8
- package/dist/{skillGenerator-GYEDLFZP.js → skillGenerator-PWEJKZNX.js} +7 -5
- package/package.json +1 -1
|
@@ -76,14 +76,16 @@ var BOOTSTRAP_LINES = [
|
|
|
76
76
|
' 2. `kuma_safety({ action: "guard" })` \u2014 Safety check before work',
|
|
77
77
|
' 3. `kuma_context({ action: "research", scope: "<area>" })` \u2014 Research before editing',
|
|
78
78
|
" 4. *(edit/read using native tools)*",
|
|
79
|
-
' 5. `kuma_memory({ action: "research_save", ... })` \u2014
|
|
80
|
-
' 6. `kuma_memory({ action: "gotcha" })` \u2014 IMMEDIATELY when bug
|
|
81
|
-
' 7. `kuma_memory({ action: "arch_flow" })` \u2014 IMMEDIATELY after
|
|
82
|
-
' 8. `kuma_memory({ action: "decision" })` \u2014
|
|
79
|
+
' 5. `kuma_memory({ action: "research_save", ... })` \u2014 After exploring area (creates search cache)',
|
|
80
|
+
' 6. `kuma_memory({ action: "gotcha" })` \u2014 \u{1F525} IMMEDIATELY when bug found (exponential value)',
|
|
81
|
+
' 7. `kuma_memory({ action: "arch_flow" })` \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential value)',
|
|
82
|
+
' 8. `kuma_memory({ action: "decision" })` \u2014 When choosing between options (preserves rationale)',
|
|
83
83
|
' 9. `kuma_safety({ action: "verify", ... })` \u2014 Run tests / confirm nothing broken',
|
|
84
84
|
' 10. `kuma_context({ action: "changes" })` \u2014 Review session activity',
|
|
85
85
|
"",
|
|
86
|
-
"\u{
|
|
86
|
+
"\u{1F525} **Power Curve:** `arch_flow` + `gotcha` are EXPONENTIAL \u2014 each record saves 5-10 files next session.",
|
|
87
|
+
" The more you record, the more overpowered the agent becomes. These are the highest-value actions.",
|
|
88
|
+
"\u{1F7E2} **SKIP** recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
87
89
|
"\u{1F9E0} Knowledge graph is persistent \u2014 nodes/edges accumulate across sessions, getting richer over time.",
|
|
88
90
|
"",
|
|
89
91
|
"\u26D4 Do NOT skip steps 5-10 after research \u2014 even if no code was changed.",
|
|
@@ -309,20 +311,43 @@ function generateInitMdContent() {
|
|
|
309
311
|
"> \u26A0\uFE0F **Research-only sessions included.** Workflow ini wajib meskipun session hanya membaca/riset tanpa code changes.",
|
|
310
312
|
"",
|
|
311
313
|
"> \u{1F9E0} **Graph Philosophy:** Record findings INLINE as you work, not just at the end. Every time you read a",
|
|
312
|
-
"> file, grep a pattern, or trace a flow \u2014 call `research_save` immediately to persist
|
|
314
|
+
"> file, grep a pattern, or trace a flow \u2014 call `research_save` immediately to persist what you learned.",
|
|
313
315
|
"> The knowledge graph accumulates across sessions. The more you use it, the richer it becomes.",
|
|
314
316
|
"",
|
|
315
|
-
"
|
|
316
|
-
"-
|
|
317
|
-
"
|
|
318
|
-
"-
|
|
319
|
-
"",
|
|
320
|
-
"**
|
|
321
|
-
"-
|
|
322
|
-
"-
|
|
323
|
-
"-
|
|
324
|
-
"
|
|
325
|
-
"
|
|
317
|
+
"> \u{1F52C} **Scanner vs Inline Recording:**",
|
|
318
|
+
"> \u2022 Scanner = cold start only. Auto-detects structure in TS/JS/TSX/JSX files during research step 3.",
|
|
319
|
+
"> \u2022 Inline Recording = primary method. You (the agent) record findings as you read/grep/edit.",
|
|
320
|
+
"> \u2022 Non-TS/JS projects (Go, Ruby, Python, Rust, PHP) rely ENTIRELY on inline recording.",
|
|
321
|
+
"",
|
|
322
|
+
"**AUTO-RECORDED (cold start scanner \u2014 TS/JS only):**",
|
|
323
|
+
"- Files, Functions, Classes \u2192 scanned during research step 3",
|
|
324
|
+
"- Imports, Calls, Extends \u2192 scanned edges",
|
|
325
|
+
"- Components, Routes \u2192 scanned when patterns match",
|
|
326
|
+
"",
|
|
327
|
+
"\u{1F534} **MUST RECORD \u2014 High Impact (use MCP):**",
|
|
328
|
+
"- `arch_flow` \u2014 IMMEDIATELY after each flow hop. Saves reading 5-10 files next session.",
|
|
329
|
+
"- `gotcha` \u2014 IMMEDIATELY when bug/quirk found. No re-research needed.",
|
|
330
|
+
"- `decision` \u2014 IMMEDIATELY when choosing. Preserves rationale context.",
|
|
331
|
+
"- `research_save` \u2014 After exploring area. Creates searchable cache + graph file node.",
|
|
332
|
+
"",
|
|
333
|
+
"\u{1F7E2} **SKIP \u2014 Low Impact (agent can grep faster):**",
|
|
334
|
+
"- Function/class nodes \u2192 grep `funcName(` / `class ClassName`",
|
|
335
|
+
"- Component nodes \u2192 glob `**/*ComponentName*`",
|
|
336
|
+
"- Import edges \u2192 check imports directly",
|
|
337
|
+
"- Route nodes \u2192 check router file directly",
|
|
338
|
+
"- Visual graph \u2192 for humans, not AI agents",
|
|
339
|
+
"",
|
|
340
|
+
"**RECORD INLINE \u2014 Focus on high-impact actions:**",
|
|
341
|
+
"- Finished tracing a flow? \u2192 `arch_flow` IMMEDIATELY (saves reading 5-10 files next session)",
|
|
342
|
+
"- Found a bug/quirk? \u2192 `gotcha` IMMEDIATELY (no re-research needed)",
|
|
343
|
+
"- Chose between options? \u2192 `decision` IMMEDIATELY (preserves rationale)",
|
|
344
|
+
"- Explored a new area? \u2192 `research_save` (creates searchable cache)",
|
|
345
|
+
"",
|
|
346
|
+
"**SKIP recording these \u2014 grep/glob is faster:**",
|
|
347
|
+
"- Function/class nodes \u2192 just `grep funcName(` or `grep class ClassName`",
|
|
348
|
+
"- Component/route nodes \u2192 glob directly",
|
|
349
|
+
"- Import edges \u2192 read import statements",
|
|
350
|
+
"- Visual graph \u2192 for humans, not AI",
|
|
326
351
|
"",
|
|
327
352
|
"### STEP 5: Save Research (RECORD INLINE \u2014 After Every Read/Grep)",
|
|
328
353
|
"```",
|
|
@@ -398,6 +423,7 @@ function generateInitMdContent() {
|
|
|
398
423
|
"| `todo` | Persistent todo CRUD | When managing tasks |",
|
|
399
424
|
"| `context` | Inject context notes | Additional notes when needed |",
|
|
400
425
|
"| `domain_rules` | Layer 1: business rules | Record business rules when discovered |",
|
|
426
|
+
"| `add_node` | Create structural nodes (low impact \u2014 grep is faster) | Rarely needed; only for visualize debugging |",
|
|
401
427
|
"| `layers` | Show all 3 layers summary | Overview memory layers |",
|
|
402
428
|
"",
|
|
403
429
|
"### \u{1F6E1}\uFE0F kuma_safety \u2014 Safety & Policy",
|
|
@@ -457,14 +483,15 @@ function generateInitMdContent() {
|
|
|
457
483
|
" 2. kuma_safety \u2192 guard \u2014 Safety check",
|
|
458
484
|
" 3. kuma_context \u2192 research \u2014 Research target area",
|
|
459
485
|
" --- EDIT/READ (use native tools) ---",
|
|
460
|
-
" 5. kuma_memory \u2192 research_save \u2014
|
|
461
|
-
" 6. kuma_memory \u2192 gotcha \u2014
|
|
462
|
-
" 7. kuma_memory \u2192 arch_flow \u2014
|
|
463
|
-
" 8. kuma_memory \u2192 decision \u2014
|
|
486
|
+
" 5. kuma_memory \u2192 research_save \u2014 After exploring area (creates search cache)",
|
|
487
|
+
" 6. kuma_memory \u2192 gotcha \u2014 \u{1F525} IMMEDIATELY when bug found (exponential)",
|
|
488
|
+
" 7. kuma_memory \u2192 arch_flow \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential)",
|
|
489
|
+
" 8. kuma_memory \u2192 decision \u2014 When choosing (preserves rationale)",
|
|
464
490
|
" 9. kuma_safety \u2192 verify \u2014 Run tests / confirm nothing broken",
|
|
465
491
|
" 10. kuma_context \u2192 changes \u2014 Review session activity",
|
|
466
492
|
"",
|
|
467
|
-
"\u{
|
|
493
|
+
"\u{1F525} `arch_flow` + `gotcha` are EXPONENTIAL \u2014 each record saves 5-10 files next session.",
|
|
494
|
+
"\u{1F7E2} SKIP recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
468
495
|
"\u{1F9E0} Graph is persistent \u2014 nodes/edges accumulate across sessions.",
|
|
469
496
|
"",
|
|
470
497
|
"ON DISCOVERY (When needed):",
|
|
@@ -472,14 +499,19 @@ function generateInitMdContent() {
|
|
|
472
499
|
" kuma_memory \u2192 context \u2014 Additional notes",
|
|
473
500
|
" kuma_memory \u2192 todo \u2014 Task management",
|
|
474
501
|
" kuma_memory \u2192 mine \u2014 Historical context",
|
|
502
|
+
" kuma_memory \u2192 add_node \u2014 Manual function/class/component node (for visualize)",
|
|
475
503
|
"```",
|
|
476
504
|
"",
|
|
477
505
|
"## \u{1F9E0} How the Scanner Works",
|
|
478
506
|
"",
|
|
479
|
-
"Kuma's code scanner (`kumaCodeScanner.ts`) uses **regex-based pattern matching**",
|
|
480
|
-
"
|
|
507
|
+
"Kuma's code scanner (`kumaCodeScanner.ts`) uses **lightweight regex-based pattern matching**",
|
|
508
|
+
"for **cold start** \u2014 giving new agents basic project structure on first session.",
|
|
509
|
+
"It is NOT a full AST parser (no Babel/TypeScript compiler dependency).",
|
|
510
|
+
"",
|
|
511
|
+
"**Scope:** TS/JS/TSX/JSX only. Non-TypeScript projects (Go, Ruby, Python, Rust, PHP, etc.)",
|
|
512
|
+
"rely entirely on **AI inline recording** \u2014 the agent records what it discovers as it works.",
|
|
481
513
|
"",
|
|
482
|
-
"**What
|
|
514
|
+
"**What auto-scanner detects (line-by-line regex, TS/JS only):**",
|
|
483
515
|
"- `function` declarations (named + async + generator)",
|
|
484
516
|
"- Arrow function assignments (`const foo = (...) => ...`)",
|
|
485
517
|
"- Typed arrow functions (`const foo: Type = (...) => ...`)",
|
|
@@ -491,41 +523,41 @@ function generateInitMdContent() {
|
|
|
491
523
|
"- Test files (`.test.`, `.spec.`, `__tests__/`)",
|
|
492
524
|
"",
|
|
493
525
|
"**Known limitations:**",
|
|
494
|
-
"- Regex-based
|
|
526
|
+
"- Regex-based: can miss multi-line constructs or non-standard patterns",
|
|
495
527
|
"- Complex generics or deeply nested syntax may not match",
|
|
496
528
|
"- TypeScript advanced types may be partially parsed",
|
|
497
|
-
"- Scanner runs
|
|
529
|
+
"- Scanner runs during `kuma_context research` step 3 (max 200 files)",
|
|
498
530
|
"- If scanner returns 0 structural nodes, the regex patterns didn't match your code style",
|
|
499
531
|
"",
|
|
500
|
-
"**
|
|
501
|
-
"
|
|
502
|
-
"
|
|
503
|
-
"
|
|
532
|
+
"**Key principle: Scanner = cold start, Inline Recording = primary.**",
|
|
533
|
+
"The scanner populates initial graph structure. Every subsequent session, the agent's",
|
|
534
|
+
"inline recording (research_save, gotcha, arch_flow, decision) enriches the graph further.",
|
|
535
|
+
"The more you use Kuma, the richer the graph becomes \u2014 persistent across sessions.",
|
|
504
536
|
"",
|
|
505
537
|
"---",
|
|
506
538
|
"",
|
|
507
|
-
"## \u{1F4BE} How to
|
|
539
|
+
"## \u{1F4BE} How to Retrieve Past Research \u2014 research_save \u2192 search",
|
|
508
540
|
"",
|
|
509
|
-
"Kuma stores knowledge in two places
|
|
541
|
+
"Kuma stores knowledge in two places. The primary retrieval method for AI agents",
|
|
542
|
+
"is **`search`**, not `visualize`. Visualize is for human debugging, not agent consumption.",
|
|
510
543
|
"",
|
|
511
|
-
"**
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
'-
|
|
515
|
-
|
|
544
|
+
"**Flow: research_save \u2192 search (for agents)**",
|
|
545
|
+
'- Save: `kuma_memory({ action: "research_save", scope: "<file or area>", confidence: 0.8 })`',
|
|
546
|
+
'- Retrieve: `kuma_memory({ action: "search", query: "<term>" })`',
|
|
547
|
+
'- Auto-load: `kuma_context({ action: "research", scope: "<area>" })`',
|
|
548
|
+
'- List cache: `kuma_context({ action: "researches" })`',
|
|
516
549
|
"",
|
|
517
|
-
"**
|
|
518
|
-
|
|
519
|
-
'
|
|
520
|
-
'- Auto-loaded during `kuma_context({ action: "research", scope: "<area>" })`',
|
|
550
|
+
"**Key design:** `research_save` now creates BOTH research cache entries AND",
|
|
551
|
+
"knowledge graph nodes (file + research scope). This means `search` finds",
|
|
552
|
+
"past research even if the graph scanner didn't detect your code style.",
|
|
521
553
|
"",
|
|
522
|
-
"**Quick
|
|
554
|
+
"**Quick retrieval tips:**",
|
|
555
|
+
'- `kuma_memory({ action: "search", query: "<term>" })` \u2014 **primary method**. Finds past research + graph nodes + codebase',
|
|
556
|
+
'- `kuma_context({ action: "research", scope: "<area>" })` \u2014 deep 5-step research, auto-loads past cache',
|
|
523
557
|
'- `kuma_context({ action: "init" })` \u2014 shows graph stats + recent research + health score',
|
|
524
|
-
'- `kuma_context({ action: "research", scope: "<area>" })` \u2014 deep research with graph query',
|
|
525
|
-
'- `kuma_memory({ action: "search", query: "<term>" })` \u2014 search all memories + graph',
|
|
526
|
-
'- `kuma_context({ action: "visualize" })` \u2014 Mermaid diagram of the graph',
|
|
527
558
|
'- `kuma_context({ action: "drift" })` \u2014 check if memories are stale vs actual code',
|
|
528
559
|
'- `kuma_context({ action: "changes" })` \u2014 view session activity log',
|
|
560
|
+
'- `kuma_context({ action: "visualize" })` \u2014 (human debugging) Mermaid diagram of the graph',
|
|
529
561
|
"",
|
|
530
562
|
"---",
|
|
531
563
|
"",
|
|
@@ -598,14 +630,15 @@ function handleOpencodeSecondary(root, results) {
|
|
|
598
630
|
' 2. `kuma_kuma_safety({ action: "guard" })` \u2014 Safety check before work',
|
|
599
631
|
' 3. `kuma_kuma_context({ action: "research", scope: "<area>" })` \u2014 Research before editing',
|
|
600
632
|
" 4. *(edit/read using native tools)*",
|
|
601
|
-
' 5. `kuma_kuma_memory({ action: "research_save", ... })` \u2014
|
|
602
|
-
' 6. `kuma_kuma_memory({ action: "gotcha" })` \u2014
|
|
603
|
-
' 7. `kuma_kuma_memory({ action: "arch_flow" })` \u2014
|
|
604
|
-
' 8. `kuma_kuma_memory({ action: "decision" })` \u2014
|
|
633
|
+
' 5. `kuma_kuma_memory({ action: "research_save", ... })` \u2014 After exploring area (creates search cache)',
|
|
634
|
+
' 6. `kuma_kuma_memory({ action: "gotcha" })` \u2014 \u{1F525} IMMEDIATELY when bug found (exponential)',
|
|
635
|
+
' 7. `kuma_kuma_memory({ action: "arch_flow" })` \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential)',
|
|
636
|
+
' 8. `kuma_kuma_memory({ action: "decision" })` \u2014 When choosing (preserves rationale)',
|
|
605
637
|
' 9. `kuma_kuma_safety({ action: "verify", ... })` \u2014 Run tests / confirm nothing broken',
|
|
606
638
|
' 10. `kuma_kuma_context({ action: "changes" })` \u2014 Review session activity',
|
|
607
639
|
"",
|
|
608
|
-
"\u{
|
|
640
|
+
"\u{1F525} `arch_flow` + `gotcha` = EXPONENTIAL value. Each record saves 5-10 files next session.",
|
|
641
|
+
"\u{1F7E2} SKIP recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
609
642
|
"\u{1F9E0} Graph is persistent \u2014 nodes/edges accumulate across sessions.",
|
|
610
643
|
"",
|
|
611
644
|
"\u26A0\uFE0F **OpenCode platform note:** Tool names are prefixed with `kuma_kuma_*`",
|
|
@@ -729,14 +762,15 @@ function getCombinedAgentsMd(selectedTypes) {
|
|
|
729
762
|
' 2. `[kuma_]safety({ action: "guard" })` \u2014 Safety check before editing',
|
|
730
763
|
' 3. `[kuma_]context({ action: "research", scope: "<area>" })` \u2014 Research before editing',
|
|
731
764
|
" 4. *(edit/read using native tools)*",
|
|
732
|
-
' 5. `[kuma_]memory({ action: "research_save", ... })` \u2014
|
|
733
|
-
' 6. `[kuma_]memory({ action: "gotcha" })` \u2014
|
|
734
|
-
' 7. `[kuma_]memory({ action: "arch_flow" })` \u2014
|
|
735
|
-
' 8. `[kuma_]memory({ action: "decision" })` \u2014
|
|
765
|
+
' 5. `[kuma_]memory({ action: "research_save", ... })` \u2014 After exploring area (creates search cache)',
|
|
766
|
+
' 6. `[kuma_]memory({ action: "gotcha" })` \u2014 \u{1F525} IMMEDIATELY when bug found (exponential)',
|
|
767
|
+
' 7. `[kuma_]memory({ action: "arch_flow" })` \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential)',
|
|
768
|
+
' 8. `[kuma_]memory({ action: "decision" })` \u2014 When choosing (preserves rationale)',
|
|
736
769
|
' 9. `[kuma_]safety({ action: "verify", ... })` \u2014 Run tests / confirm nothing broken',
|
|
737
770
|
' 10. `[kuma_]context({ action: "changes" })` \u2014 Review session activity',
|
|
738
771
|
"",
|
|
739
|
-
"\u{
|
|
772
|
+
"\u{1F525} `arch_flow` + `gotcha` = EXPONENTIAL value. Each record saves 5-10 files next session.",
|
|
773
|
+
"\u{1F7E2} SKIP recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
740
774
|
"\u{1F9E0} Graph is persistent \u2014 nodes/edges accumulate across sessions.",
|
|
741
775
|
"",
|
|
742
776
|
"\u26D4 Do NOT skip steps 5-10 after research \u2014 even if no code was changed.",
|
|
@@ -946,15 +980,16 @@ function handleQuickrefGeneration(root, results) {
|
|
|
946
980
|
' 2. `kuma_safety({ action: "guard" })` \u2014 Safety check',
|
|
947
981
|
' 3. `kuma_context({ action: "research", scope: "<area>" })` \u2014 Research',
|
|
948
982
|
" 4. *(edit/read using native tools)*",
|
|
949
|
-
' 5. `kuma_memory({ action: "research_save", ... })` \u2014
|
|
950
|
-
' 6. `kuma_memory({ action: "gotcha" })` \u2014
|
|
951
|
-
' 7. `kuma_memory({ action: "arch_flow" })` \u2014
|
|
952
|
-
' 8. `kuma_memory({ action: "decision" })` \u2014
|
|
953
|
-
' 9. `kuma_safety({ action: "verify", ... })` \u2014
|
|
954
|
-
' 10. `kuma_context({ action: "changes" })` \u2014 Review
|
|
955
|
-
"",
|
|
956
|
-
"\u{
|
|
957
|
-
"\u{
|
|
983
|
+
' 5. `kuma_memory({ action: "research_save", ... })` \u2014 After exploring area (creates search cache)',
|
|
984
|
+
' 6. `kuma_memory({ action: "gotcha" })` \u2014 \u{1F525} IMMEDIATELY when bug found (exponential)',
|
|
985
|
+
' 7. `kuma_memory({ action: "arch_flow" })` \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential)',
|
|
986
|
+
' 8. `kuma_memory({ action: "decision" })` \u2014 When choosing (preserves rationale)',
|
|
987
|
+
' 9. `kuma_safety({ action: "verify", ... })` \u2014 Run tests / confirm nothing broken',
|
|
988
|
+
' 10. `kuma_context({ action: "changes" })` \u2014 Review session activity',
|
|
989
|
+
"",
|
|
990
|
+
"\u{1F525} `arch_flow` + `gotcha` = EXPONENTIAL value. Each record saves 5-10 files next session.",
|
|
991
|
+
"\u{1F7E2} SKIP recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
992
|
+
"\u{1F9E0} Graph is persistent \u2014 nodes/edges accumulate across sessions.",
|
|
958
993
|
"",
|
|
959
994
|
"\u26D4 Steps 5-10 are mandatory even for research-only sessions!",
|
|
960
995
|
"",
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
ALL_CONFIG_TYPES,
|
|
9
9
|
formatInitResults,
|
|
10
10
|
runInit
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZIXY2COZ.js";
|
|
12
12
|
import {
|
|
13
13
|
formatDecisionTemplate,
|
|
14
14
|
getProactiveMemories,
|
|
@@ -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-
|
|
339
|
+
const { scanCodebase } = await import("./kumaCodeScanner-2RDHZ5F4.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`);
|
|
@@ -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
|
}
|
|
@@ -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-GUQM75WL.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 });
|
|
@@ -955,6 +974,39 @@ async function handleSkillsList(_params) {
|
|
|
955
974
|
const { listDistilledSkills } = await import("./kumaTrajectory-T6DXGOG4.js");
|
|
956
975
|
return await listDistilledSkills();
|
|
957
976
|
}
|
|
977
|
+
async function handleAddNode(params) {
|
|
978
|
+
const type = params.title;
|
|
979
|
+
const name = params.content;
|
|
980
|
+
const filePath = params.scope;
|
|
981
|
+
if (!type || !name) {
|
|
982
|
+
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' })";
|
|
983
|
+
}
|
|
984
|
+
const validTypes = ["function", "class", "component", "file", "api_route", "test"];
|
|
985
|
+
if (!validTypes.includes(type)) {
|
|
986
|
+
return `\u26A0\uFE0F Invalid type "${type}". Valid types: ${validTypes.join(", ")}`;
|
|
987
|
+
}
|
|
988
|
+
try {
|
|
989
|
+
const { upsertNode, nodeId, addEdge } = await import("./kumaGraph-GUQM75WL.js");
|
|
990
|
+
const nodeIdStr = filePath ? `${type}::${filePath}::${name}` : nodeId(type, name);
|
|
991
|
+
await upsertNode({
|
|
992
|
+
id: nodeIdStr,
|
|
993
|
+
type,
|
|
994
|
+
name,
|
|
995
|
+
filePath
|
|
996
|
+
});
|
|
997
|
+
if (filePath) {
|
|
998
|
+
const fileNodeId = nodeId("file", filePath);
|
|
999
|
+
await upsertNode({ id: fileNodeId, type: "file", name: filePath });
|
|
1000
|
+
try {
|
|
1001
|
+
await addEdge({ sourceId: fileNodeId, targetId: nodeIdStr, type: "contains" });
|
|
1002
|
+
} catch {
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
return `\u2705 Node created: **${name}** (${type})${filePath ? ` \u2014 ${filePath}` : ""}`;
|
|
1006
|
+
} catch (err) {
|
|
1007
|
+
return `\u274C Failed to create node: ${err}`;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
958
1010
|
async function handleLayersSummary(_params) {
|
|
959
1011
|
const { getLayersSummary } = await import("./domainRules-ED6EOFVY.js");
|
|
960
1012
|
return getLayersSummary();
|
|
@@ -2190,9 +2242,9 @@ function registerAllTools(server) {
|
|
|
2190
2242
|
);
|
|
2191
2243
|
server.tool(
|
|
2192
2244
|
"kuma_memory",
|
|
2193
|
-
"**Call
|
|
2245
|
+
"**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
2246
|
{
|
|
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"),
|
|
2247
|
+
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
2248
|
scope: z.string().optional().describe("Scope for research_save/search/todo/context/mine/federated"),
|
|
2197
2249
|
query: z.string().optional().describe("Search query for search action"),
|
|
2198
2250
|
content: z.string().optional().describe("Content/notes for research_save / context"),
|
|
@@ -2571,7 +2623,7 @@ async function main() {
|
|
|
2571
2623
|
});
|
|
2572
2624
|
(async () => {
|
|
2573
2625
|
try {
|
|
2574
|
-
const { generateInitMdContent } = await import("./init-
|
|
2626
|
+
const { generateInitMdContent } = await import("./init-RUKOPMX6.js");
|
|
2575
2627
|
const fs7 = await import("fs");
|
|
2576
2628
|
const path7 = await import("path");
|
|
2577
2629
|
const initMdPath = path7.resolve(process.cwd(), ".kuma/init.md");
|
|
@@ -2588,7 +2640,7 @@ async function main() {
|
|
|
2588
2640
|
(async () => {
|
|
2589
2641
|
try {
|
|
2590
2642
|
const { detectAgent, getSkillPath, getAgentLabel } = await import("./agentDetector-YOWQVJFR.js");
|
|
2591
|
-
const { generateSkill, getSecondaryFiles } = await import("./skillGenerator-
|
|
2643
|
+
const { generateSkill, getSecondaryFiles } = await import("./skillGenerator-PWEJKZNX.js");
|
|
2592
2644
|
const fs7 = await import("fs");
|
|
2593
2645
|
const path7 = await import("path");
|
|
2594
2646
|
const detection = detectAgent();
|
|
@@ -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(
|
|
253
|
-
if (!isComponent &&
|
|
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 });
|
|
@@ -10,14 +10,16 @@ var BOOTSTRAP = [
|
|
|
10
10
|
' 2. `kuma_safety({ action: "guard" })` \u2014 Safety check before work',
|
|
11
11
|
' 3. `kuma_context({ action: "research", scope: "<area>" })` \u2014 Research before editing',
|
|
12
12
|
" 4. *(edit/read using native tools)*",
|
|
13
|
-
' 5. `kuma_memory({ action: "research_save", ... })` \u2014
|
|
14
|
-
' 6. `kuma_memory({ action: "gotcha" })` \u2014
|
|
15
|
-
' 7. `kuma_memory({ action: "arch_flow" })` \u2014
|
|
16
|
-
' 8. `kuma_memory({ action: "decision" })` \u2014
|
|
13
|
+
' 5. `kuma_memory({ action: "research_save", ... })` \u2014 After exploring area (creates search cache)',
|
|
14
|
+
' 6. `kuma_memory({ action: "gotcha" })` \u2014 \u{1F525} IMMEDIATELY when bug found (exponential value)',
|
|
15
|
+
' 7. `kuma_memory({ action: "arch_flow" })` \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential value)',
|
|
16
|
+
' 8. `kuma_memory({ action: "decision" })` \u2014 When choosing between options (preserves rationale)',
|
|
17
17
|
' 9. `kuma_safety({ action: "verify", ... })` \u2014 Run tests / confirm nothing broken',
|
|
18
18
|
' 10. `kuma_context({ action: "changes" })` \u2014 Review session activity',
|
|
19
19
|
"",
|
|
20
|
-
"\u{
|
|
20
|
+
"\u{1F525} **Power Curve:** `arch_flow` + `gotcha` are EXPONENTIAL \u2014 each record saves 5-10 files next session.",
|
|
21
|
+
" The more you record, the more overpowered the agent becomes. These are the highest-value actions.",
|
|
22
|
+
"\u{1F7E2} **SKIP** recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
21
23
|
"\u{1F9E0} Knowledge graph is persistent \u2014 nodes/edges accumulate across sessions, getting richer over time.",
|
|
22
24
|
"",
|
|
23
25
|
"\u26D4 Do NOT skip steps 5-10 after research \u2014 even if no code was changed.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumpslabs/kuma",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.18",
|
|
4
4
|
"description": "Safety-first context & orchestration engine for AI coding agents. MCP server with mandatory research pipeline, knowledge graph, impact analysis, decision memory, and safety guard — works with any MCP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|