@omiron33/omi-neuron-web 0.2.21 → 0.2.22

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
@@ -12,6 +12,9 @@ If you are working inside this repo, also read `AGENTS.md` for execution rules,
12
12
  - A CLI that scaffolds configuration, Docker Postgres (pgvector), and Next.js route handlers.
13
13
  - A Node/Edge/Cluster data model, plus analysis and embeddings pipelines.
14
14
  - A React provider and hooks that wrap the API client.
15
+ - **Static mode** (`StaticDataProvider`) for authored graphs without API/database dependency.
16
+ - **Status-based node coloring** for workflow visualization (draft/active/complete/blocked/archived).
17
+ - **Static cluster rendering** with convex hull boundaries around explicit node groups.
15
18
 
16
19
  ## Package entry points
17
20
 
@@ -99,6 +102,11 @@ export type {
99
102
  export * from './react/hooks';
100
103
  export { NeuronWebProvider } from './react/NeuronWebProvider';
101
104
 
105
+ // Static mode (no API/database required)
106
+ export { StaticDataProvider } from './react/StaticDataProvider';
107
+ export type { StaticDataProviderProps } from './react/StaticDataProvider';
108
+ export { StaticModeError } from './react/static/in-memory-api-client';
109
+
102
110
  // Version constant
103
111
  export { VERSION } from './version';
104
112
  ```
@@ -300,8 +308,17 @@ export default defineNeuronConfig({
300
308
  - analysis fields: `embedding`, `embeddingModel`, `embeddingGeneratedAt`, `clusterId`, `clusterSimilarity`
301
309
  - relationship counts: `connectionCount`, `inboundCount`, `outboundCount`
302
310
  - status: `analysisStatus`, `analysisError`
311
+ - workflow status: `status?: NodeStatus` (for status-based coloring)
303
312
  - visualization hints: `tier`, `visualPriority`, `positionOverride`
304
313
 
314
+ `NodeStatus` type (for workflow-based coloring):
315
+
316
+ ```ts
317
+ export type NodeStatus = 'default' | 'draft' | 'active' | 'complete' | 'blocked' | 'archived';
318
+ ```
319
+
320
+ When a node has a `status` set, it takes priority over domain-based coloring in visualization.
321
+
305
322
  Input types:
306
323
 
307
324
  - `NeuronNodeCreate` (minimal required fields: `label`; optional `slug`, `nodeType`, `domain`, `summary`, `description`, `content`, `metadata`, `tier`)
@@ -334,6 +351,21 @@ Visualization type: `NeuronVisualEdge` uses `from` and `to` slugs.
334
351
  - stats: `memberCount`, `avgSimilarity`, `cohesion`
335
352
  - metadata: `description`, `keywords`, `metadata`
336
353
 
354
+ `NeuronVisualCluster` (for static/authored cluster visualization):
355
+
356
+ ```ts
357
+ export interface NeuronVisualCluster {
358
+ id: string;
359
+ label: string;
360
+ nodeIds: string[]; // explicit node membership
361
+ color?: string; // optional cluster color
362
+ position?: { x: number; y: number; z: number }; // optional fixed center
363
+ metadata?: Record<string, unknown>;
364
+ }
365
+ ```
366
+
367
+ Visual clusters render as convex hull boundaries around their member nodes with labels at the centroid.
368
+
337
369
  ### Analysis
338
370
 
339
371
  `AnalysisRun`, `AnalysisRequest`, `AnalysisResponse`, `AnalysisPipelineConfig` are in `src/core/types/analysis.ts`.
@@ -686,6 +718,128 @@ Notes:
686
718
  - Keep secrets server-side. Do not pass `OPENAI_API_KEY` (or database URLs) into client components.
687
719
  - Configure OpenAI + database access in your Next.js route handlers (see `docs/secure-nextjs-setup.md`).
688
720
 
721
+ ### StaticDataProvider (Standalone Mode)
722
+
723
+ Use `StaticDataProvider` for static/authored graphs that don't require API or database connectivity. Perfect for:
724
+ - Quest/narrative authoring tools
725
+ - Documentation/knowledge graphs
726
+ - Workflow/pipeline visualizers
727
+ - Game skill trees
728
+ - Org charts and hierarchies
729
+
730
+ ```tsx
731
+ import { StaticDataProvider, NeuronWeb } from '@omiron33/omi-neuron-web';
732
+
733
+ const nodes = [
734
+ { id: 'q001', label: 'Start Quest', domain: 'quest', status: 'complete' },
735
+ { id: 'q002', label: 'Find Artifact', domain: 'quest', status: 'active' },
736
+ { id: 'q003', label: 'Return Home', domain: 'quest', status: 'draft' },
737
+ ];
738
+
739
+ const edges = [
740
+ { id: 'e1', from: 'q001', to: 'q002', relationshipType: 'leads_to' },
741
+ { id: 'e2', from: 'q002', to: 'q003', relationshipType: 'leads_to' },
742
+ ];
743
+
744
+ const clusters = [
745
+ { id: 'act1', label: 'Act 1', nodeIds: ['q001', 'q002'], color: '#4a5568' },
746
+ { id: 'act2', label: 'Act 2', nodeIds: ['q003'], color: '#2d3748' },
747
+ ];
748
+
749
+ export default function QuestGraph() {
750
+ return (
751
+ <StaticDataProvider
752
+ nodes={nodes}
753
+ edges={edges}
754
+ clusters={clusters}
755
+ mutableMode={false}
756
+ >
757
+ <NeuronWeb graphData={{ nodes, edges, clusters }} />
758
+ </StaticDataProvider>
759
+ );
760
+ }
761
+ ```
762
+
763
+ `StaticDataProviderProps`:
764
+
765
+ ```ts
766
+ interface StaticDataProviderProps {
767
+ children: React.ReactNode;
768
+ nodes: (NeuronNode | NeuronVisualNode)[];
769
+ edges: (NeuronEdge | NeuronVisualEdge)[];
770
+ clusters?: NeuronVisualCluster[];
771
+ settings?: Partial<NeuronSettings>;
772
+ mutableMode?: boolean; // if true, mutations modify in-memory store
773
+ onEvent?: (event: NeuronEvent) => void;
774
+ onError?: (error: Error, context: ErrorContext) => void;
775
+ }
776
+ ```
777
+
778
+ Behavior:
779
+ - All hooks (`useNeuronNodes`, `useNeuronGraph`, etc.) work unchanged
780
+ - Analysis and search methods throw `StaticModeError` (not available in static mode)
781
+ - Context provides `isStaticMode: true` flag
782
+ - Data updates via `updateData()` on the internal client or by passing new props
783
+
784
+ ### Status-based coloring
785
+
786
+ Nodes with a `status` field render with status colors that override domain colors:
787
+
788
+ ```ts
789
+ const DEFAULT_STATUS_COLORS = {
790
+ default: '#c0c5ff', // Same as defaultDomainColor
791
+ draft: '#9ca3af', // Gray
792
+ active: '#4ade80', // Green
793
+ complete: '#60a5fa', // Blue
794
+ blocked: '#f87171', // Red
795
+ archived: '#6b7280', // Dark gray
796
+ };
797
+ ```
798
+
799
+ Override via theme:
800
+
801
+ ```tsx
802
+ <NeuronWeb
803
+ graphData={graphData}
804
+ theme={{
805
+ colors: {
806
+ statusColors: {
807
+ default: '#c0c5ff',
808
+ draft: '#888888',
809
+ active: '#00ff00',
810
+ complete: '#0088ff',
811
+ blocked: '#ff0000',
812
+ archived: '#444444',
813
+ },
814
+ },
815
+ }}
816
+ />
817
+ ```
818
+
819
+ ### Static clusters (convex hull visualization)
820
+
821
+ Pass `clusters` in `graphData` to render convex hull boundaries around node groups:
822
+
823
+ ```tsx
824
+ <NeuronWeb
825
+ graphData={{
826
+ nodes,
827
+ edges,
828
+ clusters: [
829
+ { id: 'cluster1', label: 'Group A', nodeIds: ['n1', 'n2', 'n3'], color: '#4a5568' },
830
+ { id: 'cluster2', label: 'Group B', nodeIds: ['n4', 'n5'], color: '#2d3748' },
831
+ ],
832
+ }}
833
+ />
834
+ ```
835
+
836
+ Cluster rendering:
837
+ - Computes 2D convex hull from projected node positions (Graham scan algorithm)
838
+ - Renders semi-transparent mesh fill with border outline
839
+ - Displays label at cluster centroid
840
+ - Updates when node positions change (e.g., ambient motion)
841
+ - Requires 3+ nodes to show hull; fewer shows only the label
842
+
689
843
  ### Hooks
690
844
 
691
845
  - `useNeuronContext()` -> access provider context.
@@ -729,6 +883,7 @@ export interface NeuronWebProps {
729
883
  nodes: NeuronVisualNode[];
730
884
  edges: NeuronVisualEdge[];
731
885
  storyBeats?: NeuronStoryBeat[];
886
+ clusters?: NeuronVisualCluster[];
732
887
  };
733
888
  fullHeight?: boolean;
734
889
  isFullScreen?: boolean;
@@ -1059,8 +1214,9 @@ Key behavior in `NeuronWeb`:
1059
1214
  Key internal modules:
1060
1215
 
1061
1216
  - `src/visualization/scene/scene-manager.ts` - sets up Three.js scene, camera, renderer, lights, starfield, labels.
1062
- - `src/visualization/scene/node-renderer.ts` - renders nodes, labels, hover/selection states.
1217
+ - `src/visualization/scene/node-renderer.ts` - renders nodes, labels, hover/selection states, status-based coloring.
1063
1218
  - `src/visualization/scene/edge-renderer.ts` - renders edges, flow animations.
1219
+ - `src/visualization/scene/cluster-renderer.ts` - renders convex hull boundaries around static clusters.
1064
1220
  - `src/visualization/interactions/interaction-manager.ts` - hover/click/double-click handling.
1065
1221
  - `src/visualization/animations/animation-controller.ts` - camera focus/transition animations.
1066
1222
  - `src/visualization/layouts/fuzzy-layout.ts` - layout generation.
@@ -1,5 +1,5 @@
1
1
  import React__default from 'react';
2
- import { N as NeuronVisualNode, a as NeuronVisualEdge, b as NeuronNode, c as NeuronEdge, d as NodeTier } from './edge-U2Qgwg-K.js';
2
+ import { N as NeuronVisualNode, a as NeuronVisualEdge, b as NeuronVisualCluster, c as NeuronNode, d as NeuronEdge, e as NodeStatus, f as NodeTier } from './cluster-CU_pBUcK.cjs';
3
3
 
4
4
  interface NeuronStoryBeat {
5
5
  id: string;
@@ -36,6 +36,8 @@ interface NeuronWebTheme {
36
36
  background: string;
37
37
  domainColors: Record<string, string>;
38
38
  defaultDomainColor: string;
39
+ /** Status-based node colors for workflow visualization */
40
+ statusColors?: Record<NodeStatus, string>;
39
41
  edgeDefault: string;
40
42
  edgeActive: string;
41
43
  edgeSelected: string;
@@ -283,6 +285,8 @@ interface NeuronWebProps {
283
285
  nodes: NeuronVisualNode[];
284
286
  edges: NeuronVisualEdge[];
285
287
  storyBeats?: NeuronStoryBeat[];
288
+ /** Static cluster definitions for visual grouping */
289
+ clusters?: NeuronVisualCluster[];
286
290
  };
287
291
  fullHeight?: boolean;
288
292
  isFullScreen?: boolean;
@@ -1,5 +1,5 @@
1
1
  import React__default from 'react';
2
- import { N as NeuronVisualNode, a as NeuronVisualEdge, b as NeuronNode, c as NeuronEdge, d as NodeTier } from './edge-U2Qgwg-K.cjs';
2
+ import { N as NeuronVisualNode, a as NeuronVisualEdge, b as NeuronVisualCluster, c as NeuronNode, d as NeuronEdge, e as NodeStatus, f as NodeTier } from './cluster-CU_pBUcK.js';
3
3
 
4
4
  interface NeuronStoryBeat {
5
5
  id: string;
@@ -36,6 +36,8 @@ interface NeuronWebTheme {
36
36
  background: string;
37
37
  domainColors: Record<string, string>;
38
38
  defaultDomainColor: string;
39
+ /** Status-based node colors for workflow visualization */
40
+ statusColors?: Record<NodeStatus, string>;
39
41
  edgeDefault: string;
40
42
  edgeActive: string;
41
43
  edgeSelected: string;
@@ -283,6 +285,8 @@ interface NeuronWebProps {
283
285
  nodes: NeuronVisualNode[];
284
286
  edges: NeuronVisualEdge[];
285
287
  storyBeats?: NeuronStoryBeat[];
288
+ /** Static cluster definitions for visual grouping */
289
+ clusters?: NeuronVisualCluster[];
286
290
  };
287
291
  fullHeight?: boolean;
288
292
  isFullScreen?: boolean;
@@ -1,7 +1,7 @@
1
- import { G as GraphStoreContext, N as NeuronConfig, a as GraphStore, E as EmbeddingProvider, S as SelectOptions, W as WhereClause, b as NeuronCluster, c as NeuronSettings, d as NeuronSettingsUpdate, A as AnalysisRun, e as SuggestedEdge, f as SuggestedEdgeCreate, g as SuggestedEdgeListParams, C as ConnectorType, I as IngestionSource, h as IngestionSourceItem, i as IngestionSyncRun, j as SyncRunStatus, k as GetGraphParams, l as ExpandGraphRequest, F as FindPathRequest, m as GetGraphResponse, n as ExpandGraphResponse, o as FindPathResponse } from '../query-helpers-DMnkjfO0.cjs';
2
- export { p as AnalysisRequest, q as AnalysisResponse, ac as ApiErrorResponse, T as ApproveSuggestionResponse, V as BulkApproveSuggestionsRequest, X as BulkApproveSuggestionsResponse, _ as BulkRejectSuggestionsRequest, $ as BulkRejectSuggestionsResponse, O as CancelAnalysisResponse, B as CreateEdgesRequest, H as CreateEdgesResponse, v as CreateNodesRequest, w as CreateNodesResponse, K as DeleteEdgeResponse, D as DeleteNodeResponse, a5 as FindSimilarOptions, a4 as FindSimilarRequest, a6 as FindSimilarResponse, M as GetAnalysisJobResponse, x as GetNodeResponse, a7 as GetSettingsResponse, t as GraphFilters, ad as HealthCheckResponse, y as ListEdgesParams, z as ListEdgesResponse, L as ListNodesParams, u as ListNodesResponse, Q as ListSuggestionsParams, R as ListSuggestionsResponse, s as PaginationMeta, r as PaginationParams, P as PostgresGraphStore, Y as RejectSuggestionRequest, Z as RejectSuggestionResponse, aa as ResetSettingsRequest, ab as ResetSettingsResponse, a3 as SearchResult, a1 as SemanticSearchOptions, a0 as SemanticSearchRequest, a2 as SemanticSearchResponse, J as UpdateEdgeRequest, U as UpdateNodeRequest, a8 as UpdateSettingsRequest, a9 as UpdateSettingsResponse } from '../query-helpers-DMnkjfO0.cjs';
1
+ import { G as GraphStoreContext, N as NeuronConfig, a as GraphStore, E as EmbeddingProvider, S as SelectOptions, W as WhereClause, b as NeuronSettings, c as NeuronSettingsUpdate, A as AnalysisRun, d as SuggestedEdge, e as SuggestedEdgeCreate, f as SuggestedEdgeListParams, C as ConnectorType, I as IngestionSource, g as IngestionSourceItem, h as IngestionSyncRun, i as SyncRunStatus, j as GetGraphParams, k as ExpandGraphRequest, F as FindPathRequest, l as GetGraphResponse, m as ExpandGraphResponse, n as FindPathResponse } from '../query-helpers-CA23s1ct.cjs';
2
+ export { o as AnalysisRequest, p as AnalysisResponse, ab as ApiErrorResponse, R as ApproveSuggestionResponse, T as BulkApproveSuggestionsRequest, V as BulkApproveSuggestionsResponse, Z as BulkRejectSuggestionsRequest, _ as BulkRejectSuggestionsResponse, M as CancelAnalysisResponse, z as CreateEdgesRequest, B as CreateEdgesResponse, u as CreateNodesRequest, v as CreateNodesResponse, J as DeleteEdgeResponse, D as DeleteNodeResponse, a4 as FindSimilarOptions, a3 as FindSimilarRequest, a5 as FindSimilarResponse, K as GetAnalysisJobResponse, w as GetNodeResponse, a6 as GetSettingsResponse, s as GraphFilters, ac as HealthCheckResponse, x as ListEdgesParams, y as ListEdgesResponse, L as ListNodesParams, t as ListNodesResponse, O as ListSuggestionsParams, Q as ListSuggestionsResponse, r as PaginationMeta, q as PaginationParams, P as PostgresGraphStore, X as RejectSuggestionRequest, Y as RejectSuggestionResponse, a9 as ResetSettingsRequest, aa as ResetSettingsResponse, a2 as SearchResult, a0 as SemanticSearchOptions, $ as SemanticSearchRequest, a1 as SemanticSearchResponse, H as UpdateEdgeRequest, U as UpdateNodeRequest, a7 as UpdateSettingsRequest, a8 as UpdateSettingsResponse } from '../query-helpers-CA23s1ct.cjs';
3
3
  import { D as Database } from '../database-B0vplyA4.cjs';
4
- import { b as NeuronNode, e as NeuronNodeCreate, f as NeuronNodeUpdate, c as NeuronEdge, g as NeuronEdgeCreate, h as NeuronEdgeUpdate } from '../edge-U2Qgwg-K.cjs';
4
+ import { c as NeuronNode, g as NeuronNodeCreate, i as NeuronNodeUpdate, d as NeuronEdge, j as NeuronEdgeCreate, k as NeuronEdgeUpdate, h as NeuronCluster } from '../cluster-CU_pBUcK.cjs';
5
5
  import 'pg';
6
6
 
7
7
  type RouteHandler = (request: Request) => Promise<Response>;
@@ -1,7 +1,7 @@
1
- import { G as GraphStoreContext, N as NeuronConfig, a as GraphStore, E as EmbeddingProvider, S as SelectOptions, W as WhereClause, b as NeuronCluster, c as NeuronSettings, d as NeuronSettingsUpdate, A as AnalysisRun, e as SuggestedEdge, f as SuggestedEdgeCreate, g as SuggestedEdgeListParams, C as ConnectorType, I as IngestionSource, h as IngestionSourceItem, i as IngestionSyncRun, j as SyncRunStatus, k as GetGraphParams, l as ExpandGraphRequest, F as FindPathRequest, m as GetGraphResponse, n as ExpandGraphResponse, o as FindPathResponse } from '../query-helpers-BpVwXZJk.js';
2
- export { p as AnalysisRequest, q as AnalysisResponse, ac as ApiErrorResponse, T as ApproveSuggestionResponse, V as BulkApproveSuggestionsRequest, X as BulkApproveSuggestionsResponse, _ as BulkRejectSuggestionsRequest, $ as BulkRejectSuggestionsResponse, O as CancelAnalysisResponse, B as CreateEdgesRequest, H as CreateEdgesResponse, v as CreateNodesRequest, w as CreateNodesResponse, K as DeleteEdgeResponse, D as DeleteNodeResponse, a5 as FindSimilarOptions, a4 as FindSimilarRequest, a6 as FindSimilarResponse, M as GetAnalysisJobResponse, x as GetNodeResponse, a7 as GetSettingsResponse, t as GraphFilters, ad as HealthCheckResponse, y as ListEdgesParams, z as ListEdgesResponse, L as ListNodesParams, u as ListNodesResponse, Q as ListSuggestionsParams, R as ListSuggestionsResponse, s as PaginationMeta, r as PaginationParams, P as PostgresGraphStore, Y as RejectSuggestionRequest, Z as RejectSuggestionResponse, aa as ResetSettingsRequest, ab as ResetSettingsResponse, a3 as SearchResult, a1 as SemanticSearchOptions, a0 as SemanticSearchRequest, a2 as SemanticSearchResponse, J as UpdateEdgeRequest, U as UpdateNodeRequest, a8 as UpdateSettingsRequest, a9 as UpdateSettingsResponse } from '../query-helpers-BpVwXZJk.js';
1
+ import { G as GraphStoreContext, N as NeuronConfig, a as GraphStore, E as EmbeddingProvider, S as SelectOptions, W as WhereClause, b as NeuronSettings, c as NeuronSettingsUpdate, A as AnalysisRun, d as SuggestedEdge, e as SuggestedEdgeCreate, f as SuggestedEdgeListParams, C as ConnectorType, I as IngestionSource, g as IngestionSourceItem, h as IngestionSyncRun, i as SyncRunStatus, j as GetGraphParams, k as ExpandGraphRequest, F as FindPathRequest, l as GetGraphResponse, m as ExpandGraphResponse, n as FindPathResponse } from '../query-helpers-CdDGFiK3.js';
2
+ export { o as AnalysisRequest, p as AnalysisResponse, ab as ApiErrorResponse, R as ApproveSuggestionResponse, T as BulkApproveSuggestionsRequest, V as BulkApproveSuggestionsResponse, Z as BulkRejectSuggestionsRequest, _ as BulkRejectSuggestionsResponse, M as CancelAnalysisResponse, z as CreateEdgesRequest, B as CreateEdgesResponse, u as CreateNodesRequest, v as CreateNodesResponse, J as DeleteEdgeResponse, D as DeleteNodeResponse, a4 as FindSimilarOptions, a3 as FindSimilarRequest, a5 as FindSimilarResponse, K as GetAnalysisJobResponse, w as GetNodeResponse, a6 as GetSettingsResponse, s as GraphFilters, ac as HealthCheckResponse, x as ListEdgesParams, y as ListEdgesResponse, L as ListNodesParams, t as ListNodesResponse, O as ListSuggestionsParams, Q as ListSuggestionsResponse, r as PaginationMeta, q as PaginationParams, P as PostgresGraphStore, X as RejectSuggestionRequest, Y as RejectSuggestionResponse, a9 as ResetSettingsRequest, aa as ResetSettingsResponse, a2 as SearchResult, a0 as SemanticSearchOptions, $ as SemanticSearchRequest, a1 as SemanticSearchResponse, H as UpdateEdgeRequest, U as UpdateNodeRequest, a7 as UpdateSettingsRequest, a8 as UpdateSettingsResponse } from '../query-helpers-CdDGFiK3.js';
3
3
  import { D as Database } from '../database-B0vplyA4.js';
4
- import { b as NeuronNode, e as NeuronNodeCreate, f as NeuronNodeUpdate, c as NeuronEdge, g as NeuronEdgeCreate, h as NeuronEdgeUpdate } from '../edge-U2Qgwg-K.js';
4
+ import { c as NeuronNode, g as NeuronNodeCreate, i as NeuronNodeUpdate, d as NeuronEdge, j as NeuronEdgeCreate, k as NeuronEdgeUpdate, h as NeuronCluster } from '../cluster-CU_pBUcK.js';
5
5
  import 'pg';
6
6
 
7
7
  type RouteHandler = (request: Request) => Promise<Response>;