@plumpslabs/kuma 2.3.23 → 2.3.24
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/index.js +176 -64
- package/package.json +1 -1
- package/packages/ide/studio/public/index.html +3 -4
package/dist/index.js
CHANGED
|
@@ -8866,33 +8866,24 @@ function handleQuickrefGeneration(root, results) {
|
|
|
8866
8866
|
const content = [
|
|
8867
8867
|
"# Kuma Quick Reference",
|
|
8868
8868
|
"",
|
|
8869
|
-
"
|
|
8869
|
+
"## Lean Mode (default \u2014 for speed)",
|
|
8870
|
+
"1. `init` \u2192 edit \u2192 record (if needed)",
|
|
8870
8871
|
"",
|
|
8871
|
-
"##
|
|
8872
|
+
"## Standard Mode (for safety)",
|
|
8873
|
+
"1. `init` \u2192 `guard` \u2192 `research` \u2192 edit \u2192 `record` \u2192 `verify`",
|
|
8872
8874
|
"",
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
' 3. `kuma_context({ action: "research", scope: "<area>" })` \u2014 Research',
|
|
8876
|
-
" 4. *(edit/read using native tools)*",
|
|
8877
|
-
' 5. `kuma_memory({ action: "research_save", ... })` \u2014 After exploring area (creates search cache)',
|
|
8878
|
-
' 6. `kuma_memory({ action: "gotcha" })` \u2014 \u{1F525} IMMEDIATELY when bug found (exponential)',
|
|
8879
|
-
' 7. `kuma_memory({ action: "arch_flow" })` \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential)',
|
|
8880
|
-
' 8. `kuma_memory({ action: "decision" })` \u2014 When choosing (preserves rationale)',
|
|
8881
|
-
' 9. `kuma_safety({ action: "verify", ... })` \u2014 Run tests / confirm nothing broken',
|
|
8882
|
-
' 10. `kuma_context({ action: "changes" })` \u2014 Review session activity',
|
|
8883
|
-
"",
|
|
8884
|
-
"\u{1F525} `arch_flow` + `gotcha` = EXPONENTIAL value. Each record saves 5-10 files next session.",
|
|
8885
|
-
"\u{1F7E2} SKIP recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
8886
|
-
"\u{1F9E0} Graph is persistent \u2014 nodes/edges accumulate across sessions.",
|
|
8875
|
+
"## Full Mode (for complex changes)",
|
|
8876
|
+
"1. `init` \u2192 `guard` \u2192 `research` \u2192 `impact` \u2192 edit \u2192 `record` \u2192 `verify` \u2192 `changes`",
|
|
8887
8877
|
"",
|
|
8888
|
-
"
|
|
8878
|
+
"## Record Rules",
|
|
8879
|
+
"- **MUST:** decision, gotcha",
|
|
8880
|
+
"- **SKIP:** function, class, import, route",
|
|
8889
8881
|
"",
|
|
8890
8882
|
"## Platform Tool Names",
|
|
8883
|
+
"- OpenCode / Antigravity: `kuma_kuma_*`",
|
|
8884
|
+
"- Others: `kuma_*`",
|
|
8891
8885
|
"",
|
|
8892
|
-
"
|
|
8893
|
-
"- **Other platforms:** Use `kuma_*` directly (e.g. `kuma_context`)",
|
|
8894
|
-
"",
|
|
8895
|
-
"\u{1F4D6} Full rules: `.kuma/init.md`",
|
|
8886
|
+
"\u{1F4D6} Full: `.kuma/init.md` | \u{1F4CA} Modes: `.kuma/MODE.md` | \u{1F7E2} Skip: `.kuma/SKIP_RULES.md`",
|
|
8896
8887
|
"_Generated by Kuma MCP - https://github.com/plumpslabs/kuma_"
|
|
8897
8888
|
].join("\n");
|
|
8898
8889
|
try {
|
|
@@ -8904,11 +8895,9 @@ function handleQuickrefGeneration(root, results) {
|
|
|
8904
8895
|
results.push({ type: "claude", filePath: ".kuma/quickref.md", action: "skipped" });
|
|
8905
8896
|
return;
|
|
8906
8897
|
}
|
|
8907
|
-
results.push({ type: "claude", filePath: ".kuma/quickref.md", action: "skipped" });
|
|
8908
|
-
} else {
|
|
8909
|
-
fs24.writeFileSync(quickrefPath, content, "utf-8");
|
|
8910
|
-
results.push({ type: "claude", filePath: ".kuma/quickref.md", action: "created" });
|
|
8911
8898
|
}
|
|
8899
|
+
fs24.writeFileSync(quickrefPath, content, "utf-8");
|
|
8900
|
+
results.push({ type: "claude", filePath: ".kuma/quickref.md", action: "created" });
|
|
8912
8901
|
} catch (err) {
|
|
8913
8902
|
results.push({
|
|
8914
8903
|
type: "claude",
|
|
@@ -8918,6 +8907,150 @@ function handleQuickrefGeneration(root, results) {
|
|
|
8918
8907
|
});
|
|
8919
8908
|
}
|
|
8920
8909
|
}
|
|
8910
|
+
function handleModeMdGeneration(root, results) {
|
|
8911
|
+
const filePath = path24.resolve(root, ".kuma/MODE.md");
|
|
8912
|
+
const content = [
|
|
8913
|
+
"# Adaptive Mode Selector",
|
|
8914
|
+
"",
|
|
8915
|
+
"## Mode Definitions",
|
|
8916
|
+
"",
|
|
8917
|
+
"| Mode | When to Use | Token Cost | Steps |",
|
|
8918
|
+
"|------|-------------|------------|-------|",
|
|
8919
|
+
"| **Lean** (default) | Small fixes, familiar code, hotfixes, < 3 files | ~100 | 3 |",
|
|
8920
|
+
"| **Standard** | New features, unfamiliar modules, 3-10 files | ~300 | 5 |",
|
|
8921
|
+
"| **Full** | Cross-module refactors, architecture changes, > 10 files | ~500 | 7 |",
|
|
8922
|
+
"",
|
|
8923
|
+
"## Auto-Detection Rules",
|
|
8924
|
+
"",
|
|
8925
|
+
"```",
|
|
8926
|
+
"IF file_count < 3 AND area_familiar == true:",
|
|
8927
|
+
' mode = "lean"',
|
|
8928
|
+
"ELSE IF file_count <= 10 OR area_familiar == false:",
|
|
8929
|
+
' mode = "standard"',
|
|
8930
|
+
"ELSE IF file_count > 10 OR cross_module == true:",
|
|
8931
|
+
' mode = "full"',
|
|
8932
|
+
"```",
|
|
8933
|
+
"",
|
|
8934
|
+
"## Mode Behaviors",
|
|
8935
|
+
"",
|
|
8936
|
+
"### Lean Mode (Default)",
|
|
8937
|
+
"- Skip: guard, research, verify, changes",
|
|
8938
|
+
"- Record: only if decision/gotcha explicit",
|
|
8939
|
+
"- Focus: speed, minimal overhead",
|
|
8940
|
+
"",
|
|
8941
|
+
"### Standard Mode",
|
|
8942
|
+
"- Include: guard (before unfamiliar), research (before edit)",
|
|
8943
|
+
"- Record: decision, gotcha, arch_flow (if complex)",
|
|
8944
|
+
"- Focus: safety + knowledge capture",
|
|
8945
|
+
"",
|
|
8946
|
+
"### Full Mode",
|
|
8947
|
+
"- Include: all steps including impact, changes",
|
|
8948
|
+
"- Record: everything valuable",
|
|
8949
|
+
"- Focus: completeness, audit trail",
|
|
8950
|
+
"",
|
|
8951
|
+
"_Generated by Kuma MCP - https://github.com/plumpslabs/kuma_"
|
|
8952
|
+
].join("\n");
|
|
8953
|
+
try {
|
|
8954
|
+
const dir = path24.dirname(filePath);
|
|
8955
|
+
if (!fs24.existsSync(dir)) fs24.mkdirSync(dir, { recursive: true });
|
|
8956
|
+
if (!fs24.existsSync(filePath)) {
|
|
8957
|
+
fs24.writeFileSync(filePath, content, "utf-8");
|
|
8958
|
+
results.push({ type: "claude", filePath: ".kuma/MODE.md", action: "created" });
|
|
8959
|
+
}
|
|
8960
|
+
} catch (err) {
|
|
8961
|
+
results.push({ type: "claude", filePath: ".kuma/MODE.md", action: "error", error: err instanceof Error ? err.message : String(err) });
|
|
8962
|
+
}
|
|
8963
|
+
}
|
|
8964
|
+
function handleSkipRulesMdGeneration(root, results) {
|
|
8965
|
+
const filePath = path24.resolve(root, ".kuma/SKIP_RULES.md");
|
|
8966
|
+
const content = [
|
|
8967
|
+
"# Skip Rules \u2014 What NOT to Record",
|
|
8968
|
+
"",
|
|
8969
|
+
"## \u{1F7E2} NEVER Record (grep/glob is faster)",
|
|
8970
|
+
"",
|
|
8971
|
+
"| What | Why Skip | Better Tool |",
|
|
8972
|
+
"|------|----------|-------------|",
|
|
8973
|
+
"| Function definitions | `grep funcName(` | Grep |",
|
|
8974
|
+
"| Class definitions | `grep class ClassName` | Grep |",
|
|
8975
|
+
"| Import statements | Read import block | Read |",
|
|
8976
|
+
"| Component definitions | `glob **/*Component*` | Glob |",
|
|
8977
|
+
"| Route definitions | Check router file | Read |",
|
|
8978
|
+
"| Type/interface definitions | `grep interface TypeName` | Grep |",
|
|
8979
|
+
"| Variable/const declarations | `grep const varName` | Grep |",
|
|
8980
|
+
"| Test file locations | `glob **/*.test.*` | Glob |",
|
|
8981
|
+
"",
|
|
8982
|
+
"## \u{1F534} ALWAYS Record (high value)",
|
|
8983
|
+
"",
|
|
8984
|
+
"| What | Why Record | Tool |",
|
|
8985
|
+
"|------|------------|------|",
|
|
8986
|
+
"| Architecture decisions with rationale | Preserves context | `decision` |",
|
|
8987
|
+
"| Bugs/quirks found and fixed | Prevents re-discovery | `gotcha` |",
|
|
8988
|
+
"| Cross-module flow paths | Saves 5-10 files next session | `arch_flow` |",
|
|
8989
|
+
"| Business rules discovered | Domain knowledge | `domain_rules` |",
|
|
8990
|
+
"",
|
|
8991
|
+
"## \u{1F7E1} Record ONLY If Complex",
|
|
8992
|
+
"",
|
|
8993
|
+
"| What | Condition | Tool |",
|
|
8994
|
+
"|------|-----------|------|",
|
|
8995
|
+
"| Research findings | Multi-file exploration (> 3 files) | `research_save` |",
|
|
8996
|
+
"| Architecture flow | Cross-service or > 3 hops | `arch_flow` |",
|
|
8997
|
+
"| Feature definition | High-level feature with owns edges | `feature` |",
|
|
8998
|
+
"",
|
|
8999
|
+
"_Generated by Kuma MCP - https://github.com/plumpslabs/kuma_"
|
|
9000
|
+
].join("\n");
|
|
9001
|
+
try {
|
|
9002
|
+
const dir = path24.dirname(filePath);
|
|
9003
|
+
if (!fs24.existsSync(dir)) fs24.mkdirSync(dir, { recursive: true });
|
|
9004
|
+
if (!fs24.existsSync(filePath)) {
|
|
9005
|
+
fs24.writeFileSync(filePath, content, "utf-8");
|
|
9006
|
+
results.push({ type: "claude", filePath: ".kuma/SKIP_RULES.md", action: "created" });
|
|
9007
|
+
}
|
|
9008
|
+
} catch (err) {
|
|
9009
|
+
results.push({ type: "claude", filePath: ".kuma/SKIP_RULES.md", action: "error", error: err instanceof Error ? err.message : String(err) });
|
|
9010
|
+
}
|
|
9011
|
+
}
|
|
9012
|
+
function handleStalenessMdGeneration(root, results) {
|
|
9013
|
+
const filePath = path24.resolve(root, ".kuma/STALENESS.md");
|
|
9014
|
+
const content = [
|
|
9015
|
+
"# Auto-Staleness Detection",
|
|
9016
|
+
"",
|
|
9017
|
+
"## Staleness Signals",
|
|
9018
|
+
"",
|
|
9019
|
+
"| Signal | Detection | Action |",
|
|
9020
|
+
"|--------|-----------|--------|",
|
|
9021
|
+
"| File modified after save | Compare file mtime vs research_save timestamp | Mark STALE, skip cache |",
|
|
9022
|
+
"| Git commit touches file | `git log --since` on researched files | Mark STALE, warn |",
|
|
9023
|
+
'| Age > 7 days | Current time - research_save timestamp | Warn: "Cache may be stale" |',
|
|
9024
|
+
"| Age > 30 days | Current time - research_save timestamp | Auto-invalidate, re-read |",
|
|
9025
|
+
"",
|
|
9026
|
+
"## Recovery Protocol",
|
|
9027
|
+
"",
|
|
9028
|
+
"```",
|
|
9029
|
+
"ON stale_detected:",
|
|
9030
|
+
" 1. Skip cached data",
|
|
9031
|
+
" 2. Re-read file from disk",
|
|
9032
|
+
" 3. Update research_save timestamp",
|
|
9033
|
+
" 4. Continue with fresh data",
|
|
9034
|
+
"",
|
|
9035
|
+
"ON search_conflict:",
|
|
9036
|
+
" 1. Prefer recent research (newer timestamp)",
|
|
9037
|
+
" 2. If same age, prefer live file over cache",
|
|
9038
|
+
" 3. Log conflict for review",
|
|
9039
|
+
"```",
|
|
9040
|
+
"",
|
|
9041
|
+
"_Generated by Kuma MCP - https://github.com/plumpslabs/kuma_"
|
|
9042
|
+
].join("\n");
|
|
9043
|
+
try {
|
|
9044
|
+
const dir = path24.dirname(filePath);
|
|
9045
|
+
if (!fs24.existsSync(dir)) fs24.mkdirSync(dir, { recursive: true });
|
|
9046
|
+
if (!fs24.existsSync(filePath)) {
|
|
9047
|
+
fs24.writeFileSync(filePath, content, "utf-8");
|
|
9048
|
+
results.push({ type: "claude", filePath: ".kuma/STALENESS.md", action: "created" });
|
|
9049
|
+
}
|
|
9050
|
+
} catch (err) {
|
|
9051
|
+
results.push({ type: "claude", filePath: ".kuma/STALENESS.md", action: "error", error: err instanceof Error ? err.message : String(err) });
|
|
9052
|
+
}
|
|
9053
|
+
}
|
|
8921
9054
|
function handleInitMdGeneration(root, results) {
|
|
8922
9055
|
const initMdPath = path24.resolve(root, ".kuma/init.md");
|
|
8923
9056
|
try {
|
|
@@ -8944,6 +9077,9 @@ function handleInitMdGeneration(root, results) {
|
|
|
8944
9077
|
});
|
|
8945
9078
|
}
|
|
8946
9079
|
handleQuickrefGeneration(root, results);
|
|
9080
|
+
handleModeMdGeneration(root, results);
|
|
9081
|
+
handleSkipRulesMdGeneration(root, results);
|
|
9082
|
+
handleStalenessMdGeneration(root, results);
|
|
8947
9083
|
}
|
|
8948
9084
|
function handleCodewhaleSecondary(root, results) {
|
|
8949
9085
|
const mcpPath = path24.resolve(root, ".codewhale/mcp.json");
|
|
@@ -9681,30 +9817,18 @@ var init_skillGenerator = __esm({
|
|
|
9681
9817
|
"use strict";
|
|
9682
9818
|
BOOTSTRAP = [
|
|
9683
9819
|
"Kuma MCP tools are available (kuma_context, kuma_memory, kuma_safety).",
|
|
9684
|
-
'**Before coding, call `kuma_context({ action: "init" })`** to load project context
|
|
9820
|
+
'**Before coding, call `kuma_context({ action: "init" })`** to load project context.',
|
|
9685
9821
|
"Project knowledge persists in `.kuma/memories/*.md` across sessions.",
|
|
9686
9822
|
"",
|
|
9687
|
-
"\
|
|
9823
|
+
"\u26A1 **ADAPTIVE WORKFLOW (Lean Mode by Default):**",
|
|
9824
|
+
" \u2022 **Lean Mode (Default, < 3 files):** `init` \u2192 edit/read \u2192 record (`decision`/`gotcha` if needed)",
|
|
9825
|
+
" \u2022 **Standard Mode (3-10 files/unfamiliar):** `init` \u2192 `guard` \u2192 `research` \u2192 edit \u2192 `record` \u2192 `verify`",
|
|
9826
|
+
" \u2022 **Full Mode (> 10 files/refactor):** `init` \u2192 `guard` \u2192 `research` \u2192 `impact` \u2192 edit \u2192 `record` \u2192 `verify` \u2192 `changes`",
|
|
9688
9827
|
"",
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
' 3. `kuma_context({ action: "research", scope: "<area>" })` \u2014 Research before editing',
|
|
9692
|
-
" 4. *(edit/read using native tools)*",
|
|
9693
|
-
' 5. `kuma_memory({ action: "research_save", ... })` \u2014 After exploring area (creates search cache)',
|
|
9694
|
-
' 6. `kuma_memory({ action: "gotcha" })` \u2014 \u{1F525} IMMEDIATELY when bug found (exponential value)',
|
|
9695
|
-
' 7. `kuma_memory({ action: "arch_flow" })` \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential value)',
|
|
9696
|
-
' 8. `kuma_memory({ action: "decision" })` \u2014 When choosing between options (preserves rationale)',
|
|
9697
|
-
' 9. `kuma_safety({ action: "verify", ... })` \u2014 Run tests / confirm nothing broken',
|
|
9698
|
-
' 10. `kuma_context({ action: "changes" })` \u2014 Review session activity',
|
|
9699
|
-
"",
|
|
9700
|
-
"\u{1F525} **Power Curve:** `arch_flow` + `gotcha` are EXPONENTIAL \u2014 each record saves 5-10 files next session.",
|
|
9701
|
-
" The more you record, the more overpowered the agent becomes. These are the highest-value actions.",
|
|
9702
|
-
"\u{1F7E2} **SKIP** recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
9703
|
-
"\u{1F9E0} Knowledge graph is persistent \u2014 nodes/edges accumulate across sessions, getting richer over time.",
|
|
9828
|
+
"\u{1F534} **MUST RECORD:** `decision` (rationale), `gotcha` (bug/quirk), `arch_flow` (complex flow)",
|
|
9829
|
+
"\u{1F7E2} **SKIP RECORDING:** function, class, import, route (use native grep/glob instead)",
|
|
9704
9830
|
"",
|
|
9705
|
-
"\
|
|
9706
|
-
"\u{1F5D1}\uFE0F **Delete/Clear:** `delete_node` (delete node/gotcha/todo/decision) | `clear` (wipe entire graph)",
|
|
9707
|
-
"\u{1F4D6} Full rules: `.kuma/init.md`",
|
|
9831
|
+
"\u{1F4D6} Full rules & modes: `.kuma/init.md` | `.kuma/MODE.md` | `.kuma/SKIP_RULES.md`",
|
|
9708
9832
|
"\u{1F9E0} Tools: `kuma_context` | `kuma_memory` | `kuma_safety`"
|
|
9709
9833
|
].join("\n");
|
|
9710
9834
|
BOOTSTRAP_OPENCODE = [
|
|
@@ -9712,27 +9836,15 @@ var init_skillGenerator = __esm({
|
|
|
9712
9836
|
'**Before coding, call `kuma_kuma_context({ action: "init" })`** to load project context.',
|
|
9713
9837
|
"Project knowledge persists in `.kuma/memories/*.md` across sessions.",
|
|
9714
9838
|
"",
|
|
9715
|
-
"\
|
|
9716
|
-
"",
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
' 3. `kuma_kuma_context({ action: "research", scope: "<area>" })` \u2014 Research before editing',
|
|
9720
|
-
" 4. *(edit/read using native tools)*",
|
|
9721
|
-
' 5. `kuma_kuma_memory({ action: "research_save", ... })` \u2014 After exploring area (creates search cache)',
|
|
9722
|
-
' 6. `kuma_kuma_memory({ action: "gotcha" })` \u2014 \u{1F525} IMMEDIATELY when bug found (exponential value)',
|
|
9723
|
-
' 7. `kuma_kuma_memory({ action: "arch_flow" })` \u2014 \u{1F525} IMMEDIATELY after each flow hop (exponential value)',
|
|
9724
|
-
' 8. `kuma_kuma_memory({ action: "decision" })` \u2014 When choosing between options (preserves rationale)',
|
|
9725
|
-
' 9. `kuma_kuma_safety({ action: "verify", ... })` \u2014 Run tests / confirm nothing broken',
|
|
9726
|
-
' 10. `kuma_kuma_context({ action: "changes" })` \u2014 Review session activity',
|
|
9839
|
+
"\u26A1 **ADAPTIVE WORKFLOW (Lean Mode by Default):**",
|
|
9840
|
+
' \u2022 **Lean Mode (Default, < 3 files):** `kuma_kuma_context({ action: "init" })` \u2192 edit/read \u2192 record (`decision`/`gotcha`)',
|
|
9841
|
+
" \u2022 **Standard Mode (3-10 files/unfamiliar):** `init` \u2192 `guard` \u2192 `research` \u2192 edit \u2192 `record` \u2192 `verify`",
|
|
9842
|
+
" \u2022 **Full Mode (> 10 files/refactor):** `init` \u2192 `guard` \u2192 `research` \u2192 `impact` \u2192 edit \u2192 `record` \u2192 `verify` \u2192 `changes`",
|
|
9727
9843
|
"",
|
|
9728
|
-
"\u{
|
|
9729
|
-
"
|
|
9730
|
-
"\u{1F7E2} **SKIP** recording function/class/component nodes \u2014 grep/glob is faster.",
|
|
9731
|
-
"\u{1F9E0} Knowledge graph is persistent \u2014 nodes/edges accumulate across sessions, getting richer over time.",
|
|
9844
|
+
"\u{1F534} **MUST RECORD:** `decision` (rationale), `gotcha` (bug/quirk), `arch_flow` (complex flow)",
|
|
9845
|
+
"\u{1F7E2} **SKIP RECORDING:** function, class, import, route (use native grep/glob instead)",
|
|
9732
9846
|
"",
|
|
9733
|
-
"\
|
|
9734
|
-
"\u{1F5D1}\uFE0F **Delete/Clear:** `delete_node` (delete node/gotcha/todo/decision) | `clear` (wipe entire graph)",
|
|
9735
|
-
"\u{1F4D6} Full rules: `.kuma/init.md`",
|
|
9847
|
+
"\u{1F4D6} Full rules & modes: `.kuma/init.md` | `.kuma/MODE.md` | `.kuma/SKIP_RULES.md`",
|
|
9736
9848
|
"\u{1F9E0} Tools: `kuma_kuma_context` | `kuma_kuma_memory` | `kuma_kuma_safety`"
|
|
9737
9849
|
].join("\n");
|
|
9738
9850
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumpslabs/kuma",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.24",
|
|
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",
|
|
@@ -234,8 +234,7 @@ header .status .dot.off { background: var(--red); }
|
|
|
234
234
|
<div id="graph-container"></div>
|
|
235
235
|
<div id="search-box"><input id="node-search" type="text" placeholder="Search nodes..." /></div>
|
|
236
236
|
<div id="graph-controls">
|
|
237
|
-
<button onclick="
|
|
238
|
-
<button onclick="if(network)network.fit()" title="Fit to viewport"><i data-lucide="maximize-2" style="width:12px;height:12px"></i></button>
|
|
237
|
+
<button onclick="if(network)network.fit()" title="Fit to viewport"><i data-lucide="maximize-2" style="width:12px;height:12px"></i> Fit</button>
|
|
239
238
|
<div class="ctrl-sep"></div>
|
|
240
239
|
<button class="depth-btn" data-depth="1" onclick="setDepth(1)">1</button>
|
|
241
240
|
<button class="depth-btn active" data-depth="2" onclick="setDepth(2)">2</button>
|
|
@@ -482,7 +481,7 @@ function renderGraph(data) {
|
|
|
482
481
|
stabilization: { iterations: 120, updateInterval: 50, onlyDynamicEdges: false, fit: false },
|
|
483
482
|
},
|
|
484
483
|
interaction: { hover: true, tooltipDelay: 300, zoomView: true, dragView: true, dragNodes: true, keyboard: true, multiselect: true, selectable: true, selectConnectedEdges: false },
|
|
485
|
-
nodes: { borderWidth: 0, font: { color: '#ffffff', size: 11, face: 'sans-serif'
|
|
484
|
+
nodes: { borderWidth: 0, font: { color: '#ffffff', size: 11, face: 'sans-serif' }, margin: { top: 6, bottom: 6, left: 10, right: 10 }, shapeProperties: { borderRadius: 6 } },
|
|
486
485
|
edges: { smooth: { type: 'continuous', roundness: 0.2 }, width: 1, color: { color: '#4a4a6a', highlight: '#7c3aed' } },
|
|
487
486
|
configure: { enabled: false },
|
|
488
487
|
});
|
|
@@ -780,7 +779,7 @@ function renderFeatures(data) {
|
|
|
780
779
|
var items = data.features || [];
|
|
781
780
|
var el = document.getElementById("panel-features");
|
|
782
781
|
if(!el) return;
|
|
783
|
-
if(!items.length){el.innerHTML='<div class="empty">No features recorded yet.<br><br>Use:<br><code style="color:var(--accent)">kuma_memory
|
|
782
|
+
if(!items.length){el.innerHTML='<div class="empty">No features recorded yet.<br><br>Use:<br><code style="color:var(--accent)">kuma_memory</code></div>';return;}
|
|
784
783
|
el.innerHTML = items.map(function(f){
|
|
785
784
|
var feat = typeof f === 'string' ? JSON.parse(f) : f;
|
|
786
785
|
var meta = {};
|