@andespindola/brainlink 0.1.0-beta.104 → 0.1.0-beta.105

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
@@ -604,7 +604,7 @@ The graph UI shows:
604
604
  - WebGL node and edge acceleration when supported, falling back to Canvas 2D without changing graph behavior
605
605
  - compact macro-to-micro density progression so reset keeps the graph mass oriented and zoom-in separates local neighborhoods progressively
606
606
  - 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
607
- - graph LOD progression: graphs up to 1000 notes render directly; larger graphs use one recursive model where each visible level targets up to 999 non-hub nodes, starts from a memory-hub-centered mesh, and each supernode can expand into another same-shape subgraph level (again up to 999 children) with latent fade-in, aggregated real links and local sibling mesh links so org-heavy and stress-50k follow the same structure at different depths; for massive graphs the first expansion starts much deeper in zoom, low-size child levels use slower easing, and expansion is additionally gated by focus readiness (screen-space isolation of the focused parent) so child levels open only when that subgraph is truly centered and separated in view
607
+ - graph LOD progression: hierarchical rendering now follows one recursive graph-of-graphs standard whenever a graph has more than one hierarchy level; each level expands through intermediate subgraph sizes (instead of jumping directly to leaves), starts from a memory-hub-centered mesh, and each supernode can expand into another same-shape subgraph level (up to 999 children) with latent fade-in, aggregated real links and local sibling mesh links so org-heavy-like and stress-50k-like structures share the same layered behavior at different depths; for massive graphs the first expansion starts deeper in zoom and is additionally gated by focus readiness (screen-space isolation of the focused parent) so child levels open only when that subgraph is truly centered and separated in view
608
608
 
609
609
  The server indexes before starting by default. Use `--no-index` to skip that step:
610
610
 
@@ -596,7 +596,7 @@ const recomputeVisibility = () => {
596
596
  y: macroHub ? macroHub.y : (bounds.minY + bounds.maxY) / 2
597
597
  }
598
598
  : { x: 0, y: 0 }
599
- const ecosystemGraph = nodes.length > ecosystemActivationNodeThreshold
599
+ const ecosystemGraph = nodes.length > 1
600
600
  ? buildEcosystemGraph(nodes, state.macroCenter, primaryHub)
601
601
  : {
602
602
  clusters: [],
@@ -768,12 +768,29 @@ const ecosystemLayoutSpacingForSize = size => {
768
768
  return 7
769
769
  }
770
770
 
771
+ const buildIntermediateEcosystemSizes = (fromSize, toSize) => {
772
+ if (fromSize <= toSize + 1) {
773
+ return []
774
+ }
775
+ const intermediate = []
776
+ let current = fromSize
777
+ while (current > toSize + 1) {
778
+ const stepped = Math.max(toSize + 1, Math.ceil(current / 3))
779
+ if (stepped >= current) {
780
+ break
781
+ }
782
+ intermediate.push(stepped)
783
+ current = stepped
784
+ }
785
+ return intermediate
786
+ }
787
+
771
788
  const buildEcosystemLevelSizes = nodeCount => {
772
789
  if (nodeCount <= 0) return []
773
- const sizes = []
790
+ const primarySizes = []
774
791
  let currentSize = Math.max(1, Math.ceil(nodeCount / ecosystemLevelNodeCap))
775
792
  while (currentSize >= 1) {
776
- sizes.push(currentSize)
793
+ primarySizes.push(currentSize)
777
794
  if (currentSize === 1) {
778
795
  break
779
796
  }
@@ -783,7 +800,28 @@ const buildEcosystemLevelSizes = nodeCount => {
783
800
  }
784
801
  currentSize = nextSize
785
802
  }
786
- return sizes
803
+ const expandedSizes = []
804
+ for (let index = 0; index < primarySizes.length; index += 1) {
805
+ const size = primarySizes[index]
806
+ if (expandedSizes.length === 0 || expandedSizes[expandedSizes.length - 1] !== size) {
807
+ expandedSizes.push(size)
808
+ }
809
+ const nextSize = primarySizes[index + 1]
810
+ if (!Number.isFinite(nextSize)) {
811
+ continue
812
+ }
813
+ const intermediate = buildIntermediateEcosystemSizes(size, nextSize)
814
+ for (let intermediateIndex = 0; intermediateIndex < intermediate.length; intermediateIndex += 1) {
815
+ const candidate = intermediate[intermediateIndex]
816
+ if (expandedSizes[expandedSizes.length - 1] !== candidate) {
817
+ expandedSizes.push(candidate)
818
+ }
819
+ }
820
+ }
821
+ if (expandedSizes[expandedSizes.length - 1] !== 1) {
822
+ expandedSizes.push(1)
823
+ }
824
+ return expandedSizes
787
825
  }
788
826
 
789
827
  const buildEcosystemExpansionLevels = (levelSizes, nodeCount) => {
@@ -794,12 +832,12 @@ const buildEcosystemExpansionLevels = (levelSizes, nodeCount) => {
794
832
  const maxScale = isMassive
795
833
  ? massiveEcosystemClusterScaleThreshold
796
834
  : ecosystemClusterScaleThreshold
797
- const startScale = isMassive ? 0.82 : 0.18
835
+ const startScale = isMassive ? 1.12 : 0.24
798
836
  const transitionCount = levelSizes.length - 1
799
837
  const usableScale = Math.max(0.08, maxScale - startScale)
800
838
  const step = usableScale / transitionCount
801
- const stride = isMassive ? 0.9 : 0.78
802
- const overlap = isMassive ? 1.28 : 1.75
839
+ const stride = isMassive ? 0.93 : 0.82
840
+ const overlap = isMassive ? 1.22 : 1.62
803
841
  const levels = []
804
842
  for (let index = 0; index < transitionCount; index += 1) {
805
843
  const start = startScale + step * index * stride
@@ -2985,7 +3023,7 @@ const computeRenderVisibility = () => {
2985
3023
  ? massiveEcosystemClusterScaleThreshold
2986
3024
  : ecosystemClusterScaleThreshold
2987
3025
  if (
2988
- state.visibleNodes.length > ecosystemActivationNodeThreshold &&
3026
+ state.ecosystemExpansionLevels.length > 0 &&
2989
3027
  state.transform.scale <= ecosystemScaleThreshold &&
2990
3028
  state.ecosystemClusters.length > 0
2991
3029
  ) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andespindola/brainlink",
3
- "version": "0.1.0-beta.104",
3
+ "version": "0.1.0-beta.105",
4
4
  "description": "Local-first knowledge memory for agents with Markdown, backlinks, indexing and context retrieval.",
5
5
  "type": "module",
6
6
  "license": "MIT",