helixmind 0.2.26 → 0.2.28

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.
@@ -1 +1 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/cli/brain/template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CA6gE3D"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/cli/brain/template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAqrE3D"}
@@ -593,19 +593,196 @@ const EDGE_COLORS = {
593
593
  belongs_to: '#ff6600', part_of: '#ff6600', supersedes: '#ff4444',
594
594
  default: '#334466',
595
595
  };
596
- // V5: OG Chandelier Brain — iconic shape + modern rendering + 3D spiral spread
597
- // Shape: small/dim at top (deep archive) large/bright at bottom (focus)
598
- // Activity BOOSTS brightness (active = brighter, not dimmer)
599
- // cx/cz: spiral center offsets for 3D depth
600
- const SPATIAL = {
601
- 5: { iR: 8, oR: 110, yBase: 420, yS: 70, size: 18, pulse: 0.3, activity: 0.3, cx: 0, cz: 0 },
602
- 4: { iR: 12, oR: 180, yBase: 250, yS: 80, size: 24, pulse: 0.6, activity: 0.5, cx: 30, cz: 20 },
603
- 3: { iR: 18, oR: 260, yBase: 60, yS: 90, size: 30, pulse: 1.0, activity: 0.7, cx: -25, cz: 40 },
604
- 2: { iR: 25, oR: 340, yBase: -140, yS: 100, size: 34, pulse: 1.5, activity: 0.85, cx: -45, cz: -15 },
605
- 1: { iR: 35, oR: 430, yBase: -360, yS: 110, size: 40, pulse: 2.2, activity: 1.0, cx: -15, cz: -40 },
606
- 6: { iR: 40, oR: 470, yBase: -560, yS: 110, size: 34, pulse: 0.8, activity: 0.75, cx: 40, cz: -30 },
596
+ // V7: Clustered Galaxy Brain — Force-directed with level clustering
597
+ // Each level forms an organic morphed blob; blobs barely touch each other
598
+ const LEVEL_STYLE = {
599
+ 1: { size: 22, pulse: 2.0, activity: 1.0 },
600
+ 2: { size: 20, pulse: 1.5, activity: 0.85 },
601
+ 3: { size: 17, pulse: 1.0, activity: 0.7 },
602
+ 4: { size: 15, pulse: 0.6, activity: 0.5 },
603
+ 5: { size: 13, pulse: 0.3, activity: 0.3 },
604
+ 6: { size: 18, pulse: 0.8, activity: 0.7 },
607
605
  };
608
- const MAX_RENDERED_EDGES = 8000; // cap for performance + clarity
606
+ const MAX_RENDERED_EDGES = 12000; // more edges visible in galaxy layout
607
+
608
+ // Clustered force-directed layout: each level forms an organic blob
609
+ // Blobs are pushed apart so they barely touch — morphed spheres
610
+ function computeForceLayout(nodeList, edgeList, nodeIdxMapLocal) {
611
+ const N = nodeList.length;
612
+ if (N === 0) return [];
613
+
614
+ // Group nodes by level
615
+ const levelGroups = {};
616
+ for (let i = 0; i < N; i++) {
617
+ const lv = nodeList[i].level || 3;
618
+ if (!levelGroups[lv]) levelGroups[lv] = [];
619
+ levelGroups[lv].push(i);
620
+ }
621
+
622
+ // Assign each level a seed centroid direction (icosahedron-like placement)
623
+ const levels = Object.keys(levelGroups).map(Number).sort();
624
+ const seedCentroids = {};
625
+ const CLUSTER_SPREAD = 320;
626
+ // Evenly space level centroids on a sphere
627
+ for (let li = 0; li < levels.length; li++) {
628
+ const lv = levels[li];
629
+ const golden = 2.399963;
630
+ const theta = golden * li * 2.5; // multiplied for wider spread
631
+ const phi = Math.acos(1 - 2 * (li + 0.5) / Math.max(levels.length, 2));
632
+ seedCentroids[lv] = {
633
+ x: CLUSTER_SPREAD * Math.sin(phi) * Math.cos(theta),
634
+ y: CLUSTER_SPREAD * Math.cos(phi),
635
+ z: CLUSTER_SPREAD * Math.sin(phi) * Math.sin(theta)
636
+ };
637
+ }
638
+
639
+ const pos = new Array(N);
640
+ // Initialize nodes near their level's seed centroid
641
+ for (let i = 0; i < N; i++) {
642
+ const lv = nodeList[i].level || 3;
643
+ const c = seedCentroids[lv] || { x: 0, y: 0, z: 0 };
644
+ const INIT_SPREAD = 100;
645
+ pos[i] = {
646
+ x: c.x + (srand(i * 7) - 0.5) * INIT_SPREAD,
647
+ y: c.y + (srand(i * 13) - 0.5) * INIT_SPREAD,
648
+ z: c.z + (srand(i * 19) - 0.5) * INIT_SPREAD
649
+ };
650
+ }
651
+
652
+ // Build adjacency
653
+ const adjList = new Array(N);
654
+ for (let i = 0; i < N; i++) adjList[i] = [];
655
+ for (const e of edgeList) {
656
+ const si = nodeIdxMapLocal[e.source];
657
+ const ti = nodeIdxMapLocal[e.target];
658
+ if (si !== undefined && ti !== undefined) {
659
+ adjList[si].push(ti);
660
+ adjList[ti].push(si);
661
+ }
662
+ }
663
+
664
+ const ITERATIONS = 60;
665
+ const REPULSION = 5000;
666
+ const ATTRACTION = 0.012;
667
+ const CLUSTER_PULL = 0.02; // pull nodes toward their own level centroid
668
+ const INTER_REPEL = 18000; // push different-level centroids apart
669
+ const CENTERING = 0.0005;
670
+ const DAMPING = 0.82;
671
+ const K_SAMPLES = Math.min(N, 25);
672
+
673
+ const vel = new Array(N);
674
+ for (let i = 0; i < N; i++) vel[i] = { x: 0, y: 0, z: 0 };
675
+
676
+ for (let iter = 0; iter < ITERATIONS; iter++) {
677
+ const temp = 1.0 - iter / ITERATIONS;
678
+ const repScale = REPULSION * temp;
679
+
680
+ // Compute dynamic level centroids
681
+ const dynC = {};
682
+ const dynN = {};
683
+ for (let i = 0; i < N; i++) {
684
+ const lv = nodeList[i].level || 3;
685
+ if (!dynC[lv]) { dynC[lv] = { x: 0, y: 0, z: 0 }; dynN[lv] = 0; }
686
+ dynC[lv].x += pos[i].x; dynC[lv].y += pos[i].y; dynC[lv].z += pos[i].z;
687
+ dynN[lv]++;
688
+ }
689
+ for (const lv in dynC) {
690
+ dynC[lv].x /= dynN[lv]; dynC[lv].y /= dynN[lv]; dynC[lv].z /= dynN[lv];
691
+ }
692
+
693
+ for (let i = 0; i < N; i++) {
694
+ let fx = 0, fy = 0, fz = 0;
695
+ const myLevel = nodeList[i].level || 3;
696
+
697
+ // Node-node repulsion (sampled)
698
+ for (let k = 0; k < K_SAMPLES; k++) {
699
+ const j = Math.floor(srand(iter * 10007 + i * 997 + k * 31) * N);
700
+ if (j === i) continue;
701
+ const dx = pos[i].x - pos[j].x;
702
+ const dy = pos[i].y - pos[j].y;
703
+ const dz = pos[i].z - pos[j].z;
704
+ const distSq = dx * dx + dy * dy + dz * dz + 1;
705
+ // Stronger repulsion between different levels
706
+ const crossMult = (nodeList[j].level || 3) !== myLevel ? 2.5 : 1.0;
707
+ const f = repScale * crossMult / distSq;
708
+ const dist = Math.sqrt(distSq);
709
+ fx += (dx / dist) * f; fy += (dy / dist) * f; fz += (dz / dist) * f;
710
+ }
711
+ const repBias = N / K_SAMPLES;
712
+ fx *= repBias; fy *= repBias; fz *= repBias;
713
+
714
+ // Attraction: pull toward connected nodes (stronger for same level)
715
+ for (const j of adjList[i]) {
716
+ const dx = pos[j].x - pos[i].x;
717
+ const dy = pos[j].y - pos[i].y;
718
+ const dz = pos[j].z - pos[i].z;
719
+ const dist = Math.sqrt(dx * dx + dy * dy + dz * dz + 1);
720
+ const sameLvl = (nodeList[j].level || 3) === myLevel ? 2.5 : 0.3;
721
+ const f = ATTRACTION * dist * sameLvl;
722
+ fx += (dx / dist) * f; fy += (dy / dist) * f; fz += (dz / dist) * f;
723
+ }
724
+
725
+ // Cluster cohesion: pull toward own level centroid
726
+ const mc = dynC[myLevel];
727
+ if (mc) {
728
+ fx += (mc.x - pos[i].x) * CLUSTER_PULL * temp;
729
+ fy += (mc.y - pos[i].y) * CLUSTER_PULL * temp;
730
+ fz += (mc.z - pos[i].z) * CLUSTER_PULL * temp;
731
+ }
732
+
733
+ // Inter-cluster repulsion: push away from OTHER level centroids
734
+ for (const lv in dynC) {
735
+ if (parseInt(lv) === myLevel) continue;
736
+ const oc = dynC[lv];
737
+ const dx = pos[i].x - oc.x;
738
+ const dy = pos[i].y - oc.y;
739
+ const dz = pos[i].z - oc.z;
740
+ const distSq = dx * dx + dy * dy + dz * dz + 1;
741
+ const f = INTER_REPEL * temp / distSq;
742
+ const dist = Math.sqrt(distSq);
743
+ fx += (dx / dist) * f; fy += (dy / dist) * f; fz += (dz / dist) * f;
744
+ }
745
+
746
+ // Light centering
747
+ fx -= pos[i].x * CENTERING;
748
+ fy -= pos[i].y * CENTERING;
749
+ fz -= pos[i].z * CENTERING;
750
+
751
+ vel[i].x = (vel[i].x + fx) * DAMPING;
752
+ vel[i].y = (vel[i].y + fy) * DAMPING;
753
+ vel[i].z = (vel[i].z + fz) * DAMPING;
754
+
755
+ const maxV = 30 * temp + 2;
756
+ const vLen = Math.sqrt(vel[i].x * vel[i].x + vel[i].y * vel[i].y + vel[i].z * vel[i].z);
757
+ if (vLen > maxV) {
758
+ vel[i].x = vel[i].x / vLen * maxV;
759
+ vel[i].y = vel[i].y / vLen * maxV;
760
+ vel[i].z = vel[i].z / vLen * maxV;
761
+ }
762
+ }
763
+
764
+ for (let i = 0; i < N; i++) {
765
+ pos[i].x += vel[i].x;
766
+ pos[i].y += vel[i].y;
767
+ pos[i].z += vel[i].z;
768
+ }
769
+ }
770
+
771
+ // Scale to fit (target radius ~650 for spacious clusters)
772
+ let maxDist = 0;
773
+ for (let i = 0; i < N; i++) {
774
+ const d = Math.sqrt(pos[i].x * pos[i].x + pos[i].y * pos[i].y + pos[i].z * pos[i].z);
775
+ if (d > maxDist) maxDist = d;
776
+ }
777
+ const scale = maxDist > 0 ? 650 / maxDist : 1;
778
+ for (let i = 0; i < N; i++) {
779
+ pos[i].x *= scale;
780
+ pos[i].y *= scale;
781
+ pos[i].z *= scale;
782
+ }
783
+
784
+ return pos;
785
+ }
609
786
 
610
787
  function srand(s) { const x = Math.sin(s * 9301 + 49297) * 49297; return x - Math.floor(x); }
611
788
  function escapeHtml(s) { return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }
@@ -618,21 +795,19 @@ document.body.prepend(renderer.domElement);
618
795
 
619
796
  const scene = new THREE.Scene();
620
797
  scene.background = new THREE.Color('#030308');
621
- scene.fog = new THREE.FogExp2('#030308', 0.00015);
798
+ scene.fog = new THREE.FogExp2('#030308', 0.00018);
622
799
 
623
800
  const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 12000);
624
- camera.position.set(500, 300, 750);
801
+ camera.position.set(900, 500, 900);
625
802
 
626
803
  const controls = new OrbitControls(camera, renderer.domElement);
627
804
  controls.target.set(0, 0, 0);
628
805
  controls.enableDamping = true;
629
806
  controls.dampingFactor = 0.06;
630
807
  controls.autoRotate = true;
631
- controls.autoRotateSpeed = 0.08;
808
+ controls.autoRotateSpeed = 0.12;
632
809
  controls.minDistance = 80;
633
810
  controls.maxDistance = 4000;
634
- controls.maxPolarAngle = Math.PI * 0.85;
635
- controls.minPolarAngle = Math.PI * 0.15;
636
811
  controls.update();
637
812
 
638
813
  // =========== BACKGROUND STARS ===========
@@ -693,13 +868,13 @@ const nodeMat = new THREE.ShaderMaterial({
693
868
  vec2 c = gl_PointCoord - vec2(.5);
694
869
  float d = length(c);
695
870
  if(d > .5) discard;
696
- float act = 0.5 + vActivity * 0.5;
697
- float core = exp(-d*d*120.0) * (0.6 + act * 0.4);
698
- float g1 = exp(-d*d*20.0) * .4 * act;
699
- float g2 = exp(-d*d*5.0) * .15 * act;
700
- float g3 = exp(-d*d*1.5) * .05;
701
- float i = core + g1 + g2 + g3;
702
- gl_FragColor = vec4(vColor * (1.0 + core * .4), i * vAlpha);
871
+ // Sharp saturated core with minimal glow — preserves level color
872
+ float core = exp(-d*d*180.0) * 0.95;
873
+ float halo = exp(-d*d*22.0) * 0.25;
874
+ float outer = exp(-d*d*6.0) * 0.06;
875
+ float intensity = core + halo + outer;
876
+ // Keep color saturated minimal brightness boost on core
877
+ gl_FragColor = vec4(vColor * (0.85 + core * 0.15), intensity * vAlpha);
703
878
  }
704
879
  \`,
705
880
  transparent: true, depthWrite: false, blending: THREE.AdditiveBlending,
@@ -753,7 +928,6 @@ let pData = [];
753
928
  let nCount = 0;
754
929
  let eCount = 0;
755
930
  let pCount = 0;
756
- let orbitRings = [];
757
931
 
758
932
  const PARTICLES_PER_EDGE = 3;
759
933
  const tc = new THREE.Color();
@@ -764,8 +938,6 @@ function rebuildScene() {
764
938
  if (nodeGeo) { nodeGeo.dispose(); scene.remove(nodePoints); }
765
939
  if (edgeGeo) { edgeGeo.dispose(); scene.remove(edgeLines); }
766
940
  if (particleGeo) { particleGeo.dispose(); scene.remove(particlePoints); }
767
- orbitRings.forEach(r => { r.geometry.dispose(); r.material.dispose(); scene.remove(r); });
768
- orbitRings = [];
769
941
 
770
942
  nodes = BRAIN_DATA.nodes;
771
943
  nCount = nodes.length;
@@ -778,30 +950,17 @@ function rebuildScene() {
778
950
  byLevel[lv].push(i);
779
951
  });
780
952
 
781
- // Compute radial spiral positions
782
- positions = new Array(nCount);
783
- for (const [lv, indices] of Object.entries(byLevel)) {
784
- const s = SPATIAL[lv] || SPATIAL[3];
785
- const c = indices.length;
786
- indices.forEach((ni, j) => {
787
- const angle = (j / Math.max(c, 1)) * Math.PI * 2 + (srand(ni * 19) - 0.5) * 1.2;
788
- const r = s.iR + srand(ni * 7) * (s.oR - s.iR);
789
- const spiral = angle + r * 0.005 + srand(ni * 23) * 0.8;
790
- const y = (s.yBase || 0) + (srand(ni * 11) - 0.5) * s.yS;
791
- // Organic jitter for 3D spread
792
- const jitterX = (srand(ni * 29) - 0.5) * r * 0.2;
793
- const jitterZ = (srand(ni * 37) - 0.5) * r * 0.2;
794
- positions[ni] = new THREE.Vector3(
795
- Math.cos(spiral) * r + jitterX + (s.cx || 0),
796
- y,
797
- Math.sin(spiral) * r + jitterZ + (s.cz || 0)
798
- );
799
- });
800
- }
801
-
802
- // Build adjacency + nodeIdxMap
953
+ // Build nodeIdxMap first (needed for force layout)
803
954
  nodeIdxMap = {};
804
955
  nodes.forEach((n, i) => { nodeIdxMap[n.id] = i; });
956
+
957
+ // Force-directed 3D layout
958
+ const forcePos = computeForceLayout(nodes, BRAIN_DATA.edges, nodeIdxMap);
959
+ positions = new Array(nCount);
960
+ for (let i = 0; i < nCount; i++) {
961
+ const fp = forcePos[i] || { x: 0, y: 0, z: 0 };
962
+ positions[i] = new THREE.Vector3(fp.x, fp.y, fp.z);
963
+ }
805
964
  adj = {};
806
965
  nodeEdgeMap = {};
807
966
  BRAIN_DATA.edges.forEach((e, ei) => {
@@ -817,6 +976,33 @@ function rebuildScene() {
817
976
  nodeEdgeMap[ti].push(ei);
818
977
  });
819
978
 
979
+ // ---- NODE COLOR: blend level + dominant edge type ----
980
+ // Pre-compute dominant edge type per node
981
+ const nodeEdgeTypeCounts = {};
982
+ for (const e of BRAIN_DATA.edges) {
983
+ const si = nodeIdxMap[e.source], ti = nodeIdxMap[e.target];
984
+ if (si === undefined || ti === undefined) continue;
985
+ const type = e.type || 'related_to';
986
+ if (!nodeEdgeTypeCounts[si]) nodeEdgeTypeCounts[si] = {};
987
+ if (!nodeEdgeTypeCounts[ti]) nodeEdgeTypeCounts[ti] = {};
988
+ nodeEdgeTypeCounts[si][type] = (nodeEdgeTypeCounts[si][type] || 0) + 1;
989
+ nodeEdgeTypeCounts[ti][type] = (nodeEdgeTypeCounts[ti][type] || 0) + 1;
990
+ }
991
+ const nodeDomType = {};
992
+ for (const idx in nodeEdgeTypeCounts) {
993
+ let maxT = 'default', maxC = 0;
994
+ for (const [t, c] of Object.entries(nodeEdgeTypeCounts[idx])) {
995
+ if (c > maxC) { maxC = c; maxT = t; }
996
+ }
997
+ nodeDomType[idx] = maxT;
998
+ }
999
+ // Max degree for brightness scaling
1000
+ let maxDegree = 1;
1001
+ for (let i = 0; i < nCount; i++) {
1002
+ const deg = adj[i] ? adj[i].size : 0;
1003
+ if (deg > maxDegree) maxDegree = deg;
1004
+ }
1005
+
820
1006
  // ---- NODE POINTS ----
821
1007
  nodeGeo = new THREE.BufferGeometry();
822
1008
  const nPos = new Float32Array(nCount * 3);
@@ -825,13 +1011,23 @@ function rebuildScene() {
825
1011
  const nHighlight = new Float32Array(nCount);
826
1012
  const nPulse = new Float32Array(nCount);
827
1013
  const nActivity = new Float32Array(nCount);
1014
+ const ec = new THREE.Color();
828
1015
 
829
1016
  for (let i = 0; i < nCount; i++) {
830
1017
  const p = positions[i];
831
1018
  const n = nodes[i];
832
- const s = SPATIAL[n.level] || SPATIAL[3];
1019
+ const s = LEVEL_STYLE[n.level] || LEVEL_STYLE[3];
833
1020
  nPos[i * 3] = p.x; nPos[i * 3 + 1] = p.y; nPos[i * 3 + 2] = p.z;
1021
+ // Base level color
834
1022
  tc.set(LEVEL_COLORS_HEX[n.level] || 0x00FFFF);
1023
+ // Blend with dominant edge type color (35% influence) for color variety
1024
+ const domType = nodeDomType[i] || 'default';
1025
+ ec.set(EDGE_COLORS[domType] || EDGE_COLORS.default);
1026
+ tc.lerp(ec, 0.35);
1027
+ // Brightness by degree: low-degree dimmer, high-degree brighter
1028
+ const deg = adj[i] ? adj[i].size : 0;
1029
+ const bright = 0.6 + (deg / maxDegree) * 0.4;
1030
+ tc.multiplyScalar(bright);
835
1031
  nCol[i * 3] = tc.r; nCol[i * 3 + 1] = tc.g; nCol[i * 3 + 2] = tc.b;
836
1032
  nSize[i] = s.size;
837
1033
  nHighlight[i] = 1.0;
@@ -847,40 +1043,16 @@ function rebuildScene() {
847
1043
  nodePoints = new THREE.Points(nodeGeo, nodeMat);
848
1044
  scene.add(nodePoints);
849
1045
 
850
- // ---- ORBIT RINGS (one per layer, centered at layer's spiral offset) ----
851
- for (let lv = 1; lv <= 6; lv++) {
852
- const s = SPATIAL[lv];
853
- if (!s || !(byLevel[lv] || []).length) continue;
854
- const ringRadius = s.oR * 0.85;
855
- const ringGeo = new THREE.RingGeometry(ringRadius - 0.3, ringRadius + 0.3, 96);
856
- const ringColor = new THREE.Color(LEVEL_COLORS_HEX[lv] || 0x00FFFF);
857
- const ringMat = new THREE.MeshBasicMaterial({
858
- color: ringColor, transparent: true, opacity: 0.06 + (s.activity || 0.5) * 0.06, side: THREE.DoubleSide,
859
- blending: THREE.AdditiveBlending, depthWrite: false,
860
- });
861
- const ring = new THREE.Mesh(ringGeo, ringMat);
862
- ring.rotation.x = -Math.PI / 2;
863
- ring.position.set(s.cx || 0, s.yBase, s.cz || 0);
864
- ring.userData.level = lv;
865
- scene.add(ring);
866
- orbitRings.push(ring);
867
- }
868
-
869
1046
  // ---- EDGES (LineSegments) ----
870
- // Prioritize cross-level edges (vertical) over intra-level (horizontal)
871
1047
  const allEdges = [];
872
1048
  BRAIN_DATA.edges.forEach((e, i) => {
873
1049
  const si = nodeIdxMap[e.source], ti = nodeIdxMap[e.target];
874
1050
  if (si !== undefined && ti !== undefined) {
875
- const crossLevel = nodes[si].level !== nodes[ti].level;
876
- allEdges.push({ si, ti, weight: e.weight, type: e.type, idx: i, crossLevel });
1051
+ allEdges.push({ si, ti, weight: e.weight, type: e.type, idx: i });
877
1052
  }
878
1053
  });
879
- // Sort: cross-level edges first (they create the beautiful vertical connections)
880
- allEdges.sort((a, b) => {
881
- if (a.crossLevel !== b.crossLevel) return b.crossLevel ? 1 : -1;
882
- return b.weight - a.weight; // then by weight
883
- });
1054
+ // Sort by weight (strongest connections first)
1055
+ allEdges.sort((a, b) => b.weight - a.weight);
884
1056
  validEdges = allEdges.slice(0, MAX_RENDERED_EDGES);
885
1057
 
886
1058
  eCount = validEdges.length;
@@ -893,17 +1065,18 @@ function rebuildScene() {
893
1065
  const alphaScale = Math.min(1.0, 3000 / eCount);
894
1066
 
895
1067
  for (let i = 0; i < eCount; i++) {
896
- const { si, ti, weight, crossLevel } = validEdges[i];
1068
+ const { si, ti, weight, type } = validEdges[i];
897
1069
  const s = positions[si], t = positions[ti];
898
1070
  const o = i * 6;
899
1071
  ePos[o] = s.x; ePos[o + 1] = s.y; ePos[o + 2] = s.z;
900
1072
  ePos[o + 3] = t.x; ePos[o + 4] = t.y; ePos[o + 5] = t.z;
901
- sc.set(LEVEL_COLORS_HEX[nodes[si].level] || 0x00FFFF);
902
- dc.set(LEVEL_COLORS_HEX[nodes[ti].level] || 0x00FFFF);
1073
+ // Color by edge type for galaxy look
1074
+ const edgeColor = EDGE_COLORS[type] || EDGE_COLORS.default;
1075
+ sc.set(edgeColor); dc.set(edgeColor);
903
1076
  eCol[o] = sc.r; eCol[o + 1] = sc.g; eCol[o + 2] = sc.b;
904
1077
  eCol[o + 3] = dc.r; eCol[o + 4] = dc.g; eCol[o + 5] = dc.b;
905
- // Cross-level edges brighter, intra-level edges dimmer
906
- const baseAlpha = crossLevel ? (0.08 + weight * 0.12) : (0.03 + weight * 0.04);
1078
+ // Boosted edge alpha for colorful connections
1079
+ const baseAlpha = 0.12 + weight * 0.28;
907
1080
  eAlpha[i * 2] = baseAlpha * alphaScale;
908
1081
  eAlpha[i * 2 + 1] = baseAlpha * alphaScale;
909
1082
  }
@@ -915,13 +1088,13 @@ function rebuildScene() {
915
1088
  edgeLines = new THREE.LineSegments(edgeGeo, edgeMat);
916
1089
  scene.add(edgeLines);
917
1090
 
918
- // ---- FLOWING PARTICLES (only on cross-level edges for clarity) ----
1091
+ // ---- FLOWING PARTICLES (on stronger connections) ----
919
1092
  pData = [];
920
1093
  const maxParticleEdges = Math.min(eCount, 2000);
921
1094
  for (let i = 0; i < maxParticleEdges; i++) {
922
- const { si, ti, weight, crossLevel } = validEdges[i];
923
- if (!crossLevel) continue; // only particles on vertical connections
924
- const particleCount = weight > 0.6 ? 2 : 1;
1095
+ const { si, ti, weight } = validEdges[i];
1096
+ if (weight < 0.4) continue; // only on stronger connections
1097
+ const particleCount = weight > 0.7 ? 2 : 1;
925
1098
  for (let j = 0; j < particleCount; j++) {
926
1099
  pData.push({
927
1100
  edgeIdx: i, progress: srand(i * 100 + j * 31),
@@ -1071,8 +1244,8 @@ function updateHighlights() {
1071
1244
  const activeEdgeTypes = getActiveEdgeTypes();
1072
1245
  const alphaS = Math.min(1.0, 3000 / eCount);
1073
1246
  for (let i = 0; i < eCount; i++) {
1074
- const { si, ti, weight, type, crossLevel } = validEdges[i];
1075
- const baseA = crossLevel ? (0.08 + weight * 0.12) : (0.03 + weight * 0.04);
1247
+ const { si, ti, weight, type } = validEdges[i];
1248
+ const baseA = 0.06 + weight * 0.14;
1076
1249
  let a = baseA * alphaS;
1077
1250
 
1078
1251
  // Level toggle: hide edges connected to hidden levels
@@ -1100,11 +1273,6 @@ function updateHighlights() {
1100
1273
  }
1101
1274
  ea.needsUpdate = true;
1102
1275
 
1103
- // Update orbit ring visibility
1104
- orbitRings.forEach(ring => {
1105
- const lv = ring.userData.level;
1106
- ring.material.opacity = levelToggles[lv] === false ? 0 : 0.08;
1107
- });
1108
1276
  }
1109
1277
 
1110
1278
  function getActiveEdgeTypes() {
@@ -1167,7 +1335,7 @@ function closeSidebar(evt) {
1167
1335
  controls.autoRotate = true;
1168
1336
  camTween = {
1169
1337
  startPos: camera.position.clone(), startLookAt: controls.target.clone(),
1170
- targetPos: new THREE.Vector3(500, 300, 750), targetLookAt: new THREE.Vector3(0, -50, 0),
1338
+ targetPos: new THREE.Vector3(600, 350, 600), targetLookAt: new THREE.Vector3(0, 0, 0),
1171
1339
  progress: 0
1172
1340
  };
1173
1341
  }
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/cli/brain/template.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAAC,IAAiB;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEtC,OAAO;;;;;;0CAMiC,IAAI,CAAC,IAAI,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCA2ZxB,IAAI,CAAC,IAAI,CAAC,UAAU,iBAAiB,IAAI,CAAC,IAAI,CAAC,UAAU,eAAe,IAAI,CAAC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC,IAAI,CAAC,WAAW;;wCAE3L,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;uCACpD,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAkKvE,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA43BL,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAukBvE,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/cli/brain/template.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAAC,IAAiB;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEtC,OAAO;;;;;;0CAMiC,IAAI,CAAC,IAAI,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCA2ZxB,IAAI,CAAC,IAAI,CAAC,UAAU,iBAAiB,IAAI,CAAC,IAAI,CAAC,UAAU,eAAe,IAAI,CAAC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC,IAAI,CAAC,WAAW;;wCAE3L,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;uCACpD,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAkKvE,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAoiCL,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAukBvE,CAAC;AACT,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"keybinding.d.ts","sourceRoot":"","sources":["../../../src/cli/checkpoints/keybinding.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjG,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CAMvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EACzD,KAAK,EAAE,eAAe,GACrB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA0BvC"}
1
+ {"version":3,"file":"keybinding.d.ts","sourceRoot":"","sources":["../../../src/cli/checkpoints/keybinding.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjG,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CAMvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EACzD,KAAK,EAAE,eAAe,GACrB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA2BvC"}
@@ -4,7 +4,7 @@
4
4
  export function createKeybindingState() {
5
5
  return {
6
6
  lastEscTime: 0,
7
- doubleEscThreshold: 300,
7
+ doubleEscThreshold: 500,
8
8
  inBrowser: false,
9
9
  };
10
10
  }
@@ -38,6 +38,7 @@ export function processKeypress(key, state) {
38
38
  state.lastEscTime = now;
39
39
  return { action: 'ignore' };
40
40
  }
41
+ state.lastEscTime = 0;
41
42
  return { action: 'ignore' };
42
43
  }
43
44
  //# sourceMappingURL=keybinding.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keybinding.js","sourceRoot":"","sources":["../../../src/cli/checkpoints/keybinding.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,WAAW,EAAE,CAAC;QACd,kBAAkB,EAAE,GAAG;QACvB,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAyD,EACzD,KAAsB;IAEtB,0CAA0C;IAC1C,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC/C,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACnD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACtD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QACvD,kCAAkC;QAClC,IAAI,GAAG,CAAC,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,oCAAoC;IACpC,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,kBAAkB,EAAE,CAAC;YACvD,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;YACtB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;QACxB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"keybinding.js","sourceRoot":"","sources":["../../../src/cli/checkpoints/keybinding.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,WAAW,EAAE,CAAC;QACd,kBAAkB,EAAE,GAAG;QACvB,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAyD,EACzD,KAAsB;IAEtB,0CAA0C;IAC1C,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC/C,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACnD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACtD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QACvD,kCAAkC;QAClC,IAAI,GAAG,CAAC,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,oCAAoC;IACpC,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,kBAAkB,EAAE,CAAC;YACvD,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;YACtB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;QACxB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { JarvisTask, JarvisTaskStatus, JarvisTaskPriority, JarvisDaemonState, JarvisStatusInfo } from './types.js';
2
+ export declare class JarvisQueue {
3
+ private data;
4
+ private filePath;
5
+ private onChange?;
6
+ private daemonStartTime;
7
+ constructor(projectRoot: string, onChange?: (event: string, task: JarvisTask) => void);
8
+ private load;
9
+ private save;
10
+ addTask(title: string, description: string, opts?: {
11
+ priority?: JarvisTaskPriority;
12
+ dependencies?: number[];
13
+ tags?: string[];
14
+ maxRetries?: number;
15
+ }): JarvisTask;
16
+ getTask(id: number): JarvisTask | undefined;
17
+ updateTask(id: number, updates: Partial<Pick<JarvisTask, 'status' | 'priority' | 'title' | 'description' | 'result' | 'error' | 'startedAt' | 'completedAt' | 'retries' | 'sessionId' | 'tags'>>): JarvisTask | undefined;
18
+ removeTask(id: number): boolean;
19
+ /**
20
+ * Returns the next task to execute: highest priority pending task
21
+ * whose dependencies (if any) are all completed.
22
+ */
23
+ getNextTask(): JarvisTask | undefined;
24
+ getByStatus(status: JarvisTaskStatus): JarvisTask[];
25
+ getAllTasks(): JarvisTask[];
26
+ clearCompleted(): number;
27
+ get count(): number;
28
+ get pendingCount(): number;
29
+ getDaemonState(): JarvisDaemonState;
30
+ setDaemonState(state: JarvisDaemonState): void;
31
+ getStatus(): JarvisStatusInfo;
32
+ /**
33
+ * Build a summary string for injection into the system prompt.
34
+ */
35
+ getSummaryForPrompt(): string | null;
36
+ /** Short status line for the status bar */
37
+ getStatusLine(): string;
38
+ /** Set or replace the onChange callback */
39
+ setOnChange(handler: (event: string, task: JarvisTask) => void): void;
40
+ }
41
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/cli/jarvis/queue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,kBAAkB,EAAmB,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMzI,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,CAA4C;IAC7D,OAAO,CAAC,eAAe,CAAuB;gBAElC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI;IAiBrF,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QACjD,QAAQ,CAAC,EAAE,kBAAkB,CAAC;QAC9B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,UAAU;IAoBd,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI3C,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EACrD,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,GACpE,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAC/D,CAAC,GAAG,UAAU,GAAG,SAAS;IAsB3B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ/B;;;OAGG;IACH,WAAW,IAAI,UAAU,GAAG,SAAS;IAqBrC,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU,EAAE;IAInD,WAAW,IAAI,UAAU,EAAE;IAI3B,cAAc,IAAI,MAAM;IAQxB,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAID,cAAc,IAAI,iBAAiB;IAInC,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAW9C,SAAS,IAAI,gBAAgB;IAa7B;;OAEG;IACH,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAoCpC,2CAA2C;IAC3C,aAAa,IAAI,MAAM;IAgBvB,2CAA2C;IAC3C,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;CAGtE"}
@@ -0,0 +1,236 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ const EMPTY_DATA = { version: 1, nextId: 1, tasks: [], daemonState: 'stopped' };
4
+ const PRIORITY_ORDER = { high: 0, medium: 1, low: 2 };
5
+ export class JarvisQueue {
6
+ data;
7
+ filePath;
8
+ onChange;
9
+ daemonStartTime = null;
10
+ constructor(projectRoot, onChange) {
11
+ this.filePath = join(projectRoot, '.helixmind', 'jarvis', 'tasks.json');
12
+ this.onChange = onChange;
13
+ this.data = this.load();
14
+ // Crash recovery: reset any stale 'running' tasks back to 'pending'
15
+ for (const task of this.data.tasks) {
16
+ if (task.status === 'running') {
17
+ task.status = 'pending';
18
+ task.updatedAt = Date.now();
19
+ }
20
+ }
21
+ if (this.data.tasks.some(t => t.status === 'pending')) {
22
+ this.save();
23
+ }
24
+ }
25
+ load() {
26
+ try {
27
+ if (existsSync(this.filePath)) {
28
+ const raw = readFileSync(this.filePath, 'utf-8');
29
+ const parsed = JSON.parse(raw);
30
+ if (parsed.version === 1 && Array.isArray(parsed.tasks)) {
31
+ return parsed;
32
+ }
33
+ }
34
+ }
35
+ catch {
36
+ // Corrupted file — start fresh
37
+ }
38
+ return { ...EMPTY_DATA, tasks: [] };
39
+ }
40
+ save() {
41
+ const dir = dirname(this.filePath);
42
+ if (!existsSync(dir)) {
43
+ mkdirSync(dir, { recursive: true });
44
+ }
45
+ writeFileSync(this.filePath, JSON.stringify(this.data, null, 2), 'utf-8');
46
+ }
47
+ addTask(title, description, opts) {
48
+ const task = {
49
+ id: this.data.nextId++,
50
+ title,
51
+ description,
52
+ status: 'pending',
53
+ priority: opts?.priority ?? 'medium',
54
+ createdAt: Date.now(),
55
+ updatedAt: Date.now(),
56
+ retries: 0,
57
+ maxRetries: opts?.maxRetries ?? 3,
58
+ dependencies: opts?.dependencies,
59
+ tags: opts?.tags,
60
+ };
61
+ this.data.tasks.push(task);
62
+ this.save();
63
+ this.onChange?.('task_created', task);
64
+ return task;
65
+ }
66
+ getTask(id) {
67
+ return this.data.tasks.find(t => t.id === id);
68
+ }
69
+ updateTask(id, updates) {
70
+ const task = this.data.tasks.find(t => t.id === id);
71
+ if (!task)
72
+ return undefined;
73
+ if (updates.status !== undefined)
74
+ task.status = updates.status;
75
+ if (updates.priority !== undefined)
76
+ task.priority = updates.priority;
77
+ if (updates.title !== undefined)
78
+ task.title = updates.title;
79
+ if (updates.description !== undefined)
80
+ task.description = updates.description;
81
+ if (updates.result !== undefined)
82
+ task.result = updates.result;
83
+ if (updates.error !== undefined)
84
+ task.error = updates.error;
85
+ if (updates.startedAt !== undefined)
86
+ task.startedAt = updates.startedAt;
87
+ if (updates.completedAt !== undefined)
88
+ task.completedAt = updates.completedAt;
89
+ if (updates.retries !== undefined)
90
+ task.retries = updates.retries;
91
+ if (updates.sessionId !== undefined)
92
+ task.sessionId = updates.sessionId;
93
+ if (updates.tags !== undefined)
94
+ task.tags = updates.tags;
95
+ task.updatedAt = Date.now();
96
+ this.save();
97
+ this.onChange?.('task_updated', task);
98
+ return task;
99
+ }
100
+ removeTask(id) {
101
+ const idx = this.data.tasks.findIndex(t => t.id === id);
102
+ if (idx === -1)
103
+ return false;
104
+ this.data.tasks.splice(idx, 1);
105
+ this.save();
106
+ return true;
107
+ }
108
+ /**
109
+ * Returns the next task to execute: highest priority pending task
110
+ * whose dependencies (if any) are all completed.
111
+ */
112
+ getNextTask() {
113
+ const pending = this.data.tasks
114
+ .filter(t => t.status === 'pending')
115
+ .filter(t => {
116
+ if (!t.dependencies || t.dependencies.length === 0)
117
+ return true;
118
+ return t.dependencies.every(depId => {
119
+ const dep = this.data.tasks.find(d => d.id === depId);
120
+ return dep?.status === 'completed';
121
+ });
122
+ });
123
+ pending.sort((a, b) => {
124
+ if (PRIORITY_ORDER[a.priority] !== PRIORITY_ORDER[b.priority]) {
125
+ return PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority];
126
+ }
127
+ return a.createdAt - b.createdAt;
128
+ });
129
+ return pending[0];
130
+ }
131
+ getByStatus(status) {
132
+ return this.data.tasks.filter(t => t.status === status);
133
+ }
134
+ getAllTasks() {
135
+ return [...this.data.tasks];
136
+ }
137
+ clearCompleted() {
138
+ const before = this.data.tasks.length;
139
+ this.data.tasks = this.data.tasks.filter(t => t.status !== 'completed');
140
+ const removed = before - this.data.tasks.length;
141
+ if (removed > 0)
142
+ this.save();
143
+ return removed;
144
+ }
145
+ get count() {
146
+ return this.data.tasks.length;
147
+ }
148
+ get pendingCount() {
149
+ return this.getByStatus('pending').length;
150
+ }
151
+ // --- Daemon state (persisted) ---
152
+ getDaemonState() {
153
+ return this.data.daemonState;
154
+ }
155
+ setDaemonState(state) {
156
+ this.data.daemonState = state;
157
+ if (state === 'running') {
158
+ this.data.lastRunAt = Date.now();
159
+ this.daemonStartTime = Date.now();
160
+ }
161
+ else if (state === 'stopped') {
162
+ this.daemonStartTime = null;
163
+ }
164
+ this.save();
165
+ }
166
+ getStatus() {
167
+ const running = this.data.tasks.find(t => t.status === 'running');
168
+ return {
169
+ daemonState: this.data.daemonState,
170
+ currentTaskId: running?.id ?? null,
171
+ pendingCount: this.getByStatus('pending').length,
172
+ completedCount: this.getByStatus('completed').length,
173
+ failedCount: this.getByStatus('failed').length,
174
+ totalCount: this.data.tasks.length,
175
+ uptimeMs: this.daemonStartTime ? Date.now() - this.daemonStartTime : 0,
176
+ };
177
+ }
178
+ /**
179
+ * Build a summary string for injection into the system prompt.
180
+ */
181
+ getSummaryForPrompt() {
182
+ if (this.data.tasks.length === 0)
183
+ return null;
184
+ const pending = this.getByStatus('pending');
185
+ const running = this.getByStatus('running');
186
+ const failed = this.getByStatus('failed');
187
+ if (pending.length === 0 && running.length === 0 && failed.length === 0)
188
+ return null;
189
+ const lines = ['## Jarvis Task Queue'];
190
+ if (running.length > 0) {
191
+ lines.push(`\nRunning:`);
192
+ for (const t of running) {
193
+ lines.push(`- #${t.id}: ${t.title} [${t.priority}]`);
194
+ }
195
+ }
196
+ if (pending.length > 0) {
197
+ lines.push(`\nPending (${pending.length}):`);
198
+ for (const t of pending.slice(0, 5)) {
199
+ lines.push(`- #${t.id}: ${t.title} [${t.priority}]`);
200
+ }
201
+ if (pending.length > 5)
202
+ lines.push(` ... and ${pending.length - 5} more`);
203
+ }
204
+ if (failed.length > 0) {
205
+ lines.push(`\nFailed (${failed.length}):`);
206
+ for (const t of failed.slice(0, 3)) {
207
+ lines.push(`- #${t.id}: ${t.title} — ${t.error || 'unknown error'}`);
208
+ }
209
+ }
210
+ return lines.join('\n');
211
+ }
212
+ /** Short status line for the status bar */
213
+ getStatusLine() {
214
+ const pending = this.getByStatus('pending').length;
215
+ const running = this.getByStatus('running').length;
216
+ const completed = this.getByStatus('completed').length;
217
+ const failed = this.getByStatus('failed').length;
218
+ if (pending + running + completed + failed === 0)
219
+ return '';
220
+ const parts = [];
221
+ if (running > 0)
222
+ parts.push(`${running} running`);
223
+ if (pending > 0)
224
+ parts.push(`${pending} pending`);
225
+ if (completed > 0)
226
+ parts.push(`${completed} done`);
227
+ if (failed > 0)
228
+ parts.push(`${failed} failed`);
229
+ return parts.join(', ');
230
+ }
231
+ /** Set or replace the onChange callback */
232
+ setOnChange(handler) {
233
+ this.onChange = handler;
234
+ }
235
+ }
236
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../src/cli/jarvis/queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ export type JarvisTaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'paused';
2
+ export type JarvisTaskPriority = 'high' | 'medium' | 'low';
3
+ export type JarvisDaemonState = 'stopped' | 'running' | 'paused';
4
+ export interface JarvisTask {
5
+ id: number;
6
+ title: string;
7
+ description: string;
8
+ status: JarvisTaskStatus;
9
+ priority: JarvisTaskPriority;
10
+ createdAt: number;
11
+ updatedAt: number;
12
+ startedAt?: number;
13
+ completedAt?: number;
14
+ result?: string;
15
+ error?: string;
16
+ retries: number;
17
+ maxRetries: number;
18
+ sessionId?: string;
19
+ dependencies?: number[];
20
+ tags?: string[];
21
+ }
22
+ export interface JarvisQueueData {
23
+ version: 1;
24
+ nextId: number;
25
+ tasks: JarvisTask[];
26
+ daemonState: JarvisDaemonState;
27
+ lastRunAt?: number;
28
+ }
29
+ export interface JarvisStatusInfo {
30
+ daemonState: JarvisDaemonState;
31
+ currentTaskId: number | null;
32
+ pendingCount: number;
33
+ completedCount: number;
34
+ failedCount: number;
35
+ totalCount: number;
36
+ uptimeMs: number;
37
+ }
38
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/jarvis/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AACzF,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAC3D,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/cli/jarvis/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helixmind",
3
- "version": "0.2.26",
3
+ "version": "0.2.28",
4
4
  "description": "HelixMind – AI Coding CLI with Persistent Spiral Memory",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",