@andespindola/brainlink 0.1.0-beta.94 → 0.1.0-beta.96

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
@@ -602,7 +602,7 @@ The graph UI shows:
602
602
  - WebGL node and edge acceleration when supported, falling back to Canvas 2D without changing graph behavior
603
603
  - compact macro-to-micro density progression so reset keeps the graph mass oriented and zoom-in separates local neighborhoods progressively
604
604
  - graph camera treats hub-centered navigation as structural only when the hub is dominant; diffuse stress graphs reset and zoom around the full graph mass
605
- - graph LOD progression: graphs up to 1000 notes render directly; larger graphs use a compact memory-hub-centered mesh of alpha-particle 1000-note points, zoom-in keeps focused child clusters latent at the parent position before fading them in and only then separating them through 500-note, 250-note, 125-note and 60-note subgraphs with aggregated real links plus local sibling mesh links, and in massive graphs keeps this subgraph mode active much longer with finer wheel steps so deep zoom does not abruptly switch to a broad sampled node cloud
605
+ - graph LOD progression: graphs up to 1000 notes render directly; larger graphs use a compact memory-hub-centered mesh where each 1000-note point already carries a faint connected 500-note micro-structure, then zoom-in keeps focused child clusters latent at the parent position before fading and separating them through 250-note, 125-note, 60-note, 30-note, 15-note and 8-note subgraphs with aggregated real links plus local sibling mesh links, and in massive graphs keeps this subgraph mode active much longer with finer wheel steps so deep zoom does not abruptly switch to a broad sampled node cloud
606
606
 
607
607
  The server indexes before starting by default. Use `--no-index` to skip that step:
608
608
 
@@ -23,12 +23,12 @@ const transformCoordinateLimit = 20_000_000
23
23
  const hoverHitTestIntervalMs = 64
24
24
  const ecosystemGroupSize = 1000
25
25
  const ecosystemActivationNodeThreshold = 1000
26
- const ecosystemGroupSizes = [1000, 500, 250, 125, 60]
26
+ const ecosystemGroupSizes = [1000, 500, 250, 125, 60, 30, 15, 8]
27
27
  const ecosystemClusterEdgeLimit = 520
28
28
  const ecosystemHubEdgeLimit = 120
29
29
  const ecosystemSiblingEdgeLimit = 180
30
30
  const ecosystemClusterScaleThreshold = 0.78
31
- const massiveEcosystemClusterScaleThreshold = 2.4
31
+ const massiveEcosystemClusterScaleThreshold = 4.2
32
32
  const ecosystemSubgraphScaleThreshold = 0.18
33
33
  const ecosystemMicroScaleThreshold = 0.08
34
34
  const ecosystemFocusedParentLimit = 2
@@ -36,7 +36,10 @@ const ecosystemExpansionLevels = [
36
36
  { parentSize: 1000, childSize: 500, start: 0.04, end: 0.62 },
37
37
  { parentSize: 500, childSize: 250, start: 0.16, end: 0.72 },
38
38
  { parentSize: 250, childSize: 125, start: 0.3, end: 0.78 },
39
- { parentSize: 125, childSize: 60, start: 0.46, end: 0.86 }
39
+ { parentSize: 125, childSize: 60, start: 0.46, end: 0.86 },
40
+ { parentSize: 60, childSize: 30, start: 0.64, end: 1.06 },
41
+ { parentSize: 30, childSize: 15, start: 0.84, end: 1.38 },
42
+ { parentSize: 15, childSize: 8, start: 1.08, end: 1.82 }
40
43
  ]
41
44
  const zoomRecoveryGuardMs = 4200
42
45
  const zoomCapTargetViewportShare = 0.72
@@ -748,7 +751,10 @@ const ecosystemLayoutSpacingForSize = size => {
748
751
  if (size >= 500) return 92
749
752
  if (size >= 250) return 52
750
753
  if (size >= 125) return 28
751
- return 16
754
+ if (size >= 60) return 16
755
+ if (size >= 30) return 11
756
+ if (size >= 15) return 7
757
+ return 5
752
758
  }
753
759
 
754
760
  const ecosystemCompactPoint = (index, total, center, spacing) => {
@@ -895,9 +901,21 @@ const smoothStep = value => {
895
901
  const zoomProgress = (scale, start, end) =>
896
902
  smoothStep((scale - start) / Math.max(end - start, 0.0001))
897
903
 
898
- const semanticZoomSpread = progress => Math.pow(progress, 4.2)
904
+ const semanticZoomSpread = (progress, childSize) => {
905
+ const curve = Math.pow(progress, 4.2)
906
+ if (childSize >= 500) {
907
+ return 0.12 + curve * 0.88
908
+ }
909
+ return curve
910
+ }
899
911
 
900
- const opacityForProgress = progress => Math.pow(progress, 2.1)
912
+ const opacityForProgress = (progress, childSize) => {
913
+ const eased = Math.pow(progress, 2.1)
914
+ if (childSize >= 500) {
915
+ return 0.22 + eased * 0.78
916
+ }
917
+ return eased
918
+ }
901
919
 
902
920
  const expandFocusedClusters = (parentClusters, childSize, progress, spread, viewport) => {
903
921
  const focusPoint = ecosystemFocusPoint()
@@ -909,7 +927,7 @@ const expandFocusedClusters = (parentClusters, childSize, progress, spread, view
909
927
  const childClusters = state.ecosystemClustersBySize.get(childSize) ?? []
910
928
  const visibleChildClusters = childClusters
911
929
  .filter(cluster => expandedParentIds.has(cluster.parentId))
912
- .map(cluster => spreadChildClusterFromParent(cluster, progress, spread))
930
+ .map(cluster => spreadChildClusterFromParent(cluster, childSize, progress, spread))
913
931
  .filter(cluster => isClusterInViewport(cluster, viewport))
914
932
 
915
933
  return {
@@ -918,11 +936,11 @@ const expandFocusedClusters = (parentClusters, childSize, progress, spread, view
918
936
  }
919
937
  }
920
938
 
921
- const spreadChildClusterFromParent = (cluster, progress, spread) => {
939
+ const spreadChildClusterFromParent = (cluster, childSize, progress, spread) => {
922
940
  if (!Number.isFinite(cluster.parentX) || !Number.isFinite(cluster.parentY)) {
923
941
  return {
924
942
  ...cluster,
925
- lodOpacity: opacityForProgress(progress)
943
+ lodOpacity: opacityForProgress(progress, childSize)
926
944
  }
927
945
  }
928
946
 
@@ -930,7 +948,7 @@ const spreadChildClusterFromParent = (cluster, progress, spread) => {
930
948
  ...cluster,
931
949
  x: cluster.parentX + (cluster.x - cluster.parentX) * spread,
932
950
  y: cluster.parentY + (cluster.y - cluster.parentY) * spread,
933
- lodOpacity: opacityForProgress(progress)
951
+ lodOpacity: opacityForProgress(progress, childSize)
934
952
  }
935
953
  }
936
954
 
@@ -947,7 +965,7 @@ const selectHierarchicalEcosystemClusters = viewport => {
947
965
  continue
948
966
  }
949
967
  const progress = zoomProgress(state.transform.scale, level.start, level.end)
950
- const spread = semanticZoomSpread(progress)
968
+ const spread = semanticZoomSpread(progress, level.childSize)
951
969
  const expansion = expandFocusedClusters(parentClusters, level.childSize, progress, spread, viewport)
952
970
  visibleClusters.push(...expansion.childClusters)
953
971
  }
@@ -2529,11 +2547,25 @@ const clusterRadiusPx = cluster => {
2529
2547
  return 10
2530
2548
  }
2531
2549
  if (cluster.isHub) {
2532
- return 3.2
2550
+ return 3.8
2533
2551
  }
2534
2552
  if (String(cluster.id).startsWith('ecosystem-')) {
2535
- const base = cluster.size >= 1000 ? 0.68 : cluster.size >= 500 ? 0.64 : cluster.size >= 250 ? 0.6 : cluster.size >= 125 ? 0.56 : 0.52
2536
- return Math.max(0.5, Math.min(1.55, base + Math.log10(cluster.count + 1) * 0.12))
2553
+ const base = cluster.size >= 1000
2554
+ ? 0.96
2555
+ : cluster.size >= 500
2556
+ ? 0.9
2557
+ : cluster.size >= 250
2558
+ ? 0.82
2559
+ : cluster.size >= 125
2560
+ ? 0.74
2561
+ : cluster.size >= 60
2562
+ ? 0.66
2563
+ : cluster.size >= 30
2564
+ ? 0.62
2565
+ : cluster.size >= 15
2566
+ ? 0.74
2567
+ : 0.9
2568
+ return Math.max(0.62, Math.min(2.2, base + Math.log10(cluster.count + 1) * 0.14))
2537
2569
  }
2538
2570
  return Math.max(8, Math.min(28, 8 + Math.log2(cluster.count + 1) * 3))
2539
2571
  }
@@ -3164,8 +3196,8 @@ const wheelZoomFactor = event => {
3164
3196
  const isMassiveEcosystemZoom =
3165
3197
  state.visibleNodes.length > massiveGraphNodeThreshold &&
3166
3198
  state.transform.scale <= massiveEcosystemClusterScaleThreshold
3167
- const sensitivityMultiplier = isMassiveEcosystemZoom ? 0.62 : 1
3168
- const capMultiplier = isMassiveEcosystemZoom ? 0.48 : 1
3199
+ const sensitivityMultiplier = isMassiveEcosystemZoom ? 0.48 : 1
3200
+ const capMultiplier = isMassiveEcosystemZoom ? 0.34 : 1
3169
3201
  const sensitivity = wheelZoomExponent * (isModifierZoom ? wheelZoomModifierBoost : 1) * sensitivityMultiplier
3170
3202
  const exponentCap = wheelZoomExponentCap * capMultiplier
3171
3203
  const exponent = Math.max(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andespindola/brainlink",
3
- "version": "0.1.0-beta.94",
3
+ "version": "0.1.0-beta.96",
4
4
  "description": "Local-first knowledge memory for agents with Markdown, backlinks, indexing and context retrieval.",
5
5
  "type": "module",
6
6
  "license": "MIT",