get-claudia 1.40.4 → 1.40.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "get-claudia",
3
- "version": "1.40.4",
3
+ "version": "1.40.5",
4
4
  "description": "An AI assistant who learns how you work.",
5
5
  "keywords": [
6
6
  "claudia",
@@ -22,7 +22,7 @@ const QUALITY_PRESETS = {
22
22
  low: { bloom: false, bloomStrength: 0, bloomRadius: 0, bloomThreshold: 0 },
23
23
  medium: { bloom: true, bloomStrength: 1.0, bloomRadius: 0.8, bloomThreshold: 0.2 },
24
24
  high: null, // use theme defaults
25
- ultra: { bloom: true, bloomStrength: 3.0, bloomRadius: 1.2, bloomThreshold: 0.05 }
25
+ ultra: { bloom: true, bloomStrength: 2.1, bloomRadius: 0.9, bloomThreshold: 0.05 }
26
26
  };
27
27
 
28
28
  // FPS tracking
@@ -136,6 +136,9 @@ export function animateNodes(Graph, elapsed, delta) {
136
136
  const ud = obj.userData;
137
137
  if (!ud || ud.hidden) continue;
138
138
 
139
+ // Skip memory nodes with no active animations (they don't breathe/rotate)
140
+ if (ud.nodeType === 'memory' && !node.__spawn && !node.__pulse && !node.__shimmer) continue;
141
+
139
142
  const baseScale = ud.baseScale || 1;
140
143
  const phase = ud.phase || 0;
141
144
  const coreMesh = ud.coreMesh;
@@ -6,6 +6,9 @@
6
6
  * the library handles all of that internally.
7
7
  */
8
8
 
9
+ import { Color } from 'three';
10
+ import { getActiveTheme } from './themes.js';
11
+
9
12
  let Graph = null;
10
13
  let graphData = { nodes: [], links: [] };
11
14
  let fullData = null; // Stashed for filter/reset
@@ -13,6 +16,10 @@ let highlightNodes = new Set();
13
16
  let highlightLinks = new Set();
14
17
  let selectedNode = null;
15
18
 
19
+ // Saved material state for restoring after clearSelection()
20
+ let savedMaterials = new Map(); // nodeId -> { color, emissiveIntensity }
21
+ let savedLinkColors = new Map(); // link -> { color, width }
22
+
16
23
  // ── Graph instance ─────────────────────────────────────────
17
24
 
18
25
  export function setGraphInstance(instance) {
@@ -62,13 +69,13 @@ export function updateNodeData(nodeId, updates) {
62
69
  // ── Selection + highlighting ──────────────────────────────
63
70
 
64
71
  export function highlightNeighborhood(node) {
72
+ // Restore previous highlight before applying new one
73
+ restoreSavedMaterials();
74
+
65
75
  highlightNodes.clear();
66
76
  highlightLinks.clear();
67
77
 
68
- if (!node) {
69
- triggerRefresh();
70
- return;
71
- }
78
+ if (!node) return;
72
79
 
73
80
  highlightNodes.add(node.id);
74
81
 
@@ -86,14 +93,14 @@ export function highlightNeighborhood(node) {
86
93
  }
87
94
  }
88
95
 
89
- triggerRefresh();
96
+ applyHighlightMaterials();
90
97
  }
91
98
 
92
99
  export function clearSelection() {
93
100
  selectedNode = null;
101
+ restoreSavedMaterials();
94
102
  highlightNodes.clear();
95
103
  highlightLinks.clear();
96
- triggerRefresh();
97
104
  document.getElementById('detail-panel')?.classList.add('hidden');
98
105
  }
99
106
 
@@ -130,12 +137,71 @@ function pushData() {
130
137
  Graph.graphData({ nodes: graphData.nodes, links: graphData.links });
131
138
  }
132
139
 
133
- function triggerRefresh() {
140
+ /**
141
+ * Apply highlight visuals directly on Three.js materials for the
142
+ * selected neighborhood. O(k) where k = neighborhood size, not O(N).
143
+ */
144
+ function applyHighlightMaterials() {
134
145
  if (!Graph) return;
135
- // Trigger visual refresh without rebuilding the graph
136
- Graph.nodeColor(Graph.nodeColor());
137
- Graph.linkColor(Graph.linkColor());
138
- Graph.linkWidth(Graph.linkWidth());
146
+ const theme = getActiveTheme();
147
+ const highlightColor = new Color(0x7dd3fc); // bright cyan highlight
148
+
149
+ // Highlight nodes: boost emissive intensity
150
+ for (const nodeId of highlightNodes) {
151
+ const node = graphData.nodes.find(n => n.id === nodeId);
152
+ if (!node?.__threeObj) continue;
153
+
154
+ const ud = node.__threeObj.userData;
155
+ const mesh = ud?.coreMesh;
156
+ if (!mesh?.material) continue;
157
+
158
+ // Save original state
159
+ savedMaterials.set(nodeId, {
160
+ emissiveIntensity: mesh.material.emissiveIntensity,
161
+ emissive: mesh.material.emissive.getHex()
162
+ });
163
+
164
+ // Boost: brighter emissive
165
+ mesh.material.emissiveIntensity = Math.min(1.0, mesh.material.emissiveIntensity * 2.5);
166
+ }
167
+
168
+ // Highlight links: change color and width
169
+ for (const link of highlightLinks) {
170
+ const linkObj = link.__lineObj;
171
+ if (linkObj?.material) {
172
+ savedLinkColors.set(link, {
173
+ color: linkObj.material.color.getHex(),
174
+ linewidth: linkObj.material.linewidth
175
+ });
176
+ linkObj.material.color.set(theme.links.highlight);
177
+ }
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Restore materials saved before highlighting.
183
+ */
184
+ function restoreSavedMaterials() {
185
+ // Restore node materials
186
+ for (const [nodeId, saved] of savedMaterials) {
187
+ const node = graphData.nodes.find(n => n.id === nodeId);
188
+ if (!node?.__threeObj) continue;
189
+ const mesh = node.__threeObj.userData?.coreMesh;
190
+ if (!mesh?.material) continue;
191
+
192
+ mesh.material.emissiveIntensity = saved.emissiveIntensity;
193
+ mesh.material.emissive.setHex(saved.emissive);
194
+ }
195
+ savedMaterials.clear();
196
+
197
+ // Restore link materials
198
+ for (const [link, saved] of savedLinkColors) {
199
+ const linkObj = link.__lineObj;
200
+ if (linkObj?.material) {
201
+ linkObj.material.color.setHex(saved.color);
202
+ }
203
+ }
204
+ savedLinkColors.clear();
139
205
  }
140
206
 
141
207
  // ── Focus camera on a node ───────────────────────────────
@@ -10,11 +10,15 @@
10
10
  */
11
11
 
12
12
  import { getGraphInstance, getHighlightLinks } from './graph.js';
13
- import { getActiveTheme, onThemeChange } from './themes.js';
13
+ import { getActiveTheme, getActiveThemeId, onThemeChange } from './themes.js';
14
14
  import { getSetting } from './settings.js';
15
15
 
16
- // Re-configure links when theme changes
16
+ // Re-configure links when theme actually changes (guard against redundant calls)
17
+ let lastLinkThemeId = null;
17
18
  onThemeChange(() => {
19
+ const currentId = getActiveThemeId();
20
+ if (currentId === lastLinkThemeId) return;
21
+ lastLinkThemeId = currentId;
18
22
  const Graph = getGraphInstance();
19
23
  if (Graph) configureLinks(Graph);
20
24
  });
@@ -89,7 +89,7 @@ async function init() {
89
89
  .backgroundColor(theme.background)
90
90
 
91
91
  // Force simulation tuning
92
- .d3AlphaDecay(getSetting('simulation.alphaDecay') ?? 0.008)
92
+ .d3AlphaDecay(getSetting('simulation.alphaDecay') ?? 0.02)
93
93
  .d3VelocityDecay(getSetting('simulation.velocityDecay') ?? 0.4)
94
94
 
95
95
  // Node rendering
@@ -6,7 +6,7 @@
6
6
  * Patterns use wireframe icosahedra.
7
7
  *
8
8
  * Colors and emissive intensities are read from the active theme.
9
- * A theme change listener forces re-render of all nodes.
9
+ * Theme changes update materials in-place (no geometry recreation).
10
10
  */
11
11
 
12
12
  import {
@@ -20,10 +20,10 @@ import {
20
20
  Group,
21
21
  Sprite,
22
22
  SpriteMaterial,
23
- CanvasTexture
23
+ CanvasTexture,
24
+ Color
24
25
  } from 'three';
25
-
26
- import { getActiveTheme, onThemeChange } from './themes.js';
26
+ import { getActiveTheme, getActiveThemeId, onThemeChange } from './themes.js';
27
27
  import { getSetting } from './settings.js';
28
28
  import { getGraphInstance } from './graph.js';
29
29
 
@@ -32,14 +32,45 @@ import { getGraphInstance } from './graph.js';
32
32
  export let ENTITY_COLORS = { ...getActiveTheme().entities };
33
33
  export let MEMORY_COLORS = { ...getActiveTheme().memories };
34
34
 
35
+ // Direct material color update instead of rebuilding all Three.js objects
36
+ let lastNodeThemeId = null;
35
37
  onThemeChange((theme) => {
38
+ const currentId = getActiveThemeId();
39
+ if (currentId === lastNodeThemeId) return;
40
+ lastNodeThemeId = currentId;
41
+
36
42
  Object.assign(ENTITY_COLORS, theme.entities);
37
43
  Object.assign(MEMORY_COLORS, theme.memories);
38
44
 
39
- // Force re-render of all nodes
45
+ // Update existing node materials in-place (no geometry recreation)
40
46
  const Graph = getGraphInstance();
41
- if (Graph) {
42
- Graph.nodeThreeObject(node => createNodeObject(node));
47
+ if (!Graph) return;
48
+ const graphData = Graph.graphData();
49
+ if (!graphData?.nodes) return;
50
+
51
+ for (const node of graphData.nodes) {
52
+ const obj = node.__threeObj;
53
+ if (!obj) continue;
54
+
55
+ const ud = obj.userData;
56
+ const mesh = ud?.coreMesh;
57
+ if (!mesh?.material) continue;
58
+
59
+ if (ud.nodeType === 'entity') {
60
+ const color = theme.entities[node.entityType] || node.color || '#888888';
61
+ mesh.material.color.set(color);
62
+ mesh.material.emissive.set(color);
63
+ mesh.material.emissiveIntensity = theme.emissive.entity;
64
+ } else if (ud.nodeType === 'pattern') {
65
+ mesh.material.color.set(theme.pattern.color);
66
+ mesh.material.emissive.set(theme.pattern.emissive);
67
+ mesh.material.emissiveIntensity = theme.emissive.pattern;
68
+ } else if (ud.nodeType === 'memory') {
69
+ const color = theme.memories[node.memoryType] || node.color || '#888888';
70
+ mesh.material.color.set(color);
71
+ mesh.material.emissive.set(color);
72
+ mesh.material.emissiveIntensity = theme.emissive.memory;
73
+ }
43
74
  }
44
75
  });
45
76
 
@@ -61,7 +61,7 @@ const THEMES = {
61
61
  strong: '#00ffaa',
62
62
  normal: '#818cf8',
63
63
  },
64
- bloom: { strength: 2.0, radius: 1.0, threshold: 0.12 },
64
+ bloom: { strength: 1.4, radius: 0.75, threshold: 0.12 },
65
65
  emissive: { entity: 0.35, memory: 0.04, pattern: 0.5 },
66
66
  },
67
67
 
@@ -110,7 +110,7 @@ const THEMES = {
110
110
  strong: '#f0abfc',
111
111
  normal: '#d946ef',
112
112
  },
113
- bloom: { strength: 2.2, radius: 1.1, threshold: 0.10 },
113
+ bloom: { strength: 1.55, radius: 0.8, threshold: 0.10 },
114
114
  emissive: { entity: 0.40, memory: 0.04, pattern: 0.55 },
115
115
  },
116
116
 
@@ -159,7 +159,7 @@ const THEMES = {
159
159
  strong: '#4ade80',
160
160
  normal: '#06b6d4',
161
161
  },
162
- bloom: { strength: 2.0, radius: 1.0, threshold: 0.10 },
162
+ bloom: { strength: 1.4, radius: 0.75, threshold: 0.10 },
163
163
  emissive: { entity: 0.38, memory: 0.04, pattern: 0.5 },
164
164
  },
165
165
 
@@ -208,7 +208,7 @@ const THEMES = {
208
208
  strong: '#fbbf24',
209
209
  normal: '#f97316',
210
210
  },
211
- bloom: { strength: 2.2, radius: 1.0, threshold: 0.12 },
211
+ bloom: { strength: 1.55, radius: 0.75, threshold: 0.12 },
212
212
  emissive: { entity: 0.40, memory: 0.05, pattern: 0.5 },
213
213
  },
214
214
 
@@ -257,7 +257,7 @@ const THEMES = {
257
257
  strong: '#e0f2fe',
258
258
  normal: '#38bdf8',
259
259
  },
260
- bloom: { strength: 1.8, radius: 0.9, threshold: 0.14 },
260
+ bloom: { strength: 1.25, radius: 0.7, threshold: 0.14 },
261
261
  emissive: { entity: 0.35, memory: 0.04, pattern: 0.45 },
262
262
  },
263
263
 
@@ -306,7 +306,7 @@ const THEMES = {
306
306
  strong: '#86efac',
307
307
  normal: '#22c55e',
308
308
  },
309
- bloom: { strength: 2.5, radius: 0.8, threshold: 0.08 },
309
+ bloom: { strength: 1.75, radius: 0.6, threshold: 0.08 },
310
310
  emissive: { entity: 0.45, memory: 0.03, pattern: 0.55 },
311
311
  },
312
312
 
@@ -355,7 +355,7 @@ const THEMES = {
355
355
  strong: '#fb923c',
356
356
  normal: '#f43f5e',
357
357
  },
358
- bloom: { strength: 2.0, radius: 1.0, threshold: 0.12 },
358
+ bloom: { strength: 1.4, radius: 0.75, threshold: 0.12 },
359
359
  emissive: { entity: 0.38, memory: 0.05, pattern: 0.50 },
360
360
  },
361
361
 
@@ -404,7 +404,7 @@ const THEMES = {
404
404
  strong: '#e4e4e7',
405
405
  normal: '#a1a1aa',
406
406
  },
407
- bloom: { strength: 1.8, radius: 0.8, threshold: 0.15 },
407
+ bloom: { strength: 1.25, radius: 0.6, threshold: 0.15 },
408
408
  emissive: { entity: 0.32, memory: 0.04, pattern: 0.40 },
409
409
  },
410
410
 
@@ -453,7 +453,7 @@ const THEMES = {
453
453
  strong: '#fbcfe8',
454
454
  normal: '#f9a8d4',
455
455
  },
456
- bloom: { strength: 1.8, radius: 1.0, threshold: 0.14 },
456
+ bloom: { strength: 1.25, radius: 0.75, threshold: 0.14 },
457
457
  emissive: { entity: 0.35, memory: 0.05, pattern: 0.45 },
458
458
  },
459
459
 
@@ -502,7 +502,7 @@ const THEMES = {
502
502
  strong: '#a5b4fc',
503
503
  normal: '#6366f1',
504
504
  },
505
- bloom: { strength: 3.0, radius: 1.2, threshold: 0.08 },
505
+ bloom: { strength: 2.1, radius: 0.9, threshold: 0.08 },
506
506
  emissive: { entity: 0.50, memory: 0.02, pattern: 0.60 },
507
507
  },
508
508
  };