@andespindola/brainlink 0.1.0-beta.29 → 0.1.0-beta.30

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
@@ -565,6 +565,8 @@ The graph UI shows:
565
565
  - realtime refresh while `--watch` is enabled
566
566
  - graph controls for zoom in, zoom out, fit visible nodes and reset-to-fit-all
567
567
  - wheel zoom (including `cmd+scroll` and `ctrl+scroll`) anchored to cursor position for faster navigation in large graphs
568
+ - keyboard shortcuts: `+` zoom in, `-` zoom out, `0` reset fit
569
+ - double-click on canvas zooms in at cursor position
568
570
  - floating graph totals (notes, links, tags) below the Brainlink title
569
571
  - large-graph rendering safeguards (edge draw caps, lower redraw rate, zoom-aware interaction)
570
572
 
@@ -675,16 +675,16 @@ const zoomAtPoint = (screenX, screenY, factor) => {
675
675
  const wheelZoomFactor = event => {
676
676
  const isModifierZoom = event.metaKey || event.ctrlKey
677
677
  const deltaModeFactor = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? 120 : 1
678
- const normalizedDelta = Math.min(Math.abs(event.deltaY * deltaModeFactor), 1200) / 220
678
+ const absoluteDelta = Math.min(Math.abs(event.deltaY * deltaModeFactor), 1600)
679
679
 
680
- if (normalizedDelta <= 0.0001) {
680
+ if (absoluteDelta <= 0.0001) {
681
681
  return 1
682
682
  }
683
683
 
684
- const sensitivity = isModifierZoom ? 0.2 : 0.14
685
- const direction = event.deltaY < 0 ? 1 : -1
684
+ const baseStep = Math.max(0.06, Math.min(0.45, absoluteDelta / 480))
685
+ const adjustedStep = baseStep * (isModifierZoom ? 1.4 : 1)
686
686
 
687
- return Math.exp(direction * normalizedDelta * sensitivity)
687
+ return event.deltaY < 0 ? 1 + adjustedStep : 1 / (1 + adjustedStep)
688
688
  }
689
689
 
690
690
  const bindEvents = () => {
@@ -707,11 +707,11 @@ const bindEvents = () => {
707
707
  })
708
708
  elements.zoomIn.addEventListener('click', () => {
709
709
  const rect = canvas.getBoundingClientRect()
710
- zoomAtPoint(Math.max(rect.width, 320) / 2, Math.max(rect.height, 320) / 2, 1.18)
710
+ zoomAtPoint(Math.max(rect.width, 320) / 2, Math.max(rect.height, 320) / 2, 1.3)
711
711
  })
712
712
  elements.zoomOut.addEventListener('click', () => {
713
713
  const rect = canvas.getBoundingClientRect()
714
- zoomAtPoint(Math.max(rect.width, 320) / 2, Math.max(rect.height, 320) / 2, 0.84)
714
+ zoomAtPoint(Math.max(rect.width, 320) / 2, Math.max(rect.height, 320) / 2, 0.77)
715
715
  })
716
716
  if (elements.fit) {
717
717
  elements.fit.addEventListener('click', () => {
@@ -738,6 +738,12 @@ const bindEvents = () => {
738
738
  const factor = wheelZoomFactor(event)
739
739
  zoomAtPoint(cursorX, cursorY, factor)
740
740
  }, { passive: false })
741
+ canvas.addEventListener('dblclick', event => {
742
+ const rect = canvas.getBoundingClientRect()
743
+ const cursorX = event.clientX - rect.left
744
+ const cursorY = event.clientY - rect.top
745
+ zoomAtPoint(cursorX, cursorY, 1.25)
746
+ })
741
747
  canvas.addEventListener('pointerdown', event => {
742
748
  const point = worldPoint(event)
743
749
  const node = hitNode(point)
@@ -774,6 +780,26 @@ const bindEvents = () => {
774
780
  canvas.addEventListener('pointercancel', () => {
775
781
  state.pointer = { x: 0, y: 0, down: false, dragNode: null, moved: false }
776
782
  })
783
+ window.addEventListener('keydown', event => {
784
+ if (event.key === '+' || event.key === '=') {
785
+ event.preventDefault()
786
+ const rect = canvas.getBoundingClientRect()
787
+ zoomAtPoint(Math.max(rect.width, 320) / 2, Math.max(rect.height, 320) / 2, 1.25)
788
+ return
789
+ }
790
+
791
+ if (event.key === '-' || event.key === '_') {
792
+ event.preventDefault()
793
+ const rect = canvas.getBoundingClientRect()
794
+ zoomAtPoint(Math.max(rect.width, 320) / 2, Math.max(rect.height, 320) / 2, 0.8)
795
+ return
796
+ }
797
+
798
+ if (event.key === '0') {
799
+ event.preventDefault()
800
+ resetView()
801
+ }
802
+ })
777
803
  }
778
804
 
779
805
  const loadAgents = async () => {
@@ -544,7 +544,7 @@ Without `--vault`, the graph UI serves `$HOME/.brainlink/vault`.
544
544
 
545
545
  The frontend includes an agent selector that shows only the agent id. Selecting an agent calls the same read APIs with `agent=<agent-id>` and renders that namespace instead of merging every agent into one graph.
546
546
 
547
- Graph navigation controls include zoom in, zoom out, fit visible nodes and reset-to-fit-all nodes. Mouse wheel zoom (including `cmd+scroll` and `ctrl+scroll`) is anchored to the cursor. Totals for notes, links and tags stay visible as floating metrics under the Brainlink title, and node details open on click in a modal (tags, outgoing links, backlinks and Markdown content).
547
+ Graph navigation controls include zoom in, zoom out, fit visible nodes and reset-to-fit-all nodes. Mouse wheel zoom (including `cmd+scroll` and `ctrl+scroll`) is anchored to the cursor. Keyboard shortcuts are `+` (zoom in), `-` (zoom out) and `0` (reset fit). Double-click on canvas zooms in at cursor position. Totals for notes, links and tags stay visible as floating metrics under the Brainlink title, and node details open on click in a modal (tags, outgoing links, backlinks and Markdown content).
548
548
 
549
549
  The command reindexes by default, then serves:
550
550
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andespindola/brainlink",
3
- "version": "0.1.0-beta.29",
3
+ "version": "0.1.0-beta.30",
4
4
  "description": "Local-first knowledge memory for agents with Markdown, backlinks, indexing and context retrieval.",
5
5
  "type": "module",
6
6
  "license": "MIT",