get-claudia 1.17.0 → 1.17.2

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/README.md CHANGED
@@ -106,6 +106,15 @@ npx get-claudia .
106
106
 
107
107
  This upgrades framework files while preserving your data (context/, people/, projects/).
108
108
 
109
+ **Add the Brain Visualizer to an existing install:**
110
+ ```bash
111
+ # macOS/Linux
112
+ bash "$(npm root -g)/get-claudia/visualizer/scripts/install.sh"
113
+
114
+ # Windows (PowerShell)
115
+ & "$(npm root -g)\get-claudia\visualizer\scripts\install.ps1"
116
+ ```
117
+
109
118
  ---
110
119
 
111
120
  ## Demo Mode
package/bin/index.js CHANGED
@@ -157,7 +157,6 @@ async function main() {
157
157
  };
158
158
 
159
159
  const setupMemory = await askYesNo(`\n${colors.yellow}?${colors.reset} Set up enhanced memory system? (recommended) [y/n]: `);
160
- const setupGateway = await askYesNo(`${colors.yellow}?${colors.reset} Set up messaging gateway (Telegram/Slack)? [y/n]: `);
161
160
  rl.close();
162
161
 
163
162
  // Helper: seed demo database using spawn (safe, no shell injection)
@@ -299,13 +298,9 @@ async function main() {
299
298
  showNextSteps(memoryInstalled, visualizerInstalled, gatewayInstalled);
300
299
  }
301
300
 
302
- // Helper: run gateway if requested, then finish
301
+ // Helper: run gateway setup (auto-install like visualizer), then finish
303
302
  function maybeRunGateway(memoryInstalled, visualizerInstalled) {
304
- if (setupGateway) {
305
- runGatewaySetup((gatewayOk) => finishInstall(memoryInstalled, visualizerInstalled, gatewayOk));
306
- } else {
307
- finishInstall(memoryInstalled, visualizerInstalled, false);
308
- }
303
+ runGatewaySetup((gatewayOk) => finishInstall(memoryInstalled, visualizerInstalled, gatewayOk));
309
304
  }
310
305
 
311
306
  // Helper: auto-install visualizer after memory (if memory was installed), then chain to gateway
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "get-claudia",
3
- "version": "1.17.0",
3
+ "version": "1.17.2",
4
4
  "description": "An AI assistant who learns how you work.",
5
5
  "keywords": [
6
6
  "claudia",
@@ -84,9 +84,9 @@ New-Item -ItemType Directory -Force -Path $THREEJS_DIR | Out-Null
84
84
  New-Item -ItemType Directory -Force -Path $BIN_DIR | Out-Null
85
85
 
86
86
  Write-Host " ${GREEN}✓${NC} Created $CLAUDIA_DIR"
87
- Write-Host " ${DIM}├── visualizer\ (API backend)${NC}"
88
- Write-Host " ${DIM}├── visualizer-threejs\ (3D frontend)${NC}"
89
- Write-Host " ${DIM}└── bin\ (launcher)${NC}"
87
+ Write-Host (" " + $DIM + " visualizer - API backend" + $NC)
88
+ Write-Host (" " + $DIM + " visualizer-threejs - 3D frontend" + $NC)
89
+ Write-Host (" " + $DIM + " bin - launcher" + $NC)
90
90
 
91
91
  Write-Host ""
92
92
  Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
@@ -652,3 +652,20 @@ body {
652
652
  85% { opacity: 1; transform: translateY(0); }
653
653
  100% { opacity: 0; transform: translateY(-5px); }
654
654
  }
655
+
656
+ /* ── Design panel folder highlight ────────────────────────── */
657
+
658
+ .lil-gui .folder-highlight > .title {
659
+ animation: folderHighlight 1.5s ease-out;
660
+ }
661
+
662
+ @keyframes folderHighlight {
663
+ 0% {
664
+ background: var(--accent);
665
+ color: var(--bg);
666
+ }
667
+ 100% {
668
+ background: transparent;
669
+ color: inherit;
670
+ }
671
+ }
@@ -28,6 +28,12 @@ let gui = null;
28
28
  let visible = false;
29
29
  let toastTimeout = null;
30
30
 
31
+ // Folder references for smart navigation
32
+ let folders = {};
33
+
34
+ // Callback to get selected node from main.js
35
+ let getSelectedNodeCallback = null;
36
+
31
37
  /**
32
38
  * Show a temporary toast notification for reload-required settings
33
39
  * @param {string} message - The message to display
@@ -50,6 +56,69 @@ function showReloadHint(message) {
50
56
  }, 3000);
51
57
  }
52
58
 
59
+ /**
60
+ * Set callback to get the currently selected node
61
+ * @param {Function} callback - Returns the selected node or null
62
+ */
63
+ export function setSelectedNodeCallback(callback) {
64
+ getSelectedNodeCallback = callback;
65
+ }
66
+
67
+ /**
68
+ * Focus on the relevant settings section for a node type
69
+ * Opens the folder, scrolls it into view, and briefly highlights it
70
+ * @param {Object} node - The selected node
71
+ * @returns {boolean} - True if a section was focused
72
+ */
73
+ function focusSectionForNode(node) {
74
+ if (!node || !gui) return false;
75
+
76
+ let targetFolder = null;
77
+ let subFolder = null;
78
+
79
+ // Determine which folder to open based on node type
80
+ if (node.nodeType === 'entity') {
81
+ targetFolder = folders.nodes;
82
+ // Also open entity colors if available
83
+ subFolder = folders.entityColors;
84
+ } else if (node.nodeType === 'memory') {
85
+ targetFolder = folders.nodes;
86
+ subFolder = folders.memoryColors;
87
+ } else if (node.nodeType === 'pattern') {
88
+ targetFolder = folders.nodes;
89
+ }
90
+
91
+ if (!targetFolder) return false;
92
+
93
+ // Close all top-level folders first for cleaner view
94
+ gui.folders.forEach(f => f.close());
95
+
96
+ // Open target folder
97
+ targetFolder.open();
98
+
99
+ // Open sub-folder if specified
100
+ if (subFolder) {
101
+ // Need to open parent first (Colors folder)
102
+ if (folders.colors) folders.colors.open();
103
+ subFolder.open();
104
+ }
105
+
106
+ // Scroll the folder into view and highlight it
107
+ const folderEl = targetFolder.domElement;
108
+ if (folderEl) {
109
+ // Scroll into view with smooth behavior
110
+ folderEl.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
111
+
112
+ // Add highlight animation
113
+ folderEl.classList.add('folder-highlight');
114
+ setTimeout(() => {
115
+ folderEl.classList.remove('folder-highlight');
116
+ }, 1500);
117
+ }
118
+
119
+ return true;
120
+ }
121
+
53
122
  /**
54
123
  * Initialize the design panel
55
124
  * @param {Function} onUpdate - Called whenever a config value changes
@@ -101,9 +170,11 @@ export function initDesignPanel(onUpdate) {
101
170
 
102
171
  // ── Colors ─────────────────────────────────────────────────
103
172
  const colorsFolder = gui.addFolder('Colors');
173
+ folders.colors = colorsFolder;
104
174
  colorsFolder.addColor(config, 'background').name('Background').onChange(() => update('background'));
105
175
 
106
176
  const entityColorsFolder = colorsFolder.addFolder('Entity Colors');
177
+ folders.entityColors = entityColorsFolder;
107
178
  entityColorsFolder.addColor(config.entityColors, 'person').name('Person').onChange(() => update('entityColors.person'));
108
179
  entityColorsFolder.addColor(config.entityColors, 'organization').name('Organization').onChange(() => update('entityColors.organization'));
109
180
  entityColorsFolder.addColor(config.entityColors, 'project').name('Project').onChange(() => update('entityColors.project'));
@@ -112,6 +183,7 @@ export function initDesignPanel(onUpdate) {
112
183
  entityColorsFolder.close();
113
184
 
114
185
  const memoryColorsFolder = colorsFolder.addFolder('Memory Colors');
186
+ folders.memoryColors = memoryColorsFolder;
115
187
  memoryColorsFolder.addColor(config.memoryColors, 'fact').name('Fact').onChange(() => update('memoryColors.fact'));
116
188
  memoryColorsFolder.addColor(config.memoryColors, 'commitment').name('Commitment').onChange(() => update('memoryColors.commitment'));
117
189
  memoryColorsFolder.addColor(config.memoryColors, 'learning').name('Learning').onChange(() => update('memoryColors.learning'));
@@ -144,6 +216,7 @@ export function initDesignPanel(onUpdate) {
144
216
 
145
217
  // ── Nodes ──────────────────────────────────────────────────
146
218
  const nodesFolder = gui.addFolder('Nodes');
219
+ folders.nodes = nodesFolder;
147
220
  nodesFolder.add(config.nodes, 'emissiveIntensity', 0, 1, 0.05).name('Emissive').onChange(() => update('nodes.emissiveIntensity'));
148
221
  nodesFolder.add(config.nodes, 'glowSize', 1, 10, 0.5).name('Glow Size').onChange(() => update('nodes.glowSize'));
149
222
  nodesFolder.add(config.nodes, 'glowIntensity', 0, 1, 0.05).name('Glow Intensity').onChange(() => update('nodes.glowIntensity'));
@@ -154,6 +227,7 @@ export function initDesignPanel(onUpdate) {
154
227
 
155
228
  // ── Links ──────────────────────────────────────────────────
156
229
  const linksFolder = gui.addFolder('Links');
230
+ folders.links = linksFolder;
157
231
  linksFolder.add(config.links, 'curvature', 0, 0.5, 0.01).name('Curvature').onChange(() => update('links.curvature'));
158
232
  linksFolder.add(config.links, 'tubeRadius', 0.05, 0.5, 0.01).name('Tube Radius').onChange(() => update('links.tubeRadius'));
159
233
  linksFolder.add(config.links, 'highlightRadius', 1, 3, 0.1).name('Highlight Multiplier').onChange(() => update('links.highlightRadius'));
@@ -244,6 +318,7 @@ export function initDesignPanel(onUpdate) {
244
318
 
245
319
  // ── Simulation ─────────────────────────────────────────────
246
320
  const simFolder = gui.addFolder('Force Simulation');
321
+ folders.simulation = simFolder;
247
322
  simFolder.add(config.simulation, 'chargeEntity', -500, 0, 10).name('Entity Charge').onChange(() => update('simulation.chargeEntity'));
248
323
  simFolder.add(config.simulation, 'chargePattern', -300, 0, 10).name('Pattern Charge').onChange(() => update('simulation.chargePattern'));
249
324
  simFolder.add(config.simulation, 'chargeMemory', -100, 0, 5).name('Memory Charge').onChange(() => update('simulation.chargeMemory'));
@@ -303,6 +378,15 @@ export function initDesignPanel(onUpdate) {
303
378
  if (e.key.toLowerCase() === 'h' && !e.ctrlKey && !e.metaKey && !e.altKey) {
304
379
  // Don't toggle if typing in an input
305
380
  if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
381
+
382
+ // Smart navigation: if panel is open and node is selected, jump to relevant section
383
+ if (visible && getSelectedNodeCallback) {
384
+ const selectedNode = getSelectedNodeCallback();
385
+ if (selectedNode && focusSectionForNode(selectedNode)) {
386
+ return; // Don't toggle, we navigated instead
387
+ }
388
+ }
389
+
306
390
  togglePanel();
307
391
  }
308
392
  });
@@ -15,7 +15,7 @@ import * as THREE from 'three';
15
15
  import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
16
16
 
17
17
  import { config } from './config.js';
18
- import { initDesignPanel } from './design-panel.js';
18
+ import { initDesignPanel, setSelectedNodeCallback } from './design-panel.js';
19
19
  import { applyTheme, loadThemePreference } from './themes.js';
20
20
 
21
21
  import {
@@ -26,6 +26,7 @@ import {
26
26
  addLink,
27
27
  updateNodeData,
28
28
  getGraphData,
29
+ getSelectedNode,
29
30
  setSelectedNode,
30
31
  highlightNeighborhood,
31
32
  clearSelection,
@@ -174,6 +175,9 @@ async function init() {
174
175
  // Initialize design panel (no need for separate onConfigUpdate since panel calls it)
175
176
  initDesignPanel(handleConfigUpdate);
176
177
 
178
+ // Provide selected node callback for smart H-key navigation
179
+ setSelectedNodeCallback(() => getSelectedNode());
180
+
177
181
  } catch (err) {
178
182
  console.error('Failed to initialize:', err);
179
183
  const errorDiv = document.createElement('div');