laminark 0.1.0 → 2.21.7
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/.claude-plugin/marketplace.json +15 -0
- package/README.md +71 -36
- package/package.json +7 -9
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/dist/hooks/handler.d.ts +1 -3
- package/plugin/dist/hooks/handler.d.ts.map +1 -1
- package/plugin/dist/hooks/handler.js +22 -310
- package/plugin/dist/hooks/handler.js.map +1 -1
- package/plugin/dist/index.d.ts +1 -3
- package/plugin/dist/index.d.ts.map +1 -1
- package/plugin/dist/index.js +392 -1895
- package/plugin/dist/index.js.map +1 -1
- package/plugin/dist/{observations-CorAAc1A.d.mts → observations-Ch0nc47i.d.mts} +1 -23
- package/plugin/dist/observations-Ch0nc47i.d.mts.map +1 -0
- package/plugin/dist/{tool-registry-e710BvXq.mjs → tool-registry-CZ3mJ4iR.mjs} +13 -932
- package/plugin/dist/tool-registry-CZ3mJ4iR.mjs.map +1 -0
- package/plugin/hooks/hooks.json +6 -6
- package/plugin/scripts/README.md +1 -19
- package/plugin/scripts/bump-version.sh +3 -1
- package/plugin/scripts/ensure-deps.sh +2 -5
- package/plugin/scripts/install.sh +39 -115
- package/plugin/scripts/local-install.sh +58 -93
- package/plugin/scripts/setup-tmpdir.sh +65 -0
- package/plugin/scripts/uninstall.sh +38 -76
- package/plugin/scripts/update.sh +69 -20
- package/plugin/scripts/verify-install.sh +25 -69
- package/plugin/ui/activity.js +0 -12
- package/plugin/ui/app.js +54 -24
- package/plugin/ui/graph.js +186 -413
- package/plugin/ui/help.js +172 -876
- package/plugin/ui/index.html +242 -506
- package/plugin/ui/settings.js +17 -781
- package/plugin/ui/styles.css +44 -990
- package/plugin/ui/timeline.js +2 -2
- package/plugin/CLAUDE.md +0 -10
- package/plugin/commands/recall.md +0 -55
- package/plugin/commands/remember.md +0 -34
- package/plugin/commands/resume.md +0 -45
- package/plugin/commands/stash.md +0 -34
- package/plugin/commands/status.md +0 -33
- package/plugin/dist/observations-CorAAc1A.d.mts.map +0 -1
- package/plugin/dist/tool-registry-e710BvXq.mjs.map +0 -1
- package/plugin/laminark.db +0 -0
- package/plugin/package.json +0 -17
- package/plugin/scripts/dev-sync.sh +0 -58
- package/plugin/ui/help/activity-feed.png +0 -0
- package/plugin/ui/help/analysis-panel.png +0 -0
- package/plugin/ui/help/graph-toolbar.png +0 -0
- package/plugin/ui/help/graph-view.png +0 -0
- package/plugin/ui/help/settings.png +0 -0
- package/plugin/ui/help/timeline.png +0 -0
- package/plugin/ui/tools.js +0 -826
package/plugin/ui/help.js
CHANGED
|
@@ -1,840 +1,200 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Laminark Help tab
|
|
3
|
-
*
|
|
4
|
-
* Data-driven: all content defined as structured sections, auto-generates
|
|
5
|
-
* table of contents, supports search filtering, and cross-links between
|
|
6
|
-
* sections via smooth-scroll anchors.
|
|
2
|
+
* Laminark Help tab -- in-app documentation for MCP tools,
|
|
3
|
+
* knowledge graph concepts, UI features, and keyboard shortcuts.
|
|
7
4
|
*/
|
|
8
5
|
|
|
9
6
|
(function () {
|
|
10
|
-
// -----------------------------------------------------------------------
|
|
11
|
-
// Section data
|
|
12
|
-
// -----------------------------------------------------------------------
|
|
13
|
-
|
|
14
|
-
var SECTIONS = [
|
|
15
|
-
{
|
|
16
|
-
id: 'getting-started',
|
|
17
|
-
title: 'Getting Started',
|
|
18
|
-
blocks: [
|
|
19
|
-
{
|
|
20
|
-
type: 'text',
|
|
21
|
-
content:
|
|
22
|
-
'Laminark is a persistent adaptive memory system for Claude Code. ' +
|
|
23
|
-
'It automatically captures observations during your coding sessions ' +
|
|
24
|
-
'via hooks (PostToolUse, SessionStart, etc.), classifies them with ' +
|
|
25
|
-
'Haiku AI, extracts entities and relationships into a knowledge graph, ' +
|
|
26
|
-
'and streams live updates over SSE.',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
type: 'list',
|
|
30
|
-
items: [
|
|
31
|
-
'Observations are captured automatically — no manual tagging needed.',
|
|
32
|
-
'Haiku classifies each observation by kind: change, finding, decision, reference, or verification.',
|
|
33
|
-
'Graph extraction identifies entities (Project, File, Decision, Problem, Solution, Reference) and their relationships.',
|
|
34
|
-
'Topic detection uses EWMA to identify conversation shifts.',
|
|
35
|
-
'All data is project-scoped — switch projects via the selector in the nav bar.',
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
type: 'tip',
|
|
40
|
-
content:
|
|
41
|
-
'<strong>Tip:</strong> Use the project selector in the top navigation bar to switch between projects. Each project maintains its own memory, graph, and timeline.',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
type: 'crosslinks',
|
|
45
|
-
links: [
|
|
46
|
-
{ target: 'knowledge-graph', label: 'Knowledge Graph' },
|
|
47
|
-
{ target: 'mcp-tools', label: 'MCP Tools' },
|
|
48
|
-
],
|
|
49
|
-
},
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
id: 'knowledge-graph',
|
|
54
|
-
title: 'Knowledge Graph',
|
|
55
|
-
blocks: [
|
|
56
|
-
{
|
|
57
|
-
type: 'text',
|
|
58
|
-
content:
|
|
59
|
-
'The knowledge graph visualizes entities extracted from your observations and ' +
|
|
60
|
-
'the relationships between them. Nodes are sized by observation count and degree ' +
|
|
61
|
-
'(number of connections). Edges are colored by relationship type.',
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
type: 'subsection',
|
|
65
|
-
title: 'Entity Types',
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
type: 'cards',
|
|
69
|
-
items: [
|
|
70
|
-
{ name: 'Project', desc: 'Represents a codebase or project workspace.', color: '#58a6ff' },
|
|
71
|
-
{ name: 'File', desc: 'Source files, configs, or other project files.', color: '#3fb950' },
|
|
72
|
-
{ name: 'Decision', desc: 'Architectural or implementation decisions.', color: '#d29922' },
|
|
73
|
-
{ name: 'Problem', desc: 'Issues, bugs, or challenges encountered.', color: '#f85149' },
|
|
74
|
-
{ name: 'Solution', desc: 'Fixes, workarounds, or approaches that resolved problems.', color: '#a371f7' },
|
|
75
|
-
{ name: 'Reference', desc: 'External docs, libraries, APIs, or resources.', color: '#f0883e' },
|
|
76
|
-
],
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
type: 'subsection',
|
|
80
|
-
title: 'Relationship Types',
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
type: 'table',
|
|
84
|
-
rows: [
|
|
85
|
-
['related_to', 'General association between entities'],
|
|
86
|
-
['solved_by', 'Problem resolved by a Solution'],
|
|
87
|
-
['caused_by', 'Problem caused by another entity'],
|
|
88
|
-
['modifies', 'Decision or Solution that modifies a File'],
|
|
89
|
-
['informed_by', 'Decision informed by a Reference'],
|
|
90
|
-
['references', 'Entity references another entity'],
|
|
91
|
-
['verified_by', 'Change verified by a verification observation'],
|
|
92
|
-
['preceded_by', 'Temporal ordering between entities'],
|
|
93
|
-
],
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
type: 'img',
|
|
97
|
-
src: 'help/graph-view.png',
|
|
98
|
-
caption: 'Knowledge graph showing entities and relationships',
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
type: 'tip',
|
|
102
|
-
content:
|
|
103
|
-
'<strong>Tip:</strong> Node size reflects importance — larger nodes have more observations and connections. Hover over any node for a tooltip with details.',
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
type: 'crosslinks',
|
|
107
|
-
links: [
|
|
108
|
-
{ target: 'graph-interactions', label: 'Graph Interactions' },
|
|
109
|
-
{ target: 'graph-toolbar', label: 'Graph Toolbar' },
|
|
110
|
-
],
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
id: 'graph-interactions',
|
|
116
|
-
title: 'Graph Interactions',
|
|
117
|
-
blocks: [
|
|
118
|
-
{
|
|
119
|
-
type: 'text',
|
|
120
|
-
content:
|
|
121
|
-
'The graph is fully interactive. Click, drag, pan, and zoom to explore your knowledge.',
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
type: 'list',
|
|
125
|
-
items: [
|
|
126
|
-
'Click a node to select it and open the detail panel with observations and relationships.',
|
|
127
|
-
'Drag nodes to reposition them. The simulation will adjust.',
|
|
128
|
-
'Pan by clicking and dragging the background.',
|
|
129
|
-
'Zoom with the mouse wheel or trackpad.',
|
|
130
|
-
'Right-click a node for a context menu with Focus, Find Path, and Details options.',
|
|
131
|
-
'Click a relationship in the detail panel to navigate to the connected node.',
|
|
132
|
-
],
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
type: 'subsection',
|
|
136
|
-
title: 'Detail Panel',
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
type: 'text',
|
|
140
|
-
content:
|
|
141
|
-
'When you click a node, the detail panel slides in from the right showing the entity type, ' +
|
|
142
|
-
'creation date, a scrollable list of observations, and all relationships. Click any ' +
|
|
143
|
-
'relationship to navigate to the connected node.',
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
type: 'subsection',
|
|
147
|
-
title: 'Focus Mode',
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
type: 'text',
|
|
151
|
-
content:
|
|
152
|
-
'Focus mode zooms into a single node and its immediate neighbors. A breadcrumb bar ' +
|
|
153
|
-
'appears at the top showing your navigation path. Click any breadcrumb to go back. ' +
|
|
154
|
-
'Use the focus button in the detail panel or right-click context menu to enter focus mode.',
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
type: 'crosslinks',
|
|
158
|
-
links: [
|
|
159
|
-
{ target: 'graph-toolbar', label: 'Graph Toolbar' },
|
|
160
|
-
{ target: 'keyboard-shortcuts', label: 'Keyboard Shortcuts' },
|
|
161
|
-
],
|
|
162
|
-
},
|
|
163
|
-
],
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
id: 'graph-toolbar',
|
|
167
|
-
title: 'Graph Toolbar',
|
|
168
|
-
blocks: [
|
|
169
|
-
{
|
|
170
|
-
type: 'text',
|
|
171
|
-
content:
|
|
172
|
-
'The toolbar in the top-right corner of the graph view provides layout and analysis controls.',
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
type: 'subsection',
|
|
176
|
-
title: 'Layout Modes',
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
type: 'table',
|
|
180
|
-
rows: [
|
|
181
|
-
['Clustered', 'Force-directed layout grouping related nodes together (default)'],
|
|
182
|
-
['Hierarchical', 'Top-down tree layout organized by entity relationships'],
|
|
183
|
-
['Concentric', 'Radial layout with most-connected nodes at the center'],
|
|
184
|
-
['Communities', 'Detects and separates graph communities into distinct clusters'],
|
|
185
|
-
],
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
type: 'subsection',
|
|
189
|
-
title: 'Toolbar Buttons',
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
type: 'list',
|
|
193
|
-
items: [
|
|
194
|
-
'Edge Labels — Toggle edge relationship labels on/off. Use the dropdown to show/hide specific relationship types.',
|
|
195
|
-
'Pathfinder — Find the shortest path between two nodes. Click two nodes to see the highlighted path.',
|
|
196
|
-
'Analysis — Open the analysis panel showing entity type distribution, relationship stats, top entities by degree, and detected clusters.',
|
|
197
|
-
'Freeze — Pause live graph updates. A stale-data indicator appears when frozen and new data arrives.',
|
|
198
|
-
'Fit to View — Reset zoom and pan to fit all nodes in the viewport.',
|
|
199
|
-
],
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
type: 'subsection',
|
|
203
|
-
title: 'Pathfinder',
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
type: 'text',
|
|
207
|
-
content:
|
|
208
|
-
'Activate Pathfinder from the toolbar, then click a start node (green ring) and an end node ' +
|
|
209
|
-
'(red ring). The shortest path is highlighted in orange. Non-path elements are dimmed. ' +
|
|
210
|
-
'Click the Pathfinder button again or press Escape to exit.',
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
type: 'img',
|
|
214
|
-
src: 'help/graph-toolbar.png',
|
|
215
|
-
caption: 'Graph toolbar: layout modes, edge labels, pathfinder, analysis, freeze, fit-to-view',
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
type: 'img',
|
|
219
|
-
src: 'help/analysis-panel.png',
|
|
220
|
-
caption: 'Analysis panel showing entity types, relationship distribution, top entities, and clusters',
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
type: 'crosslinks',
|
|
224
|
-
links: [
|
|
225
|
-
{ target: 'graph-interactions', label: 'Graph Interactions' },
|
|
226
|
-
{ target: 'search-filtering', label: 'Search & Filtering' },
|
|
227
|
-
],
|
|
228
|
-
},
|
|
229
|
-
],
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
id: 'search-filtering',
|
|
233
|
-
title: 'Search & Filtering',
|
|
234
|
-
blocks: [
|
|
235
|
-
{
|
|
236
|
-
type: 'text',
|
|
237
|
-
content:
|
|
238
|
-
'Filter and search your knowledge graph to find exactly what you need.',
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
type: 'subsection',
|
|
242
|
-
title: 'Entity Type Filters',
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
type: 'text',
|
|
246
|
-
content:
|
|
247
|
-
'The filter bar below the navigation shows colored pills for each entity type with counts. ' +
|
|
248
|
-
'Click a pill to toggle that type on/off. Click "All" to show/hide everything. ' +
|
|
249
|
-
'Active pills are highlighted with their entity color.',
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
type: 'subsection',
|
|
253
|
-
title: 'Time Range',
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
type: 'text',
|
|
257
|
-
content:
|
|
258
|
-
'Below the filter bar, time range presets let you focus on recent data: All, Hour, Today, ' +
|
|
259
|
-
'Week, or Month. For custom ranges, set the From/To date inputs and click Apply. ' +
|
|
260
|
-
'Presets filter client-side instantly; custom ranges fetch from the server.',
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
type: 'subsection',
|
|
264
|
-
title: 'Search Box',
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
type: 'list',
|
|
268
|
-
items: [
|
|
269
|
-
'Type to client-filter — matches are highlighted in the graph as you type.',
|
|
270
|
-
'Press Enter to trigger a server-side full-text search for deeper results.',
|
|
271
|
-
'Use Arrow keys to navigate the results dropdown.',
|
|
272
|
-
'Press Escape to clear the search.',
|
|
273
|
-
'Click a result to select and center that node in the graph.',
|
|
274
|
-
],
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
type: 'crosslinks',
|
|
278
|
-
links: [
|
|
279
|
-
{ target: 'knowledge-graph', label: 'Knowledge Graph' },
|
|
280
|
-
{ target: 'keyboard-shortcuts', label: 'Keyboard Shortcuts' },
|
|
281
|
-
],
|
|
282
|
-
},
|
|
283
|
-
],
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
id: 'timeline',
|
|
287
|
-
title: 'Timeline',
|
|
288
|
-
blocks: [
|
|
289
|
-
{
|
|
290
|
-
type: 'text',
|
|
291
|
-
content:
|
|
292
|
-
'The Timeline tab shows a chronological view of your coding sessions and observations. ' +
|
|
293
|
-
'Sessions are grouped as cards along a vertical spine.',
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
type: 'list',
|
|
297
|
-
items: [
|
|
298
|
-
'Each session card shows the start time, duration, and observation count.',
|
|
299
|
-
'Click the session header to expand/collapse its observations.',
|
|
300
|
-
'Observations display timestamps, type dots (color-coded by source), and text previews.',
|
|
301
|
-
'Topic shift markers appear between observations when the AI detects a conversation change, with a confidence percentage.',
|
|
302
|
-
'Session summaries (italic text) provide an AI-generated overview of the session.',
|
|
303
|
-
'Infinite scroll pagination loads older sessions as you scroll down.',
|
|
304
|
-
'The "Jump to Today" button in the bottom-right corner scrolls to the most recent session.',
|
|
305
|
-
],
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
type: 'img',
|
|
309
|
-
src: 'help/timeline.png',
|
|
310
|
-
caption: 'Timeline view with sessions, observations, and topic shift markers',
|
|
311
|
-
},
|
|
312
|
-
{
|
|
313
|
-
type: 'tip',
|
|
314
|
-
content:
|
|
315
|
-
'<strong>Tip:</strong> Active sessions show a pulsing green badge. Completed sessions show a blue badge with the observation count.',
|
|
316
|
-
},
|
|
317
|
-
{
|
|
318
|
-
type: 'crosslinks',
|
|
319
|
-
links: [
|
|
320
|
-
{ target: 'activity-feed', label: 'Activity Feed' },
|
|
321
|
-
{ target: 'getting-started', label: 'Getting Started' },
|
|
322
|
-
],
|
|
323
|
-
},
|
|
324
|
-
],
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
id: 'activity-feed',
|
|
328
|
-
title: 'Activity Feed',
|
|
329
|
-
blocks: [
|
|
330
|
-
{
|
|
331
|
-
type: 'text',
|
|
332
|
-
content:
|
|
333
|
-
'The Activity tab shows a real-time event stream powered by Server-Sent Events (SSE). ' +
|
|
334
|
-
'Events appear with a slide-in animation as they arrive.',
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
type: 'subsection',
|
|
338
|
-
title: 'Event Types',
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
type: 'table',
|
|
342
|
-
rows: [
|
|
343
|
-
['Observation', 'New memory observation captured (blue)'],
|
|
344
|
-
['Entity', 'Knowledge graph entity created or updated (purple)'],
|
|
345
|
-
['Topic Shift', 'Conversation topic change detected (orange)'],
|
|
346
|
-
['Session Start', 'New coding session began (green)'],
|
|
347
|
-
['Session End', 'Coding session ended (gray)'],
|
|
348
|
-
],
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
type: 'list',
|
|
352
|
-
items: [
|
|
353
|
-
'Maximum 100 items are retained in the feed.',
|
|
354
|
-
'Each item shows an icon, event type, description, and timestamp.',
|
|
355
|
-
'Use the Clear button in the header to reset the feed.',
|
|
356
|
-
'Events are project-scoped — only events from the selected project appear.',
|
|
357
|
-
],
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
type: 'img',
|
|
361
|
-
src: 'help/activity-feed.png',
|
|
362
|
-
caption: 'Activity feed showing live SSE events',
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
type: 'crosslinks',
|
|
366
|
-
links: [
|
|
367
|
-
{ target: 'timeline', label: 'Timeline' },
|
|
368
|
-
{ target: 'settings', label: 'Settings' },
|
|
369
|
-
],
|
|
370
|
-
},
|
|
371
|
-
],
|
|
372
|
-
},
|
|
373
|
-
{
|
|
374
|
-
id: 'settings',
|
|
375
|
-
title: 'Settings',
|
|
376
|
-
blocks: [
|
|
377
|
-
{
|
|
378
|
-
type: 'text',
|
|
379
|
-
content:
|
|
380
|
-
'The Settings tab provides database statistics, configuration controls, and data management.',
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
type: 'subsection',
|
|
384
|
-
title: 'Database Statistics',
|
|
385
|
-
},
|
|
386
|
-
{
|
|
387
|
-
type: 'text',
|
|
388
|
-
content:
|
|
389
|
-
'A grid of stat cards shows live metrics for the selected project scope:',
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
type: 'table',
|
|
393
|
-
rows: [
|
|
394
|
-
['Observations', 'Total memory observations stored'],
|
|
395
|
-
['Embeddings', 'Vector embeddings for semantic search'],
|
|
396
|
-
['Staleness', 'Percentage of observations without embeddings'],
|
|
397
|
-
['Graph Nodes', 'Total entities in the knowledge graph'],
|
|
398
|
-
['Graph Edges', 'Total relationships between entities'],
|
|
399
|
-
['Sessions', 'Coding sessions recorded'],
|
|
400
|
-
['Stashes', 'Saved context stashes'],
|
|
401
|
-
['Topic Shifts', 'Detected topic changes'],
|
|
402
|
-
['Notifications', 'System notifications generated'],
|
|
403
|
-
['Projects', 'Total projects tracked'],
|
|
404
|
-
],
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
type: 'subsection',
|
|
408
|
-
title: 'Topic Detection Config',
|
|
409
|
-
},
|
|
410
|
-
{
|
|
411
|
-
type: 'text',
|
|
412
|
-
content:
|
|
413
|
-
'Enable or disable automatic topic detection. Choose sensitivity presets (Low, Medium, High) ' +
|
|
414
|
-
'or fine-tune EWMA parameters: alpha (smoothing factor), threshold, and window size.',
|
|
415
|
-
},
|
|
416
|
-
{
|
|
417
|
-
type: 'subsection',
|
|
418
|
-
title: 'Graph Extraction Config',
|
|
419
|
-
},
|
|
420
|
-
{
|
|
421
|
-
type: 'text',
|
|
422
|
-
content:
|
|
423
|
-
'Configure how entities and relationships are extracted: temporal decay rate, fuzzy dedup ' +
|
|
424
|
-
'similarity threshold, quality gate thresholds for each entity type, and relationship ' +
|
|
425
|
-
'detector sensitivity.',
|
|
426
|
-
},
|
|
427
|
-
{
|
|
428
|
-
type: 'subsection',
|
|
429
|
-
title: 'Danger Zone',
|
|
430
|
-
},
|
|
431
|
-
{
|
|
432
|
-
type: 'text',
|
|
433
|
-
content:
|
|
434
|
-
'Choose a scope (global or current project), then use reset operations to clear specific data. ' +
|
|
435
|
-
'All destructive actions require typing a confirmation phrase.',
|
|
436
|
-
},
|
|
437
|
-
{
|
|
438
|
-
type: 'table',
|
|
439
|
-
rows: [
|
|
440
|
-
['Reset Observations', 'Delete all observations and embeddings'],
|
|
441
|
-
['Reset Graph', 'Delete all knowledge graph nodes and edges'],
|
|
442
|
-
['Reset Sessions', 'Delete all session records and topic shifts'],
|
|
443
|
-
['Reset Everything', 'Complete data wipe — observations, graph, sessions, and config'],
|
|
444
|
-
],
|
|
445
|
-
},
|
|
446
|
-
{
|
|
447
|
-
type: 'img',
|
|
448
|
-
src: 'help/settings.png',
|
|
449
|
-
caption: 'Settings view with database statistics, config sections, and danger zone',
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
type: 'crosslinks',
|
|
453
|
-
links: [
|
|
454
|
-
{ target: 'getting-started', label: 'Getting Started' },
|
|
455
|
-
{ target: 'mcp-tools', label: 'MCP Tools' },
|
|
456
|
-
],
|
|
457
|
-
},
|
|
458
|
-
],
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
id: 'mcp-tools',
|
|
462
|
-
title: 'MCP Tools',
|
|
463
|
-
blocks: [
|
|
464
|
-
{
|
|
465
|
-
type: 'text',
|
|
466
|
-
content:
|
|
467
|
-
'Laminark exposes tools via the Model Context Protocol (MCP) that Claude Code uses ' +
|
|
468
|
-
'to save memories, search knowledge, query the graph, manage debug paths, track work branches, and ingest codebase knowledge.',
|
|
469
|
-
},
|
|
470
|
-
{
|
|
471
|
-
type: 'cards',
|
|
472
|
-
items: [
|
|
473
|
-
{ name: 'save_memory', desc: 'Save a new memory observation with text content and optional title. Supports kind classification: change, reference, finding, decision, or verification.' },
|
|
474
|
-
{ name: 'recall', desc: 'Search, view, purge, or restore memories. Full-text search with detail levels: compact, timeline, or full.' },
|
|
475
|
-
{ name: 'topic_context', desc: 'Show recently stashed context threads. Use when asked "where was I?" to resume abandoned work.' },
|
|
476
|
-
{ name: 'query_graph', desc: 'Query the knowledge graph for entities and relationships with configurable traversal depth (1-4).' },
|
|
477
|
-
{ name: 'graph_stats', desc: 'Get knowledge graph statistics: entity counts, relationship distribution, and health metrics.' },
|
|
478
|
-
{ name: 'status', desc: 'Show Laminark system status: connection info, memory count, token estimates, and capabilities.' },
|
|
479
|
-
{ name: 'discover_tools', desc: 'Search the tool registry by keyword or description. Supports semantic search across all registered tools.' },
|
|
480
|
-
{ name: 'report_available_tools', desc: 'Register all tools available in this session with Laminark for discovery and routing.' },
|
|
481
|
-
{ name: 'path_start', desc: 'Start tracking a debug path. Use when actively debugging an issue to record the investigation.' },
|
|
482
|
-
{ name: 'path_resolve', desc: 'Resolve the active debug path with a resolution summary. Generates a KISS summary (Problem/Cause/Fix/Prevention).' },
|
|
483
|
-
{ name: 'path_show', desc: 'Show a debug path with its waypoints and KISS summary. Omit path ID for the active path.' },
|
|
484
|
-
{ name: 'path_list', desc: 'List recent debug paths, optionally filtered by status: active, resolved, or abandoned.' },
|
|
485
|
-
{ name: 'query_branches', desc: 'Search and list thought branches — coherent units of work like investigations, bug fixes, or features.' },
|
|
486
|
-
{ name: 'show_branch', desc: 'Show detailed view of a thought branch with observation timeline and arc stage annotations.' },
|
|
487
|
-
{ name: 'branch_summary', desc: 'Summary of recent work activity grouped by time window. Shows what was investigated, fixed, and built.' },
|
|
488
|
-
{ name: 'hygiene', desc: 'Analyze observations for deletion candidates with confidence scoring. Simulate mode for dry-run, purge mode to execute.' },
|
|
489
|
-
{ name: 'ingest_knowledge', desc: 'Ingest structured markdown documents into queryable per-project reference memories. Auto-detects .planning/codebase/ (GSD output).' },
|
|
490
|
-
],
|
|
491
|
-
},
|
|
492
|
-
{
|
|
493
|
-
type: 'crosslinks',
|
|
494
|
-
links: [
|
|
495
|
-
{ target: 'getting-started', label: 'Getting Started' },
|
|
496
|
-
{ target: 'settings', label: 'Settings' },
|
|
497
|
-
],
|
|
498
|
-
},
|
|
499
|
-
],
|
|
500
|
-
},
|
|
501
|
-
{
|
|
502
|
-
id: 'keyboard-shortcuts',
|
|
503
|
-
title: 'Keyboard Shortcuts',
|
|
504
|
-
blocks: [
|
|
505
|
-
{
|
|
506
|
-
type: 'shortcuts',
|
|
507
|
-
items: [
|
|
508
|
-
{ keys: ['Ctrl', 'Shift', 'P'], desc: 'Toggle performance overlay (graph view)' },
|
|
509
|
-
{ keys: ['Escape'], desc: 'Close detail panel, cancel pathfinder, dismiss dialogs' },
|
|
510
|
-
{ keys: ['Enter'], desc: 'Trigger server-side search (in search input)' },
|
|
511
|
-
{ keys: ['Arrow Up', 'Arrow Down'], desc: 'Navigate search results dropdown' },
|
|
512
|
-
],
|
|
513
|
-
},
|
|
514
|
-
{
|
|
515
|
-
type: 'crosslinks',
|
|
516
|
-
links: [
|
|
517
|
-
{ target: 'graph-interactions', label: 'Graph Interactions' },
|
|
518
|
-
{ target: 'search-filtering', label: 'Search & Filtering' },
|
|
519
|
-
],
|
|
520
|
-
},
|
|
521
|
-
],
|
|
522
|
-
},
|
|
523
|
-
];
|
|
524
|
-
|
|
525
|
-
// -----------------------------------------------------------------------
|
|
526
|
-
// Render engine — sidebar tree layout
|
|
527
|
-
// -----------------------------------------------------------------------
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Extract subsections from a section's blocks (blocks with type 'subsection').
|
|
531
|
-
*/
|
|
532
|
-
function getSubsections(section) {
|
|
533
|
-
var subs = [];
|
|
534
|
-
section.blocks.forEach(function (b) {
|
|
535
|
-
if (b.type === 'subsection') {
|
|
536
|
-
subs.push({ title: b.title, id: section.id + '--' + b.title.toLowerCase().replace(/[^a-z0-9]+/g, '-') });
|
|
537
|
-
}
|
|
538
|
-
});
|
|
539
|
-
return subs;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
var activeSection = null;
|
|
543
|
-
var treeItems = {};
|
|
544
|
-
var contentArea = null;
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* Build the sidebar tree from SECTIONS.
|
|
548
|
-
*/
|
|
549
|
-
function renderSidebar() {
|
|
550
|
-
var sidebar = document.createElement('aside');
|
|
551
|
-
sidebar.className = 'help-sidebar';
|
|
552
|
-
|
|
553
|
-
// Search
|
|
554
|
-
var searchDiv = document.createElement('div');
|
|
555
|
-
searchDiv.className = 'help-sidebar-search';
|
|
556
|
-
var searchInput = document.createElement('input');
|
|
557
|
-
searchInput.type = 'text';
|
|
558
|
-
searchInput.className = 'help-search-input';
|
|
559
|
-
searchInput.placeholder = 'Search...';
|
|
560
|
-
searchDiv.appendChild(searchInput);
|
|
561
|
-
sidebar.appendChild(searchDiv);
|
|
562
|
-
|
|
563
|
-
// Tree container
|
|
564
|
-
var treeContainer = document.createElement('div');
|
|
565
|
-
treeContainer.className = 'help-tree-container';
|
|
566
|
-
var tree = document.createElement('ul');
|
|
567
|
-
tree.className = 'help-tree';
|
|
568
|
-
|
|
569
|
-
SECTIONS.forEach(function (section) {
|
|
570
|
-
var li = document.createElement('li');
|
|
571
|
-
li.className = 'help-tree-item';
|
|
572
|
-
li.setAttribute('data-section', section.id);
|
|
573
|
-
|
|
574
|
-
var subs = getSubsections(section);
|
|
575
|
-
|
|
576
|
-
// Label
|
|
577
|
-
var label = document.createElement('span');
|
|
578
|
-
label.className = 'help-tree-label';
|
|
579
|
-
|
|
580
|
-
if (subs.length > 0) {
|
|
581
|
-
var toggle = document.createElement('span');
|
|
582
|
-
toggle.className = 'help-tree-toggle';
|
|
583
|
-
toggle.textContent = '\u25B8'; // ▸
|
|
584
|
-
label.appendChild(toggle);
|
|
585
|
-
} else {
|
|
586
|
-
// spacer for alignment
|
|
587
|
-
var spacer = document.createElement('span');
|
|
588
|
-
spacer.style.width = '16px';
|
|
589
|
-
spacer.style.flexShrink = '0';
|
|
590
|
-
label.appendChild(spacer);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
var text = document.createTextNode(section.title);
|
|
594
|
-
label.appendChild(text);
|
|
595
|
-
li.appendChild(label);
|
|
596
|
-
|
|
597
|
-
// Children (subsections)
|
|
598
|
-
if (subs.length > 0) {
|
|
599
|
-
var childUl = document.createElement('ul');
|
|
600
|
-
childUl.className = 'help-tree-children';
|
|
601
|
-
|
|
602
|
-
subs.forEach(function (sub) {
|
|
603
|
-
var childLi = document.createElement('li');
|
|
604
|
-
var childLabel = document.createElement('span');
|
|
605
|
-
childLabel.className = 'help-tree-child-label';
|
|
606
|
-
childLabel.textContent = sub.title;
|
|
607
|
-
childLabel.addEventListener('click', function (e) {
|
|
608
|
-
e.stopPropagation();
|
|
609
|
-
showSection(section.id);
|
|
610
|
-
// Scroll to subsection after rendering
|
|
611
|
-
setTimeout(function () {
|
|
612
|
-
var el = document.getElementById('help-sub-' + sub.id);
|
|
613
|
-
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
614
|
-
}, 50);
|
|
615
|
-
});
|
|
616
|
-
childLi.appendChild(childLabel);
|
|
617
|
-
childUl.appendChild(childLi);
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
li.appendChild(childUl);
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
// Click handler for top-level label
|
|
624
|
-
label.addEventListener('click', function () {
|
|
625
|
-
showSection(section.id);
|
|
626
|
-
});
|
|
627
|
-
|
|
628
|
-
treeItems[section.id] = li;
|
|
629
|
-
tree.appendChild(li);
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
treeContainer.appendChild(tree);
|
|
633
|
-
sidebar.appendChild(treeContainer);
|
|
634
|
-
|
|
635
|
-
// Search filtering
|
|
636
|
-
var debounce = null;
|
|
637
|
-
searchInput.addEventListener('input', function () {
|
|
638
|
-
if (debounce) clearTimeout(debounce);
|
|
639
|
-
debounce = setTimeout(function () {
|
|
640
|
-
var query = searchInput.value.trim().toLowerCase();
|
|
641
|
-
SECTIONS.forEach(function (section) {
|
|
642
|
-
var li = treeItems[section.id];
|
|
643
|
-
if (!query) {
|
|
644
|
-
li.style.display = '';
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
var text = (section.title + ' ' + getBlocksText(section.blocks)).toLowerCase();
|
|
648
|
-
li.style.display = text.indexOf(query) !== -1 ? '' : 'none';
|
|
649
|
-
});
|
|
650
|
-
}, 150);
|
|
651
|
-
});
|
|
652
|
-
|
|
653
|
-
return sidebar;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
/**
|
|
657
|
-
* Show a specific section in the content area. Updates tree active state.
|
|
658
|
-
*/
|
|
659
|
-
function showSection(sectionId) {
|
|
660
|
-
if (!contentArea) return;
|
|
661
|
-
|
|
662
|
-
// Find section data
|
|
663
|
-
var section = null;
|
|
664
|
-
for (var i = 0; i < SECTIONS.length; i++) {
|
|
665
|
-
if (SECTIONS[i].id === sectionId) {
|
|
666
|
-
section = SECTIONS[i];
|
|
667
|
-
break;
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
if (!section) return;
|
|
671
|
-
|
|
672
|
-
activeSection = sectionId;
|
|
673
|
-
|
|
674
|
-
// Update tree active states
|
|
675
|
-
Object.keys(treeItems).forEach(function (id) {
|
|
676
|
-
var li = treeItems[id];
|
|
677
|
-
var label = li.querySelector('.help-tree-label');
|
|
678
|
-
if (id === sectionId) {
|
|
679
|
-
label.classList.add('active');
|
|
680
|
-
li.classList.add('expanded');
|
|
681
|
-
} else {
|
|
682
|
-
label.classList.remove('active');
|
|
683
|
-
li.classList.remove('expanded');
|
|
684
|
-
}
|
|
685
|
-
});
|
|
686
|
-
|
|
687
|
-
// Render section content
|
|
688
|
-
contentArea.innerHTML = '';
|
|
689
|
-
contentArea.scrollTop = 0;
|
|
690
|
-
var el = renderSection(section);
|
|
691
|
-
contentArea.appendChild(el);
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* Main entry point: builds layout, renders sidebar + content area.
|
|
696
|
-
*/
|
|
697
7
|
function renderHelp() {
|
|
698
8
|
var container = document.getElementById('help-content');
|
|
699
9
|
if (!container) return;
|
|
700
10
|
|
|
701
11
|
container.innerHTML = '';
|
|
702
12
|
|
|
703
|
-
//
|
|
704
|
-
|
|
705
|
-
|
|
13
|
+
// -----------------------------------------------------------------------
|
|
14
|
+
// Section 1: Getting Started
|
|
15
|
+
// -----------------------------------------------------------------------
|
|
16
|
+
var startSection = document.createElement('div');
|
|
17
|
+
startSection.className = 'help-section';
|
|
18
|
+
|
|
19
|
+
var startTitle = document.createElement('h2');
|
|
20
|
+
startTitle.className = 'help-section-title';
|
|
21
|
+
startTitle.textContent = 'Getting Started';
|
|
22
|
+
startSection.appendChild(startTitle);
|
|
23
|
+
|
|
24
|
+
var startIntro = document.createElement('p');
|
|
25
|
+
startIntro.className = 'help-intro';
|
|
26
|
+
startIntro.textContent =
|
|
27
|
+
'Laminark is a persistent adaptive memory system for Claude Code. ' +
|
|
28
|
+
'It automatically captures observations during your coding sessions ' +
|
|
29
|
+
'and builds a knowledge graph of entities and relationships across your projects.';
|
|
30
|
+
startSection.appendChild(startIntro);
|
|
31
|
+
|
|
32
|
+
container.appendChild(startSection);
|
|
33
|
+
|
|
34
|
+
// -----------------------------------------------------------------------
|
|
35
|
+
// Section 2: MCP Tools
|
|
36
|
+
// -----------------------------------------------------------------------
|
|
37
|
+
var toolsSection = document.createElement('div');
|
|
38
|
+
toolsSection.className = 'help-section';
|
|
39
|
+
|
|
40
|
+
var toolsTitle = document.createElement('h2');
|
|
41
|
+
toolsTitle.className = 'help-section-title';
|
|
42
|
+
toolsTitle.textContent = 'MCP Tools';
|
|
43
|
+
toolsSection.appendChild(toolsTitle);
|
|
44
|
+
|
|
45
|
+
var tools = [
|
|
46
|
+
{ name: 'save_memory', desc: 'Save a new memory observation. Provide text content and an optional title.' },
|
|
47
|
+
{ name: 'recall', desc: 'Search, view, purge, or restore memories. Search first to find matches, then act on specific results by ID.' },
|
|
48
|
+
{ name: 'topic_context', desc: 'Shows recently stashed context threads. Use when asked \'where was I?\' or to see abandoned conversation threads.' },
|
|
49
|
+
{ name: 'query_graph', desc: 'Query the knowledge graph to find entities and relationships. Answer questions like \'what files does this decision affect?\'' },
|
|
50
|
+
{ name: 'graph_stats', desc: 'Get knowledge graph statistics: entity counts, relationship distribution, health metrics.' },
|
|
51
|
+
{ name: 'status', desc: 'Show Laminark system status: connection info, memory count, token estimates, and capabilities.' },
|
|
52
|
+
{ name: 'discover_tools', desc: 'Search the tool registry to find available tools by keyword or description. Supports semantic search.' },
|
|
53
|
+
{ name: 'report_available_tools', desc: 'Register all tools available in this session with Laminark. Call once at session start.' },
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
var toolsGrid = document.createElement('div');
|
|
57
|
+
toolsGrid.className = 'help-cards';
|
|
58
|
+
|
|
59
|
+
tools.forEach(function (tool) {
|
|
60
|
+
var card = document.createElement('div');
|
|
61
|
+
card.className = 'help-card';
|
|
706
62
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
63
|
+
var name = document.createElement('div');
|
|
64
|
+
name.className = 'help-card-name';
|
|
65
|
+
name.textContent = tool.name;
|
|
66
|
+
card.appendChild(name);
|
|
711
67
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
}
|
|
68
|
+
var desc = document.createElement('div');
|
|
69
|
+
desc.className = 'help-card-desc';
|
|
70
|
+
desc.textContent = tool.desc;
|
|
71
|
+
card.appendChild(desc);
|
|
717
72
|
|
|
718
|
-
|
|
719
|
-
* Extract all text content from blocks for search matching.
|
|
720
|
-
*/
|
|
721
|
-
function getBlocksText(blocks) {
|
|
722
|
-
var parts = [];
|
|
723
|
-
blocks.forEach(function (b) {
|
|
724
|
-
if (b.type === 'text') parts.push(b.content);
|
|
725
|
-
if (b.type === 'tip') parts.push(b.content);
|
|
726
|
-
if (b.type === 'subsection') parts.push(b.title);
|
|
727
|
-
if (b.type === 'list' && b.items) b.items.forEach(function (i) { parts.push(i); });
|
|
728
|
-
if (b.type === 'cards' && b.items) b.items.forEach(function (c) { parts.push(c.name + ' ' + c.desc); });
|
|
729
|
-
if (b.type === 'table' && b.rows) b.rows.forEach(function (r) { parts.push(r.join(' ')); });
|
|
730
|
-
if (b.type === 'shortcuts' && b.items) b.items.forEach(function (s) { parts.push(s.keys.join('+') + ' ' + s.desc); });
|
|
73
|
+
toolsGrid.appendChild(card);
|
|
731
74
|
});
|
|
732
|
-
return parts.join(' ');
|
|
733
|
-
}
|
|
734
75
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
76
|
+
toolsSection.appendChild(toolsGrid);
|
|
77
|
+
container.appendChild(toolsSection);
|
|
78
|
+
|
|
79
|
+
// -----------------------------------------------------------------------
|
|
80
|
+
// Section 3: Knowledge Graph
|
|
81
|
+
// -----------------------------------------------------------------------
|
|
82
|
+
var graphSection = document.createElement('div');
|
|
83
|
+
graphSection.className = 'help-section';
|
|
84
|
+
|
|
85
|
+
var graphTitle = document.createElement('h2');
|
|
86
|
+
graphTitle.className = 'help-section-title';
|
|
87
|
+
graphTitle.textContent = 'Knowledge Graph';
|
|
88
|
+
graphSection.appendChild(graphTitle);
|
|
89
|
+
|
|
90
|
+
var entities = [
|
|
91
|
+
{ name: 'Project', color: '#58a6ff', desc: 'Represents a codebase or project workspace.' },
|
|
92
|
+
{ name: 'File', color: '#3fb950', desc: 'Source files, configs, or other project files.' },
|
|
93
|
+
{ name: 'Decision', color: '#d29922', desc: 'Architectural or implementation decisions made during development.' },
|
|
94
|
+
{ name: 'Problem', color: '#f85149', desc: 'Issues, bugs, or challenges encountered.' },
|
|
95
|
+
{ name: 'Solution', color: '#a371f7', desc: 'Fixes, workarounds, or approaches that resolved problems.' },
|
|
96
|
+
{ name: 'Reference', color: '#f0883e', desc: 'External docs, libraries, APIs, or resources referenced.' },
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
var entityList = document.createElement('div');
|
|
100
|
+
entityList.className = 'help-entity-list';
|
|
101
|
+
|
|
102
|
+
entities.forEach(function (entity) {
|
|
103
|
+
var item = document.createElement('div');
|
|
104
|
+
item.className = 'help-entity-item';
|
|
105
|
+
|
|
106
|
+
var dot = document.createElement('span');
|
|
107
|
+
dot.className = 'help-entity-dot';
|
|
108
|
+
dot.style.background = entity.color;
|
|
109
|
+
item.appendChild(dot);
|
|
110
|
+
|
|
111
|
+
var name = document.createElement('span');
|
|
112
|
+
name.className = 'help-entity-name';
|
|
113
|
+
name.textContent = entity.name;
|
|
114
|
+
item.appendChild(name);
|
|
115
|
+
|
|
116
|
+
var desc = document.createElement('span');
|
|
117
|
+
desc.className = 'help-entity-desc';
|
|
118
|
+
desc.textContent = entity.desc;
|
|
119
|
+
item.appendChild(desc);
|
|
120
|
+
|
|
121
|
+
entityList.appendChild(item);
|
|
750
122
|
});
|
|
751
123
|
|
|
752
|
-
|
|
753
|
-
|
|
124
|
+
graphSection.appendChild(entityList);
|
|
125
|
+
container.appendChild(graphSection);
|
|
126
|
+
|
|
127
|
+
// -----------------------------------------------------------------------
|
|
128
|
+
// Section 4: UI Guide
|
|
129
|
+
// -----------------------------------------------------------------------
|
|
130
|
+
var uiSection = document.createElement('div');
|
|
131
|
+
uiSection.className = 'help-section';
|
|
132
|
+
|
|
133
|
+
var uiTitle = document.createElement('h2');
|
|
134
|
+
uiTitle.className = 'help-section-title';
|
|
135
|
+
uiTitle.textContent = 'UI Guide';
|
|
136
|
+
uiSection.appendChild(uiTitle);
|
|
137
|
+
|
|
138
|
+
var tabs = [
|
|
139
|
+
{
|
|
140
|
+
name: 'Knowledge Graph',
|
|
141
|
+
desc: 'Interactive visualization of entities and their relationships. Click nodes for details, use filters to focus on specific entity types, search to find nodes, and use layout buttons to change the graph arrangement.',
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'Timeline',
|
|
145
|
+
desc: 'Chronological view of sessions and observations. Shows when memories were captured and topic shifts detected.',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'Activity',
|
|
149
|
+
desc: 'Live feed of real-time events from Laminark via SSE (Server-Sent Events). Shows new observations, entity updates, and session events as they happen.',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'Settings',
|
|
153
|
+
desc: 'Database statistics and danger zone for resetting data. View counts of observations, graph nodes, sessions, etc.',
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
tabs.forEach(function (tab) {
|
|
158
|
+
var item = document.createElement('div');
|
|
159
|
+
item.className = 'help-tab-item';
|
|
754
160
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
switch (block.type) {
|
|
760
|
-
case 'text': return renderText(block);
|
|
761
|
-
case 'list': return renderList(block);
|
|
762
|
-
case 'cards': return renderCards(block);
|
|
763
|
-
case 'table': return renderTable(block);
|
|
764
|
-
case 'shortcuts': return renderShortcuts(block);
|
|
765
|
-
case 'tip': return renderTip(block);
|
|
766
|
-
case 'subsection': return renderSubsection(block);
|
|
767
|
-
case 'crosslinks': return renderCrosslinks(block);
|
|
768
|
-
case 'img': return renderImage(block);
|
|
769
|
-
default:
|
|
770
|
-
var el = document.createElement('div');
|
|
771
|
-
return el;
|
|
772
|
-
}
|
|
773
|
-
}
|
|
161
|
+
var name = document.createElement('div');
|
|
162
|
+
name.className = 'help-tab-name';
|
|
163
|
+
name.textContent = tab.name;
|
|
164
|
+
item.appendChild(name);
|
|
774
165
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
return p;
|
|
780
|
-
}
|
|
166
|
+
var desc = document.createElement('div');
|
|
167
|
+
desc.className = 'help-tab-desc';
|
|
168
|
+
desc.textContent = tab.desc;
|
|
169
|
+
item.appendChild(desc);
|
|
781
170
|
|
|
782
|
-
|
|
783
|
-
var ul = document.createElement('ul');
|
|
784
|
-
ul.className = 'help-list';
|
|
785
|
-
block.items.forEach(function (item) {
|
|
786
|
-
var li = document.createElement('li');
|
|
787
|
-
li.textContent = item;
|
|
788
|
-
ul.appendChild(li);
|
|
171
|
+
uiSection.appendChild(item);
|
|
789
172
|
});
|
|
790
|
-
return ul;
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
function renderCards(block) {
|
|
794
|
-
var grid = document.createElement('div');
|
|
795
|
-
grid.className = 'help-cards';
|
|
796
|
-
block.items.forEach(function (card) {
|
|
797
|
-
var el = document.createElement('div');
|
|
798
|
-
el.className = 'help-card';
|
|
799
173
|
|
|
800
|
-
|
|
801
|
-
name.className = 'help-card-name';
|
|
802
|
-
name.textContent = card.name;
|
|
803
|
-
if (card.color) {
|
|
804
|
-
name.style.borderLeft = '3px solid ' + card.color;
|
|
805
|
-
name.style.paddingLeft = '8px';
|
|
806
|
-
}
|
|
807
|
-
el.appendChild(name);
|
|
174
|
+
container.appendChild(uiSection);
|
|
808
175
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
176
|
+
// -----------------------------------------------------------------------
|
|
177
|
+
// Section 5: Keyboard Shortcuts
|
|
178
|
+
// -----------------------------------------------------------------------
|
|
179
|
+
var kbSection = document.createElement('div');
|
|
180
|
+
kbSection.className = 'help-section';
|
|
813
181
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
182
|
+
var kbTitle = document.createElement('h2');
|
|
183
|
+
kbTitle.className = 'help-section-title';
|
|
184
|
+
kbTitle.textContent = 'Keyboard Shortcuts';
|
|
185
|
+
kbSection.appendChild(kbTitle);
|
|
818
186
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
var td = document.createElement('td');
|
|
826
|
-
td.textContent = cell;
|
|
827
|
-
tr.appendChild(td);
|
|
828
|
-
});
|
|
829
|
-
table.appendChild(tr);
|
|
830
|
-
});
|
|
831
|
-
return table;
|
|
832
|
-
}
|
|
187
|
+
var shortcuts = [
|
|
188
|
+
{ keys: ['Ctrl', 'Shift', 'P'], desc: 'Toggle performance overlay (graph view)' },
|
|
189
|
+
{ keys: ['Escape'], desc: 'Close detail panel / cancel dialog' },
|
|
190
|
+
{ keys: ['Enter'], desc: 'Trigger server-side search (graph search input)' },
|
|
191
|
+
{ keys: ['Arrow keys'], desc: 'Navigate search results dropdown' },
|
|
192
|
+
];
|
|
833
193
|
|
|
834
|
-
function renderShortcuts(block) {
|
|
835
194
|
var table = document.createElement('table');
|
|
836
195
|
table.className = 'help-shortcuts';
|
|
837
|
-
|
|
196
|
+
|
|
197
|
+
shortcuts.forEach(function (sc) {
|
|
838
198
|
var row = document.createElement('tr');
|
|
839
199
|
|
|
840
200
|
var keyCell = document.createElement('td');
|
|
@@ -854,76 +214,12 @@
|
|
|
854
214
|
|
|
855
215
|
table.appendChild(row);
|
|
856
216
|
});
|
|
857
|
-
return table;
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
function renderTip(block) {
|
|
861
|
-
var div = document.createElement('div');
|
|
862
|
-
div.className = 'help-tip';
|
|
863
|
-
div.innerHTML = block.content;
|
|
864
|
-
return div;
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
function renderSubsection(block) {
|
|
868
|
-
var h3 = document.createElement('h3');
|
|
869
|
-
h3.className = 'help-subsection-title';
|
|
870
|
-
h3.textContent = block.title;
|
|
871
|
-
// Generate an anchor ID for subsection scrolling
|
|
872
|
-
if (activeSection) {
|
|
873
|
-
h3.id = 'help-sub-' + activeSection + '--' + block.title.toLowerCase().replace(/[^a-z0-9]+/g, '-');
|
|
874
|
-
}
|
|
875
|
-
return h3;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
function renderCrosslinks(block) {
|
|
879
|
-
var div = document.createElement('div');
|
|
880
|
-
div.className = 'help-crosslinks';
|
|
881
|
-
|
|
882
|
-
var label = document.createTextNode('See also:');
|
|
883
|
-
div.appendChild(label);
|
|
884
|
-
|
|
885
|
-
block.links.forEach(function (link, idx) {
|
|
886
|
-
var a = document.createElement('a');
|
|
887
|
-
a.className = 'help-crosslink';
|
|
888
|
-
a.textContent = link.label;
|
|
889
|
-
a.addEventListener('click', function (e) {
|
|
890
|
-
e.preventDefault();
|
|
891
|
-
showSection(link.target);
|
|
892
|
-
});
|
|
893
|
-
div.appendChild(a);
|
|
894
|
-
|
|
895
|
-
if (idx < block.links.length - 1) {
|
|
896
|
-
div.appendChild(document.createTextNode(','));
|
|
897
|
-
}
|
|
898
|
-
});
|
|
899
217
|
|
|
900
|
-
|
|
218
|
+
kbSection.appendChild(table);
|
|
219
|
+
container.appendChild(kbSection);
|
|
901
220
|
}
|
|
902
221
|
|
|
903
|
-
|
|
904
|
-
var wrap = document.createElement('div');
|
|
905
|
-
wrap.className = 'help-screenshot';
|
|
906
|
-
|
|
907
|
-
var img = document.createElement('img');
|
|
908
|
-
img.src = block.src;
|
|
909
|
-
img.alt = block.caption || '';
|
|
910
|
-
img.loading = 'lazy';
|
|
911
|
-
wrap.appendChild(img);
|
|
912
|
-
|
|
913
|
-
if (block.caption) {
|
|
914
|
-
var caption = document.createElement('div');
|
|
915
|
-
caption.className = 'help-screenshot-caption';
|
|
916
|
-
caption.textContent = block.caption;
|
|
917
|
-
wrap.appendChild(caption);
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
return wrap;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
// -----------------------------------------------------------------------
|
|
924
|
-
// Auto-render
|
|
925
|
-
// -----------------------------------------------------------------------
|
|
926
|
-
|
|
222
|
+
// Auto-render when DOM is ready (help.js loads after app.js)
|
|
927
223
|
if (document.readyState === 'loading') {
|
|
928
224
|
document.addEventListener('DOMContentLoaded', renderHelp);
|
|
929
225
|
} else {
|