opencode-fractal-memory 0.2.0

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 (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +493 -0
  3. package/agent/memory-hints.md +98 -0
  4. package/agent/memory-researcher.md +56 -0
  5. package/commands/memory-auto-test.md +10 -0
  6. package/commands/memory-cache-status.md +13 -0
  7. package/commands/memory-check-context.md +4 -0
  8. package/commands/memory-compress.md +13 -0
  9. package/commands/memory-dashboard.md +23 -0
  10. package/commands/memory-delete.md +24 -0
  11. package/commands/memory-detect-topics.md +28 -0
  12. package/commands/memory-distill.md +35 -0
  13. package/commands/memory-drilldown-query.md +28 -0
  14. package/commands/memory-drilldown.md +11 -0
  15. package/commands/memory-extract-patterns.md +4 -0
  16. package/commands/memory-generate-embeddings.md +26 -0
  17. package/commands/memory-get.md +26 -0
  18. package/commands/memory-help.md +55 -0
  19. package/commands/memory-injection-feedback.md +26 -0
  20. package/commands/memory-injection-stats.md +11 -0
  21. package/commands/memory-list.md +4 -0
  22. package/commands/memory-llm-compress.md +34 -0
  23. package/commands/memory-mcp.md +20 -0
  24. package/commands/memory-prune.md +4 -0
  25. package/commands/memory-rate.md +48 -0
  26. package/commands/memory-reflect.md +37 -0
  27. package/commands/memory-replace.md +26 -0
  28. package/commands/memory-retrieve.md +34 -0
  29. package/commands/memory-search.md +28 -0
  30. package/commands/memory-session-stats.md +4 -0
  31. package/commands/memory-set.md +31 -0
  32. package/commands/memory-stats.md +11 -0
  33. package/commands/memory-summarize.md +29 -0
  34. package/commands/memory-tool-stats.md +4 -0
  35. package/commands/memory-total-tokens.md +10 -0
  36. package/commands/memory-verify.md +4 -0
  37. package/commands/memory-version.md +9 -0
  38. package/dist/cache.js +39 -0
  39. package/dist/config.js +120 -0
  40. package/dist/embeddings.js +125 -0
  41. package/dist/ensure-models.js +70 -0
  42. package/dist/file-summary.js +143 -0
  43. package/dist/frontmatter.js +28 -0
  44. package/dist/hnsw-index.js +138 -0
  45. package/dist/hooks/auto-discover.js +4 -0
  46. package/dist/hooks/auto-distill.js +120 -0
  47. package/dist/hooks/auto-retrieve/content.js +47 -0
  48. package/dist/hooks/auto-retrieve/detection.js +50 -0
  49. package/dist/hooks/auto-retrieve/formatting.js +19 -0
  50. package/dist/hooks/auto-retrieve/index.js +163 -0
  51. package/dist/hooks/auto-retrieve/scoring.js +56 -0
  52. package/dist/hooks/auto-retrieve.js +1 -0
  53. package/dist/hooks/index.js +4 -0
  54. package/dist/hooks/predictive-rating.js +87 -0
  55. package/dist/journal.js +279 -0
  56. package/dist/logging.js +147 -0
  57. package/dist/management/helpers.js +227 -0
  58. package/dist/management/router.js +48 -0
  59. package/dist/management/routes.js +197 -0
  60. package/dist/management-server.js +4 -0
  61. package/dist/management-standalone.js +31 -0
  62. package/dist/mcp/logging.js +57 -0
  63. package/dist/mcp/server.js +251 -0
  64. package/dist/mcp/transform.js +48 -0
  65. package/dist/mcp-server.js +18 -0
  66. package/dist/memory.js +2 -0
  67. package/dist/ollama.js +74 -0
  68. package/dist/plugin/hooks.js +168 -0
  69. package/dist/plugin/index.js +28 -0
  70. package/dist/plugin/init.js +109 -0
  71. package/dist/plugin/state.js +75 -0
  72. package/dist/plugin/tools.js +45 -0
  73. package/dist/plugin.js +2 -0
  74. package/dist/procedural/store.js +1 -0
  75. package/dist/procedural/types.js +1 -0
  76. package/dist/seed-nodes.js +804 -0
  77. package/dist/storage/compress-ops.js +129 -0
  78. package/dist/storage/compression/formatters.js +243 -0
  79. package/dist/storage/compression/index.js +107 -0
  80. package/dist/storage/compression/patterns.js +138 -0
  81. package/dist/storage/expiration.js +66 -0
  82. package/dist/storage/index.js +1 -0
  83. package/dist/storage/injection-events.js +82 -0
  84. package/dist/storage/lifecycle.js +65 -0
  85. package/dist/storage/maintenance.js +60 -0
  86. package/dist/storage/migrations/definitions.js +374 -0
  87. package/dist/storage/migrations/index.js +21 -0
  88. package/dist/storage/navigation.js +98 -0
  89. package/dist/storage/queries/base.js +44 -0
  90. package/dist/storage/queries/links.js +32 -0
  91. package/dist/storage/queries/nodes.js +189 -0
  92. package/dist/storage/queries/search-helpers.js +239 -0
  93. package/dist/storage/scoring.js +36 -0
  94. package/dist/storage/search.js +233 -0
  95. package/dist/storage/session-tracking.js +180 -0
  96. package/dist/storage/sqlite.js +329 -0
  97. package/dist/storage/tool-usage.js +56 -0
  98. package/dist/storage/types.js +1 -0
  99. package/dist/storage/utils.js +94 -0
  100. package/dist/tools/auto-test.js +24 -0
  101. package/dist/tools/cache-status.js +36 -0
  102. package/dist/tools/compress.js +186 -0
  103. package/dist/tools/core.js +307 -0
  104. package/dist/tools/dashboard.js +97 -0
  105. package/dist/tools/help.js +59 -0
  106. package/dist/tools/index.js +12 -0
  107. package/dist/tools/inject.js +91 -0
  108. package/dist/tools/injection-debug.js +48 -0
  109. package/dist/tools/journal.js +105 -0
  110. package/dist/tools/llm-compress.js +41 -0
  111. package/dist/tools/middle-term.js +68 -0
  112. package/dist/tools/playbook.js +64 -0
  113. package/dist/tools/reflect.js +291 -0
  114. package/dist/tools/search.js +188 -0
  115. package/dist/tools/session.js +189 -0
  116. package/dist/tools/shared.js +74 -0
  117. package/dist/tools/skill.js +37 -0
  118. package/dist/tools/stats.js +256 -0
  119. package/dist/tools/version.js +13 -0
  120. package/dist/tools.js +18 -0
  121. package/dist/utils/hybridScore.js +67 -0
  122. package/management/public/app.js +1529 -0
  123. package/management/public/index.html +486 -0
  124. package/management/public/three.min.js +6 -0
  125. package/package.json +65 -0
  126. package/scripts/download-models.ts +16 -0
  127. package/scripts/postinstall.cjs +30 -0
@@ -0,0 +1,486 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Fractal Memory Viewer</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ body { background: #0a0a0f; color: #e0e0e0; font-family: 'Inter', -apple-system, sans-serif; overflow: hidden; }
10
+ #canvas-container { width: 100vw; height: 100vh; position: fixed; top: 0; left: 0; }
11
+ canvas { display: block; }
12
+
13
+ #sidebar {
14
+ position: fixed; top: 0; left: 0; width: 280px; height: 100vh;
15
+ background: rgba(15, 15, 25, 0.95); border-right: 1px solid rgba(255,255,255,0.1);
16
+ padding: 20px; overflow-y: auto; z-index: 100;
17
+ backdrop-filter: blur(10px);
18
+ }
19
+ #sidebar h1 { font-size: 18px; margin-bottom: 4px; color: #fff; }
20
+ #sidebar .subtitle { font-size: 12px; color: #888; margin-bottom: 20px; }
21
+
22
+ .section { margin-bottom: 20px; }
23
+ .section h3 { font-size: 13px; color: #aaa; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 10px; }
24
+
25
+ .stat-row { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid rgba(255,255,255,0.05); }
26
+ .stat-label { font-size: 13px; color: #888; }
27
+ .stat-value { font-size: 13px; color: #fff; font-weight: 500; }
28
+
29
+ .filter-group { display: flex; flex-wrap: wrap; gap: 6px; }
30
+ .filter-btn {
31
+ padding: 4px 10px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.2);
32
+ background: transparent; color: #ccc; font-size: 12px; cursor: pointer;
33
+ transition: all 0.2s;
34
+ }
35
+ .filter-btn:hover { background: rgba(255,255,255,0.1); }
36
+ .filter-btn.active { background: rgba(100, 150, 255, 0.3); border-color: rgba(100, 150, 255, 0.5); color: #fff; }
37
+
38
+ .legend-item { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
39
+ .legend-dot { width: 12px; height: 12px; border-radius: 50%; }
40
+ .legend-label { font-size: 12px; color: #ccc; }
41
+
42
+ #search-input {
43
+ width: 100%; padding: 8px 12px; border-radius: 6px;
44
+ border: 1px solid rgba(255,255,255,0.2); background: rgba(255,255,255,0.05);
45
+ color: #fff; font-size: 13px; outline: none;
46
+ }
47
+ #search-input:focus { border-color: rgba(100, 150, 255, 0.5); }
48
+ .search-mode-btn { padding: 4px 8px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.2); background: transparent; color: #888; font-size: 11px; cursor: pointer; transition: all 0.2s; flex: 1; }
49
+ .search-mode-btn:hover { background: rgba(255,255,255,0.1); color: #ccc; }
50
+ .search-mode-btn.active { background: rgba(100, 150, 255, 0.3); border-color: rgba(100, 150, 255, 0.5); color: #fff; }
51
+ #search-info { font-size: 11px; color: #666; margin-top: 4px; text-align: center; min-height: 16px; }
52
+ #search-info.loading::before {
53
+ content: ''; display: inline-block; width: 12px; height: 12px;
54
+ border: 2px solid rgba(100,150,255,0.3); border-top-color: #4a9eff;
55
+ border-radius: 50%; animation: spin 0.6s linear infinite;
56
+ margin-right: 6px; vertical-align: middle;
57
+ }
58
+ @keyframes spin { to { transform: rotate(360deg); } }
59
+ .search-btn {
60
+ width: 100%; margin-top: 6px; padding: 6px; border-radius: 6px;
61
+ border: 1px solid rgba(100,150,255,0.5); background: rgba(100,150,255,0.2);
62
+ color: #fff; font-size: 12px; cursor: pointer; transition: all 0.2s;
63
+ }
64
+ .search-btn:hover { background: rgba(100,150,255,0.4); }
65
+
66
+ #detail-panel {
67
+ position: fixed; top: 0; right: 0; width: 360px; height: 100vh;
68
+ background: rgba(15, 15, 25, 0.95); border-left: 1px solid rgba(255,255,255,0.1);
69
+ padding: 20px; overflow-y: auto; z-index: 100;
70
+ backdrop-filter: blur(10px); transform: translateX(100%);
71
+ transition: transform 0.3s ease;
72
+ }
73
+ #detail-panel.open { transform: translateX(0); }
74
+ #detail-panel .close-btn {
75
+ position: absolute; top: 15px; right: 15px; background: none; border: none;
76
+ color: #888; font-size: 20px; cursor: pointer;
77
+ }
78
+ #detail-panel .close-btn:hover { color: #fff; }
79
+ #detail-panel h2 { font-size: 16px; margin-bottom: 15px; color: #fff; word-break: break-word; }
80
+ #detail-panel .detail-section { margin-bottom: 15px; }
81
+ #detail-panel .detail-section h4 { font-size: 12px; color: #888; text-transform: uppercase; margin-bottom: 6px; }
82
+ #detail-panel .detail-value { font-size: 13px; color: #ccc; }
83
+ #detail-panel .content-full {
84
+ background: rgba(255,255,255,0.03); border-radius: 6px; padding: 12px;
85
+ font-size: 12px; line-height: 1.5; color: #aaa; max-height: 60vh;
86
+ overflow-y: auto; white-space: pre-wrap; word-break: break-word;
87
+ }
88
+
89
+ .edit-btn {
90
+ position: absolute; top: 15px; right: 45px; background: none; border: none;
91
+ color: #888; font-size: 14px; cursor: pointer;
92
+ }
93
+ .edit-btn:hover { color: #fff; }
94
+ .delete-btn {
95
+ position: absolute; top: 15px; right: 75px; background: none; border: none;
96
+ color: #f44; font-size: 14px; cursor: pointer;
97
+ }
98
+ .delete-btn:hover { color: #f66; }
99
+
100
+ .inject-btn {
101
+ position: absolute; top: 15px; right: 105px; background: none; border: none;
102
+ color: #4f4; font-size: 12px; cursor: pointer;
103
+ }
104
+ .inject-btn:hover { color: #6f6; }
105
+ #inject-status {
106
+ position: absolute; top: 40px; right: 105px; font-size: 11px; color: #4f4;
107
+ display: none; pointer-events: none;
108
+ }
109
+
110
+ .edit-field { margin-bottom: 12px; }
111
+ .edit-field label { display: block; font-size: 11px; color: #888; margin-bottom: 4px; text-transform: uppercase; }
112
+ .edit-field input[type="text"], .edit-field input[type="number"], .edit-field select {
113
+ width: 100%; padding: 6px 8px; border-radius: 4px;
114
+ border: 1px solid rgba(255,255,255,0.2); background: rgba(255,255,255,0.05);
115
+ color: #fff; font-size: 12px;
116
+ }
117
+ .edit-field input:focus, .edit-field select:focus { border-color: rgba(100, 150, 255, 0.5); outline: none; }
118
+ .edit-field textarea {
119
+ width: 100%; padding: 8px; border-radius: 4px;
120
+ border: 1px solid rgba(255,255,255,0.2); background: rgba(255,255,255,0.05);
121
+ color: #fff; font-size: 12px; font-family: monospace; line-height: 1.5;
122
+ resize: vertical; min-height: 120px;
123
+ }
124
+ .edit-field textarea:focus { border-color: rgba(100, 150, 255, 0.5); outline: none; }
125
+ .edit-field .checkbox-row { display: flex; align-items: center; gap: 8px; }
126
+ .edit-field .checkbox-row input[type="checkbox"] { width: auto; }
127
+
128
+ .edit-actions { display: flex; gap: 8px; margin-top: 16px; }
129
+ .edit-actions button {
130
+ flex: 1; padding: 8px; border-radius: 6px; border: none; font-size: 13px; cursor: pointer;
131
+ }
132
+ .btn-save { background: rgba(100, 150, 255, 0.3); color: #fff; }
133
+ .btn-save:hover { background: rgba(100, 150, 255, 0.5); }
134
+ .btn-cancel { background: rgba(255,255,255,0.1); color: #ccc; }
135
+ .btn-cancel:hover { background: rgba(255,255,255,0.2); }
136
+ .btn-delete { background: rgba(255, 60, 60, 0.2); color: #f66; }
137
+ .btn-delete:hover { background: rgba(255, 60, 60, 0.4); }
138
+
139
+ #tooltip {
140
+ position: fixed; background: rgba(0,0,0,0.9); color: #fff; padding: 8px 12px;
141
+ border-radius: 6px; font-size: 12px; pointer-events: none; z-index: 200;
142
+ display: none; max-width: 250px; border: 1px solid rgba(255,255,255,0.1);
143
+ }
144
+
145
+ #loading {
146
+ position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
147
+ color: #888; font-size: 14px; z-index: 300;
148
+ }
149
+
150
+ .toggle-sidebar {
151
+ position: fixed; top: 15px; left: 290px; z-index: 150;
152
+ background: rgba(15, 15, 25, 0.9); border: 1px solid rgba(255,255,255,0.1);
153
+ color: #ccc; padding: 6px 10px; border-radius: 6px; cursor: pointer;
154
+ font-size: 12px;
155
+ }
156
+ .toggle-sidebar:hover { background: rgba(255,255,255,0.1); }
157
+
158
+ /* Tabs */
159
+ .tab-buttons { display: flex; gap: 4px; margin-bottom: 16px; }
160
+ .tab-btn {
161
+ flex: 1; padding: 8px 0; border-radius: 6px; border: 1px solid rgba(255,255,255,0.2);
162
+ background: transparent; color: #888; font-size: 12px; cursor: pointer; transition: all 0.2s;
163
+ }
164
+ .tab-btn:hover { background: rgba(255,255,255,0.1); }
165
+ .tab-btn.active { background: rgba(100, 150, 255, 0.3); border-color: rgba(100, 150, 255, 0.5); color: #fff; }
166
+
167
+ /* Settings Panel */
168
+ .settings-panel { display: none; }
169
+ .settings-panel.active { display: block; }
170
+ .config-field { margin-bottom: 12px; }
171
+ .config-field label { display: block; font-size: 12px; color: #888; margin-bottom: 4px; }
172
+ .config-field input[type="text"], .config-field input[type="number"], .config-field select {
173
+ width: 100%; padding: 6px 8px; border-radius: 4px;
174
+ border: 1px solid rgba(255,255,255,0.2); background: rgba(255,255,255,0.05);
175
+ color: #fff; font-size: 12px;
176
+ }
177
+ .config-field input:focus, .config-field select:focus { border-color: rgba(100, 150, 255, 0.5); outline: none; }
178
+ .save-btn {
179
+ width: 100%; padding: 8px; border-radius: 6px; border: none;
180
+ background: rgba(100, 150, 255, 0.3); color: #fff; font-size: 13px; cursor: pointer;
181
+ }
182
+ .save-btn:hover { background: rgba(100, 150, 255, 0.5); }
183
+ .save-message { font-size: 11px; color: #4f4; margin-top: 8px; text-align: center; }
184
+
185
+ /* Playbook styles */
186
+ .playbook-card {
187
+ background: rgba(255,255,255,0.03); border-radius: 8px; padding: 12px;
188
+ margin-bottom: 10px; border: 1px solid rgba(255,255,255,0.08);
189
+ transition: border-color 0.2s;
190
+ }
191
+ .playbook-card:hover { border-color: rgba(100,150,255,0.3); }
192
+ .playbook-card .pb-header { display: flex; justify-content: space-between; align-items: flex-start; }
193
+ .playbook-card .pb-name { font-size: 14px; color: #fff; font-weight: 500; }
194
+ .playbook-card .pb-desc { font-size: 11px; color: #888; margin-top: 2px; }
195
+ .playbook-card .pb-meta { font-size: 10px; color: #666; margin-top: 6px; }
196
+ .playbook-card .pb-meta span { display: inline-block; margin-right: 12px; }
197
+ .playbook-card .pb-tags { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 4px; }
198
+ .playbook-card .pb-tag {
199
+ padding: 2px 8px; border-radius: 10px; background: rgba(100,150,255,0.15);
200
+ color: rgba(100,150,255,0.8); font-size: 10px;
201
+ }
202
+ .playbook-card .pb-steps { margin-top: 8px; }
203
+ .playbook-card .pb-step {
204
+ padding: 4px 8px; margin: 2px 0; border-radius: 4px;
205
+ background: rgba(255,255,255,0.03); font-size: 11px; color: #aaa;
206
+ display: flex; align-items: center; gap: 6px;
207
+ }
208
+ .playbook-card .pb-step .step-tool {
209
+ padding: 1px 6px; border-radius: 4px; background: rgba(100,150,255,0.2);
210
+ color: #4a9eff; font-size: 10px; font-weight: 500;
211
+ }
212
+ .playbook-card .pb-step .step-critical {
213
+ color: #f66; font-size: 10px; font-weight: 700;
214
+ }
215
+ .playbook-card .pb-delete-btn {
216
+ background: none; border: 1px solid rgba(255,60,60,0.3); color: #f66;
217
+ padding: 2px 10px; border-radius: 4px; font-size: 11px; cursor: pointer;
218
+ }
219
+ .playbook-card .pb-delete-btn:hover { background: rgba(255,60,60,0.2); }
220
+ .playbook-card .pb-triggers { margin-top: 6px; }
221
+ .playbook-card .pb-trigger { font-size: 10px; color: #888; font-style: italic; }
222
+
223
+ #node-list {
224
+ max-height: 40vh; overflow-y: auto; border: 1px solid rgba(255,255,255,0.1);
225
+ border-radius: 6px;
226
+ }
227
+ .node-list-item {
228
+ padding: 8px 10px; cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.05);
229
+ transition: background 0.15s;
230
+ }
231
+ .node-list-item:hover { background: rgba(255,255,255,0.08); }
232
+ .node-list-item.selected { background: rgba(100, 150, 255, 0.2); }
233
+ .node-list-item .node-label { font-size: 12px; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
234
+ .node-list-item .node-meta { font-size: 10px; color: #666; margin-top: 2px; }
235
+ .node-list-count { font-size: 11px; color: #666; margin-left: 8px; }
236
+ </style>
237
+ </head>
238
+ <body>
239
+ <div id="canvas-container"></div>
240
+ <div id="loading">Loading memory nodes...</div>
241
+
242
+ <div id="sidebar">
243
+ <h1>Fractal Memory</h1>
244
+ <div class="subtitle"><span id="version">3D Node Visualization</span></div>
245
+
246
+ <div class="tab-buttons">
247
+ <button class="tab-btn active" data-tab="visualize">Visualize</button>
248
+ <button class="tab-btn" data-tab="playbooks">Playbooks</button>
249
+ <button class="tab-btn" data-tab="settings">Settings</button>
250
+ </div>
251
+
252
+ <!-- Visualize Panel -->
253
+ <div id="visualize-panel" class="settings-panel active">
254
+
255
+ <div class="section">
256
+ <h3>Scope</h3>
257
+ <div class="filter-group" id="scope-filters"></div>
258
+ </div>
259
+
260
+ <div class="section">
261
+ <input type="text" id="search-input" placeholder="Search nodes...">
262
+ <div style="display:flex; gap:4px; margin-top:6px;">
263
+ <button class="search-mode-btn active" data-mode="text">Text</button>
264
+ <button class="search-mode-btn" data-mode="embedding">Embedding</button>
265
+ <button class="search-mode-btn" data-mode="bm25">BM25</button>
266
+ </div>
267
+ <button class="search-btn" id="search-btn">Search</button>
268
+ <div id="search-info"></div>
269
+ </div>
270
+
271
+ <div class="section">
272
+ <h3>Statistics</h3>
273
+ <div id="stats-container"></div>
274
+ </div>
275
+
276
+ <div class="section">
277
+ <h3>Filter by Level</h3>
278
+ <div class="filter-group" id="level-filters"></div>
279
+ </div>
280
+
281
+ <div class="section">
282
+ <h3>Filter by Type</h3>
283
+ <div class="filter-group" id="type-filters"></div>
284
+ </div>
285
+
286
+ <div class="section">
287
+ <h3>Filter by Custom Type</h3>
288
+ <div class="filter-group" id="custom-type-filters"></div>
289
+ </div>
290
+
291
+ <div class="section">
292
+ <h3>Filter by Shape</h3>
293
+ <div class="filter-group" id="shape-filters"></div>
294
+ </div>
295
+
296
+ <div class="section">
297
+ <h3>Legend</h3>
298
+ <div id="legend"></div>
299
+ </div>
300
+
301
+ <div class="section">
302
+ <h3>Nodes <span class="node-list-count" id="node-list-count"></span></h3>
303
+ <div id="node-list"></div>
304
+ </div>
305
+ </div>
306
+
307
+ <!-- Playbooks Panel -->
308
+ <div id="playbooks-panel" class="settings-panel">
309
+ <div class="section">
310
+ <h3>Playbooks</h3>
311
+ <div style="margin-bottom: 10px;">
312
+ <input type="text" id="playbook-search-input" placeholder="Search playbooks..." style="width:100%;padding:6px 10px;border-radius:6px;border:1px solid rgba(255,255,255,0.2);background:rgba(255,255,255,0.05);color:#fff;font-size:12px;outline:none;">
313
+ </div>
314
+ <div id="playbook-list"></div>
315
+ </div>
316
+ </div>
317
+
318
+ <!-- Settings Panel -->
319
+ <div id="settings-panel" class="settings-panel">
320
+ <div class="section">
321
+ <h3>Per-Node TTL</h3>
322
+ <div class="config-field">
323
+ <label>Default TTL (days, 0 = no expiry)</label>
324
+ <input type="number" id="defaultTtlDays" min="0" max="3650">
325
+ </div>
326
+ </div>
327
+
328
+ <div class="section">
329
+ <h3>Auto-Retrieve</h3>
330
+ <div class="config-field">
331
+ <label>Enabled</label>
332
+ <select id="autoRetrieve-enabled">
333
+ <option value="true">Enabled</option>
334
+ <option value="false">Disabled</option>
335
+ </select>
336
+ </div>
337
+ <div class="config-field">
338
+ <label>Candidate Count</label>
339
+ <input type="number" id="autoRetrieve-candidateCount" min="5" max="100">
340
+ </div>
341
+ <div class="config-field">
342
+ <label>Max Inject Nodes</label>
343
+ <input type="number" id="autoRetrieve-maxInjectNodes" min="1" max="20">
344
+ </div>
345
+ </div>
346
+
347
+ <div class="section">
348
+ <h3>Auto File Summarization</h3>
349
+ <div class="config-field">
350
+ <label>Enabled</label>
351
+ <select id="autoFileSummarization-enabled">
352
+ <option value="true">Enabled</option>
353
+ <option value="false">Disabled</option>
354
+ </select>
355
+ </div>
356
+ </div>
357
+
358
+ <div class="section">
359
+ <h3>Ollama</h3>
360
+ <div class="config-field">
361
+ <label>Enabled</label>
362
+ <select id="ollama-enabled">
363
+ <option value="true">Enabled</option>
364
+ <option value="false">Disabled</option>
365
+ </select>
366
+ </div>
367
+ <div class="config-field">
368
+ <label>Model</label>
369
+ <input type="text" id="ollama-model" placeholder="qwen2.5-coder:1.5b">
370
+ </div>
371
+ <div class="config-field">
372
+ <label>Base URL</label>
373
+ <input type="text" id="ollama-baseUrl" placeholder="http://localhost:11434">
374
+ </div>
375
+ </div>
376
+
377
+ <div class="section">
378
+ <h3>LLM Compression</h3>
379
+ <div class="config-field">
380
+ <label>Enabled</label>
381
+ <select id="llmCompression-enabled">
382
+ <option value="true">Enabled</option>
383
+ <option value="false">Disabled</option>
384
+ </select>
385
+ </div>
386
+ <div class="config-field">
387
+ <label>Max Summary Tokens</label>
388
+ <input type="number" id="llmCompression-maxSummaryTokens" min="100" max="4000">
389
+ </div>
390
+ <div class="config-field">
391
+ <label>Model (optional)</label>
392
+ <input type="text" id="llmCompression-model" placeholder="default session model">
393
+ </div>
394
+ </div>
395
+
396
+ <div class="section">
397
+ <h3>Auto Distill</h3>
398
+ <div class="config-field">
399
+ <label>Enabled</label>
400
+ <select id="autoDistill-enabled">
401
+ <option value="true">Enabled</option>
402
+ <option value="false">Disabled</option>
403
+ </select>
404
+ </div>
405
+ <div class="config-field">
406
+ <label>Min Lessons</label>
407
+ <input type="number" id="autoDistill-minLessons" min="1" max="20">
408
+ </div>
409
+ <div class="config-field">
410
+ <label>Use LLM</label>
411
+ <select id="autoDistill-useLlm">
412
+ <option value="true">Yes</option>
413
+ <option value="false">No</option>
414
+ </select>
415
+ </div>
416
+ </div>
417
+
418
+ <div class="section">
419
+ <h3>Predictive Rating</h3>
420
+ <div class="config-field">
421
+ <label>Enabled</label>
422
+ <select id="predictiveRating-enabled">
423
+ <option value="true">Enabled</option>
424
+ <option value="false">Disabled</option>
425
+ </select>
426
+ </div>
427
+ <div class="config-field">
428
+ <label>Decay Days</label>
429
+ <input type="number" id="predictiveRating-decayDays" min="1" max="90">
430
+ </div>
431
+ <div class="config-field">
432
+ <label>Positive Boost</label>
433
+ <input type="number" id="predictiveRating-positiveBoost" min="0" max="1" step="0.05">
434
+ </div>
435
+ <div class="config-field">
436
+ <label>Negative Penalty</label>
437
+ <input type="number" id="predictiveRating-negativePenalty" min="0" max="1" step="0.05">
438
+ </div>
439
+ </div>
440
+
441
+ <div class="section">
442
+ <h3>Auto Discover (Playbooks)</h3>
443
+ <div class="config-field">
444
+ <label>Enabled</label>
445
+ <select id="autoDiscover-enabled">
446
+ <option value="true">Enabled</option>
447
+ <option value="false">Disabled</option>
448
+ </select>
449
+ </div>
450
+ <div class="config-field">
451
+ <label>Min Sequence Length</label>
452
+ <input type="number" id="autoDiscover-minSequenceLength" min="2" max="10">
453
+ </div>
454
+ <div class="config-field">
455
+ <label>Min Repeat Count</label>
456
+ <input type="number" id="autoDiscover-minRepeatCount" min="1" max="10">
457
+ </div>
458
+ <div class="config-field">
459
+ <label>Max Inject Playbooks</label>
460
+ <input type="number" id="autoDiscover-maxInjectPlaybooks" min="0" max="10">
461
+ </div>
462
+ </div>
463
+
464
+ <button class="save-btn" id="save-config">Save Settings</button>
465
+ <div class="save-message" id="save-message"></div>
466
+ </div>
467
+ </div>
468
+
469
+ <button class="toggle-sidebar" id="toggle-sidebar">☰</button>
470
+
471
+ <div id="detail-panel">
472
+ <button class="close-btn" id="close-detail">×</button>
473
+ <button class="delete-btn" id="delete-node" title="Delete node">🗑</button>
474
+ <button class="edit-btn" id="edit-node" title="Edit node">✎</button>
475
+ <button class="inject-btn" id="inject-node" title="Inject into agent context">→ Agent</button>
476
+ <div id="inject-status"></div>
477
+ <h2 id="detail-title"></h2>
478
+ <div id="detail-content"></div>
479
+ </div>
480
+
481
+ <div id="tooltip"></div>
482
+
483
+ <script src="three.min.js"></script>
484
+ <script src="app.js"></script>
485
+ </body>
486
+ </html>