@coreason-ai/sensory-core 1.0.3 → 1.1.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.
- package/dist/components/ConformanceGuillotine.d.ts +11 -0
- package/dist/components/ConformanceGuillotine.js +69 -0
- package/dist/components/SVIDBadge.d.ts +12 -0
- package/dist/components/SVIDBadge.js +133 -0
- package/dist/components/StatusPulse.d.ts +1 -1
- package/dist/components/StatusPulse.js +10 -8
- package/dist/components/ThermodynamicGovernor.d.ts +2 -1
- package/dist/components/ThermodynamicGovernor.js +32 -12
- package/dist/components/TopologicalCanvas.d.ts +1 -1
- package/dist/components/TopologicalCanvas.js +139 -11
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ConformanceGuillotineProps {
|
|
3
|
+
nodeId: string;
|
|
4
|
+
errorName?: string;
|
|
5
|
+
panicMessage: string;
|
|
6
|
+
backtrace: string;
|
|
7
|
+
onClose?: () => void;
|
|
8
|
+
onRecover?: () => void;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const ConformanceGuillotine: React.FC<ConformanceGuillotineProps>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Copyright (c) 2026 CoReason, Inc
|
|
2
|
+
//
|
|
3
|
+
// This software is proprietary and dual-licensed
|
|
4
|
+
// Licensed under the Prosperity Public License 3.0 (the "License")
|
|
5
|
+
// A copy of the license is available at <https://prosperitylicense.com/versions/3.0.0>
|
|
6
|
+
// For details, see the LICENSE file
|
|
7
|
+
// Commercial use beyond a 30-day trial requires a separate license
|
|
8
|
+
//
|
|
9
|
+
// Source Code: <https://github.com/CoReason-AI/coreason-sensory-core>
|
|
10
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
11
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
12
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
13
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
14
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
15
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
16
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
import React, { useState } from 'react';
|
|
20
|
+
import { GlassBox } from './GlassBox';
|
|
21
|
+
import { AlertOctagon, Terminal, Copy, Check, RefreshCw, X } from 'lucide-react';
|
|
22
|
+
export const ConformanceGuillotine = ({ nodeId, errorName = 'ManifestConformanceError', panicMessage, backtrace, onClose, onRecover, className }) => {
|
|
23
|
+
const [copied, setCopied] = useState(false);
|
|
24
|
+
const handleCopy = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
try {
|
|
26
|
+
yield navigator.clipboard.writeText(`${errorName} in node [${nodeId}]:\n${panicMessage}\n\nStack Trace:\n${backtrace}`);
|
|
27
|
+
setCopied(true);
|
|
28
|
+
setTimeout(() => setCopied(false), 2000);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
console.error('Failed to copy panic diagnostic details', err);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return (React.createElement(GlassBox, { density: "dense", className: `border border-red-900/60 shadow-[0_12px_48px_rgba(255,0,0,0.15)] bg-[rgba(15,5,5,0.9)] max-w-2xl w-full ${className || ''}` },
|
|
35
|
+
React.createElement("div", { className: "flex flex-col space-y-4 font-mono text-sm" },
|
|
36
|
+
React.createElement("div", { className: "flex justify-between items-center border-b border-red-900/40 pb-2" },
|
|
37
|
+
React.createElement("div", { className: "flex items-center space-x-2 text-red-500" },
|
|
38
|
+
React.createElement(AlertOctagon, { className: "w-5 h-5 animate-pulse" }),
|
|
39
|
+
React.createElement("span", { className: "font-bold uppercase tracking-wider text-xs" }, "Guest Conformance Quarantine")),
|
|
40
|
+
React.createElement("div", { className: "flex items-center space-x-2" },
|
|
41
|
+
React.createElement("span", { className: "text-[10px] text-gray-500" },
|
|
42
|
+
"Node: ",
|
|
43
|
+
nodeId),
|
|
44
|
+
onClose && (React.createElement("button", { onClick: onClose, className: "text-gray-500 hover:text-white p-1 rounded hover:bg-white/5 transition-colors", title: "Close Diagnostics" },
|
|
45
|
+
React.createElement(X, { className: "w-4 h-4" }))))),
|
|
46
|
+
React.createElement("div", { className: "bg-red-950/20 border border-red-900/30 rounded p-3 text-red-400" },
|
|
47
|
+
React.createElement("div", { className: "text-xs font-bold text-red-500 uppercase tracking-widest mb-1" }, errorName),
|
|
48
|
+
React.createElement("div", { className: "text-[12px] whitespace-pre-wrap leading-relaxed" }, panicMessage)),
|
|
49
|
+
React.createElement("div", { className: "flex flex-col space-y-1" },
|
|
50
|
+
React.createElement("div", { className: "flex justify-between items-center text-xs text-gray-500 px-1" },
|
|
51
|
+
React.createElement("span", { className: "flex items-center gap-1.5" },
|
|
52
|
+
React.createElement(Terminal, { className: "w-3.5 h-3.5" }),
|
|
53
|
+
" Enclave Backtrace"),
|
|
54
|
+
React.createElement("button", { onClick: handleCopy, className: "flex items-center gap-1 text-[10px] hover:text-white transition-colors" }, copied ? (React.createElement(React.Fragment, null,
|
|
55
|
+
React.createElement(Check, { className: "w-3 h-3 text-green-400" }),
|
|
56
|
+
" Copied")) : (React.createElement(React.Fragment, null,
|
|
57
|
+
React.createElement(Copy, { className: "w-3 h-3" }),
|
|
58
|
+
" Copy Log")))),
|
|
59
|
+
React.createElement("div", { className: "bg-black/80 border border-gray-900 rounded p-3 h-48 overflow-y-auto custom-scrollbar font-mono text-[11px] leading-relaxed text-gray-400 select-text" }, backtrace.split('\n').map((line, index) => {
|
|
60
|
+
// Highlight source code files or frame numbers
|
|
61
|
+
const isFrameLine = line.trim().startsWith('at ') || line.includes('::') || /^\s*\d+:/.test(line);
|
|
62
|
+
return (React.createElement("div", { key: index, className: `whitespace-pre-wrap ${isFrameLine ? 'text-gray-300' : 'text-gray-600'}` }, line));
|
|
63
|
+
}))),
|
|
64
|
+
React.createElement("div", { className: "flex justify-between items-center border-t border-red-900/20 pt-3" },
|
|
65
|
+
React.createElement("span", { className: "text-[10px] text-gray-600" }, "ENCLAVE HOST STATUS: CONFINED"),
|
|
66
|
+
React.createElement("div", { className: "flex gap-2" }, onRecover && (React.createElement("button", { onClick: onRecover, className: "flex items-center gap-1.5 bg-red-900/30 border border-red-500/50 hover:bg-red-900/50 text-red-200 text-xs uppercase tracking-wider px-3.5 py-1.5 rounded transition-all font-bold" },
|
|
67
|
+
React.createElement(RefreshCw, { className: "w-3.5 h-3.5" }),
|
|
68
|
+
" Hot Reload Guest Enclave")))))));
|
|
69
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface SVIDBadgeProps {
|
|
3
|
+
spiffeId: string;
|
|
4
|
+
tenantId: string;
|
|
5
|
+
validUntil: number;
|
|
6
|
+
trustDomain: string;
|
|
7
|
+
fingerprint: string;
|
|
8
|
+
signatureAlgorithm?: string;
|
|
9
|
+
status: 'VERIFIED' | 'REVOKED' | 'EXPIRED' | 'PENDING';
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const SVIDBadge: React.FC<SVIDBadgeProps>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Copyright (c) 2026 CoReason, Inc
|
|
2
|
+
//
|
|
3
|
+
// This software is proprietary and dual-licensed
|
|
4
|
+
// Licensed under the Prosperity Public License 3.0 (the "License")
|
|
5
|
+
// A copy of the license is available at <https://prosperitylicense.com/versions/3.0.0>
|
|
6
|
+
// For details, see the LICENSE file
|
|
7
|
+
// Commercial use beyond a 30-day trial requires a separate license
|
|
8
|
+
//
|
|
9
|
+
// Source Code: <https://github.com/CoReason-AI/coreason-sensory-core>
|
|
10
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
11
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
12
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
13
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
14
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
15
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
16
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
import React, { useState, useEffect } from 'react';
|
|
20
|
+
import { GlassBox } from './GlassBox';
|
|
21
|
+
import { Shield, ShieldAlert, ShieldCheck, Copy, Check, Clock, Key } from 'lucide-react';
|
|
22
|
+
export const SVIDBadge = ({ spiffeId, tenantId, validUntil, trustDomain, fingerprint, signatureAlgorithm = 'ECDSA-SHA256', status, className }) => {
|
|
23
|
+
const [copied, setCopied] = useState(false);
|
|
24
|
+
const [timeRemaining, setTimeRemaining] = useState('');
|
|
25
|
+
const [lifePercent, setLifePercent] = useState(100);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const updateTime = () => {
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
const diff = validUntil - now;
|
|
30
|
+
if (diff <= 0) {
|
|
31
|
+
setTimeRemaining('Expired');
|
|
32
|
+
setLifePercent(0);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const hours = Math.floor(diff / 3600000);
|
|
36
|
+
const minutes = Math.floor((diff % 3600000) / 60000);
|
|
37
|
+
const seconds = Math.floor((diff % 60000) / 1000);
|
|
38
|
+
if (hours > 0) {
|
|
39
|
+
setTimeRemaining(`${hours}h ${minutes}m`);
|
|
40
|
+
}
|
|
41
|
+
else if (minutes > 0) {
|
|
42
|
+
setTimeRemaining(`${minutes}m ${seconds}s`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
setTimeRemaining(`${seconds}s`);
|
|
46
|
+
}
|
|
47
|
+
// Assume a standard 24h total duration for SVID to calculate life ratio
|
|
48
|
+
const totalLifetime = 24 * 60 * 60 * 1000;
|
|
49
|
+
const created = validUntil - totalLifetime;
|
|
50
|
+
const elapsed = now - created;
|
|
51
|
+
const percent = Math.max(0, Math.min(100, 100 - (elapsed / totalLifetime) * 100));
|
|
52
|
+
setLifePercent(percent);
|
|
53
|
+
};
|
|
54
|
+
updateTime();
|
|
55
|
+
const interval = setInterval(updateTime, 1000);
|
|
56
|
+
return () => clearInterval(interval);
|
|
57
|
+
}, [validUntil]);
|
|
58
|
+
const copyToClipboard = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
+
try {
|
|
60
|
+
yield navigator.clipboard.writeText(spiffeId);
|
|
61
|
+
setCopied(true);
|
|
62
|
+
setTimeout(() => setCopied(false), 2000);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
console.error('Failed to copy SPIFFE ID', err);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const getStatusColor = () => {
|
|
69
|
+
switch (status) {
|
|
70
|
+
case 'VERIFIED':
|
|
71
|
+
return 'border-[var(--cr-accent-cyan)] shadow-[0_0_10px_rgba(0,255,204,0.15)] text-[var(--cr-accent-cyan)]';
|
|
72
|
+
case 'REVOKED':
|
|
73
|
+
return 'border-red-500 shadow-[0_0_10px_rgba(239,68,68,0.2)] text-red-500 animate-pulse';
|
|
74
|
+
case 'EXPIRED':
|
|
75
|
+
return 'border-gray-600 text-gray-500';
|
|
76
|
+
case 'PENDING':
|
|
77
|
+
return 'border-[var(--cr-accent-orange)] text-[var(--cr-accent-orange)]';
|
|
78
|
+
default:
|
|
79
|
+
return 'border-gray-800 text-white';
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const getStatusIcon = () => {
|
|
83
|
+
switch (status) {
|
|
84
|
+
case 'VERIFIED':
|
|
85
|
+
return React.createElement(ShieldCheck, { className: "w-4 h-4 text-[var(--cr-accent-cyan)]" });
|
|
86
|
+
case 'REVOKED':
|
|
87
|
+
return React.createElement(ShieldAlert, { className: "w-4 h-4 text-red-500" });
|
|
88
|
+
case 'PENDING':
|
|
89
|
+
return React.createElement(Shield, { className: "w-4 h-4 text-[var(--cr-accent-orange)]" });
|
|
90
|
+
default:
|
|
91
|
+
return React.createElement(Shield, { className: "w-4 h-4 text-gray-500" });
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const truncatedFingerprint = fingerprint.length > 20
|
|
95
|
+
? `${fingerprint.substring(0, 10)}...${fingerprint.substring(fingerprint.length - 10)}`
|
|
96
|
+
: fingerprint;
|
|
97
|
+
return (React.createElement(GlassBox, { density: "dense", className: `border ${getStatusColor()} ${className || ''}` },
|
|
98
|
+
React.createElement("div", { className: "flex flex-col space-y-3 font-mono" },
|
|
99
|
+
React.createElement("div", { className: "flex justify-between items-center border-b border-white/10 pb-2" },
|
|
100
|
+
React.createElement("div", { className: "flex items-center space-x-2" },
|
|
101
|
+
getStatusIcon(),
|
|
102
|
+
React.createElement("span", { className: "text-[10px] font-bold tracking-widest uppercase text-white" }, "SVID Attestation")),
|
|
103
|
+
React.createElement("span", { className: "text-[9px] uppercase tracking-wider px-2 py-0.5 rounded bg-black/40 border border-white/5" }, status)),
|
|
104
|
+
React.createElement("div", { className: "flex items-center justify-between bg-black/30 p-2 rounded border border-white/5 group" },
|
|
105
|
+
React.createElement("div", { className: "flex flex-col min-w-0 pr-2" },
|
|
106
|
+
React.createElement("span", { className: "text-[9px] text-gray-500 uppercase tracking-widest" }, "SPIFFE ID"),
|
|
107
|
+
React.createElement("span", { className: "text-xs text-white truncate max-w-[200px]", title: spiffeId }, spiffeId)),
|
|
108
|
+
React.createElement("button", { onClick: copyToClipboard, className: "p-1 rounded text-gray-500 hover:text-white hover:bg-white/10 transition-colors", title: "Copy SPIFFE ID" }, copied ? React.createElement(Check, { className: "w-3.5 h-3.5 text-green-400" }) : React.createElement(Copy, { className: "w-3.5 h-3.5" }))),
|
|
109
|
+
React.createElement("div", { className: "flex flex-col space-y-1" },
|
|
110
|
+
React.createElement("div", { className: "flex justify-between text-[9px] text-gray-400" },
|
|
111
|
+
React.createElement("span", { className: "flex items-center gap-1" },
|
|
112
|
+
React.createElement(Clock, { className: "w-3 h-3" }),
|
|
113
|
+
" Expiration Countdown"),
|
|
114
|
+
React.createElement("span", null, timeRemaining)),
|
|
115
|
+
React.createElement("div", { className: "h-1 bg-gray-900 rounded-full overflow-hidden border border-white/5" },
|
|
116
|
+
React.createElement("div", { className: `h-full transition-all duration-1000 ${status === 'VERIFIED' ? 'bg-[var(--cr-accent-cyan)]' : 'bg-red-500'}`, style: { width: `${lifePercent}%` } }))),
|
|
117
|
+
React.createElement("div", { className: "grid grid-cols-2 gap-3 text-[10px] border-t border-white/5 pt-2" },
|
|
118
|
+
React.createElement("div", { className: "flex flex-col" },
|
|
119
|
+
React.createElement("span", { className: "text-gray-500 uppercase tracking-widest" }, "Tenant ID"),
|
|
120
|
+
React.createElement("span", { className: "text-white truncate font-bold" }, tenantId)),
|
|
121
|
+
React.createElement("div", { className: "flex flex-col" },
|
|
122
|
+
React.createElement("span", { className: "text-gray-500 uppercase tracking-widest" }, "Trust Domain"),
|
|
123
|
+
React.createElement("span", { className: "text-white truncate" }, trustDomain)),
|
|
124
|
+
React.createElement("div", { className: "flex flex-col" },
|
|
125
|
+
React.createElement("span", { className: "text-gray-500 uppercase tracking-widest" }, "Signature"),
|
|
126
|
+
React.createElement("span", { className: "text-white flex items-center gap-1" },
|
|
127
|
+
React.createElement(Key, { className: "w-3 h-3 text-gray-400" }),
|
|
128
|
+
" ",
|
|
129
|
+
signatureAlgorithm)),
|
|
130
|
+
React.createElement("div", { className: "flex flex-col" },
|
|
131
|
+
React.createElement("span", { className: "text-gray-500 uppercase tracking-widest" }, "Fingerprint"),
|
|
132
|
+
React.createElement("span", { className: "text-gray-400 truncate cursor-pointer hover:text-white", title: fingerprint }, truncatedFingerprint))))));
|
|
133
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export interface StatusPulseProps {
|
|
3
|
-
status: 'executing' | 'suspended_vfe_breach' | 'completed' | 'idle';
|
|
3
|
+
status: 'executing' | 'suspended_vfe_breach' | 'completed' | 'idle' | 'suspended_security_violation';
|
|
4
4
|
vfeValue?: number;
|
|
5
5
|
label?: string;
|
|
6
6
|
className?: string;
|
|
@@ -11,16 +11,18 @@ import React from 'react';
|
|
|
11
11
|
import { motion } from 'framer-motion';
|
|
12
12
|
import { cn } from './GlassBox';
|
|
13
13
|
export const StatusPulse = ({ status, vfeValue, label, className }) => {
|
|
14
|
-
const isError = status === 'suspended_vfe_breach';
|
|
14
|
+
const isError = status === 'suspended_vfe_breach' || status === 'suspended_security_violation';
|
|
15
15
|
const isExecuting = status === 'executing';
|
|
16
16
|
const isCompleted = status === 'completed';
|
|
17
|
-
const baseColor =
|
|
18
|
-
? '
|
|
19
|
-
:
|
|
20
|
-
? 'var(--cr-accent-
|
|
21
|
-
:
|
|
22
|
-
? '
|
|
23
|
-
:
|
|
17
|
+
const baseColor = status === 'suspended_security_violation'
|
|
18
|
+
? '#ff9900'
|
|
19
|
+
: isError
|
|
20
|
+
? 'var(--cr-accent-orange)'
|
|
21
|
+
: isExecuting
|
|
22
|
+
? 'var(--cr-accent-cyan)'
|
|
23
|
+
: isCompleted
|
|
24
|
+
? '#00cc44'
|
|
25
|
+
: '#666';
|
|
24
26
|
// Compute dynamic pulse duration based on VFE stress
|
|
25
27
|
const pulseDuration = vfeValue !== undefined && vfeValue > 0
|
|
26
28
|
? Math.max(0.3, 1.5 - (vfeValue * 0.8)) // breathing rate speeds up as VFE increases
|
|
@@ -4,7 +4,8 @@ export interface ThermodynamicGovernorProps {
|
|
|
4
4
|
tokenBurnRateSec: number;
|
|
5
5
|
maxBudgetTokens: number;
|
|
6
6
|
consumedTokens: number;
|
|
7
|
-
spiffeStatus: 'VERIFIED' | 'REVOKED' | 'PENDING';
|
|
7
|
+
spiffeStatus: 'VERIFIED' | 'REVOKED' | 'PENDING' | 'EXPIRED';
|
|
8
|
+
wasmAllocationMb?: number;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* ThermodynamicGovernor
|
|
@@ -17,34 +17,54 @@ import { GlassBox } from './GlassBox';
|
|
|
17
17
|
* Translates abstract AI usage into physical thermodynamic costs (VRAM, Token Burn)
|
|
18
18
|
* and cryptographic identity (SPIFFE/SPIRE).
|
|
19
19
|
*/
|
|
20
|
-
export const ThermodynamicGovernor = ({ vramAllocationMb, tokenBurnRateSec, maxBudgetTokens, consumedTokens, spiffeStatus }) => {
|
|
20
|
+
export const ThermodynamicGovernor = ({ vramAllocationMb, tokenBurnRateSec, maxBudgetTokens, consumedTokens, spiffeStatus, wasmAllocationMb = 6.8 }) => {
|
|
21
21
|
const budgetPercent = Math.min((consumedTokens / maxBudgetTokens) * 100, 100);
|
|
22
22
|
const isCritical = budgetPercent > 90;
|
|
23
|
+
const MAX_WASM_ALLOCATION = 10.0; // 10MB hard volumetric ceiling
|
|
24
|
+
const wasmPercent = Math.min((wasmAllocationMb / MAX_WASM_ALLOCATION) * 100, 100);
|
|
25
|
+
const isWasmWarning = wasmAllocationMb >= 8.0;
|
|
26
|
+
const isWasmDanger = wasmAllocationMb >= 9.5;
|
|
23
27
|
return (React.createElement(GlassBox, { density: "dense" },
|
|
24
|
-
React.createElement("div", { className: "flex flex-col space-y-3" },
|
|
28
|
+
React.createElement("div", { className: "flex flex-col space-y-3 font-mono" },
|
|
25
29
|
React.createElement("div", { className: "flex justify-between items-center border-b border-gray-700 pb-2" },
|
|
26
|
-
React.createElement("h3", { className: "text-
|
|
27
|
-
React.createElement("span", { className: `text-
|
|
30
|
+
React.createElement("h3", { className: "text-xs font-semibold text-white tracking-widest uppercase" }, "Thermodynamic Governor"),
|
|
31
|
+
React.createElement("span", { className: `text-[10px] uppercase font-bold tracking-wider px-2 py-0.5 rounded ${spiffeStatus === 'VERIFIED' ? 'bg-green-900/60 text-green-300 border border-green-500/30' : 'bg-red-900/60 text-red-300 border border-red-500/30'}` },
|
|
28
32
|
"SPIFFE: ",
|
|
29
33
|
spiffeStatus)),
|
|
30
34
|
React.createElement("div", { className: "grid grid-cols-2 gap-4" },
|
|
31
35
|
React.createElement("div", { className: "flex flex-col" },
|
|
32
|
-
React.createElement("span", { className: "text-
|
|
33
|
-
React.createElement("span", { className: "text-
|
|
36
|
+
React.createElement("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider" }, "VRAM Allocation"),
|
|
37
|
+
React.createElement("span", { className: "text-base font-bold text-white" },
|
|
34
38
|
vramAllocationMb.toLocaleString(),
|
|
35
39
|
" MB")),
|
|
36
40
|
React.createElement("div", { className: "flex flex-col" },
|
|
37
|
-
React.createElement("span", { className: "text-
|
|
38
|
-
React.createElement("span", { className: "text-
|
|
41
|
+
React.createElement("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider" }, "Token Velocity"),
|
|
42
|
+
React.createElement("span", { className: "text-base font-bold text-[var(--cr-accent-orange)]" },
|
|
39
43
|
tokenBurnRateSec,
|
|
40
44
|
" T/s"))),
|
|
41
|
-
React.createElement("div", { className: "flex flex-col space-y-1 pt-
|
|
42
|
-
React.createElement("div", { className: "flex justify-between text-
|
|
45
|
+
React.createElement("div", { className: "flex flex-col space-y-1 pt-1" },
|
|
46
|
+
React.createElement("div", { className: "flex justify-between text-[10px]" },
|
|
47
|
+
React.createElement("span", { className: "text-gray-400" }, "Guest WASM Allocation"),
|
|
48
|
+
React.createElement("span", { className: isWasmDanger ? 'text-red-400 font-bold animate-pulse' : isWasmWarning ? 'text-yellow-400' : 'text-gray-400' },
|
|
49
|
+
wasmAllocationMb.toFixed(2),
|
|
50
|
+
" / ",
|
|
51
|
+
MAX_WASM_ALLOCATION.toFixed(1),
|
|
52
|
+
" MB")),
|
|
53
|
+
React.createElement("div", { className: "w-full bg-gray-900 rounded-full h-2 overflow-hidden border border-white/5 relative" },
|
|
54
|
+
React.createElement("div", { className: `h-full rounded-full transition-all duration-500 ${isWasmDanger
|
|
55
|
+
? 'bg-red-500 shadow-[0_0_10px_rgba(239,68,68,0.5)]'
|
|
56
|
+
: isWasmWarning
|
|
57
|
+
? 'bg-yellow-500'
|
|
58
|
+
: 'bg-blue-500'}`, style: { width: `${wasmPercent}%` } }),
|
|
59
|
+
React.createElement("div", { className: "absolute right-[5%] top-0 bottom-0 w-0.5 bg-red-600/60", title: "9.5MB Danger Zone" })),
|
|
60
|
+
isWasmDanger && (React.createElement("div", { className: "text-[9px] text-red-500 uppercase font-bold tracking-widest mt-0.5 animate-pulse" }, "\u25B2 CRITICAL: APPROACHING 10MB VOLUMETRIC LIMIT"))),
|
|
61
|
+
React.createElement("div", { className: "flex flex-col space-y-1 pt-1" },
|
|
62
|
+
React.createElement("div", { className: "flex justify-between text-[10px]" },
|
|
43
63
|
React.createElement("span", { className: "text-gray-400" }, "Compute Budget"),
|
|
44
64
|
React.createElement("span", { className: isCritical ? 'text-red-400' : 'text-gray-400' },
|
|
45
65
|
consumedTokens.toLocaleString(),
|
|
46
66
|
" / ",
|
|
47
67
|
maxBudgetTokens.toLocaleString())),
|
|
48
|
-
React.createElement("div", { className: "w-full bg-gray-
|
|
49
|
-
React.createElement("div", { className: `h-
|
|
68
|
+
React.createElement("div", { className: "w-full bg-gray-900 rounded-full h-1.5 overflow-hidden border border-white/5" },
|
|
69
|
+
React.createElement("div", { className: `h-full rounded-full ${isCritical ? 'bg-red-500' : 'bg-[var(--cr-accent-orange)]'}`, style: { width: `${budgetPercent}%`, transition: 'width 0.5s ease-out' } }))))));
|
|
50
70
|
};
|
|
@@ -22,6 +22,6 @@ export interface TopologicalCanvasProps {
|
|
|
22
22
|
* TopologicalCanvas
|
|
23
23
|
*
|
|
24
24
|
* Concept: Visualizes the Macro-Swarm Architecture
|
|
25
|
-
* Uses ReactFlow to map mathematical DAGs to the UI
|
|
25
|
+
* Uses ReactFlow to map mathematical DAGs to the UI
|
|
26
26
|
*/
|
|
27
27
|
export declare const TopologicalCanvas: React.FC<TopologicalCanvasProps>;
|
|
@@ -21,22 +21,46 @@ import { ReactFlow, Background, Controls, getBezierPath, EdgeLabelRenderer, Pane
|
|
|
21
21
|
import '@xyflow/react/dist/style.css';
|
|
22
22
|
import { GlassBox } from './GlassBox';
|
|
23
23
|
import { StatusPulse } from './StatusPulse';
|
|
24
|
+
import { Lock, Unlock, ShieldAlert, ShieldX } from 'lucide-react';
|
|
25
|
+
import { ConformanceGuillotine } from './ConformanceGuillotine';
|
|
24
26
|
// Custom Node: SwarmNode
|
|
25
27
|
const SwarmNode = ({ data }) => {
|
|
26
28
|
var _a;
|
|
27
|
-
|
|
29
|
+
const isBreached = data.status === 'suspended_security_violation' || data.isSecurityViolation;
|
|
30
|
+
return (React.createElement(GlassBox, { density: "dense", className: `border relative overflow-hidden ${data.isPanicked
|
|
31
|
+
? 'border-red-600/80 shadow-[0_0_15px_rgba(220,38,38,0.3)]'
|
|
32
|
+
: isBreached
|
|
33
|
+
? 'border-orange-500/80 shadow-[0_0_15px_rgba(249,115,22,0.3)]'
|
|
34
|
+
: data.isAnomalous
|
|
35
|
+
? 'border-[var(--cr-accent-orange)]'
|
|
36
|
+
: 'border-gray-800'} min-w-[150px]` },
|
|
28
37
|
React.createElement("div", { className: "flex flex-col" },
|
|
29
38
|
React.createElement("div", { className: "flex justify-between items-center mb-2" },
|
|
30
39
|
React.createElement("span", { className: "text-[10px] uppercase tracking-widest text-gray-500" }, data.typeLabel || 'AGENT'),
|
|
31
40
|
React.createElement(StatusPulse, { status: data.status || 'idle' })),
|
|
32
|
-
React.createElement("span", { className: "text-sm font-mono text-white truncate max-w-[120px]", title: data.urn }, ((_a = data.urn) === null || _a === void 0 ? void 0 : _a.split(':').slice(-2).join(':')) || 'urn:unknown'))
|
|
41
|
+
React.createElement("span", { className: "text-sm font-mono text-white truncate max-w-[120px]", title: data.urn }, ((_a = data.urn) === null || _a === void 0 ? void 0 : _a.split(':').slice(-2).join(':')) || 'urn:unknown')),
|
|
42
|
+
data.isPanicked && (React.createElement("div", { className: "absolute inset-0 pointer-events-none overflow-hidden rounded-xl border border-red-500/50 bg-red-950/20" },
|
|
43
|
+
React.createElement("svg", { className: "absolute inset-0 w-full h-full opacity-60 stroke-red-500", strokeWidth: "1", strokeLinecap: "round" },
|
|
44
|
+
React.createElement("line", { x1: "0", y1: "0", x2: "60", y2: "40" }),
|
|
45
|
+
React.createElement("line", { x1: "60", y1: "40", x2: "30", y2: "80" }),
|
|
46
|
+
React.createElement("line", { x1: "60", y1: "40", x2: "110", y2: "30" }),
|
|
47
|
+
React.createElement("line", { x1: "110", y1: "30", x2: "150", y2: "70" }),
|
|
48
|
+
React.createElement("line", { x1: "110", y1: "30", x2: "140", y2: "10" }),
|
|
49
|
+
React.createElement("line", { x1: "30", y1: "80", x2: "0", y2: "100" }),
|
|
50
|
+
React.createElement("line", { x1: "30", y1: "80", x2: "80", y2: "95" })),
|
|
51
|
+
React.createElement("div", { className: "absolute bottom-1 right-2 text-[8px] font-mono text-red-500 font-bold uppercase tracking-widest animate-pulse" }, "\u2623 CONFORMANCE PANIC"))),
|
|
52
|
+
isBreached && (React.createElement("div", { className: "absolute inset-0 pointer-events-none rounded-xl border border-orange-500 bg-orange-950/35 flex flex-col justify-center items-center" },
|
|
53
|
+
React.createElement(ShieldX, { className: "w-8 h-8 text-orange-500 animate-bounce" }),
|
|
54
|
+
React.createElement("span", { className: "text-[7px] text-orange-400 font-bold uppercase tracking-widest mt-1" }, "BREACH BLOCK")))));
|
|
33
55
|
};
|
|
34
56
|
// Custom Node: SandboxNode (For Fractal Infrastructure)
|
|
35
57
|
const SandboxNode = ({ id, data }) => {
|
|
36
58
|
const fuelPercentage = data.cpuFuel && data.maxFuel ? (data.cpuFuel / data.maxFuel) * 100 : 100;
|
|
37
59
|
const memoryPercentage = data.memoryUsage && data.maxMemory ? (data.memoryUsage / data.maxMemory) * 100 : 0;
|
|
38
|
-
return (React.createElement("div", { className:
|
|
39
|
-
|
|
60
|
+
return (React.createElement("div", { className: `bg-[rgba(20,20,20,0.8)] border relative rounded-lg p-4 min-w-[300px] min-h-[200px] shadow-[0_0_15px_rgba(255,100,0,0.2)] ${data.isPanicked
|
|
61
|
+
? 'border-red-600/80 shadow-[0_0_20px_rgba(220,38,38,0.4)]'
|
|
62
|
+
: 'border-[var(--cr-accent-orange)]'}` },
|
|
63
|
+
React.createElement("div", { className: `absolute top-0 left-0 right-0 text-[10px] font-bold uppercase tracking-wider px-2 py-1 rounded-t-sm flex justify-between items-center ${data.isPanicked ? 'bg-red-600 text-white' : 'bg-[var(--cr-accent-orange)] text-black'}` },
|
|
40
64
|
React.createElement("span", null,
|
|
41
65
|
"\u26CA ",
|
|
42
66
|
data.sandboxType || 'WASM ENCLAVE',
|
|
@@ -59,7 +83,17 @@ const SandboxNode = ({ id, data }) => {
|
|
|
59
83
|
data.maxMemory || 10,
|
|
60
84
|
"MB")),
|
|
61
85
|
React.createElement("div", { className: "h-1 bg-gray-800 rounded-full overflow-hidden" },
|
|
62
|
-
React.createElement("div", { className: "h-full bg-blue-400 transition-all", style: { width: `${memoryPercentage}%` } })))
|
|
86
|
+
React.createElement("div", { className: "h-full bg-blue-400 transition-all", style: { width: `${memoryPercentage}%` } }))),
|
|
87
|
+
data.isPanicked && (React.createElement("div", { className: "absolute inset-0 pointer-events-none overflow-hidden rounded-lg border border-red-500/50 bg-red-950/20" },
|
|
88
|
+
React.createElement("svg", { className: "absolute inset-0 w-full h-full opacity-60 stroke-red-500", strokeWidth: "1", strokeLinecap: "round" },
|
|
89
|
+
React.createElement("line", { x1: "0", y1: "0", x2: "100", y2: "80" }),
|
|
90
|
+
React.createElement("line", { x1: "100", y1: "80", x2: "80", y2: "160" }),
|
|
91
|
+
React.createElement("line", { x1: "100", y1: "80", x2: "220", y2: "60" }),
|
|
92
|
+
React.createElement("line", { x1: "220", y1: "60", x2: "290", y2: "140" }),
|
|
93
|
+
React.createElement("line", { x1: "220", y1: "60", x2: "280", y2: "20" }),
|
|
94
|
+
React.createElement("line", { x1: "80", y1: "160", x2: "0", y2: "200" }),
|
|
95
|
+
React.createElement("line", { x1: "80", y1: "160", x2: "180", y2: "190" })),
|
|
96
|
+
React.createElement("div", { className: "absolute bottom-1 right-2 text-[8px] font-mono text-red-500 font-bold uppercase tracking-widest animate-pulse" }, "\u2623 CONFORMANCE PANIC")))));
|
|
63
97
|
};
|
|
64
98
|
// Custom Edge: TelemetryEdge
|
|
65
99
|
const TelemetryEdge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, style = {}, markerEnd, data }) => {
|
|
@@ -71,9 +105,83 @@ const TelemetryEdge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition,
|
|
|
71
105
|
targetY,
|
|
72
106
|
targetPosition,
|
|
73
107
|
});
|
|
108
|
+
const [showDetails, setShowDetails] = React.useState(false);
|
|
109
|
+
const getEdgeColor = () => {
|
|
110
|
+
if (data === null || data === void 0 ? void 0 : data.isSecurityViolation)
|
|
111
|
+
return '#f97316'; // Flashing firewall orange
|
|
112
|
+
if (data === null || data === void 0 ? void 0 : data.isSecureMtls)
|
|
113
|
+
return '#00ffcc'; // Glowing mTLS cyan
|
|
114
|
+
if (data === null || data === void 0 ? void 0 : data.isUnsecureEgress)
|
|
115
|
+
return '#cca700'; // Warning cleartext amber
|
|
116
|
+
return (data === null || data === void 0 ? void 0 : data.isStreaming) ? 'var(--cr-accent-orange)' : '#4B5563';
|
|
117
|
+
};
|
|
118
|
+
const getStrokeDashArray = () => {
|
|
119
|
+
if ((data === null || data === void 0 ? void 0 : data.isSecureMtls) || (data === null || data === void 0 ? void 0 : data.isStreaming) || (data === null || data === void 0 ? void 0 : data.isSecurityViolation))
|
|
120
|
+
return '5,5';
|
|
121
|
+
return 'none';
|
|
122
|
+
};
|
|
123
|
+
const getAnimation = () => {
|
|
124
|
+
if (data === null || data === void 0 ? void 0 : data.isSecurityViolation)
|
|
125
|
+
return 'dashdraw 0.5s linear infinite';
|
|
126
|
+
if ((data === null || data === void 0 ? void 0 : data.isStreaming) || (data === null || data === void 0 ? void 0 : data.isSecureMtls))
|
|
127
|
+
return 'dashdraw 1s linear infinite';
|
|
128
|
+
return 'none';
|
|
129
|
+
};
|
|
74
130
|
return (React.createElement("g", null,
|
|
75
|
-
React.createElement("path", { id: id, style: Object.assign(Object.assign({}, style), { strokeWidth:
|
|
76
|
-
(data === null || data === void 0 ? void 0 : data.
|
|
131
|
+
React.createElement("path", { id: id, style: Object.assign(Object.assign({}, style), { strokeWidth: (data === null || data === void 0 ? void 0 : data.isSecureMtls) || (data === null || data === void 0 ? void 0 : data.isSecurityViolation) ? 3 : 2, stroke: getEdgeColor(), strokeDasharray: getStrokeDashArray(), animation: getAnimation() }), className: "react-flow__edge-path", d: edgePath, markerEnd: markerEnd }),
|
|
132
|
+
(data === null || data === void 0 ? void 0 : data.isSecureMtls) && (React.createElement(EdgeLabelRenderer, null,
|
|
133
|
+
React.createElement("div", { style: {
|
|
134
|
+
position: 'absolute',
|
|
135
|
+
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
|
|
136
|
+
pointerEvents: 'all',
|
|
137
|
+
}, className: "flex flex-col items-center z-50" },
|
|
138
|
+
React.createElement("button", { onClick: (e) => {
|
|
139
|
+
e.stopPropagation();
|
|
140
|
+
setShowDetails(!showDetails);
|
|
141
|
+
}, className: "bg-black/90 border border-[var(--cr-accent-cyan)] hover:bg-[rgba(0,255,204,0.1)] text-[var(--cr-accent-cyan)] p-1 rounded-full shadow-[0_0_10px_rgba(0,255,204,0.3)] transition-all cursor-pointer", title: "Inspect mTLS Tunnel" },
|
|
142
|
+
React.createElement(Lock, { className: "w-3 h-3" })),
|
|
143
|
+
showDetails && (React.createElement("div", { className: "absolute top-6 bg-black/95 border border-[var(--cr-accent-cyan)] p-2 rounded text-[9px] font-mono text-gray-300 w-44 shadow-2xl flex flex-col gap-1 z-[9999] pointer-events-auto" },
|
|
144
|
+
React.createElement("div", { className: "text-[var(--cr-accent-cyan)] font-bold border-b border-white/10 pb-0.5 mb-1 uppercase tracking-wider" }, "Envoy mTLS Active"),
|
|
145
|
+
React.createElement("div", null,
|
|
146
|
+
"Cipher: ",
|
|
147
|
+
React.createElement("span", { className: "text-white" }, data.cipherSuite || 'TLS_AES_256_GCM_SHA384')),
|
|
148
|
+
React.createElement("div", null,
|
|
149
|
+
"Domain: ",
|
|
150
|
+
React.createElement("span", { className: "text-white truncate block" }, data.spiffeId || 'spiffe://coreason.internal')),
|
|
151
|
+
React.createElement("button", { onClick: () => setShowDetails(false), className: "mt-1 text-[8px] bg-white/10 hover:bg-white/20 text-white rounded py-0.5 w-full border border-white/5 uppercase" }, "Close")))))),
|
|
152
|
+
(data === null || data === void 0 ? void 0 : data.isSecurityViolation) && (React.createElement(EdgeLabelRenderer, null,
|
|
153
|
+
React.createElement("div", { style: {
|
|
154
|
+
position: 'absolute',
|
|
155
|
+
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
|
|
156
|
+
pointerEvents: 'all',
|
|
157
|
+
}, className: "flex flex-col items-center z-50" },
|
|
158
|
+
React.createElement("button", { onClick: (e) => {
|
|
159
|
+
e.stopPropagation();
|
|
160
|
+
setShowDetails(!showDetails);
|
|
161
|
+
}, className: "bg-black/90 border border-orange-500 hover:bg-orange-950/20 text-orange-500 p-1 rounded-full shadow-[0_0_10px_rgba(249,115,22,0.3)] transition-all cursor-pointer animate-pulse", title: "Security Violation Detected" },
|
|
162
|
+
React.createElement(ShieldAlert, { className: "w-3 h-3" })),
|
|
163
|
+
showDetails && (React.createElement("div", { className: "absolute top-6 bg-black/95 border border-orange-500 p-2.5 rounded text-[9px] font-mono text-gray-300 w-52 shadow-2xl flex flex-col gap-1 z-[9999] pointer-events-auto" },
|
|
164
|
+
React.createElement("div", { className: "text-orange-500 font-bold border-b border-orange-900/30 pb-0.5 mb-1 uppercase tracking-wider" }, "Firewall Block"),
|
|
165
|
+
React.createElement("div", { className: "text-red-400 font-bold" }, "Bell-LaPadula Rule Breach"),
|
|
166
|
+
React.createElement("div", { className: "text-[8px] text-gray-400 mt-1 leading-normal" }, data.securityViolationDetails || 'Write-down from SECRET thread to UNCLASSIFIED sink blocked by Envoy proxy.'),
|
|
167
|
+
React.createElement("button", { onClick: () => setShowDetails(false), className: "mt-1 text-[8px] bg-white/10 hover:bg-white/20 text-white rounded py-0.5 w-full border border-white/5 uppercase" }, "Close")))))),
|
|
168
|
+
(data === null || data === void 0 ? void 0 : data.isUnsecureEgress) && (React.createElement(EdgeLabelRenderer, null,
|
|
169
|
+
React.createElement("div", { style: {
|
|
170
|
+
position: 'absolute',
|
|
171
|
+
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
|
|
172
|
+
pointerEvents: 'all',
|
|
173
|
+
}, className: "flex flex-col items-center z-50" },
|
|
174
|
+
React.createElement("button", { onClick: (e) => {
|
|
175
|
+
e.stopPropagation();
|
|
176
|
+
setShowDetails(!showDetails);
|
|
177
|
+
}, className: "bg-black/90 border border-yellow-500 hover:bg-yellow-950/20 text-yellow-500 p-1 rounded-full shadow-[0_0_10px_rgba(234,179,8,0.3)] transition-all cursor-pointer", title: "Unsecure Egress Channel" },
|
|
178
|
+
React.createElement(Unlock, { className: "w-3 h-3" })),
|
|
179
|
+
showDetails && (React.createElement("div", { className: "absolute top-6 bg-black/95 border border-yellow-500 p-2.5 rounded text-[9px] font-mono text-gray-300 w-52 shadow-2xl flex flex-col gap-1 z-[9999] pointer-events-auto" },
|
|
180
|
+
React.createElement("div", { className: "text-yellow-500 font-bold border-b border-yellow-900/30 pb-0.5 mb-1 uppercase tracking-wider" }, "Cleartext Egress"),
|
|
181
|
+
React.createElement("div", { className: "text-yellow-400" }, "Envoy mTLS Inactive"),
|
|
182
|
+
React.createElement("div", { className: "text-[8px] text-gray-400 mt-1 leading-normal font-sans" }, "Egress path carries no identity claims. Clearance: PUBLIC"),
|
|
183
|
+
React.createElement("button", { onClick: () => setShowDetails(false), className: "mt-1 text-[8px] bg-white/10 hover:bg-white/20 text-white rounded py-0.5 w-full border border-white/5 uppercase" }, "Close")))))),
|
|
184
|
+
!(data === null || data === void 0 ? void 0 : data.isSecureMtls) && !(data === null || data === void 0 ? void 0 : data.isSecurityViolation) && !(data === null || data === void 0 ? void 0 : data.isUnsecureEgress) && (data === null || data === void 0 ? void 0 : data.label) && (React.createElement(EdgeLabelRenderer, null,
|
|
77
185
|
React.createElement("div", { style: {
|
|
78
186
|
position: 'absolute',
|
|
79
187
|
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
|
|
@@ -91,10 +199,11 @@ const edgeTypes = {
|
|
|
91
199
|
* TopologicalCanvas
|
|
92
200
|
*
|
|
93
201
|
* Concept: Visualizes the Macro-Swarm Architecture
|
|
94
|
-
* Uses ReactFlow to map mathematical DAGs to the UI
|
|
202
|
+
* Uses ReactFlow to map mathematical DAGs to the UI
|
|
95
203
|
*/
|
|
96
204
|
export const TopologicalCanvas = ({ nodes, edges, availableCapabilities = [], onNodeClick, onNodesChange, onEdgesChange, onConnect, onDropCapability }) => {
|
|
97
205
|
const [isLayouting, setIsLayouting] = React.useState(false);
|
|
206
|
+
const [activePanicNode, setActivePanicNode] = React.useState(null);
|
|
98
207
|
const onDragStart = (event, capability) => {
|
|
99
208
|
event.dataTransfer.setData('application/reactflow', JSON.stringify(capability));
|
|
100
209
|
event.dataTransfer.effectAllowed = 'move';
|
|
@@ -116,6 +225,19 @@ export const TopologicalCanvas = ({ nodes, edges, availableCapabilities = [], on
|
|
|
116
225
|
onDropCapability(capability, position);
|
|
117
226
|
}
|
|
118
227
|
};
|
|
228
|
+
const handleInternalNodeClick = (event, node) => {
|
|
229
|
+
var _a;
|
|
230
|
+
if ((_a = node.data) === null || _a === void 0 ? void 0 : _a.isPanicked) {
|
|
231
|
+
setActivePanicNode({
|
|
232
|
+
nodeId: node.id,
|
|
233
|
+
panicMessage: node.data.panicMessage || 'WASM plugin panicked internally.',
|
|
234
|
+
backtrace: node.data.backtrace || 'No stack trace captured.'
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
if (onNodeClick) {
|
|
238
|
+
onNodeClick(event, node);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
119
241
|
const handleAutoLayout = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
120
242
|
if (nodes.length === 0)
|
|
121
243
|
return;
|
|
@@ -159,7 +281,7 @@ export const TopologicalCanvas = ({ nodes, edges, availableCapabilities = [], on
|
|
|
159
281
|
setIsLayouting(false);
|
|
160
282
|
}
|
|
161
283
|
});
|
|
162
|
-
return (React.createElement("div", { className: "flex h-full w-full rounded-xl overflow-hidden border border-gray-800 bg-black" },
|
|
284
|
+
return (React.createElement("div", { className: "flex h-full w-full rounded-xl overflow-hidden border border-gray-800 bg-black relative" },
|
|
163
285
|
availableCapabilities.length > 0 && (React.createElement("div", { className: "w-64 border-r border-gray-800 bg-[var(--cr-glass-box-black)] p-4 overflow-y-auto" },
|
|
164
286
|
React.createElement("div", { className: "text-white uppercase tracking-widest text-xs font-bold mb-4 border-b border-gray-800 pb-2" }, "URN Registry"),
|
|
165
287
|
React.createElement("div", { className: "flex flex-col gap-3" }, availableCapabilities.map((cap) => (React.createElement("div", { key: cap.urn, className: "bg-[rgba(20,20,20,0.8)] border border-gray-700 p-2 rounded cursor-grab hover:border-[var(--cr-accent-cyan)] transition-colors", onDragStart: (event) => onDragStart(event, cap), draggable: true },
|
|
@@ -175,9 +297,15 @@ export const TopologicalCanvas = ({ nodes, edges, availableCapabilities = [], on
|
|
|
175
297
|
background-color: #000;
|
|
176
298
|
}
|
|
177
299
|
`),
|
|
178
|
-
React.createElement(ReactFlow, { nodes: nodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onNodeClick:
|
|
300
|
+
React.createElement(ReactFlow, { nodes: nodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onNodeClick: handleInternalNodeClick, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, onConnect: onConnect, fitView: true, proOptions: { hideAttribution: true } },
|
|
179
301
|
React.createElement(Background, { color: "#1f2937", gap: 20 }),
|
|
180
302
|
React.createElement(Controls, { className: "bg-[var(--cr-glass-box-black)] border border-gray-800 fill-white" }),
|
|
181
303
|
React.createElement(Panel, { position: "top-right", className: "m-4" },
|
|
182
|
-
React.createElement("button", { onClick: handleAutoLayout, disabled: isLayouting, className: `bg-[var(--cr-accent-orange)] text-black font-bold uppercase tracking-wider text-[10px] px-4 py-2 rounded shadow-lg transition-opacity ${isLayouting ? 'opacity-50 cursor-not-allowed' : 'hover:opacity-90'}` }, isLayouting ? 'Computing Topology...' : 'Orthogonal Layout'))))
|
|
304
|
+
React.createElement("button", { onClick: handleAutoLayout, disabled: isLayouting, className: `bg-[var(--cr-accent-orange)] text-black font-bold uppercase tracking-wider text-[10px] px-4 py-2 rounded shadow-lg transition-opacity ${isLayouting ? 'opacity-50 cursor-not-allowed' : 'hover:opacity-90'}` }, isLayouting ? 'Computing Topology...' : 'Orthogonal Layout')))),
|
|
305
|
+
activePanicNode && (React.createElement("div", { className: "absolute inset-0 bg-black/60 backdrop-blur-sm z-[9999] flex justify-center items-center p-6" },
|
|
306
|
+
React.createElement(ConformanceGuillotine, { nodeId: activePanicNode.nodeId, panicMessage: activePanicNode.panicMessage, backtrace: activePanicNode.backtrace, onClose: () => setActivePanicNode(null), onRecover: () => {
|
|
307
|
+
console.log(`Triggering hot enclave recovery for ${activePanicNode.nodeId}`);
|
|
308
|
+
// In production this emits a hot-attestation reload request to the Temporal ledger
|
|
309
|
+
setActivePanicNode(null);
|
|
310
|
+
} })))));
|
|
183
311
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export { HolographicAuditTrail } from './components/HolographicAuditTrail';
|
|
|
8
8
|
export { MarkovBlanketLens } from './components/MarkovBlanketLens';
|
|
9
9
|
export { TopologicalCanvas } from './components/TopologicalCanvas';
|
|
10
10
|
export { CognitiveIntrospectionPanel } from './components/CognitiveIntrospectionPanel';
|
|
11
|
+
export { SVIDBadge } from './components/SVIDBadge';
|
|
12
|
+
export { ConformanceGuillotine } from './components/ConformanceGuillotine';
|
|
11
13
|
export { VFEIndicator } from './components/VFEIndicator';
|
|
12
14
|
export { VerifiedCapabilityReceipt } from './components/VerifiedCapabilityReceipt';
|
|
13
15
|
export { HardwareProfileProvider, useHardwareProfile } from './components/HardwareProfiler';
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,8 @@ export { HolographicAuditTrail } from './components/HolographicAuditTrail';
|
|
|
17
17
|
export { MarkovBlanketLens } from './components/MarkovBlanketLens';
|
|
18
18
|
export { TopologicalCanvas } from './components/TopologicalCanvas';
|
|
19
19
|
export { CognitiveIntrospectionPanel } from './components/CognitiveIntrospectionPanel';
|
|
20
|
+
export { SVIDBadge } from './components/SVIDBadge';
|
|
21
|
+
export { ConformanceGuillotine } from './components/ConformanceGuillotine';
|
|
20
22
|
export { VFEIndicator } from './components/VFEIndicator';
|
|
21
23
|
export { VerifiedCapabilityReceipt } from './components/VerifiedCapabilityReceipt';
|
|
22
24
|
export { HardwareProfileProvider, useHardwareProfile } from './components/HardwareProfiler';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreason-ai/sensory-core",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Topos-Theoretic UI primitive library for the CoReason Cybernetic Manifold. Stateless, hollow React components that project coreason-manifest Pydantic ASTs into the DOM.",
|
|
5
5
|
"license": "Prosperity-3.0",
|
|
6
6
|
"author": "CoReason, Inc. <info@coreason.ai>",
|