@ltm-blueverse/alpha-semantic-hub 0.7.0

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.
Files changed (146) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1674 -0
  3. package/explorer/README.md +282 -0
  4. package/explorer/src/App.css +0 -0
  5. package/explorer/src/App.tsx +2035 -0
  6. package/explorer/src/ErrorBoundary.tsx +112 -0
  7. package/explorer/src/ExploreWorkspaceTabs.tsx +29 -0
  8. package/explorer/src/assets/hero.png +0 -0
  9. package/explorer/src/assets/react.svg +1 -0
  10. package/explorer/src/assets/vite.svg +1 -0
  11. package/explorer/src/explorerCapabilities.ts +24 -0
  12. package/explorer/src/index.css +71 -0
  13. package/explorer/src/main.tsx +7 -0
  14. package/explorer/src/store/edgePairKeys.d.ts +2 -0
  15. package/explorer/src/store/edgePairKeys.js +7 -0
  16. package/explorer/src/store/graphStore.ts +183 -0
  17. package/explorer/src/store/registryStore.ts +78 -0
  18. package/explorer/src/types.d.ts +16 -0
  19. package/explorer/src/ui/primitives.css +414 -0
  20. package/explorer/src/ui/primitives.tsx +170 -0
  21. package/explorer/src/workspaces/DecisionWorkspace/DecisionWorkspace.tsx +279 -0
  22. package/explorer/src/workspaces/DiffMergeWorkspace/DiffMergeWorkspace.tsx +121 -0
  23. package/explorer/src/workspaces/EnrichWorkspace/EntityResolutionTab.tsx +454 -0
  24. package/explorer/src/workspaces/EnrichWorkspace/RegistryTab.tsx +285 -0
  25. package/explorer/src/workspaces/GraphWorkspace/GraphCanvas.tsx +2673 -0
  26. package/explorer/src/workspaces/GraphWorkspace/GraphInspectorPanel.tsx +771 -0
  27. package/explorer/src/workspaces/GraphWorkspace/GraphLoadingOverlay.tsx +410 -0
  28. package/explorer/src/workspaces/GraphWorkspace/GraphWorkspace.tsx +3584 -0
  29. package/explorer/src/workspaces/GraphWorkspace/MarkdownContentViewer.tsx +705 -0
  30. package/explorer/src/workspaces/GraphWorkspace/SigmaSceneAdapter.tsx +55 -0
  31. package/explorer/src/workspaces/GraphWorkspace/TimelinePanel.tsx +193 -0
  32. package/explorer/src/workspaces/GraphWorkspace/behaviors/clickSelectionBehavior.ts +29 -0
  33. package/explorer/src/workspaces/GraphWorkspace/behaviors/fitViewBehavior.ts +15 -0
  34. package/explorer/src/workspaces/GraphWorkspace/behaviors/focusCameraBehavior.ts +25 -0
  35. package/explorer/src/workspaces/GraphWorkspace/behaviors/hoverActivationBehavior.ts +15 -0
  36. package/explorer/src/workspaces/GraphWorkspace/behaviors/pathHighlightBehavior.ts +52 -0
  37. package/explorer/src/workspaces/GraphWorkspace/behaviors/searchFocusBehavior.ts +36 -0
  38. package/explorer/src/workspaces/GraphWorkspace/behaviors/types.ts +41 -0
  39. package/explorer/src/workspaces/GraphWorkspace/behaviors/viewModeSwitchBehavior.ts +29 -0
  40. package/explorer/src/workspaces/GraphWorkspace/graphAnalytics.ts +779 -0
  41. package/explorer/src/workspaces/GraphWorkspace/graphColorLegend.ts +36 -0
  42. package/explorer/src/workspaces/GraphWorkspace/graphConfig.ts +102 -0
  43. package/explorer/src/workspaces/GraphWorkspace/graphEntityShape.ts +34 -0
  44. package/explorer/src/workspaces/GraphWorkspace/graphLoading.ts +84 -0
  45. package/explorer/src/workspaces/GraphWorkspace/graphSceneLayers.ts +775 -0
  46. package/explorer/src/workspaces/GraphWorkspace/graphSceneState.ts +2753 -0
  47. package/explorer/src/workspaces/GraphWorkspace/graphStructureLayer.ts +335 -0
  48. package/explorer/src/workspaces/GraphWorkspace/graphTheme.ts +1078 -0
  49. package/explorer/src/workspaces/GraphWorkspace/graphViewCopy.ts +41 -0
  50. package/explorer/src/workspaces/GraphWorkspace/localGraphTransition.ts +9 -0
  51. package/explorer/src/workspaces/GraphWorkspace/markdownEditorState.ts +114 -0
  52. package/explorer/src/workspaces/GraphWorkspace/markdownResourceClient.ts +103 -0
  53. package/explorer/src/workspaces/GraphWorkspace/markdownUrlSafety.ts +29 -0
  54. package/explorer/src/workspaces/GraphWorkspace/nodeMarkdownSync.ts +81 -0
  55. package/explorer/src/workspaces/GraphWorkspace/pluginRegistryPredicates.ts +24 -0
  56. package/explorer/src/workspaces/GraphWorkspace/plugins/explorationEffectsPlugin.tsx +353 -0
  57. package/explorer/src/workspaces/GraphWorkspace/plugins/explorationEffectsPluginPhaseC.tsx +522 -0
  58. package/explorer/src/workspaces/GraphWorkspace/plugins/index.ts +16 -0
  59. package/explorer/src/workspaces/GraphWorkspace/plugins/legendPlugin.tsx +120 -0
  60. package/explorer/src/workspaces/GraphWorkspace/plugins/neighborhoodPanelPlugin.tsx +231 -0
  61. package/explorer/src/workspaces/GraphWorkspace/plugins/temporalOverlayPlugin.tsx +142 -0
  62. package/explorer/src/workspaces/GraphWorkspace/plugins/types.ts +106 -0
  63. package/explorer/src/workspaces/GraphWorkspace/realtimeGraphAttributes.ts +50 -0
  64. package/explorer/src/workspaces/GraphWorkspace/scene.ts +79 -0
  65. package/explorer/src/workspaces/GraphWorkspace/sigmaNativeRendering.ts +421 -0
  66. package/explorer/src/workspaces/GraphWorkspace/smallGraphLayout.ts +135 -0
  67. package/explorer/src/workspaces/GraphWorkspace/temporalLifecyclePredicates.ts +31 -0
  68. package/explorer/src/workspaces/GraphWorkspace/temporalScrubberBounds.ts +46 -0
  69. package/explorer/src/workspaces/GraphWorkspace/temporalSnapshotGuards.ts +113 -0
  70. package/explorer/src/workspaces/GraphWorkspace/types.ts +395 -0
  71. package/explorer/src/workspaces/GraphWorkspace/useLoadGraph.ts +746 -0
  72. package/explorer/src/workspaces/GraphWorkspace/useMarkdownEditor.ts +177 -0
  73. package/explorer/src/workspaces/ImportExportWorkspace/ImportExportWorkspace.tsx +196 -0
  74. package/explorer/src/workspaces/LineageWorkspace/LineageDiagram.tsx +177 -0
  75. package/explorer/src/workspaces/ManageWorkspace/KGOverviewTab.tsx +291 -0
  76. package/explorer/src/workspaces/ManageWorkspace/OntologySummaryTab.tsx +346 -0
  77. package/explorer/src/workspaces/MemoryWorkspace.tsx +464 -0
  78. package/explorer/src/workspaces/OntologyWorkspace/AlignmentsTab.tsx +437 -0
  79. package/explorer/src/workspaces/OntologyWorkspace/HealthTab.tsx +214 -0
  80. package/explorer/src/workspaces/OntologyWorkspace/OntologyEditor.tsx +770 -0
  81. package/explorer/src/workspaces/OntologyWorkspace/OntologyLoader.tsx +913 -0
  82. package/explorer/src/workspaces/OntologyWorkspace/OntologyManager.tsx +930 -0
  83. package/explorer/src/workspaces/OntologyWorkspace/OntologySearch.tsx +590 -0
  84. package/explorer/src/workspaces/OntologyWorkspace/ProposalReview.tsx +429 -0
  85. package/explorer/src/workspaces/OntologyWorkspace/SKOSVocabularyManager.tsx +696 -0
  86. package/explorer/src/workspaces/OntologyWorkspace/ShaclStudio.tsx +363 -0
  87. package/explorer/src/workspaces/OntologyWorkspace/VersionsTab.tsx +546 -0
  88. package/explorer/src/workspaces/OntologyWorkspace/api.ts +164 -0
  89. package/explorer/src/workspaces/OntologyWorkspace/index.tsx +101 -0
  90. package/explorer/src/workspaces/OntologyWorkspace/ontologyEditorModel.ts +87 -0
  91. package/explorer/src/workspaces/OntologyWorkspace/ontologyUrlState.ts +94 -0
  92. package/explorer/src/workspaces/OntologyWorkspace/types.ts +119 -0
  93. package/explorer/src/workspaces/ReasoningWorkspace.tsx +243 -0
  94. package/explorer/src/workspaces/SparqlWorkspace/SparqlWorkspace.tsx +271 -0
  95. package/explorer/src/workspaces/VocabularyWorkspace/ConceptTree.tsx +97 -0
  96. package/explorer/src/workspaces/VocabularyWorkspace/ImportDropzone.tsx +95 -0
  97. package/explorer/src/workspaces/VocabularyWorkspace/PropertyPanel.tsx +116 -0
  98. package/explorer/src/workspaces/VocabularyWorkspace/Sidebar.tsx +112 -0
  99. package/explorer/src/workspaces/VocabularyWorkspace/VocabularyWorkspace.tsx +70 -0
  100. package/explorer/src/workspaces/VocabularyWorkspace/queries.ts +52 -0
  101. package/explorer/src/workspaces/VocabularyWorkspace/types.ts +24 -0
  102. package/package.json +31 -0
  103. package/plugins/.claude-plugin/README.md +262 -0
  104. package/plugins/.claude-plugin/marketplace.json +20 -0
  105. package/plugins/.claude-plugin/plugin.json +33 -0
  106. package/plugins/.cline-plugin/README.md +32 -0
  107. package/plugins/.cline-plugin/marketplace.json +17 -0
  108. package/plugins/.cline-plugin/plugin.json +35 -0
  109. package/plugins/.codex-plugin/marketplace.json +21 -0
  110. package/plugins/.codex-plugin/plugin.json +35 -0
  111. package/plugins/.continue-plugin/README.md +34 -0
  112. package/plugins/.continue-plugin/marketplace.json +17 -0
  113. package/plugins/.continue-plugin/plugin.json +33 -0
  114. package/plugins/.cursor-plugin/marketplace.json +18 -0
  115. package/plugins/.cursor-plugin/plugin.json +32 -0
  116. package/plugins/.openclaw-plugin/README.md +62 -0
  117. package/plugins/.openclaw-plugin/marketplace.json +18 -0
  118. package/plugins/.openclaw-plugin/plugin.json +46 -0
  119. package/plugins/.pi-plugin/README.md +35 -0
  120. package/plugins/.vscode-plugin/README.md +48 -0
  121. package/plugins/.vscode-plugin/marketplace.json +17 -0
  122. package/plugins/.vscode-plugin/plugin.json +35 -0
  123. package/plugins/.windsurf-plugin/README.md +39 -0
  124. package/plugins/.windsurf-plugin/marketplace.json +17 -0
  125. package/plugins/.windsurf-plugin/plugin.json +35 -0
  126. package/plugins/agents/decision-advisor.md +126 -0
  127. package/plugins/agents/explainability.md +129 -0
  128. package/plugins/agents/kg-assistant.md +73 -0
  129. package/plugins/hooks/hooks.json +12 -0
  130. package/plugins/skills/causal/SKILL.md +74 -0
  131. package/plugins/skills/change/SKILL.md +80 -0
  132. package/plugins/skills/decision/SKILL.md +197 -0
  133. package/plugins/skills/deduplicate/SKILL.md +41 -0
  134. package/plugins/skills/embed/SKILL.md +230 -0
  135. package/plugins/skills/explain/SKILL.md +44 -0
  136. package/plugins/skills/export/SKILL.md +67 -0
  137. package/plugins/skills/extract/SKILL.md +93 -0
  138. package/plugins/skills/ingest/SKILL.md +38 -0
  139. package/plugins/skills/ontology/SKILL.md +89 -0
  140. package/plugins/skills/policy/SKILL.md +66 -0
  141. package/plugins/skills/provenance/SKILL.md +70 -0
  142. package/plugins/skills/query/SKILL.md +84 -0
  143. package/plugins/skills/reason/SKILL.md +201 -0
  144. package/plugins/skills/temporal/SKILL.md +164 -0
  145. package/plugins/skills/validate/SKILL.md +228 -0
  146. package/plugins/skills/visualize/SKILL.md +249 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * ImportDropzone.tsx
3
+ *
4
+ * Drag & drop upload zone for SKOS .ttl / .rdf files.
5
+ * Styled for the Palantir dark theme.
6
+ */
7
+ import React, { useCallback, useState } from 'react';
8
+ import { useDropzone } from 'react-dropzone';
9
+ import { UploadCloud, CheckCircle2, Loader2 } from 'lucide-react';
10
+ import { useImportVocabulary } from './queries';
11
+ import type { ImportResponse } from './types';
12
+
13
+ export const ImportDropzone: React.FC = () => {
14
+ const [file, setFile] = useState<File | null>(null);
15
+ const [importResult, setImportResult] = useState<ImportResponse | null>(null);
16
+ const importMutation = useImportVocabulary();
17
+
18
+ const onDrop = useCallback((acceptedFiles: File[]) => {
19
+ if (acceptedFiles.length > 0) {
20
+ const selectedFile = acceptedFiles[0];
21
+ setFile(selectedFile);
22
+ setImportResult(null);
23
+
24
+ importMutation.mutate(selectedFile, {
25
+ onSuccess: (data) => {
26
+ setImportResult(data);
27
+ setTimeout(() => {
28
+ setFile(null);
29
+ setImportResult(null);
30
+ }, 4000);
31
+ },
32
+ onError: (err) => {
33
+ console.error("Upload failed:", err);
34
+ setFile(null);
35
+ }
36
+ });
37
+ }
38
+ }, [importMutation]);
39
+
40
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({
41
+ onDrop,
42
+ accept: {
43
+ 'text/turtle': ['.ttl'],
44
+ 'application/rdf+xml': ['.rdf', '.owl']
45
+ },
46
+ maxFiles: 1
47
+ });
48
+
49
+ return (
50
+ <div>
51
+ <div
52
+ {...getRootProps()}
53
+ style={{
54
+ border: `2px dashed ${isDragActive ? '#ff2d4b' : 'rgba(255,45,75,0.25)'}`,
55
+ backgroundColor: isDragActive ? 'rgba(255,45,75,0.06)' : 'rgba(0,0,0,0.2)',
56
+ borderRadius: 8,
57
+ padding: '16px 12px',
58
+ textAlign: 'center',
59
+ cursor: 'pointer',
60
+ transition: 'all 0.2s ease',
61
+ }}
62
+ >
63
+ <input {...getInputProps()} />
64
+
65
+ {importMutation.isPending ? (
66
+ <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', color: '#b08b93' }}>
67
+ <Loader2 className="animate-spin" size={20} style={{ marginBottom: 6 }} />
68
+ <span style={{ fontSize: 12 }}>Uploading {file?.name}…</span>
69
+ </div>
70
+ ) : importResult ? (
71
+ <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', color: '#3fb950' }}>
72
+ <CheckCircle2 size={20} style={{ marginBottom: 6 }} />
73
+ <span style={{ fontSize: 12, fontWeight: 500 }}>Import Successful!</span>
74
+ <span style={{ fontSize: 11, marginTop: 2, color: '#43d17a' }}>
75
+ +{importResult.nodes_added} concepts · +{importResult.edges_added} links
76
+ </span>
77
+ </div>
78
+ ) : (
79
+ <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', color: '#b08b93' }}>
80
+ <UploadCloud size={20} style={{ marginBottom: 6, color: isDragActive ? '#ff2d4b' : '#484f58' }} />
81
+ <span style={{ fontSize: 12, fontWeight: 500, color: '#e8ccd1' }}>
82
+ {isDragActive ? "Drop here…" : "Import Vocabulary"}
83
+ </span>
84
+ <span style={{ fontSize: 11, marginTop: 2 }}>.ttl or .rdf</span>
85
+ </div>
86
+ )}
87
+ </div>
88
+ {importMutation.isError && (
89
+ <p style={{ color: '#f85149', fontSize: 11, marginTop: 6, textAlign: 'center' }}>
90
+ Upload failed. Check console.
91
+ </p>
92
+ )}
93
+ </div>
94
+ );
95
+ };
@@ -0,0 +1,116 @@
1
+ /**
2
+ * src/workspaces/VocabularyWorkspace/PropertyPanel.tsx
3
+ *
4
+ * Detail panel for a selected SKOS concept — shows preferred label,
5
+ * URI, alt labels, and description.
6
+ */
7
+ import type { ConceptNode } from './types';
8
+
9
+ interface PropertyPanelProps {
10
+ concept: ConceptNode | null;
11
+ }
12
+
13
+ export function PropertyPanel({ concept }: PropertyPanelProps) {
14
+ if (!concept) {
15
+ return (
16
+ <div style={{
17
+ display: 'flex', flexDirection: 'column', alignItems: 'center',
18
+ justifyContent: 'center', height: '100%', color: '#b08b93',
19
+ textAlign: 'center', padding: 40,
20
+ }}>
21
+ <svg width="48" height="48" viewBox="0 0 24 24" fill="none"
22
+ stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"
23
+ strokeLinejoin="round" style={{ marginBottom: 16, opacity: 0.4 }}>
24
+ <path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20" />
25
+ </svg>
26
+ <p style={{ fontSize: 15, fontWeight: 500, marginBottom: 4 }}>No concept selected</p>
27
+ <p style={{ fontSize: 13 }}>Click a concept in the tree to view its properties.</p>
28
+ </div>
29
+ );
30
+ }
31
+
32
+ return (
33
+ <div style={{ padding: 28, overflowY: 'auto', height: '100%' }}>
34
+ {/* Header */}
35
+ <div style={{ borderBottom: '1px solid rgba(255,45,75,0.2)', paddingBottom: 20, marginBottom: 24 }}>
36
+ <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8 }}>
37
+ <span style={{
38
+ display: 'inline-block', width: 8, height: 8, borderRadius: '50%',
39
+ background: '#d2a8ff', boxShadow: '0 0 8px rgba(210,168,255,0.6)',
40
+ }} />
41
+ <span style={{ color: '#d2a8ff', fontSize: 12, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em' }}>
42
+ SKOS Concept
43
+ </span>
44
+ </div>
45
+ <h2 style={{ margin: 0, color: '#fff', fontSize: 22, fontWeight: 700, wordBreak: 'break-word' }}>
46
+ {concept.pref_label}
47
+ </h2>
48
+ </div>
49
+
50
+ {/* URI Badge */}
51
+ <div style={{
52
+ marginBottom: 20, padding: '8px 14px',
53
+ background: 'rgba(255,45,75,0.08)',
54
+ border: '1px solid rgba(255,45,75,0.2)',
55
+ borderRadius: 6, fontSize: 13, color: '#ff8fa0',
56
+ fontFamily: "'JetBrains Mono', monospace",
57
+ wordBreak: 'break-all',
58
+ }}>
59
+ {concept.uri}
60
+ </div>
61
+
62
+ {/* Alt Labels */}
63
+ {concept.alt_labels && concept.alt_labels.length > 0 && (
64
+ <section style={{ marginBottom: 24 }}>
65
+ <h4 style={{
66
+ color: '#b08b93', fontSize: 12, textTransform: 'uppercase',
67
+ letterSpacing: '0.08em', marginBottom: 10,
68
+ }}>
69
+ Alternative Labels
70
+ </h4>
71
+ <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
72
+ {concept.alt_labels.map((lbl, i) => (
73
+ <span key={i} style={{
74
+ background: '#21262d', color: '#e8ccd1',
75
+ padding: '4px 10px', borderRadius: 4, fontSize: 13,
76
+ border: '1px solid rgba(255,255,255,0.06)',
77
+ }}>
78
+ {lbl}
79
+ </span>
80
+ ))}
81
+ </div>
82
+ </section>
83
+ )}
84
+
85
+ {/* Children summary */}
86
+ <section style={{
87
+ background: 'rgba(0,0,0,0.2)', padding: 16, borderRadius: 8,
88
+ border: '1px solid rgba(255,255,255,0.05)',
89
+ }}>
90
+ <h4 style={{
91
+ color: '#b08b93', fontSize: 12, textTransform: 'uppercase',
92
+ letterSpacing: '0.08em', marginBottom: 10,
93
+ }}>
94
+ Narrower Concepts
95
+ </h4>
96
+ {concept.children && concept.children.length > 0 ? (
97
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
98
+ {concept.children.map((child) => (
99
+ <span key={child.uri} style={{
100
+ color: '#e8ccd1', fontSize: 13, padding: '6px 10px',
101
+ background: 'rgba(255,45,75,0.06)', borderRadius: 4,
102
+ border: '1px solid rgba(255,45,75,0.12)',
103
+ }}>
104
+ {child.pref_label}
105
+ </span>
106
+ ))}
107
+ </div>
108
+ ) : (
109
+ <p style={{ margin: 0, color: '#484f58', fontStyle: 'italic', fontSize: 13 }}>
110
+ Leaf concept — no narrower concepts.
111
+ </p>
112
+ )}
113
+ </section>
114
+ </div>
115
+ );
116
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * src/workspaces/VocabularyWorkspace/Sidebar.tsx
3
+ *
4
+ * Left sidebar for the Vocabulary workspace.
5
+ * - Lists available SKOS ConceptSchemes
6
+ * - Shows the concept hierarchy tree for the active scheme
7
+ * - Includes the import dropzone
8
+ */
9
+ import { useState } from 'react';
10
+ import { useVocabularies, useConceptHierarchy } from './queries';
11
+ import { ConceptTree } from './ConceptTree';
12
+ import { ImportDropzone } from './ImportDropzone';
13
+ import type { ConceptNode, VocabularyScheme } from './types';
14
+
15
+ interface SidebarProps {
16
+ onSelectConcept: (concept: ConceptNode) => void;
17
+ }
18
+
19
+ export function Sidebar({ onSelectConcept }: SidebarProps) {
20
+ const { data: schemes = [], isLoading: schemesLoading } = useVocabularies();
21
+ const [activeScheme, setActiveScheme] = useState<string | undefined>();
22
+
23
+ // Auto-select first scheme
24
+ const selectedSchemeUri = activeScheme ?? schemes[0]?.uri;
25
+
26
+ const {
27
+ data: hierarchy = [],
28
+ isLoading: treeLoading,
29
+ } = useConceptHierarchy(selectedSchemeUri);
30
+
31
+ return (
32
+ <div style={{
33
+ width: 340, display: 'flex', flexDirection: 'column',
34
+ borderRight: '1px solid rgba(255,45,75,0.15)',
35
+ backgroundColor: '#010409', overflow: 'hidden',
36
+ }}>
37
+ {/* Header */}
38
+ <div style={{
39
+ padding: '20px 20px 16px',
40
+ borderBottom: '1px solid rgba(255,45,75,0.15)',
41
+ }}>
42
+ <h2 style={{ fontSize: 18, color: '#e8ccd1', margin: '0 0 4px 0', fontWeight: 600 }}>
43
+ Ontology & Vocabulary
44
+ </h2>
45
+ <p style={{ color: '#b08b93', fontSize: 13, margin: 0 }}>
46
+ {schemes.length
47
+ ? `${schemes.length} vocabulary scheme${schemes.length > 1 ? 's' : ''}`
48
+ : 'No vocabularies loaded'}
49
+ </p>
50
+ </div>
51
+
52
+ {/* Scheme selector */}
53
+ <div style={{ padding: '12px 16px', borderBottom: '1px solid rgba(255,45,75,0.1)' }}>
54
+ {schemesLoading ? (
55
+ <div style={{ color: '#b08b93', fontSize: 13 }}>Loading schemes…</div>
56
+ ) : schemes.length === 0 ? (
57
+ <div style={{ color: '#484f58', fontSize: 13, fontStyle: 'italic' }}>
58
+ No schemes found. Import a .ttl or .rdf file below.
59
+ </div>
60
+ ) : (
61
+ <select
62
+ value={selectedSchemeUri || ''}
63
+ onChange={(e) => setActiveScheme(e.target.value)}
64
+ style={{
65
+ width: '100%', appearance: 'none',
66
+ background: 'rgba(0,0,0,0.3)',
67
+ border: '1px solid rgba(255,45,75,0.2)',
68
+ color: '#e8ccd1', padding: '8px 12px',
69
+ borderRadius: 6, fontSize: 13, cursor: 'pointer',
70
+ outline: 'none',
71
+ }}
72
+ >
73
+ {schemes.map((s: VocabularyScheme) => (
74
+ <option key={s.uri} value={s.uri} style={{ background: '#0a0508' }}>
75
+ {s.label}
76
+ </option>
77
+ ))}
78
+ </select>
79
+ )}
80
+ </div>
81
+
82
+ {/* Concept Tree */}
83
+ <div style={{
84
+ flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column',
85
+ }}>
86
+ {treeLoading ? (
87
+ <div style={{ padding: 20, color: '#b08b93', fontSize: 13, textAlign: 'center' }}>
88
+ Loading hierarchy…
89
+ </div>
90
+ ) : hierarchy.length === 0 ? (
91
+ <div style={{ padding: 20, color: '#484f58', fontSize: 13, textAlign: 'center', fontStyle: 'italic' }}>
92
+ {selectedSchemeUri
93
+ ? 'No concepts found in this scheme.'
94
+ : 'Select a scheme to browse concepts.'}
95
+ </div>
96
+ ) : (
97
+ <div style={{ flex: 1, overflow: 'hidden' }}>
98
+ <ConceptTree data={hierarchy} onSelectConcept={onSelectConcept} />
99
+ </div>
100
+ )}
101
+ </div>
102
+
103
+ {/* Import area */}
104
+ <div style={{
105
+ padding: '12px 16px',
106
+ borderTop: '1px solid rgba(255,45,75,0.15)',
107
+ }}>
108
+ <ImportDropzone />
109
+ </div>
110
+ </div>
111
+ );
112
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * src/workspaces/VocabularyWorkspace/VocabularyWorkspace.tsx
3
+ *
4
+ * Main Vocabulary workspace — composes the Sidebar (scheme list + tree + import)
5
+ * and the PropertyPanel (concept details) into a responsive two-column layout.
6
+ *
7
+ * All data fetching is handled by TanStack Query hooks in `queries.ts`.
8
+ */
9
+ import { useState } from 'react';
10
+ import { Sidebar } from './Sidebar';
11
+ import { PropertyPanel } from './PropertyPanel';
12
+ import type { ConceptNode } from './types';
13
+
14
+ const THEME_CSS = `
15
+ .vocab-workspace {
16
+ display: flex;
17
+ width: 100%;
18
+ height: 100%;
19
+ background: #0a0508;
20
+ overflow: hidden;
21
+ }
22
+ .vocab-main {
23
+ flex: 1;
24
+ display: flex;
25
+ flex-direction: column;
26
+ position: relative;
27
+ overflow: hidden;
28
+ }
29
+ .vocab-main-content {
30
+ flex: 1;
31
+ overflow-y: auto;
32
+ }
33
+ .vocab-detail-glass {
34
+ background: linear-gradient(135deg, rgba(13,17,23,0.75), rgba(22,27,34,0.6));
35
+ backdrop-filter: blur(16px) saturate(1.2);
36
+ -webkit-backdrop-filter: blur(16px) saturate(1.2);
37
+ border: 1px solid rgba(255,45,75,0.15);
38
+ box-shadow: 0 8px 32px rgba(0,0,0,0.5), inset 1px 1px 0 rgba(255,255,255,0.04);
39
+ border-radius: 14px;
40
+ height: 100%;
41
+ }
42
+ `;
43
+
44
+ export function VocabularyWorkspace() {
45
+ const [selectedConcept, setSelectedConcept] = useState<ConceptNode | null>(null);
46
+
47
+ return (
48
+ <div className="vocab-workspace">
49
+ <style>{THEME_CSS}</style>
50
+
51
+ {/* Left: Sidebar with scheme list + concept tree + import */}
52
+ <Sidebar onSelectConcept={setSelectedConcept} />
53
+
54
+ {/* Right: Concept detail panel */}
55
+ <div className="vocab-main">
56
+ {/* Decorative background gradient */}
57
+ <div style={{
58
+ position: 'absolute', inset: 0, pointerEvents: 'none',
59
+ background: 'radial-gradient(ellipse at top right, rgba(210,168,255,0.04), transparent 60%)',
60
+ }} />
61
+
62
+ <div className="vocab-main-content" style={{ padding: 32 }}>
63
+ <div className="vocab-detail-glass">
64
+ <PropertyPanel concept={selectedConcept} />
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </div>
69
+ );
70
+ }
@@ -0,0 +1,52 @@
1
+ // queries.ts
2
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
3
+ import type { VocabularyScheme, ConceptNode, ImportResponse } from './types';
4
+
5
+ const fetchSchemes = async (): Promise<VocabularyScheme[]> => {
6
+ const res = await fetch('/api/vocabulary/schemes');
7
+ if (!res.ok) throw new Error('Failed to fetch vocabularies');
8
+ return res.json();
9
+ };
10
+
11
+ const fetchHierarchy = async (schemeUri: string): Promise<ConceptNode[]> => {
12
+ const res = await fetch(`/api/vocabulary/hierarchy?scheme=${encodeURIComponent(schemeUri)}`);
13
+ if (!res.ok) throw new Error('Failed to fetch hierarchy');
14
+ return res.json();
15
+ };
16
+
17
+ // Updated to return the ImportResponse
18
+ const importVocabulary = async (file: File): Promise<ImportResponse> => {
19
+ const formData = new FormData();
20
+ formData.append('file', file);
21
+ const res = await fetch('/api/vocabulary/import', {
22
+ method: 'POST',
23
+ body: formData,
24
+ });
25
+ if (!res.ok) throw new Error('Failed to import vocabulary');
26
+ return res.json();
27
+ };
28
+
29
+ export const useVocabularies = () => {
30
+ return useQuery({
31
+ queryKey: ['vocabularies'],
32
+ queryFn: fetchSchemes
33
+ });
34
+ };
35
+
36
+ export const useConceptHierarchy = (schemeUri: string | undefined) => {
37
+ return useQuery({
38
+ queryKey: ['hierarchy', schemeUri],
39
+ queryFn: () => fetchHierarchy(schemeUri!),
40
+ enabled: !!schemeUri,
41
+ });
42
+ };
43
+
44
+ export const useImportVocabulary = () => {
45
+ const queryClient = useQueryClient();
46
+ return useMutation({
47
+ mutationFn: importVocabulary,
48
+ onSuccess: () => {
49
+ queryClient.invalidateQueries({ queryKey: ['vocabularies'] });
50
+ },
51
+ });
52
+ };
@@ -0,0 +1,24 @@
1
+ export interface VocabularyScheme {
2
+ uri: string;
3
+ label: string;
4
+ description?: string;
5
+ }
6
+
7
+ export interface ConceptNode {
8
+ uri: string;
9
+ pref_label: string;
10
+ alt_labels: string[];
11
+ description?: string;
12
+ notation?: string;
13
+ scheme_uri?: string;
14
+ parent_uri?: string;
15
+ children?: ConceptNode[] | null;
16
+ }
17
+
18
+ export interface ImportResponse {
19
+ status: string;
20
+ filename?: string | null;
21
+ nodes_added: number;
22
+ edges_added: number;
23
+ format?: string;
24
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@ltm-blueverse/alpha-semantic-hub",
3
+ "version": "0.7.0",
4
+ "description": "Alpha Semantic Hub \u2014 Graph-Native Infrastructure for Context and Accountable AI Systems",
5
+ "keywords": [
6
+ "alpha-semantic-hub",
7
+ "pi-package",
8
+ "knowledge graph",
9
+ "context graphs",
10
+ "decision intelligence",
11
+ "mcp"
12
+ ],
13
+ "license": "MIT",
14
+ "repository": "github:DeejayAI/alpha-semantic-hub",
15
+ "pi": {
16
+ "skills": [
17
+ "plugins/skills"
18
+ ]
19
+ },
20
+ "author": "LTM Blueverse <deejay@ltmb.io>",
21
+ "files": [
22
+ "plugins",
23
+ "explorer/src",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org/"
30
+ }
31
+ }