laminark 0.1.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 (55) hide show
  1. package/README.md +147 -0
  2. package/package.json +65 -0
  3. package/plugin/.claude-plugin/plugin.json +13 -0
  4. package/plugin/.mcp.json +12 -0
  5. package/plugin/CLAUDE.md +10 -0
  6. package/plugin/commands/recall.md +55 -0
  7. package/plugin/commands/remember.md +34 -0
  8. package/plugin/commands/resume.md +45 -0
  9. package/plugin/commands/stash.md +34 -0
  10. package/plugin/commands/status.md +33 -0
  11. package/plugin/dist/analysis/worker.d.ts +1 -0
  12. package/plugin/dist/analysis/worker.js +233 -0
  13. package/plugin/dist/analysis/worker.js.map +1 -0
  14. package/plugin/dist/config-t8LZeB-u.mjs +90 -0
  15. package/plugin/dist/config-t8LZeB-u.mjs.map +1 -0
  16. package/plugin/dist/hooks/handler.d.ts +286 -0
  17. package/plugin/dist/hooks/handler.d.ts.map +1 -0
  18. package/plugin/dist/hooks/handler.js +2413 -0
  19. package/plugin/dist/hooks/handler.js.map +1 -0
  20. package/plugin/dist/index.d.ts +447 -0
  21. package/plugin/dist/index.d.ts.map +1 -0
  22. package/plugin/dist/index.js +7334 -0
  23. package/plugin/dist/index.js.map +1 -0
  24. package/plugin/dist/observations-CorAAc1A.d.mts +192 -0
  25. package/plugin/dist/observations-CorAAc1A.d.mts.map +1 -0
  26. package/plugin/dist/tool-registry-e710BvXq.mjs +3574 -0
  27. package/plugin/dist/tool-registry-e710BvXq.mjs.map +1 -0
  28. package/plugin/hooks/hooks.json +78 -0
  29. package/plugin/laminark.db +0 -0
  30. package/plugin/package.json +17 -0
  31. package/plugin/scripts/README.md +65 -0
  32. package/plugin/scripts/bump-version.sh +42 -0
  33. package/plugin/scripts/dev-sync.sh +58 -0
  34. package/plugin/scripts/ensure-deps.sh +15 -0
  35. package/plugin/scripts/install.sh +139 -0
  36. package/plugin/scripts/local-install.sh +138 -0
  37. package/plugin/scripts/uninstall.sh +133 -0
  38. package/plugin/scripts/update.sh +39 -0
  39. package/plugin/scripts/verify-install.sh +87 -0
  40. package/plugin/skills/status/SKILL.md +6 -0
  41. package/plugin/ui/activity.js +197 -0
  42. package/plugin/ui/app.js +1612 -0
  43. package/plugin/ui/graph.js +2560 -0
  44. package/plugin/ui/help/activity-feed.png +0 -0
  45. package/plugin/ui/help/analysis-panel.png +0 -0
  46. package/plugin/ui/help/graph-toolbar.png +0 -0
  47. package/plugin/ui/help/graph-view.png +0 -0
  48. package/plugin/ui/help/settings.png +0 -0
  49. package/plugin/ui/help/timeline.png +0 -0
  50. package/plugin/ui/help.js +932 -0
  51. package/plugin/ui/index.html +756 -0
  52. package/plugin/ui/settings.js +1414 -0
  53. package/plugin/ui/styles.css +3856 -0
  54. package/plugin/ui/timeline.js +652 -0
  55. package/plugin/ui/tools.js +826 -0
@@ -0,0 +1,756 @@
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>Laminark - Memory Visualization</title>
7
+ <link rel="stylesheet" href="/styles.css">
8
+ <script src="https://unpkg.com/d3@7/dist/d3.min.js"></script>
9
+ </head>
10
+ <body>
11
+ <nav id="nav-bar">
12
+ <div class="nav-brand">Laminark</div>
13
+ <select id="project-selector" class="project-selector" title="Switch project"></select>
14
+ <div class="nav-tabs">
15
+ <button class="nav-tab active" data-view="graph-view">Knowledge Graph</button>
16
+ <button class="nav-tab" data-view="timeline-view">Timeline</button>
17
+ <button class="nav-tab" data-view="activity-view">Activity</button>
18
+ <button class="nav-tab" data-view="tools-view">Tools</button>
19
+ <button class="nav-tab" data-view="settings-view">Settings</button>
20
+ <button class="nav-tab" data-view="help-view">Help</button>
21
+ </div>
22
+ <div class="nav-status">
23
+ <span id="sse-status" class="status-indicator disconnected" title="SSE connection status"></span>
24
+ </div>
25
+ </nav>
26
+
27
+ <main id="main-content">
28
+ <div id="filter-bar">
29
+ <span class="filter-label">Filter:</span>
30
+ <button class="filter-pill active" data-type="all">All <span class="count">0</span></button>
31
+ <button class="filter-pill active" data-type="Project"><svg class="type-icon" viewBox="0 0 12 12"><rect x="1" y="1" width="10" height="10" rx="2.5" fill="#58a6ff"/></svg>Project <span class="count">0</span></button>
32
+ <button class="filter-pill active" data-type="File"><svg class="type-icon" viewBox="0 0 12 12"><rect x="2" y="2" width="8" height="8" fill="#3fb950"/></svg>File <span class="count">0</span></button>
33
+ <button class="filter-pill active" data-type="Decision"><svg class="type-icon" viewBox="0 0 12 12"><polygon points="6,1 11,6 6,11 1,6" fill="#d29922"/></svg>Decision <span class="count">0</span></button>
34
+ <button class="filter-pill active" data-type="Problem"><svg class="type-icon" viewBox="0 0 12 12"><polygon points="6,1.5 11,10.5 1,10.5" fill="#f85149"/></svg>Problem <span class="count">0</span></button>
35
+ <button class="filter-pill active" data-type="Solution"><svg class="type-icon" viewBox="0 0 12 12"><polygon points="6,0.5 7.4,4.2 11.5,4.5 8.3,7.2 9.3,11.5 6,9.2 2.7,11.5 3.7,7.2 0.5,4.5 4.6,4.2" fill="#a371f7"/></svg>Solution <span class="count">0</span></button>
36
+ <button class="filter-pill active" data-type="Reference"><svg class="type-icon" viewBox="0 0 12 12"><polygon points="6,0.5 9.5,2.5 9.5,7.5 6,9.5 2.5,7.5 2.5,2.5" fill="#f0883e"/></svg>Reference <span class="count">0</span></button>
37
+ <div class="filter-search-wrapper">
38
+ <input type="text" id="graph-search" class="graph-search-input" placeholder="Search nodes..." autocomplete="off" spellcheck="false">
39
+ <div id="search-results" class="search-results-dropdown hidden"></div>
40
+ </div>
41
+ </div>
42
+
43
+ <div id="time-range-bar">
44
+ <span class="filter-label">Time:</span>
45
+ <button class="time-preset active" data-preset="all">All time</button>
46
+ <button class="time-preset" data-preset="hour">Last hour</button>
47
+ <button class="time-preset" data-preset="today">Today</button>
48
+ <button class="time-preset" data-preset="week">This week</button>
49
+ <button class="time-preset" data-preset="month">This month</button>
50
+ <span class="time-separator">|</span>
51
+ <label class="time-input-label">From <input type="datetime-local" id="time-from" class="time-input"></label>
52
+ <label class="time-input-label">To <input type="datetime-local" id="time-to" class="time-input"></label>
53
+ <button class="time-apply-btn" id="time-apply">Apply</button>
54
+ </div>
55
+
56
+ <div id="graph-view" class="view-container active">
57
+ <div id="graph-breadcrumbs" class="graph-breadcrumbs hidden">
58
+ <button class="breadcrumb-item" data-action="full">Full Graph</button>
59
+ </div>
60
+ <div class="graph-content-row">
61
+ <div class="graph-area">
62
+ <div id="cy"></div>
63
+ <div id="graph-stats" class="graph-stats">0 nodes, 0 edges</div>
64
+ <div class="graph-toolbar">
65
+ <div class="layout-selector">
66
+ <button class="layout-btn active" data-layout="clustered" title="Force-directed layout">Clustered</button>
67
+ <button class="layout-btn" data-layout="hierarchical" title="Top-down tree layout">Hierarchical</button>
68
+ <button class="layout-btn" data-layout="concentric" title="Rings by entity type">Concentric</button>
69
+ <button class="layout-btn" data-layout="communities" title="Community-grouped layout">Communities</button>
70
+ <button class="layout-btn" data-layout="detangle" title="Minimize edge crossings">Detangle</button>
71
+ </div>
72
+ <button id="edge-labels-btn" class="edge-labels-btn active" title="Toggle edge labels">
73
+ <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor">
74
+ <path d="M1.5 8a.5.5 0 01.5-.5h12a.5.5 0 010 1H2a.5.5 0 01-.5-.5z"/>
75
+ <path d="M5 5.5a1.5 1.5 0 013 0v.25h1V5.5a2.5 2.5 0 00-5 0v5a2.5 2.5 0 005 0v-.25H8v.25a1.5 1.5 0 01-3 0v-5z" opacity=".6"/>
76
+ </svg>
77
+ </button>
78
+ <button id="paths-toggle-btn" class="paths-toggle-btn" title="Find shortest path between two nodes">
79
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
80
+ <circle cx="3" cy="13" r="2" opacity=".8"/>
81
+ <circle cx="13" cy="3" r="2" opacity=".8"/>
82
+ <path d="M4.5 11.5L11.5 4.5" stroke="currentColor" stroke-width="1.5" stroke-dasharray="3 2" fill="none"/>
83
+ </svg>
84
+ </button>
85
+ <button id="analysis-btn" class="analysis-btn" title="Graph analysis">
86
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
87
+ <path d="M1 14h14v1H0V0h1v14zM3 12V8h2v4H3zm3 0V5h2v7H6zm3 0V2h2v10H9zm3 0V6h2v6h-2z"/>
88
+ </svg>
89
+ </button>
90
+ <button id="fit-btn" class="fit-btn" title="Fit to view" onclick="window.laminarkGraph && window.laminarkGraph.fitToView()">
91
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
92
+ <path d="M2 2h4v1.5H3.5V6H2V2zm8 0h4v4h-1.5V3.5H10V2zM2 10h1.5v2.5H6V14H2v-4zm10.5 2.5V10H14v4h-4v-1.5h2.5z"/>
93
+ </svg>
94
+ </button>
95
+ </div>
96
+ <div class="graph-legend" id="graph-legend">
97
+ <div class="graph-legend-title">Entity Types</div>
98
+ <div class="graph-legend-item"><span class="legend-color" style="background:#58a6ff; border-radius:3px;"></span> Project</div>
99
+ <div class="graph-legend-item"><span class="legend-color" style="background:#3fb950; border-radius:2px;"></span> File</div>
100
+ <div class="graph-legend-item"><span class="legend-color" style="background:#d29922; border-radius:0; transform:rotate(45deg); width:9px; height:9px;"></span> Decision</div>
101
+ <div class="graph-legend-item"><span class="legend-color legend-triangle" style="background:transparent; border-left:6px solid transparent; border-right:6px solid transparent; border-bottom:11px solid #f85149; border-radius:0; width:0; height:0;"></span> Problem</div>
102
+ <div class="graph-legend-item"><span class="legend-color" style="background:#a371f7; clip-path:polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);"></span> Solution</div>
103
+ <div class="graph-legend-item"><span class="legend-color" style="background:#f0883e; clip-path:polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);"></span> Reference</div>
104
+ </div>
105
+ </div>
106
+ <aside id="analysis-panel" class="analysis-panel hidden">
107
+ <div class="panel-header">
108
+ <h3>Graph Analysis</h3>
109
+ <button id="analysis-close" aria-label="Close analysis panel">&times;</button>
110
+ </div>
111
+ <div id="analysis-body" class="analysis-body">
112
+ <p class="empty-state">Loading analysis...</p>
113
+ </div>
114
+ </aside>
115
+ </div>
116
+ </div>
117
+
118
+ <div id="timeline-view" class="view-container">
119
+ <div id="timeline-content">
120
+ <p class="empty-state">Loading timeline data...</p>
121
+ </div>
122
+ <button class="jump-today-btn" title="Jump to latest">Today</button>
123
+ </div>
124
+
125
+ <div id="activity-view" class="view-container">
126
+ <div class="activity-feed-header">
127
+ <h3>Live Activity</h3>
128
+ <button id="activity-clear-btn" class="activity-clear-btn">Clear</button>
129
+ </div>
130
+ <div id="activity-feed" class="activity-feed">
131
+ <p class="empty-state">Waiting for live events...</p>
132
+ </div>
133
+ </div>
134
+
135
+ <div id="tools-view" class="view-container">
136
+ <div class="tools-toolbar">
137
+ <div class="tools-toolbar-left">
138
+ <button class="tools-layout-btn active" data-layout="force" title="Force-directed layout">Force</button>
139
+ <button class="tools-layout-btn" data-layout="cluster" title="Cluster by server">Clustered</button>
140
+ <span class="tools-separator">|</span>
141
+ <label class="tools-toggle-label">
142
+ <input type="checkbox" id="tools-cluster-toggle" checked>
143
+ <span>Show clusters</span>
144
+ </label>
145
+ </div>
146
+ <div class="tools-toolbar-right">
147
+ <select id="tools-filter-type" class="tools-filter-select" title="Filter by tool type">
148
+ <option value="">All types</option>
149
+ <option value="mcp_server">MCP Server</option>
150
+ <option value="mcp_tool">MCP Tool</option>
151
+ <option value="slash_command">Slash Command</option>
152
+ <option value="skill">Skill</option>
153
+ <option value="plugin">Plugin</option>
154
+ <option value="builtin">Built-in</option>
155
+ </select>
156
+ <select id="tools-filter-server" class="tools-filter-select" title="Filter by server">
157
+ <option value="">All servers</option>
158
+ </select>
159
+ </div>
160
+ </div>
161
+ <div class="tools-content-row">
162
+ <div class="tools-graph-area">
163
+ <svg id="tools-svg"></svg>
164
+ <div class="tools-graph-stats" id="tools-stats">0 tools, 0 flows</div>
165
+ </div>
166
+ <aside id="tools-detail-panel" class="tools-detail-panel hidden">
167
+ <div class="panel-header">
168
+ <h3 id="tools-detail-title">Tool Details</h3>
169
+ <button id="tools-detail-close" aria-label="Close detail panel">&times;</button>
170
+ </div>
171
+ <div id="tools-detail-body">
172
+ <p class="empty-state">Click a tool node to view details</p>
173
+ </div>
174
+ </aside>
175
+ </div>
176
+ <div class="tools-session-strip" id="tools-session-strip">
177
+ <div class="tools-session-strip-label">Recent sessions</div>
178
+ <div class="tools-session-strip-content" id="tools-session-strip-content"></div>
179
+ </div>
180
+ </div>
181
+
182
+ <div id="settings-view" class="view-container">
183
+ <div class="settings-layout">
184
+ <nav class="settings-sidebar">
185
+ <div class="settings-sidebar-item active" data-settings-tab="overview">Overview</div>
186
+ <div class="settings-sidebar-item" data-settings-tab="database">Database</div>
187
+ <div class="settings-sidebar-item" data-settings-tab="intelligence">Intelligence</div>
188
+ <div class="settings-sidebar-item" data-settings-tab="configuration">Configuration</div>
189
+ <div class="settings-sidebar-item settings-sidebar-item-danger" data-settings-tab="danger">Danger Zone</div>
190
+ </nav>
191
+
192
+ <div class="settings-content">
193
+ <div id="settings-success" class="settings-success hidden"></div>
194
+
195
+ <!-- Overview Panel -->
196
+ <div class="settings-panel active" data-settings-panel="overview">
197
+ <h2 class="settings-heading">Database Statistics</h2>
198
+ <div id="db-stats-grid" class="db-stats-grid">
199
+ <p class="empty-state">Loading statistics...</p>
200
+ </div>
201
+
202
+ <h2 class="settings-heading" style="margin-top:24px;">System Info</h2>
203
+ <div id="system-info-grid" class="db-stats-grid system-info-grid">
204
+ <p class="empty-state">Loading...</p>
205
+ </div>
206
+
207
+ <h2 class="settings-heading" style="margin-top:24px;">Database Storage</h2>
208
+ <div id="db-storage-grid" class="db-stats-grid">
209
+ <p class="empty-state">Loading...</p>
210
+ </div>
211
+
212
+ <h2 class="settings-heading" style="margin-top:24px;">Process Memory</h2>
213
+ <div id="process-memory-grid" class="db-stats-grid">
214
+ <p class="empty-state">Loading...</p>
215
+ </div>
216
+ </div>
217
+
218
+ <!-- Database Panel -->
219
+ <div class="settings-panel" data-settings-panel="database">
220
+ <h2 class="settings-heading">Database Hygiene</h2>
221
+ <div id="hygiene-section" class="config-section">
222
+ <div class="config-section-body" id="hy-body" style="border-top:none;">
223
+ <p class="config-field-desc" style="margin-bottom: 12px;">
224
+ Analyze observations for deletion candidates scored on 6 signals: orphaned, island node, noise classified, short content, auto-captured, stale.
225
+ </p>
226
+ <span id="hy-status" class="config-section-status disabled" style="margin-bottom:12px;display:inline-block;">Not scanned</span>
227
+
228
+ <div class="config-field">
229
+ <div class="config-field-label">Tier Filter</div>
230
+ <div class="config-field-desc">Which confidence tier to analyze</div>
231
+ <div class="config-radio-group" id="hy-tier">
232
+ <button class="config-radio active" data-value="high">High (&ge; 0.7)</button>
233
+ <button class="config-radio" data-value="medium">Medium+ (&ge; 0.5)</button>
234
+ <button class="config-radio" data-value="all">All</button>
235
+ </div>
236
+ </div>
237
+
238
+ <div class="config-actions" style="margin-bottom: 16px;">
239
+ <button class="btn-config-save" id="hy-scan">Scan Now</button>
240
+ </div>
241
+
242
+ <div id="hy-results" class="hygiene-results hidden">
243
+ <div id="hy-summary" class="hygiene-summary"></div>
244
+ <div id="hy-table-wrap" class="hygiene-table-wrap">
245
+ <table id="hy-table" class="hygiene-table">
246
+ <thead>
247
+ <tr>
248
+ <th>ID</th>
249
+ <th>Kind</th>
250
+ <th>Source</th>
251
+ <th>Confidence</th>
252
+ <th>Signals</th>
253
+ <th>Preview</th>
254
+ </tr>
255
+ </thead>
256
+ <tbody id="hy-table-body"></tbody>
257
+ </table>
258
+ </div>
259
+ <div class="config-actions" style="margin-top: 12px;">
260
+ <button class="btn-danger" id="hy-purge">Purge Selected Tier</button>
261
+ </div>
262
+ </div>
263
+ </div>
264
+ </div>
265
+
266
+ <h2 class="settings-heading" style="margin-top:24px;">Hygiene Settings</h2>
267
+ <div id="hygiene-config-section" class="config-section">
268
+ <div class="config-section-body" id="hc-body" style="border-top:none;">
269
+ <p class="config-field-desc" style="margin-bottom: 12px;">
270
+ Configure signal weights and tier thresholds used to score deletion candidates.
271
+ </p>
272
+
273
+ <div class="config-field-group-label">Signal Weights</div>
274
+
275
+ <div class="config-threshold-grid" id="hc-weights">
276
+ <div class="config-threshold-row">
277
+ <span class="config-threshold-label">Orphaned</span>
278
+ <input type="range" class="config-slider" id="hc-w-orphaned" min="0" max="1" step="0.01" value="0.30">
279
+ <span class="config-slider-value" id="hc-w-orphaned-val">0.30</span>
280
+ </div>
281
+ <div class="config-threshold-row">
282
+ <span class="config-threshold-label">Island Node</span>
283
+ <input type="range" class="config-slider" id="hc-w-islandNode" min="0" max="1" step="0.01" value="0.25">
284
+ <span class="config-slider-value" id="hc-w-islandNode-val">0.25</span>
285
+ </div>
286
+ <div class="config-threshold-row">
287
+ <span class="config-threshold-label">Noise</span>
288
+ <input type="range" class="config-slider" id="hc-w-noiseClassified" min="0" max="1" step="0.01" value="0.25">
289
+ <span class="config-slider-value" id="hc-w-noiseClassified-val">0.25</span>
290
+ </div>
291
+ <div class="config-threshold-row">
292
+ <span class="config-threshold-label">Short Content</span>
293
+ <input type="range" class="config-slider" id="hc-w-shortContent" min="0" max="1" step="0.01" value="0.10">
294
+ <span class="config-slider-value" id="hc-w-shortContent-val">0.10</span>
295
+ </div>
296
+ <div class="config-threshold-row">
297
+ <span class="config-threshold-label">Auto-Captured</span>
298
+ <input type="range" class="config-slider" id="hc-w-autoCaptured" min="0" max="1" step="0.01" value="0.10">
299
+ <span class="config-slider-value" id="hc-w-autoCaptured-val">0.10</span>
300
+ </div>
301
+ <div class="config-threshold-row">
302
+ <span class="config-threshold-label">Stale</span>
303
+ <input type="range" class="config-slider" id="hc-w-stale" min="0" max="1" step="0.01" value="0.10">
304
+ <span class="config-slider-value" id="hc-w-stale-val">0.10</span>
305
+ </div>
306
+ </div>
307
+
308
+ <div class="config-field-group-label">Thresholds</div>
309
+
310
+ <div class="config-threshold-grid" id="hc-thresholds">
311
+ <div class="config-threshold-row">
312
+ <span class="config-threshold-label">High Tier &ge;</span>
313
+ <input type="range" class="config-slider" id="hc-t-high" min="0" max="1" step="0.01" value="0.70">
314
+ <span class="config-slider-value" id="hc-t-high-val">0.70</span>
315
+ </div>
316
+ <div class="config-threshold-row">
317
+ <span class="config-threshold-label">Medium Tier &ge;</span>
318
+ <input type="range" class="config-slider" id="hc-t-medium" min="0" max="1" step="0.01" value="0.50">
319
+ <span class="config-slider-value" id="hc-t-medium-val">0.50</span>
320
+ </div>
321
+ </div>
322
+
323
+ <div class="config-field">
324
+ <div class="config-field-label">Short Content Threshold (chars)</div>
325
+ <div class="config-field-value">
326
+ <input type="number" id="hc-short-threshold" class="config-number-input" min="0" value="50">
327
+ </div>
328
+ </div>
329
+
330
+ <div class="config-actions">
331
+ <button class="btn-config-save" id="hc-save">Save</button>
332
+ <button class="btn-config-defaults" id="hc-defaults">Reset to Defaults</button>
333
+ </div>
334
+
335
+ <div class="config-field-group-label" style="margin-top:16px;">Find Analysis</div>
336
+ <p class="config-field-desc" style="margin-bottom: 12px;">
337
+ Score distribution of all observations using current weights. Shows where the cutoff line falls.
338
+ </p>
339
+ <div class="config-actions" style="margin-bottom: 12px;">
340
+ <button class="btn-config-save" id="hc-find">Find</button>
341
+ </div>
342
+ <div id="hc-find-results" class="hidden">
343
+ <div id="hc-find-summary" class="hygiene-summary"></div>
344
+ <div id="hc-find-histogram" class="hygiene-distribution"></div>
345
+ <div id="hc-find-islands" class="hygiene-summary" style="margin-top:8px;"></div>
346
+ </div>
347
+ </div>
348
+ </div>
349
+ </div>
350
+
351
+ <!-- Intelligence Panel -->
352
+ <div class="settings-panel" data-settings-panel="intelligence">
353
+ <h2 class="settings-heading">Topic Detection</h2>
354
+ <div id="topic-detection-section" class="config-section">
355
+ <div class="config-section-body" id="td-body" style="border-top:none;">
356
+ <div class="config-field">
357
+ <div class="config-field-header">
358
+ <span class="config-field-label">Enabled</span>
359
+ <label class="config-toggle">
360
+ <input type="checkbox" id="td-enabled" checked>
361
+ <span class="config-toggle-slider"></span>
362
+ </label>
363
+ </div>
364
+ <div class="config-field-desc">Master toggle for topic shift detection</div>
365
+ <span id="td-status" class="config-section-status enabled" style="margin-top:8px;display:inline-block;">Enabled</span>
366
+ </div>
367
+
368
+ <div id="td-fields">
369
+ <div class="config-field">
370
+ <div class="config-field-label">Sensitivity Preset</div>
371
+ <div class="config-field-desc">Controls how easily topic shifts are detected</div>
372
+ <div class="config-radio-group" id="td-preset">
373
+ <button class="config-radio" data-value="sensitive">Sensitive</button>
374
+ <button class="config-radio active" data-value="balanced">Balanced</button>
375
+ <button class="config-radio" data-value="relaxed">Relaxed</button>
376
+ </div>
377
+ </div>
378
+
379
+ <div class="config-field">
380
+ <div class="config-field-label">Sensitivity Multiplier</div>
381
+ <div class="config-field-desc">Multiplied with EWMA stddev for threshold (auto-filled from preset)</div>
382
+ <div class="config-field-value">
383
+ <input type="number" id="td-multiplier" class="config-number-input" step="0.1" min="0.1" value="1.5">
384
+ </div>
385
+ </div>
386
+
387
+ <div class="config-field">
388
+ <div class="config-field-header">
389
+ <span class="config-field-label">Manual Threshold</span>
390
+ <label class="config-toggle">
391
+ <input type="checkbox" id="td-manual-enabled">
392
+ <span class="config-toggle-slider"></span>
393
+ </label>
394
+ </div>
395
+ <div class="config-field-desc">Override adaptive threshold with a fixed value</div>
396
+ <div class="config-field-value">
397
+ <input type="number" id="td-manual-value" class="config-number-input" step="0.01" min="0" value="0.3" disabled>
398
+ </div>
399
+ </div>
400
+
401
+ <div class="config-field">
402
+ <div class="config-field-label">EWMA Alpha</div>
403
+ <div class="config-field-desc">Decay factor for exponentially weighted moving average (0.01 - 1.0)</div>
404
+ <div class="config-field-value">
405
+ <input type="range" id="td-ewma" class="config-slider" min="0.01" max="1" step="0.01" value="0.3">
406
+ <span id="td-ewma-val" class="config-slider-value">0.30</span>
407
+ </div>
408
+ </div>
409
+
410
+ <div class="config-field">
411
+ <div class="config-field-label">Threshold Bounds</div>
412
+ <div class="config-field-desc">Hard min/max limits for the adaptive threshold</div>
413
+ <div class="config-field-row">
414
+ <div class="config-field-inline">
415
+ <span>Min</span>
416
+ <input type="number" id="td-bounds-min" class="config-number-input" step="0.01" min="0.05" max="0.95" value="0.15">
417
+ </div>
418
+ <div class="config-field-inline">
419
+ <span>Max</span>
420
+ <input type="number" id="td-bounds-max" class="config-number-input" step="0.01" min="0.05" max="0.95" value="0.6">
421
+ </div>
422
+ </div>
423
+ </div>
424
+ </div>
425
+
426
+ <div class="config-actions">
427
+ <button class="btn-config-save" id="td-save">Save</button>
428
+ <button class="btn-config-defaults" id="td-defaults">Reset to Defaults</button>
429
+ </div>
430
+ </div>
431
+ </div>
432
+
433
+ <h2 class="settings-heading" style="margin-top:24px;">Graph Extraction</h2>
434
+ <div id="graph-extraction-section" class="config-section">
435
+ <div class="config-section-body" id="ge-body" style="border-top:none;">
436
+ <div class="config-field">
437
+ <div class="config-field-header">
438
+ <span class="config-field-label">Enabled</span>
439
+ <label class="config-toggle">
440
+ <input type="checkbox" id="ge-enabled" checked>
441
+ <span class="config-toggle-slider"></span>
442
+ </label>
443
+ </div>
444
+ <div class="config-field-desc">Master toggle for knowledge graph extraction</div>
445
+ <span id="ge-status" class="config-section-status enabled" style="margin-top:8px;display:inline-block;">Enabled</span>
446
+ </div>
447
+
448
+ <div id="ge-fields">
449
+ <div class="config-field-group-label">Temporal Decay</div>
450
+
451
+ <div class="config-field">
452
+ <div class="config-field-label">Half-Life (days)</div>
453
+ <div class="config-field-desc">How many days until edge weight decays to 50%</div>
454
+ <div class="config-field-value">
455
+ <input type="number" id="ge-halflife" class="config-number-input" min="1" value="30">
456
+ </div>
457
+ </div>
458
+
459
+ <div class="config-field">
460
+ <div class="config-field-label">Minimum Floor</div>
461
+ <div class="config-field-desc">Lowest weight an edge can decay to before deletion check</div>
462
+ <div class="config-field-value">
463
+ <input type="range" id="ge-minfloor" class="config-slider" min="0" max="0.99" step="0.01" value="0.05">
464
+ <span id="ge-minfloor-val" class="config-slider-value">0.05</span>
465
+ </div>
466
+ </div>
467
+
468
+ <div class="config-field">
469
+ <div class="config-field-label">Deletion Threshold</div>
470
+ <div class="config-field-desc">Edges below this weight are deleted during curation</div>
471
+ <div class="config-field-value">
472
+ <input type="range" id="ge-delthresh" class="config-slider" min="0" max="0.99" step="0.01" value="0.08">
473
+ <span id="ge-delthresh-val" class="config-slider-value">0.08</span>
474
+ </div>
475
+ </div>
476
+
477
+ <div class="config-field">
478
+ <div class="config-field-label">Max Age (days)</div>
479
+ <div class="config-field-desc">Maximum age before forced deletion regardless of weight</div>
480
+ <div class="config-field-value">
481
+ <input type="number" id="ge-maxage" class="config-number-input" min="1" value="180">
482
+ </div>
483
+ </div>
484
+
485
+ <div class="config-field-group-label">Fuzzy Deduplication</div>
486
+
487
+ <div class="config-field">
488
+ <div class="config-field-label">Max Levenshtein Distance</div>
489
+ <div class="config-field-desc">Maximum edit distance for typo matching</div>
490
+ <div class="config-field-value">
491
+ <input type="number" id="ge-levenshtein" class="config-number-input" min="1" max="10" value="2">
492
+ </div>
493
+ </div>
494
+
495
+ <div class="config-field">
496
+ <div class="config-field-label">Jaccard Threshold</div>
497
+ <div class="config-field-desc">Minimum word-overlap similarity for dedup matching</div>
498
+ <div class="config-field-value">
499
+ <input type="range" id="ge-jaccard" class="config-slider" min="0" max="1" step="0.01" value="0.7">
500
+ <span id="ge-jaccard-val" class="config-slider-value">0.70</span>
501
+ </div>
502
+ </div>
503
+
504
+ <div class="config-field-group-label">Quality Gate</div>
505
+
506
+ <div class="config-field">
507
+ <div class="config-field-label">Max Files per Observation</div>
508
+ <div class="config-field-desc">Maximum File nodes extracted from a single observation</div>
509
+ <div class="config-field-value">
510
+ <input type="number" id="ge-maxfiles" class="config-number-input" min="1" value="5">
511
+ </div>
512
+ </div>
513
+
514
+ <div class="config-field">
515
+ <div class="config-field-label">Type Confidence Thresholds</div>
516
+ <div class="config-field-desc">Minimum confidence to persist each entity type</div>
517
+ <div class="config-threshold-grid" id="ge-thresholds">
518
+ <div class="config-threshold-row">
519
+ <span class="config-threshold-label">File</span>
520
+ <input type="range" class="config-slider" data-type="File" min="0" max="1" step="0.01" value="0.95">
521
+ <span class="config-slider-value">0.95</span>
522
+ </div>
523
+ <div class="config-threshold-row">
524
+ <span class="config-threshold-label">Project</span>
525
+ <input type="range" class="config-slider" data-type="Project" min="0" max="1" step="0.01" value="0.8">
526
+ <span class="config-slider-value">0.80</span>
527
+ </div>
528
+ <div class="config-threshold-row">
529
+ <span class="config-threshold-label">Reference</span>
530
+ <input type="range" class="config-slider" data-type="Reference" min="0" max="1" step="0.01" value="0.85">
531
+ <span class="config-slider-value">0.85</span>
532
+ </div>
533
+ <div class="config-threshold-row">
534
+ <span class="config-threshold-label">Decision</span>
535
+ <input type="range" class="config-slider" data-type="Decision" min="0" max="1" step="0.01" value="0.65">
536
+ <span class="config-slider-value">0.65</span>
537
+ </div>
538
+ <div class="config-threshold-row">
539
+ <span class="config-threshold-label">Problem</span>
540
+ <input type="range" class="config-slider" data-type="Problem" min="0" max="1" step="0.01" value="0.6">
541
+ <span class="config-slider-value">0.60</span>
542
+ </div>
543
+ <div class="config-threshold-row">
544
+ <span class="config-threshold-label">Solution</span>
545
+ <input type="range" class="config-slider" data-type="Solution" min="0" max="1" step="0.01" value="0.6">
546
+ <span class="config-slider-value">0.60</span>
547
+ </div>
548
+ </div>
549
+ </div>
550
+
551
+ <div class="config-field">
552
+ <div class="config-field-label">File Non-Change Multiplier</div>
553
+ <div class="config-field-desc">Confidence multiplier for File paths from non-change observations</div>
554
+ <div class="config-field-value">
555
+ <input type="range" id="ge-filenonchange" class="config-slider" min="0" max="1" step="0.01" value="0.74">
556
+ <span id="ge-filenonchange-val" class="config-slider-value">0.74</span>
557
+ </div>
558
+ </div>
559
+
560
+ <div class="config-field">
561
+ <div class="config-field-row">
562
+ <div class="config-field-inline">
563
+ <span>Min Name Length</span>
564
+ <input type="number" id="ge-minname" class="config-number-input" min="1" value="3">
565
+ </div>
566
+ <div class="config-field-inline">
567
+ <span>Max Name Length</span>
568
+ <input type="number" id="ge-maxname" class="config-number-input" min="10" value="200">
569
+ </div>
570
+ </div>
571
+ </div>
572
+
573
+ <div class="config-field-group-label">Relationship Detector</div>
574
+
575
+ <div class="config-field">
576
+ <div class="config-field-label">Min Edge Confidence</div>
577
+ <div class="config-field-desc">Minimum confidence to persist a relationship edge</div>
578
+ <div class="config-field-value">
579
+ <input type="range" id="ge-minedge" class="config-slider" min="0" max="1" step="0.01" value="0.45">
580
+ <span id="ge-minedge-val" class="config-slider-value">0.45</span>
581
+ </div>
582
+ </div>
583
+
584
+ <div class="config-field-group-label">Signal Classifier</div>
585
+
586
+ <div class="config-field">
587
+ <div class="config-field-label">Min Content Length</div>
588
+ <div class="config-field-desc">Minimum characters required to process an observation</div>
589
+ <div class="config-field-value">
590
+ <input type="number" id="ge-mincontent" class="config-number-input" min="0" value="30">
591
+ </div>
592
+ </div>
593
+ </div>
594
+
595
+ <div class="config-actions">
596
+ <button class="btn-config-save" id="ge-save">Save</button>
597
+ <button class="btn-config-defaults" id="ge-defaults">Reset to Defaults</button>
598
+ </div>
599
+ </div>
600
+ </div>
601
+ </div>
602
+
603
+ <!-- Configuration Panel -->
604
+ <div class="settings-panel" data-settings-panel="configuration">
605
+ <h2 class="settings-heading">Tool Response Verbosity</h2>
606
+ <div id="tool-verbosity-section" class="config-section">
607
+ <div class="config-section-body" id="tv-body" style="border-top:none;">
608
+ <div class="config-field">
609
+ <div class="config-field-label">Verbosity Level</div>
610
+ <div class="config-field-desc">Controls how much detail MCP tool responses include</div>
611
+ <span id="tv-status" class="config-section-status enabled" style="margin-bottom:8px;display:inline-block;">Standard</span>
612
+ <div class="config-radio-group" id="tv-level">
613
+ <button class="config-radio" data-value="1">Minimal</button>
614
+ <button class="config-radio active" data-value="2">Standard</button>
615
+ <button class="config-radio" data-value="3">Verbose</button>
616
+ </div>
617
+ </div>
618
+
619
+ <div class="config-field">
620
+ <div class="config-field-desc" style="margin-top: 4px; line-height: 1.6;">
621
+ <strong>Minimal:</strong> Just confirms the tool ran<br>
622
+ <strong>Standard:</strong> Shows titles and key info<br>
623
+ <strong>Verbose:</strong> Full text with all details
624
+ </div>
625
+ </div>
626
+
627
+ <div class="config-actions">
628
+ <button class="btn-config-save" id="tv-save">Save</button>
629
+ <button class="btn-config-defaults" id="tv-defaults">Reset to Defaults</button>
630
+ </div>
631
+ </div>
632
+ </div>
633
+
634
+ <h2 class="settings-heading" style="margin-top:24px;">Cross-Project Access</h2>
635
+ <div id="cross-access-section" class="config-section">
636
+ <div class="config-section-body" id="ca-body" style="border-top:none;">
637
+ <p class="config-field-desc" style="margin-bottom: 12px;">Allow the current project to read memories from other projects. Read-only &mdash; no writes cross projects.</p>
638
+ <span id="ca-status" class="config-section-status disabled" style="margin-bottom:12px;display:inline-block;">0 projects</span>
639
+ <div class="cross-access-lists">
640
+ <div class="cross-access-list">
641
+ <div class="cross-access-list-header">Available</div>
642
+ <ul id="ca-available" class="cross-access-items"></ul>
643
+ </div>
644
+ <div class="cross-access-list">
645
+ <div class="cross-access-list-header">Can Read From</div>
646
+ <ul id="ca-readable" class="cross-access-items"></ul>
647
+ </div>
648
+ </div>
649
+ <div class="config-actions">
650
+ <button class="btn-config-save" id="ca-save">Save</button>
651
+ <button class="btn-config-defaults" id="ca-defaults">Reset to Defaults</button>
652
+ </div>
653
+ </div>
654
+ </div>
655
+ </div>
656
+
657
+ <!-- Danger Zone Panel -->
658
+ <div class="settings-panel" data-settings-panel="danger">
659
+ <h2 class="settings-heading settings-heading-danger">Danger Zone</h2>
660
+ <div class="settings-scope">
661
+ <label class="scope-radio"><input type="radio" name="reset-scope" value="current" checked> Current project only (<span id="reset-scope-project-name">—</span>)</label>
662
+ <label class="scope-radio"><input type="radio" name="reset-scope" value="all"> All projects</label>
663
+ </div>
664
+
665
+ <div class="danger-zone">
666
+ <div class="reset-action-card">
667
+ <div class="reset-action-info">
668
+ <h3>Reset Observations</h3>
669
+ <p>Delete all observations, FTS indexes, and vector embeddings.</p>
670
+ </div>
671
+ <button class="btn-danger reset-action-btn" data-reset-type="observations">Reset Observations</button>
672
+ </div>
673
+ <div class="reset-action-card">
674
+ <div class="reset-action-info">
675
+ <h3>Reset Knowledge Graph</h3>
676
+ <p>Delete all graph nodes and edges.</p>
677
+ </div>
678
+ <button class="btn-danger reset-action-btn" data-reset-type="graph">Reset Graph</button>
679
+ </div>
680
+ <div class="reset-action-card">
681
+ <div class="reset-action-info">
682
+ <h3>Reset Sessions &amp; Intelligence</h3>
683
+ <p>Delete all sessions, context stashes, threshold history, and shift decisions.</p>
684
+ </div>
685
+ <button class="btn-danger reset-action-btn" data-reset-type="sessions">Reset Sessions</button>
686
+ </div>
687
+ <div class="reset-action-card reset-action-card-destructive">
688
+ <div class="reset-action-info">
689
+ <h3>Reset Everything</h3>
690
+ <p>Delete all data across all table groups. This cannot be undone.</p>
691
+ </div>
692
+ <button class="btn-danger-primary reset-action-btn" data-reset-type="all">Reset Everything</button>
693
+ </div>
694
+ </div>
695
+ </div>
696
+ </div>
697
+ </div>
698
+ </div>
699
+
700
+ <div id="help-view" class="view-container">
701
+ <div id="help-content" style="display:flex;flex:1;min-height:0;">
702
+ <p class="empty-state">Loading help...</p>
703
+ </div>
704
+ </div>
705
+ </main>
706
+
707
+ <div id="confirm-overlay" class="confirm-overlay hidden">
708
+ <div class="confirm-dialog">
709
+ <h3 id="confirm-title">Confirm Reset</h3>
710
+ <p id="confirm-desc"></p>
711
+ <p id="confirm-count" class="confirm-count"></p>
712
+ <input type="text" id="confirm-input" class="confirm-input" autocomplete="off" spellcheck="false">
713
+ <div class="confirm-actions">
714
+ <button id="confirm-cancel" class="btn-secondary">Cancel</button>
715
+ <button id="confirm-btn" class="btn-danger-primary" disabled>Reset</button>
716
+ </div>
717
+ </div>
718
+ </div>
719
+
720
+
721
+ <aside id="detail-panel" class="hidden">
722
+ <div class="panel-header">
723
+ <h3 id="detail-title">Node Details</h3>
724
+ <div class="panel-header-actions">
725
+ <button id="detail-focus" class="panel-action-btn" aria-label="Focus on this node" title="Focus on this node">
726
+ <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor">
727
+ <path d="M8 3a5 5 0 100 10A5 5 0 008 3zm0 1.5a3.5 3.5 0 110 7 3.5 3.5 0 010-7zM8 6a2 2 0 100 4 2 2 0 000-4z"/>
728
+ </svg>
729
+ </button>
730
+ <button id="detail-close" aria-label="Close detail panel">&times;</button>
731
+ </div>
732
+ </div>
733
+ <div id="detail-body">
734
+ <p class="empty-state">Click a node to view details</p>
735
+ </div>
736
+ </aside>
737
+
738
+ <aside id="path-detail-panel" class="path-detail-panel hidden">
739
+ <div class="panel-header">
740
+ <h3 id="path-detail-title">Debug Path</h3>
741
+ <button id="path-detail-close" aria-label="Close path detail panel">&times;</button>
742
+ </div>
743
+ <div id="path-detail-body" class="path-detail-body">
744
+ <p class="empty-state">Select a debug path to view details</p>
745
+ </div>
746
+ </aside>
747
+
748
+ <script src="/app.js"></script>
749
+ <script src="/graph.js"></script>
750
+ <script src="/timeline.js"></script>
751
+ <script src="/activity.js"></script>
752
+ <script src="/settings.js"></script>
753
+ <script src="/help.js"></script>
754
+ <script src="/tools.js"></script>
755
+ </body>
756
+ </html>