2026-06-02 15:53:17 +01:00
#!/usr/bin/env node
import { createRequire } from "node:module" ;
import { dirname , join , resolve } from "node:path" ;
import { fileURLToPath , pathToFileURL } from "node:url" ;
import { existsSync , readFileSync } from "node:fs" ;
2026-06-08 19:20:11 +01:00
import { mkdir , readFile , rename , stat , writeFile } from "node:fs/promises" ;
2026-06-02 15:53:17 +01:00
const repoRoot = resolve ( dirname ( fileURLToPath ( import . meta . url ) ) , ".." ) ;
const defaultStorageRoot = resolve ( repoRoot , ".voidbot" ) ;
const defaultStatusDir = resolve ( defaultStorageRoot , "status" ) ;
const defaultSnapshotPath = resolve ( defaultStatusDir , "swarm-state.json" ) ;
const defaultDashboardPath = resolve ( defaultStatusDir , "swarm-dashboard.html" ) ;
const defaultCultMeshStorePath = resolve ( defaultStatusDir , "cultmesh" , "voidbot-swarm-state.cc" ) ;
const providerId = "voidbot.swarm" ;
const verseId = "voidbot.local" ;
const snapshotDocumentType = "voidbot.swarm_state_snapshot" ;
const snapshotSchemaId = "voidbot.swarm_state_snapshot.v1" ;
const providerAdvertisementDocumentType = "gamecult.eve.provider_advertisement" ;
const providerAdvertisementSchemaId = "gamecult.eve.provider_advertisement.v1" ;
const eveBindingDocumentType = "gamecult.eve.interface_binding" ;
const eveBindingSchemaId = "gamecult.eve.interface_binding.v1" ;
const surfaceDocumentType = "gamecult.eve.surface_state" ;
const surfaceSchemaId = "gamecult.eve.surface_state.v1" ;
2026-06-16 20:50:49 +01:00
const providerCatalogDocumentType = "voidbot.provider_advertisement_catalog" ;
const providerCatalogSchemaId = "voidbot.provider_advertisement_catalog.v0" ;
const transportProfileDocumentType = "idunn.daemon_transport_profile" ;
const transportProfileSchemaId = "idunn.daemon_transport_profile.v1" ;
const commandBoundaryDocumentType = "idunn.command_boundary" ;
const commandBoundarySchemaId = "idunn.command_boundary.v1" ;
2026-07-15 02:06:06 +01:00
const swarmControlDocumentType = "voidbot.swarm_control_state" ;
const swarmControlSchemaId = "voidbot.swarm_control_state.v1" ;
2026-07-16 00:17:49 +01:00
const swarmOperatorViewDocumentType = "voidbot.swarm_operator_view" ;
const swarmOperatorViewSchemaId = "voidbot.swarm_operator_view.v1" ;
2026-06-02 15:53:17 +01:00
const args = parseArgs ( process . argv . slice ( 2 ) ) ;
2026-08-25 14:47:11 +02:00
const env = {
... ( await readDotEnv ( resolve ( repoRoot , ".env" ) ) ) ,
... process . env ,
} ;
2026-07-05 19:17:10 +01:00
const swarmCultMeshRudpEndpoint = String (
args . rudpEndpoint ||
args [ "rudp-endpoint" ] ||
process . env . VOIDBOT _SWARM _CULTMESH _RUDP ||
env . VOIDBOT _SWARM _CULTMESH _RUDP ||
"rudp://127.0.0.1:17873" ,
) . trim ( ) ;
2026-06-02 15:53:17 +01:00
const storageRoot = resolveConfigPath ( env . STORAGE _ROOT , defaultStorageRoot ) ;
const statusDir = resolve ( storageRoot , "status" ) ;
const heartbeatStatePath = resolveConfigPath (
2026-07-16 00:27:01 +01:00
schedulerDebugProjectionPath ( env . REPO _FACE _HEARTBEAT _STATE _PATH ) ,
2026-06-02 15:53:17 +01:00
resolve ( statusDir , "repo-face-heartbeats.json" ) ,
) ;
const orchestratorPath = resolve ( statusDir , "gamecult-orchestrator.json" ) ;
const pausePath = resolve ( repoRoot , "state" , "agent-swarm-paused.json" ) ;
const snapshotPath = resolveConfigPath ( args . snapshot , defaultSnapshotPath . replace ( defaultStatusDir , statusDir ) ) ;
const dashboardPath = resolveConfigPath ( args . out , defaultDashboardPath . replace ( defaultStatusDir , statusDir ) ) ;
const cultMeshStorePath = resolveConfigPath (
args . cultmeshStore ,
defaultCultMeshStorePath . replace ( defaultStatusDir , statusDir ) ,
) ;
const requireCultMeshAdvertisement = ! isFlagEnabled ( args . public ) && ! isFlagEnabled ( args . allowUnmeshed ) ;
const renderResult = await render ( ) ;
if ( args . open ) {
console . log ( pathToFileURL ( renderResult . dashboardPath ) . href ) ;
}
if ( args . serve ) {
throw new Error ( "VoidBot swarm is exposed through CultMesh/Eve, not a web server. Use npm run swarm:render-dashboard to publish the CultMesh surface." ) ;
} else {
console . log ( ` Swarm dashboard HTML: ${ renderResult . dashboardPath } ` ) ;
console . log ( ` Swarm snapshot JSON: ${ renderResult . snapshotPath } ` ) ;
console . log ( ` CultMesh snapshot store: ${ renderResult . cultMeshStorePath } ` ) ;
}
async function render ( ) {
let snapshot = await buildSnapshot ( ) ;
if ( isFlagEnabled ( args . public ) ) {
snapshot = redactSnapshot ( snapshot ) ;
}
await mkdir ( dirname ( snapshotPath ) , { recursive : true } ) ;
await mkdir ( dirname ( dashboardPath ) , { recursive : true } ) ;
const pendingEveState = buildEveProviderState ( snapshot ) ;
const cultMeshWrite = await writeCultMeshPublication ( snapshot , pendingEveState , cultMeshStorePath ) ;
if ( requireCultMeshAdvertisement && cultMeshWrite . writeStatus !== "ok" ) {
throw new Error ( ` VoidBot swarm CultMesh advertisement failed: ${ cultMeshWrite . writeError ? ? cultMeshWrite . writeStatus } ` ) ;
}
const finalSnapshot = {
... snapshot ,
cultMesh : {
... snapshot . cultMesh ,
... cultMeshWrite ,
} ,
} ;
const finalEveState = buildEveProviderState ( finalSnapshot ) ;
2026-07-03 01:57:11 +01:00
const finalCultMeshWrite = await writeCultMeshPublication ( finalSnapshot , finalEveState , cultMeshStorePath , false ) ;
if ( requireCultMeshAdvertisement && finalCultMeshWrite . writeStatus !== "ok" ) {
throw new Error ( ` VoidBot swarm final CultMesh surface publish failed: ${ finalCultMeshWrite . writeError ? ? finalCultMeshWrite . writeStatus } ` ) ;
}
finalSnapshot . cultMesh = {
... finalSnapshot . cultMesh ,
... finalCultMeshWrite ,
} ;
2026-06-02 15:53:17 +01:00
await writeFile ( snapshotPath , ` ${ JSON . stringify ( finalSnapshot , null , 2 ) } \n ` , "utf8" ) ;
await writeFile ( dashboardPath , renderHtml ( finalSnapshot ) , "utf8" ) ;
return {
dashboardPath ,
snapshotPath ,
cultMeshStorePath ,
} ;
}
async function buildSnapshot ( ) {
const now = new Date ( ) ;
const heartbeat = await readJsonFile ( heartbeatStatePath ) ;
const orchestrator = await readJsonFile ( orchestratorPath ) ;
const pause = await readJsonFile ( pausePath ) ;
const identityMetadata = await readIdentityMetadata ( env . REPO _DISCORD _IDENTITIES _PATH ) ;
const heartbeatMtime = await getMtime ( heartbeatStatePath ) ;
const orchestratorMtime = await getMtime ( orchestratorPath ) ;
const paused = pause . ok ? pause . value ? . paused !== false : false ;
const pauseReason = pause . ok && typeof pause . value ? . reason === "string" ? pause . value . reason : undefined ;
const participants = Array . isArray ( heartbeat . value ? . participants ) ? heartbeat . value . participants : [ ] ;
const pendingMentions = Array . isArray ( heartbeat . value ? . pendingMentions ) ? heartbeat . value . pendingMentions : [ ] ;
const initiativeClock = numberOrNull ( heartbeat . value ? . initiativeClock ) ;
const participantSnapshots = participants . map ( ( participant ) =>
projectParticipant ( participant , pendingMentions , initiativeClock , identityMetadata ) ,
) ;
const faceStates = await readFaceStates ( identityMetadata ) ;
for ( const participant of participantSnapshots ) {
participant . faceState = faceStates . get ( participant . identityId . toLowerCase ( ) ) ? ? {
readable : false ,
path : participant . faceStatePath ,
error : participant . faceStatePath ? "State file was not readable." : "No Face state path registered." ,
tree : [ ] ,
} ;
participant . restState = participant . faceState . restState ? ? null ;
}
const activeTurns = participantSnapshots . filter ( ( participant ) => participant . activeJobId ) ;
const readyNow = participantSnapshots . filter ( ( participant ) =>
participant . status === "active" &&
! participant . activeJobId &&
participant . restState ? . isNapping !== true &&
typeof participant . nextTurnInMinutes === "number" &&
participant . nextTurnInMinutes <= 0 ,
) ;
const nextParticipant = [ ... participantSnapshots ]
. filter ( ( participant ) => typeof participant . nextTurnInMinutes === "number" )
. sort ( ( left , right ) => left . nextTurnInMinutes - right . nextTurnInMinutes ) [ 0 ] ;
const organs = projectOrgans ( orchestrator . value ) ;
const recentEvents = Array . isArray ( heartbeat . value ? . history )
? heartbeat . value . history . slice ( - 24 ) . reverse ( ) . map ( projectHistoryEvent )
: [ ] ;
2026-07-06 22:13:23 +01:00
const recentMentionActivity = buildRecentMentionActivity ( heartbeat . value ? . history , pendingMentions ) ;
2026-06-02 15:53:17 +01:00
const controls = projectControls ( heartbeat . value ? . controls ) ;
const upcomingTurns = buildUpcomingTurns ( participantSnapshots ) ;
const lastShuffle = findLastShuffleEvent ( recentEvents ) ;
2026-07-06 22:13:23 +01:00
const lastMentionActivity = recentMentionActivity [ 0 ] ? ? null ;
2026-06-02 15:53:17 +01:00
return {
schemaVersion : snapshotSchemaId ,
generatedAt : now . toISOString ( ) ,
title : "VoidBot Swarm State" ,
sources : {
heartbeatStatePath ,
heartbeatStateUpdatedAt : heartbeatMtime ,
heartbeatStateReadable : heartbeat . ok ,
heartbeatStateError : heartbeat . ok ? undefined : heartbeat . error ,
orchestratorPath ,
orchestratorUpdatedAt : orchestratorMtime ,
orchestratorReadable : orchestrator . ok ,
orchestratorError : orchestrator . ok ? undefined : orchestrator . error ,
pausePath ,
pauseReadable : pause . ok ,
pauseError : pause . ok ? undefined : pause . error ,
} ,
cultMesh : {
documentType : snapshotDocumentType ,
schemaId : snapshotSchemaId ,
documentKey : "voidbot-swarm" ,
storePath : cultMeshStorePath ,
writeStatus : "pending" ,
providerId ,
verseId ,
eveDeckEndpoint : primaryCultMeshEndpoint ( ) ,
note : "VoidBot swarm is a CultMesh-advertised Eve provider. The web page is a local lowering of the same surface." ,
} ,
summary : {
state : deriveSwarmState ( { heartbeat , orchestrator , paused , activeTurns } ) ,
paused ,
pauseReason ,
participantCount : participantSnapshots . length ,
activeTurnCount : activeTurns . length ,
pendingMentionCount : pendingMentions . length ,
2026-07-06 22:13:23 +01:00
recentMentionActivityCount : recentMentionActivity . length ,
lastMentionActivity ,
2026-06-02 15:53:17 +01:00
readyNowCount : readyNow . length ,
nextIdentityId : nextParticipant ? . identityId ? ? null ,
nextDisplayName : nextParticipant ? . displayName ? ? null ,
nextTurnInMinutes : nextParticipant ? . nextTurnInMinutes ? ? null ,
initiativeClock ,
baseRecoveryMinutes : numberOrNull ( heartbeat . value ? . baseRecoveryMinutes ) ,
globalHeat : numberOrNull ( heartbeat . value ? . globalHeat ) ,
cadenceMultiplier : controls . cadenceMultiplier ,
lastTickAt : stringOrNull ( heartbeat . value ? . lastTickAt ) ,
lastShuffle ,
} ,
controls ,
upcomingTurns ,
participants : participantSnapshots ,
activeTurns ,
pendingMentions : pendingMentions . map ( projectPendingMention ) ,
2026-07-06 22:13:23 +01:00
recentMentionActivity ,
2026-06-02 15:53:17 +01:00
orchestrator : {
state : deriveOrchestratorState ( organs ) ,
organs ,
} ,
recentEvents ,
} ;
}
function projectControls ( value ) {
const cadenceMultiplier = numberOrNull ( value ? . cadenceMultiplier ) ? ? 1 ;
const manualTurnRequests = Array . isArray ( value ? . manualTurnRequests )
? value . manualTurnRequests . slice ( - 12 ) . reverse ( ) . map ( ( request ) => ( {
id : stringOrNull ( request ? . id ) ,
identityId : stringOrNull ( request ? . identityId ) ,
requestedAt : stringOrNull ( request ? . requestedAt ) ,
status : stringOrNull ( request ? . status ) ? ? "pending" ,
note : stringOrNull ( request ? . note ) ,
} ) )
: [ ] ;
return {
cadenceMultiplier ,
updatedAt : stringOrNull ( value ? . updatedAt ) ,
manualTurnRequests ,
} ;
}
function buildUpcomingTurns ( participants ) {
const ordered = [ ... participants ]
. filter ( ( participant ) => participant . status === "active" )
. sort ( ( left , right ) => {
const activeDelta = Number ( Boolean ( right . activeJobId ) ) - Number ( Boolean ( left . activeJobId ) ) ;
if ( activeDelta ) return activeDelta ;
return ( left . nextTurnInMinutes ? ? 999999 ) - ( right . nextTurnInMinutes ? ? 999999 ) ;
} )
. slice ( 0 , 16 ) ;
const maxMinutes = Math . max ( 1 , ... ordered . map ( ( participant ) => Math . max ( 0 , participant . nextTurnInMinutes ? ? 0 ) ) ) ;
return ordered . map ( ( participant , index ) => ( {
identityId : participant . identityId ,
displayName : participant . displayName ,
repoName : participant . repoName ,
avatarUrl : participant . avatarUrl ,
participantKind : participant . participantKind ,
activeJobId : participant . activeJobId ,
restState : participant . restState ,
pendingMentionCount : participant . pendingMentionCount ,
shuffleReason : participant . pendingMentionCount > 0
? "mention"
: participant . activeJobId
? "active"
: participant . restState ? . isNapping === true
? "nap"
: null ,
nextTurnInMinutes : participant . nextTurnInMinutes ,
effectiveSpeed : participant . effectiveSpeed ,
heat : participant . heat ,
2026-07-12 02:21:43 +01:00
dynamicHeat : participant . dynamicHeat ,
responsePressure : participant . responsePressure ,
2026-06-02 15:53:17 +01:00
lane : index % 3 ,
timelinePosition : participant . activeJobId ? 0 : Math . min ( 100 , Math . max ( 0 , ( ( Math . max ( 0 , participant . nextTurnInMinutes ? ? 0 ) ) / maxMinutes ) * 100 ) ) ,
} ) ) ;
}
function findLastShuffleEvent ( events ) {
const directMention = events . find ( ( event ) =>
event . type === "queued" &&
typeof event . pendingMentionCount === "number" &&
event . pendingMentionCount > 0
) ;
if ( directMention ) {
return {
kind : "direct_mention" ,
identityId : directMention . identityId ,
observedAt : directMention . observedAt ,
} ;
}
const manual = events . find ( ( event ) => event . type === "manual_turn_override_applied" ) ;
if ( manual ) {
return {
kind : "manual_override" ,
identityId : manual . identityId ,
observedAt : manual . observedAt ,
} ;
}
return null ;
}
function projectParticipant ( participant , pendingMentions , initiativeClock , identityMetadata ) {
const identityId = String ( participant . identityId ? ? "unknown" ) ;
const metadata = identityMetadata . get ( identityId . toLowerCase ( ) ) ? ? { } ;
const nextTurnAt = numberOrNull ( participant . nextTurnAt ) ;
const lastTurnAt = numberOrNull ( participant . lastTurnAt ) ;
const activeTurnStartedAt = numberOrNull ( participant . activeTurnStartedAt ) ;
const channelCount = Array . isArray ( participant . groups )
? participant . groups . filter ( ( entry ) => typeof entry === "string" && entry . startsWith ( "channel:" ) ) . length
: 0 ;
const mentionCount = pendingMentions . filter ( ( mention ) => mention ? . identityId === identityId ) . length ;
const nextTurnInMinutes =
typeof nextTurnAt === "number" && typeof initiativeClock === "number"
? round ( nextTurnAt - initiativeClock , 3 )
: null ;
return {
identityId ,
displayName : String ( participant . displayName ? ? metadata . displayName ? ? identityId ) ,
repoName : String ( participant . repoName ? ? metadata . repoName ? ? "unknown" ) ,
repoPath : stringOrNull ( metadata . repoPath ) ,
faceStatePath : stringOrNull ( metadata . faceStatePath ) ,
personaStatePath : stringOrNull ( metadata . personaStatePath ) ,
description : stringOrNull ( metadata . description ) ,
avatarUrl : metadata . avatarUrl ? ? null ,
avatarPath : metadata . avatarPath ? ? null ,
channelPermissions : Array . isArray ( metadata . channelPermissions )
? metadata . channelPermissions . slice ( 0 , 12 ) . map ( ( entry ) => ( {
label : stringOrNull ( entry ? . label ) ,
topic : stringOrNull ( entry ? . topic ) ,
speechThreshold : stringOrNull ( entry ? . speechThreshold ) ,
speedMultiplier : numberOrNull ( entry ? . speedMultiplier ) ,
} ) )
: [ ] ,
participantKind : String ( participant . participantKind ? ? "repo_face" ) ,
turnKind : String ( participant . turnKind ? ? "repo_face_rumination" ) ,
status : String ( participant . status ? ? "unknown" ) ,
currentLoad : numberOrNull ( participant . currentLoad ) ,
heat : numberOrNull ( participant . heat ) ,
2026-07-12 02:21:43 +01:00
dynamicHeat : numberOrNull ( participant . dynamicHeat ) ,
responsePressure : numberOrNull ( participant . responsePressure ) ,
responsePressureEvidence : Array . isArray ( participant . responsePressureEvidence )
? participant . responsePressureEvidence . slice ( 0 , 6 ) . map ( ( entry ) => ( {
messageId : stringOrNull ( entry ? . messageId ) ,
observedAt : stringOrNull ( entry ? . observedAt ) ,
similarity : numberOrNull ( entry ? . similarity ) ,
contribution : numberOrNull ( entry ? . contribution ) ,
} ) )
: [ ] ,
2026-06-02 15:53:17 +01:00
effectiveSpeed : numberOrNull ( participant . effectiveSpeed ) ,
initiativeSpeed : numberOrNull ( participant . initiativeSpeed ) ,
nextTurnAt ,
nextTurnInMinutes ,
lastTurnAt ,
activeTurnStartedAt ,
activeJobId : stringOrNull ( participant . activeJobId ) ,
lastQueuedAt : stringOrNull ( participant . lastQueuedAt ) ,
queuedCount : numberOrNull ( participant . queuedCount ) ,
pendingMentionCount : mentionCount ,
channelCount ,
constraintCount : Array . isArray ( participant . constraints ) ? participant . constraints . length : 0 ,
constraints : Array . isArray ( participant . constraints ) ? participant . constraints . slice ( 0 , 4 ) . map ( String ) : [ ] ,
} ;
}
function projectOrgans ( orchestrator ) {
const organs = orchestrator ? . organs && typeof orchestrator . organs === "object" ? orchestrator . organs : { } ;
return Object . entries ( organs ) . map ( ( [ id , organ ] ) => ( {
id ,
label : String ( organ ? . label ? ? id ) ,
intervalMinutes : numberOrNull ( organ ? . intervalMinutes ) ,
lastStartedAt : stringOrNull ( organ ? . lastStartedAt ) ,
lastFinishedAt : stringOrNull ( organ ? . lastFinishedAt ) ,
lastExitCode : numberOrNull ( organ ? . lastExitCode ) ,
lastStatus : String ( organ ? . lastStatus ? ? "unknown" ) ,
lastLogPath : stringOrNull ( organ ? . lastLogPath ) ,
2026-07-05 19:58:59 +01:00
cultMeshServer : organ ? . cultMeshServer && typeof organ . cultMeshServer === "object"
? {
status : stringOrNull ( organ . cultMeshServer . status ) ,
pid : numberOrNull ( organ . cultMeshServer . pid ) ,
bind : stringOrNull ( organ . cultMeshServer . bind ) ,
storePath : stringOrNull ( organ . cultMeshServer . storePath ) ,
odinCultMeshUri : stringOrNull ( organ . cultMeshServer . odinCultMeshUri ) ,
odinRudpEndpoint : stringOrNull ( organ . cultMeshServer . odinRudpEndpoint ) ,
error : stringOrNull ( organ . cultMeshServer . error ) ,
}
: null ,
2026-06-02 15:53:17 +01:00
} ) ) ;
}
function projectHistoryEvent ( event ) {
return {
type : String ( event ? . type ? ? "event" ) ,
identityId : stringOrNull ( event ? . identityId ) ,
2026-07-06 22:13:23 +01:00
observedAt : stringOrNull ( event ? . observedAt ? ? event ? . queuedAt ? ? event ? . consumedAt ? ? event ? . appliedAt ) ,
2026-06-02 15:53:17 +01:00
activeJobId : stringOrNull ( event ? . activeJobId ) ,
statusPath : stringOrNull ( event ? . statusPath ) ,
reason : stringOrNull ( event ? . reason ) ,
pendingMentionCount : numberOrNull ( event ? . pendingMentionCount ) ,
2026-07-06 22:13:23 +01:00
mentionCount : numberOrNull ( event ? . mentionCount ) ,
2026-06-02 15:53:17 +01:00
nextTurnAt : numberOrNull ( event ? . nextTurnAt ) ,
recoveryMinutes : numberOrNull ( event ? . recoveryMinutes ) ,
} ;
}
2026-07-06 22:13:23 +01:00
function buildRecentMentionActivity ( history , pendingMentions ) {
const activity = [ ] ;
for ( const mention of pendingMentions ? ? [ ] ) {
const projected = projectPendingMention ( mention ) ;
activity . push ( {
kind : "pending" ,
identityId : projected . identityId ,
sourceChannelId : projected . sourceChannelId ,
sourceMessageId : projected . sourceMessageId ,
observedAt : projected . createdAt ,
mentionCount : 1 ,
prompt : projected . prompt ,
} ) ;
}
const events = Array . isArray ( history ) ? history : [ ] ;
for ( let index = events . length - 1 ; index >= 0 && activity . length < 16 ; index -= 1 ) {
const event = events [ index ] ;
const type = String ( event ? . type ? ? "" ) ;
if ( type === "pending_mentions_consumed" ) {
const mentions = Array . isArray ( event ? . mentions ) ? event . mentions . map ( projectMentionEventEntry ) : [ ] ;
activity . push ( {
kind : "consumed" ,
identityId : stringOrNull ( event ? . identityId ) ,
observedAt : stringOrNull ( event ? . consumedAt ? ? event ? . queuedAt ) ,
activeJobId : stringOrNull ( event ? . activeJobId ) ,
requestMessageId : stringOrNull ( event ? . requestMessageId ) ,
mentionCount : numberOrNull ( event ? . mentionCount ) ? ? mentions . length ,
sourceChannelId : mentions [ 0 ] ? . sourceChannelId ? ? null ,
sourceMessageId : mentions [ 0 ] ? . sourceMessageId ? ? null ,
prompt : mentions [ 0 ] ? . prompt ? ? "" ,
mentions ,
} ) ;
} else if ( type === "pending_mention_queued" || type === "pending_mention_duplicate" ) {
activity . push ( {
kind : type === "pending_mention_duplicate" ? "duplicate_intake" : "intake" ,
identityId : stringOrNull ( event ? . identityId ) ,
sourceChannelId : stringOrNull ( event ? . sourceChannelId ? ? event ? . channelId ) ,
sourceMessageId : stringOrNull ( event ? . sourceMessageId ? ? event ? . messageId ) ,
observedAt : stringOrNull ( event ? . queuedAt ? ? event ? . observedAt ) ,
mentionCount : 1 ,
prompt : "" ,
} ) ;
} else if (
type === "queued" &&
typeof event ? . pendingMentionCount === "number" &&
event . pendingMentionCount > 0
) {
activity . push ( {
kind : "handled_job" ,
identityId : stringOrNull ( event ? . identityId ) ,
observedAt : stringOrNull ( event ? . queuedAt ? ? event ? . observedAt ) ,
activeJobId : stringOrNull ( event ? . activeJobId ) ,
requestMessageId : stringOrNull ( event ? . requestMessageId ) ,
mentionCount : numberOrNull ( event ? . pendingMentionCount ) ,
prompt : "" ,
} ) ;
}
}
return activity
. sort ( ( left , right ) => timestampMs ( right . observedAt ) - timestampMs ( left . observedAt ) )
. slice ( 0 , 12 ) ;
}
function projectMentionEventEntry ( mention ) {
return {
id : stringOrNull ( mention ? . id ) ,
sourceChannelId : stringOrNull ( mention ? . sourceChannelId ? ? mention ? . channelId ) ,
sourceMessageId : stringOrNull ( mention ? . sourceMessageId ? ? mention ? . messageId ) ,
authorId : stringOrNull ( mention ? . authorId ) ,
authorName : stringOrNull ( mention ? . authorName ) ,
createdAt : stringOrNull ( mention ? . createdAt ? ? mention ? . queuedAt ) ,
prompt : truncate ( String ( mention ? . prompt ? ? mention ? . visiblePrompt ? ? mention ? . content ? ? "" ) , 220 ) ,
} ;
}
2026-06-02 15:53:17 +01:00
async function readIdentityMetadata ( registryPathValue ) {
const metadata = new Map ( ) ;
const registryPath = resolveConfigPath ( registryPathValue , resolve ( repoRoot , ".voidbot" , "private" , "repo-discord-identities.json" ) ) ;
const registry = await readJsonFile ( registryPath ) ;
const identities = Array . isArray ( registry . value ? . identities )
? registry . value . identities
: Array . isArray ( registry . value )
? registry . value
: [ ] ;
for ( const identity of identities ) {
const id = typeof identity ? . id === "string" ? identity . id . toLowerCase ( ) : "" ;
if ( id ) {
metadata . set ( id , {
id ,
displayName : stringOrNull ( identity ? . displayName ) ,
repoName : stringOrNull ( identity ? . repoName ) ,
repoPath : stringOrNull ( identity ? . repoPath ) ,
identityKind : stringOrNull ( identity ? . identityKind ) ,
faceStatePath : stringOrNull ( identity ? . faceStatePath ) ,
personaStatePath : stringOrNull ( identity ? . personaStatePath ) ,
description : stringOrNull ( identity ? . description ) ,
avatarUrl : stringOrNull ( identity ? . avatarUrl ) ,
avatarPath : stringOrNull ( identity ? . avatarPath ) ,
channelPermissions : Array . isArray ( identity ? . channelPermissions ) ? identity . channelPermissions : [ ] ,
} ) ;
}
}
return metadata ;
}
async function readFaceStates ( identityMetadata ) {
const states = new Map ( ) ;
let core = null ;
try {
const requireCore = createRequire ( resolve ( repoRoot , "packages" , "core" , "package.json" ) ) ;
core = requireCore ( resolve ( repoRoot , "packages" , "core" , "dist" , "index.js" ) ) ;
} catch ( error ) {
for ( const [ id , identity ] of identityMetadata . entries ( ) ) {
states . set ( id , {
readable : false ,
path : identity . faceStatePath ? ? null ,
error : ` Core typed-state loader unavailable: ${ error instanceof Error ? error . message : String ( error ) } ` ,
tree : [ ] ,
} ) ;
}
return states ;
}
for ( const [ id , identity ] of identityMetadata . entries ( ) ) {
if ( identity . identityKind === "native_persona" ) {
states . set ( id , readPersonaStateSummary ( identity ) ) ;
continue ;
}
if ( ! identity . faceStatePath ) {
states . set ( id , {
readable : false ,
path : null ,
error : "No Face state path registered." ,
tree : [ ] ,
} ) ;
continue ;
}
try {
const typedState = await core . loadVoidSelfStateTypedDocuments ( {
canonicalPath : identity . faceStatePath ,
identity : {
agentId : id ,
publicName : identity . displayName ? ? id ,
publicDescription : identity . description ? ? undefined ,
} ,
} ) ;
const rendered = core . buildVoidSelfStateContext
? core . buildVoidSelfStateContext ( typedState , {
sourcePath : identity . faceStatePath ,
identity : {
agentId : id ,
publicName : identity . displayName ? ? id ,
publicDescription : identity . description ? ? undefined ,
} ,
} )
: null ;
states . set ( id , {
readable : true ,
path : identity . faceStatePath ,
summary : truncate ( rendered ? . summary ? ? "" , 1200 ) ,
counts : countFaceState ( typedState ) ,
restState : projectRestState ( typedState ) ,
tree : buildFaceStateTree ( typedState ) ,
} ) ;
} catch ( error ) {
states . set ( id , {
readable : false ,
path : identity . faceStatePath ,
error : error instanceof Error ? error . message : String ( error ) ,
tree : [ ] ,
} ) ;
}
}
return states ;
}
function readPersonaStateSummary ( identity ) {
if ( ! identity . personaStatePath ) {
return {
readable : false ,
path : null ,
error : "No Persona state path registered." ,
tree : [ ] ,
} ;
}
try {
const raw = readFileSync ( resolve ( identity . personaStatePath ) , "utf8" ) ;
const state = JSON . parse ( stripBom ( raw ) ) ;
return {
readable : true ,
kind : "native_persona" ,
path : identity . personaStatePath ,
summary : truncate ( state . publicDescription ? ? state . presentation ? . voiceSummary ? ? "" , 1200 ) ,
counts : {
memory : state . thoughtMemory ? . memories ? . length ? ? 0 ,
pressures : state . agencyPressure ? . pressures ? . length ? ? 0 ,
needs : state . affect ? . needs ? . length ? ? 0 ,
statusReads : state . affect ? . statusReads ? . length ? ? 0 ,
doctrine : state . affect ? . doctrineStances ? . length ? ? 0 ,
} ,
tree : buildPersonaStateTree ( state ) ,
} ;
} catch ( error ) {
return {
readable : false ,
kind : "native_persona" ,
path : identity . personaStatePath ,
error : error instanceof Error ? error . message : String ( error ) ,
tree : [ ] ,
} ;
}
}
function buildPersonaStateTree ( state ) {
return [
node ( "Persona" , "persona" , [
leaf ( "Public Name" , state . publicName ) ,
leaf ( "Description" , state . publicDescription ) ,
leaf ( "Voice" , state . presentation ? . voiceSummary ) ,
collectionNode ( "Values" , "values" , state . values , valueNode ) ,
objectNode ( "Activation" , "activationProfile" , state . activationProfile ) ,
collectionNode ( "Private Notes" , "privateNotes" , state . privateNotes , valueNode ) ,
] ) ,
node ( "Thought Memory" , "thoughtMemory" , [
collectionNode ( "Short Term" , "thoughtMemory.shortTerm" , state . thoughtMemory ? . shortTerm , memoryNode ) ,
collectionNode ( "Durable Memories" , "thoughtMemory.memories" , state . thoughtMemory ? . memories , memoryNode ) ,
collectionNode ( "Incubation" , "thoughtMemory.incubation" , state . thoughtMemory ? . incubation , memoryNode ) ,
] ) ,
node ( "Affect" , "affect" , [
collectionNode ( "Needs" , "affect.needs" , state . affect ? . needs , valueNode ) ,
collectionNode ( "Status Reads" , "affect.statusReads" , state . affect ? . statusReads , valueNode ) ,
collectionNode ( "Doctrine" , "affect.doctrineStances" , state . affect ? . doctrineStances , valueNode ) ,
] ) ,
] ;
}
function projectRestState ( typedState ) {
const sleepCycle = typedState ? . scheduledRuntime ? . sleepCycle ;
if ( ! sleepCycle || typeof sleepCycle !== "object" ) {
return null ;
}
return {
isNapping : sleepCycle . isNapping === true ,
napEndsAt : stringOrNull ( sleepCycle . currentNapEndsAt ) ,
nextNapStartsAt : stringOrNull ( sleepCycle . nextNapStartsAt ) ,
activeDreamThemes : Array . isArray ( sleepCycle . activeDreamThemes )
? sleepCycle . activeDreamThemes . slice ( 0 , 8 ) . map ( String )
: [ ] ,
} ;
}
function countFaceState ( typedState ) {
return {
shortTerm : typedState ? . thoughtMemory ? . shortTerm ? . length ? ? 0 ,
memories : typedState ? . thoughtMemory ? . memories ? . length ? ? 0 ,
incubation : typedState ? . thoughtMemory ? . incubation ? . length ? ? 0 ,
bonds : typedState ? . faceAffect ? . socialBonds ? . length ? ? 0 ,
pressures : typedState ? . agencyPressure ? . pressures ? . length ? ? 0 ,
candidates : typedState ? . candidateInterventions ? . interventions ? . length ? ? 0 ,
} ;
}
function buildFaceStateTree ( typedState ) {
return [
node ( "Self Profile" , "selfProfile" , [
leaf ( "Public Name" , typedState ? . selfProfile ? . publicName ) ,
leaf ( "Description" , typedState ? . selfProfile ? . publicDescription ) ,
collectionNode ( "Values" , "selfProfile.values" , typedState ? . selfProfile ? . values , valueNode ) ,
objectNode ( "Activation" , "selfProfile.activationProfile" , typedState ? . selfProfile ? . activationProfile ) ,
collectionNode ( "Private Notes" , "selfProfile.privateNotes" , typedState ? . selfProfile ? . privateNotes , valueNode ) ,
] ) ,
node ( "Thought Memory" , "thoughtMemory" , [
collectionNode ( "Short Term" , "thoughtMemory.shortTerm" , typedState ? . thoughtMemory ? . shortTerm , memoryNode ) ,
collectionNode ( "Durable Memories" , "thoughtMemory.memories" , typedState ? . thoughtMemory ? . memories , memoryNode ) ,
collectionNode ( "Incubation" , "thoughtMemory.incubation" , typedState ? . thoughtMemory ? . incubation , memoryNode ) ,
] ) ,
node ( "Affect" , "faceAffect" , [
collectionNode ( "Needs" , "faceAffect.needs" , typedState ? . faceAffect ? . needs , valueNode ) ,
collectionNode ( "Social Bonds" , "faceAffect.socialBonds" , typedState ? . faceAffect ? . socialBonds , memoryNode ) ,
collectionNode ( "Status Reads" , "faceAffect.statusReads" , typedState ? . faceAffect ? . statusReads , memoryNode ) ,
objectNode ( "Mood" , "faceAffect.moodDimensions" , typedState ? . faceAffect ? . moodDimensions ) ,
collectionNode ( "Social Biases" , "faceAffect.socialBiases" , typedState ? . faceAffect ? . socialBiases , valueNode ) ,
] ) ,
node ( "Agency" , "agencyPressure" , [
collectionNode ( "Pressures" , "agencyPressure.pressures" , typedState ? . agencyPressure ? . pressures , memoryNode ) ,
collectionNode ( "Candidates" , "candidateInterventions.interventions" , typedState ? . candidateInterventions ? . interventions , memoryNode ) ,
] ) ,
node ( "Runtime" , "scheduledRuntime" , [
objectNode ( "Sleep Cycle" , "scheduledRuntime.sleepCycle" , typedState ? . scheduledRuntime ? . sleepCycle ) ,
objectNode ( "Speaking Pressure" , "scheduledRuntime.speakingPressure" , typedState ? . scheduledRuntime ? . speakingPressure ) ,
objectNode ( "Last Runs" , "scheduledRuntime.lastRuns" , typedState ? . scheduledRuntime ? . lastRuns ) ,
] ) ,
] . filter ( Boolean ) ;
}
function node ( label , path , children = [ ] ) {
const compactChildren = children . filter ( Boolean ) ;
return { kind : "branch" , label , path , children : compactChildren , count : compactChildren . length } ;
}
function leaf ( label , value , path = label ) {
if ( value === null || value === undefined || value === "" ) return null ;
return {
kind : "leaf" ,
label ,
path ,
title : label ,
preview : truncate ( renderValuePreview ( value ) , 120 ) ,
detail : renderValueDetail ( value ) ,
} ;
}
function collectionNode ( label , path , values , projector ) {
if ( ! Array . isArray ( values ) || values . length === 0 ) return node ( label , path , [ leaf ( "empty" , "No entries." , ` ${ path } .empty ` ) ] ) ;
return node ( label , path , values . slice ( 0 , 80 ) . map ( ( value , index ) => projector ( value , ` ${ path } . ${ index } ` , index ) ) ) ;
}
function objectNode ( label , path , value ) {
if ( ! value || typeof value !== "object" ) return node ( label , path , [ leaf ( "empty" , "No entries." , ` ${ path } .empty ` ) ] ) ;
const children = Object . entries ( value ) . slice ( 0 , 80 ) . map ( ( [ key , entry ] ) => {
if ( entry && typeof entry === "object" ) return objectNode ( key , ` ${ path } . ${ key } ` , entry ) ;
return leaf ( key , entry , ` ${ path } . ${ key } ` ) ;
} ) ;
return node ( label , path , children ) ;
}
function valueNode ( value , path , index ) {
if ( value && typeof value === "object" ) {
const title = value . label ? ? value . name ? ? value . kind ? ? value . id ? ? ` entry ${ index + 1 } ` ;
return leaf ( String ( title ) , value , path ) ;
}
return leaf ( ` entry ${ index + 1 } ` , value , path ) ;
}
function memoryNode ( value , path , index ) {
if ( ! value || typeof value !== "object" ) return leaf ( ` entry ${ index + 1 } ` , value , path ) ;
const target = value . target ? . label ? ? value . target ? . id ? ? value . targetKind ? ? value . target ? ? value . kind ;
const title = value . summary ? ? value . claim ? ? value . question ? ? value . title ? ? value . id ? ? value . memoryId ? ? ` entry ${ index + 1 } ` ;
const label = target ? ` ${ target } : ${ title } ` : title ;
return {
kind : "leaf" ,
label : truncate ( String ( label ) , 120 ) ,
path ,
title : String ( title ) ,
preview : truncate ( value . claim ? ? value . question ? ? value . tension ? ? value . actionImplication ? ? value . summary ? ? renderValuePreview ( value ) , 180 ) ,
detail : renderMemoryDetail ( value ) ,
} ;
}
function renderMemoryDetail ( value ) {
const lines = [ ] ;
for ( const key of [ "kind" , "summary" , "claim" , "question" , "tension" , "actionImplication" , "status" , "intensity" , "createdAt" , "updatedAt" ] ) {
if ( value ? . [ key ] !== null && value ? . [ key ] !== undefined && value ? . [ key ] !== "" ) {
lines . push ( ` ${ key } : ${ renderValuePreview ( value [ key ] ) } ` ) ;
}
}
if ( value ? . target ) lines . push ( ` target: ${ renderValuePreview ( value . target ) } ` ) ;
if ( Array . isArray ( value ? . anchorRefs ) && value . anchorRefs . length > 0 ) {
lines . push ( ` anchors: \n ${ value . anchorRefs . map ( ( anchor ) => ` - ${ renderValuePreview ( anchor ) } ` ) . join ( "\n" ) } ` ) ;
}
if ( Array . isArray ( value ? . tags ) && value . tags . length > 0 ) lines . push ( ` tags: ${ value . tags . join ( ", " ) } ` ) ;
return lines . join ( "\n\n" ) || renderValueDetail ( value ) ;
}
function renderValuePreview ( value ) {
if ( typeof value === "string" ) return value ;
if ( typeof value === "number" || typeof value === "boolean" ) return String ( value ) ;
return JSON . stringify ( value ) ;
}
function renderValueDetail ( value ) {
return typeof value === "string" ? value : JSON . stringify ( value , null , 2 ) ;
}
function projectPendingMention ( mention ) {
return {
identityId : stringOrNull ( mention ? . identityId ) ,
2026-07-05 22:34:33 +01:00
sourceChannelId : stringOrNull ( mention ? . sourceChannelId ? ? mention ? . channelId ) ,
sourceMessageId : stringOrNull ( mention ? . sourceMessageId ? ? mention ? . messageId ) ,
createdAt : stringOrNull ( mention ? . createdAt ? ? mention ? . queuedAt ) ,
prompt : truncate ( String ( mention ? . prompt ? ? mention ? . visiblePrompt ? ? mention ? . content ? ? "" ) , 220 ) ,
2026-06-02 15:53:17 +01:00
} ;
}
function deriveSwarmState ( { heartbeat , orchestrator , paused , activeTurns } ) {
if ( ! heartbeat . ok ) return "missing" ;
if ( paused ) return "paused" ;
const organ = projectOrgans ( orchestrator . value ) . find ( ( entry ) => entry . id === "repo-face-heartbeats" ) ;
if ( organ && organ . lastStatus && ! [ "ok" , "skipped_disabled" ] . includes ( organ . lastStatus ) ) {
return "warning" ;
}
if ( activeTurns . length > 0 ) return "running" ;
return "ready" ;
}
function deriveOrchestratorState ( organs ) {
if ( organs . length === 0 ) return "missing" ;
if ( organs . some ( ( organ ) => [ "failed" , "error" , "stalled" ] . includes ( organ . lastStatus ) ) ) return "warning" ;
if ( organs . some ( ( organ ) => organ . lastStatus === "running" ) ) return "running" ;
return "ok" ;
}
2026-06-08 19:20:11 +01:00
async function writeCultMeshPublication ( snapshot , eveState , storePath , allowStoreReset = true ) {
2026-06-02 15:53:17 +01:00
try {
const cultPackages = loadCultPackages ( ) ;
if ( ! cultPackages ) {
return {
writeStatus : "skipped" ,
writeError : "CultMesh/CultCache packages were not found in known local CultLib paths." ,
} ;
}
const { CultMesh , defineDocumentType } = cultPackages ;
const snapshotDefinition = defineDocumentType ( {
type : snapshotDocumentType ,
schemaName : snapshotDocumentType ,
schemaId : snapshotSchemaId ,
schemaVersion : snapshotSchemaId ,
contentHash : snapshotSchemaId ,
canonicalSchemaJson : JSON . stringify ( {
schemaName : snapshotDocumentType ,
schemaVersion : snapshotSchemaId ,
description : "Redacted read-only VoidBot swarm state snapshot for CultMesh distribution." ,
} ) ,
global : true ,
schema : {
parse ( input ) {
if ( ! input || typeof input !== "object" ) {
throw new Error ( "VoidBot swarm snapshot must be an object." ) ;
}
return input ;
} ,
} ,
} ) ;
const providerDefinition = defineDocumentType ( {
type : providerAdvertisementDocumentType ,
schemaName : providerAdvertisementDocumentType ,
schemaId : providerAdvertisementSchemaId ,
schemaVersion : providerAdvertisementSchemaId ,
contentHash : providerAdvertisementSchemaId ,
2026-06-16 20:50:49 +01:00
global : false ,
2026-06-02 15:53:17 +01:00
name : "providerId" ,
schema : { parse : parseObjectDocument ( "Eve provider advertisement" ) } ,
} ) ;
const surfaceDefinition = defineDocumentType ( {
type : surfaceDocumentType ,
schemaName : surfaceDocumentType ,
schemaId : surfaceSchemaId ,
schemaVersion : surfaceSchemaId ,
contentHash : surfaceSchemaId ,
2026-07-03 01:57:11 +01:00
global : false ,
2026-06-02 15:53:17 +01:00
name : "providerId" ,
schema : { parse : parseObjectDocument ( "Eve surface state" ) } ,
} ) ;
const eveBindingDefinition = defineDocumentType ( {
type : eveBindingDocumentType ,
schemaName : eveBindingDocumentType ,
schemaId : eveBindingSchemaId ,
schemaVersion : eveBindingSchemaId ,
contentHash : eveBindingSchemaId ,
2026-06-16 20:50:49 +01:00
global : false ,
2026-06-02 15:53:17 +01:00
name : "bindingId" ,
schema : { parse : parseObjectDocument ( "Eve interface binding" ) } ,
} ) ;
2026-06-16 20:50:49 +01:00
const providerCatalogDefinition = defineDocumentType ( {
type : providerCatalogDocumentType ,
schemaName : providerCatalogDocumentType ,
schemaId : providerCatalogSchemaId ,
schemaVersion : providerCatalogSchemaId ,
contentHash : providerCatalogSchemaId ,
global : true ,
schema : { parse : parseObjectDocument ( "VoidBot provider advertisement catalog" ) } ,
} ) ;
const transportProfileDefinition = defineDocumentType ( {
type : transportProfileDocumentType ,
schemaName : transportProfileDocumentType ,
schemaId : transportProfileSchemaId ,
schemaVersion : transportProfileSchemaId ,
contentHash : transportProfileSchemaId ,
global : false ,
name : ( value ) => value ? . profile _id || value ? . daemon _id || "voidbot" ,
schema : { parse : parseObjectDocument ( "Idunn daemon transport profile" ) } ,
} ) ;
const commandBoundaryDefinition = defineDocumentType ( {
type : commandBoundaryDocumentType ,
schemaName : commandBoundaryDocumentType ,
schemaId : commandBoundarySchemaId ,
schemaVersion : commandBoundarySchemaId ,
contentHash : commandBoundarySchemaId ,
global : false ,
name : ( value ) => value ? . boundary _id || value ? . daemon _id || "voidbot" ,
schema : { parse : parseObjectDocument ( "Idunn command boundary" ) } ,
} ) ;
2026-07-15 02:06:06 +01:00
const swarmControlDefinition = defineDocumentType ( {
type : swarmControlDocumentType ,
schemaName : swarmControlDocumentType ,
schemaId : swarmControlSchemaId ,
schemaVersion : swarmControlSchemaId ,
contentHash : swarmControlSchemaId ,
global : false ,
name : ( ) => "voidbot-swarm" ,
schema : { parse : parseObjectDocument ( "VoidBot swarm control state" ) } ,
} ) ;
2026-07-16 00:17:49 +01:00
const swarmOperatorViewDefinition = defineDocumentType ( {
type : swarmOperatorViewDocumentType ,
schemaName : swarmOperatorViewDocumentType ,
schemaId : swarmOperatorViewSchemaId ,
schemaVersion : swarmOperatorViewSchemaId ,
contentHash : swarmOperatorViewSchemaId ,
global : false ,
name : ( ) => "voidbot-swarm" ,
schema : { parse : parseObjectDocument ( "VoidBot swarm operator view" ) } ,
} ) ;
2026-06-02 15:53:17 +01:00
const node = await CultMesh . createNode ( storePath , {
2026-06-16 20:50:49 +01:00
documents : [
snapshotDefinition ,
providerDefinition ,
surfaceDefinition ,
eveBindingDefinition ,
providerCatalogDefinition ,
transportProfileDefinition ,
commandBoundaryDefinition ,
2026-07-15 02:06:06 +01:00
swarmControlDefinition ,
2026-07-16 00:17:49 +01:00
swarmOperatorViewDefinition ,
2026-06-16 20:50:49 +01:00
] ,
2026-06-02 15:53:17 +01:00
} ) ;
2026-06-16 20:50:49 +01:00
const providerCatalog = loadProviderAdvertisementCatalog ( snapshot ) ;
const providerAdvertisements = buildLiveProviderAdvertisements ( providerCatalog , snapshot ) ;
const providerAdvertisement = providerAdvertisements . find ( ( item ) => item . providerId === providerId )
? ? buildProviderAdvertisement ( snapshot ) ;
2026-06-02 15:53:17 +01:00
const eveBinding = buildEveInterfaceBinding ( snapshot , eveState ) ;
2026-06-16 20:50:49 +01:00
const commandBoundary = buildCommandBoundary ( snapshot ) ;
const transportProfile = buildTransportProfile ( snapshot ) ;
2026-06-02 15:53:17 +01:00
await node . put ( snapshotDefinition , "voidbot-swarm" , snapshot ) ;
2026-06-16 20:50:49 +01:00
await node . put ( providerCatalogDefinition , "voidbot.providers" , providerCatalog ) ;
for ( const advertisement of providerAdvertisements ) {
await node . put ( providerDefinition , advertisement . providerId , advertisement ) ;
}
2026-06-02 15:53:17 +01:00
await node . put ( surfaceDefinition , providerId , eveState ) ;
await node . put ( eveBindingDefinition , providerId , eveBinding ) ;
2026-06-16 20:50:49 +01:00
await node . put ( commandBoundaryDefinition , commandBoundary . boundary _id , commandBoundary ) ;
await node . put ( transportProfileDefinition , transportProfile . profile _id , transportProfile ) ;
2026-06-02 15:53:17 +01:00
await node . flush ? . ( true ) ;
return {
writeStatus : "ok" ,
storePath ,
2026-06-16 20:50:49 +01:00
documents : [
snapshotDocumentType ,
providerCatalogDocumentType ,
providerAdvertisementDocumentType ,
surfaceDocumentType ,
eveBindingDocumentType ,
commandBoundaryDocumentType ,
transportProfileDocumentType ,
] ,
2026-06-02 15:53:17 +01:00
providerId ,
verseId ,
eveBinding : {
documentType : eveBindingDocumentType ,
schemaId : eveBindingSchemaId ,
key : providerId ,
} ,
eveDeckEndpoint : primaryCultMeshEndpoint ( ) ,
writtenAt : new Date ( ) . toISOString ( ) ,
} ;
} catch ( error ) {
2026-06-08 19:20:11 +01:00
const message = error instanceof Error ? error . message : String ( error ) ;
if (
allowStoreReset &&
existsSync ( storePath ) &&
/global document type .* has multiple persisted entries/i . test ( message )
) {
const backupPath = ` ${ storePath } .bak-duplicate-globals- ${ timestampForFile ( new Date ( ) ) } ` ;
await rename ( storePath , backupPath ) ;
const retry = await writeCultMeshPublication ( snapshot , eveState , storePath , false ) ;
return {
... retry ,
recoveredFrom : {
reason : "duplicate-global-documents" ,
backupPath ,
} ,
} ;
}
2026-06-02 15:53:17 +01:00
return {
writeStatus : "failed" ,
storePath ,
2026-06-08 19:20:11 +01:00
writeError : message ,
2026-06-02 15:53:17 +01:00
} ;
}
}
2026-06-08 19:20:11 +01:00
function timestampForFile ( date ) {
return date . toISOString ( ) . replace ( /[:.]/g , "" ) . replace ( "T" , "-" ) . replace ( "Z" , "Z" ) ;
}
2026-06-02 15:53:17 +01:00
function loadCultPackages ( ) {
2026-07-15 01:41:41 +01:00
const cultLibRoot = process . env . VOIDBOT _CULTLIB _ROOT
? resolve ( process . env . VOIDBOT _CULTLIB _ROOT )
2026-07-15 01:47:36 +01:00
: resolve ( repoRoot , ".." , "CultLib-dev-runtime" ) ;
2026-06-02 15:53:17 +01:00
const candidates = [
2026-07-15 01:41:41 +01:00
resolve ( cultLibRoot , "packages" , "cultmesh-ts" , "package.json" ) ,
2026-06-02 15:53:17 +01:00
resolve ( repoRoot , ".." , "CultMeshTS" , "package.json" ) ,
] ;
for ( const packageJson of candidates ) {
if ( ! existsSync ( packageJson ) ) {
continue ;
}
try {
const requireCult = createRequire ( packageJson ) ;
2026-06-08 19:20:11 +01:00
const { CultMesh } = requireFirstAvailable ( requireCult , [
"cultmesh-ts" ,
"cultmesh-ts/dist/index.js" ,
] ) ;
const { defineDocumentType } = requireFirstAvailable ( requireCult , [
"cultcache-ts" ,
"cultcache-ts/dist/index.js" ,
] ) ;
2026-06-02 15:53:17 +01:00
if ( CultMesh && defineDocumentType ) {
return { CultMesh , defineDocumentType } ;
}
} catch {
continue ;
}
}
return null ;
}
2026-06-08 19:20:11 +01:00
function requireFirstAvailable ( requireFromPackage , specifiers ) {
let lastError ;
for ( const specifier of specifiers ) {
try {
return requireFromPackage ( specifier ) ;
} catch ( error ) {
lastError = error ;
}
}
throw lastError ;
}
2026-06-02 15:53:17 +01:00
function parseObjectDocument ( label ) {
return ( input ) => {
if ( ! input || typeof input !== "object" ) {
throw new Error ( ` ${ label } must be an object. ` ) ;
}
return input ;
} ;
}
2026-06-16 20:50:49 +01:00
function loadProviderAdvertisementCatalog ( snapshot ) {
const fixturePath = resolve ( repoRoot , "docs" , "architecture" , "voidbot-provider-advertisements.fixture.json" ) ;
const fixture = JSON . parse ( readFileSync ( fixturePath , "utf8" ) ) ;
fixture . fixtureKind = "daemon-live-publication" ;
fixture . generatedAt = snapshot . generatedAt ;
fixture . cultMeshKeys . liveSwarmStore = cultMeshStorePath ;
return fixture ;
}
function buildLiveProviderAdvertisements ( catalog , snapshot ) {
const providers = Array . isArray ( catalog . providers ) ? catalog . providers : [ ] ;
return providers . map ( ( provider ) => {
if ( provider . providerId === providerId ) {
return {
... provider ,
status : snapshot . summary ? . state ? ? provider . status ? ? "unknown" ,
updatedAt : snapshot . generatedAt ,
2026-07-05 19:17:10 +01:00
endpoints : providerEndpoints ( ) ,
routes : providerRoutes ( ) ,
cultMeshAddress : primaryCultMeshEndpoint ( ) ,
2026-06-16 20:50:49 +01:00
witnesses : Array . isArray ( provider . witnesses )
? provider . witnesses . map ( ( witness ) =>
witness . id === "voidbot.swarm_state_snapshot"
? { ... witness , path : cultMeshStorePath }
: witness )
: provider . witnesses ,
} ;
}
return {
... provider ,
updatedAt : snapshot . generatedAt ,
} ;
} ) ;
}
2026-06-02 15:53:17 +01:00
function buildProviderAdvertisement ( snapshot ) {
2026-07-05 19:17:10 +01:00
const endpoints = providerEndpoints ( ) ;
2026-06-02 15:53:17 +01:00
return {
schemaVersion : providerAdvertisementSchemaId ,
providerId ,
verseId ,
title : "VoidBot Swarm" ,
description : "VoidBot swarm status, CTB order, controls, and selected Face state as an Eve/CultUI surface." ,
version : String ( snapshot . summary ? . initiativeClock ? ? Date . now ( ) ) ,
status : snapshot . summary ? . state ? ? "unknown" ,
updatedAt : snapshot . generatedAt ,
endpoints ,
2026-07-05 19:17:10 +01:00
routes : providerRoutes ( ) ,
cultMeshAddress : primaryCultMeshEndpoint ( ) ,
2026-06-02 15:53:17 +01:00
provider : providerManifest ( ) ,
controlSurface : {
primary : primaryCultMeshEndpoint ( ) ,
controls : {
transport : "cultmesh-binding" ,
documentType : eveBindingDocumentType ,
key : providerId ,
} ,
} ,
documents : [ {
type : snapshotDocumentType ,
schemaId : snapshotSchemaId ,
key : "voidbot-swarm" ,
} , {
type : surfaceDocumentType ,
schemaId : surfaceSchemaId ,
key : providerId ,
} , {
type : eveBindingDocumentType ,
schemaId : eveBindingSchemaId ,
key : providerId ,
} ] ,
} ;
}
2026-06-16 20:50:49 +01:00
function buildCommandBoundary ( snapshot ) {
return {
boundary _id : "command-boundary:voidbot" ,
daemon _id : "voidbot" ,
owner : "VoidBot local stack" ,
restart _authority : "E:\\Projects\\Odin\\scripts\\restart-voidbot.cmd" ,
deploy _authority : "none" ,
health _authority : "voidbot.cultnet-rudp-stack-health" ,
alarm _authority : "bifrost.operator-notification" ,
2026-07-03 01:57:11 +01:00
command _lowerings : [
2026-06-16 20:50:49 +01:00
"E:\\Projects\\Odin\\scripts\\restart-voidbot.cmd" ,
] ,
forbidden _authority : "Health commands, operations watchdog probes, static HTML lowerings, and Odin renderers do not own VoidBot provider state or restart truth." ,
observed _at : snapshot . generatedAt ,
} ;
}
function buildTransportProfile ( snapshot ) {
return {
profile _id : "transport:voidbot" ,
daemon _id : "voidbot" ,
target _transport : "cultnet.transport.rudp.v0" ,
2026-07-05 19:17:10 +01:00
current _transport : "daemon-published-rudp-health + daemon-owned-cultmesh-rudp-provider" ,
state : "rudp-health-and-provider-cultmesh-live" ,
2026-06-16 20:50:49 +01:00
health _contract : "voidbot.cultnet-rudp-stack-health" ,
publication _schema : "gamecult.eve.provider_advertisement.v1 + idunn.command_boundary.v1 + idunn.daemon_transport_profile.v1" ,
2026-07-03 01:57:11 +01:00
debug _mechanism : "operations-health.json debug witness only" ,
2026-07-05 19:17:10 +01:00
provider _document _route : swarmCultMeshRudpEndpoint ,
cut _line : ` VoidBot publishes provider advertisements, command boundary, transport profile, and Eve surface through ${ primaryCultMeshEndpoint ( ) } with direct CultMesh/RUDP document route ${ swarmCultMeshRudpEndpoint } ; local probes do not own daemon health or provider transport. ` ,
2026-06-16 20:50:49 +01:00
observed _at : snapshot . generatedAt ,
} ;
}
2026-06-02 15:53:17 +01:00
function buildEveInterfaceBinding ( snapshot , eveState ) {
return {
schemaVersion : eveBindingSchemaId ,
bindingId : providerId ,
providerId ,
verseId ,
title : "VoidBot Swarm" ,
kind : "eve-cultui-surface" ,
updatedAt : snapshot . generatedAt ,
authority : {
owner : "VoidBot swarm renderer" ,
sourceDocuments : [ {
type : snapshotDocumentType ,
schemaId : snapshotSchemaId ,
key : "voidbot-swarm" ,
} ] ,
surfaceDocument : {
type : surfaceDocumentType ,
schemaId : surfaceSchemaId ,
key : providerId ,
} ,
controlOwner : "VoidBot heartbeat state" ,
} ,
surface : eveState . surface ,
stateSummary : {
state : snapshot . summary ? . state ? ? "unknown" ,
participantCount : snapshot . summary ? . participantCount ? ? 0 ,
activeTurnCount : snapshot . summary ? . activeTurnCount ? ? 0 ,
pendingMentionCount : snapshot . summary ? . pendingMentionCount ? ? 0 ,
2026-07-06 22:13:23 +01:00
recentMentionActivityCount : snapshot . summary ? . recentMentionActivityCount ? ? 0 ,
lastMentionActivity : snapshot . summary ? . lastMentionActivity ? ? null ,
2026-06-02 15:53:17 +01:00
nextIdentityId : snapshot . summary ? . nextIdentityId ? ? null ,
nextDisplayName : snapshot . summary ? . nextDisplayName ? ? null ,
lastTickAt : snapshot . summary ? . lastTickAt ? ? null ,
} ,
controls : [ {
id : "swarm.pause" ,
label : "Pause swarm" ,
command : "set-pause" ,
writes : {
documentType : eveBindingDocumentType ,
key : providerId ,
field : "controlIntent.pause" ,
} ,
2026-07-13 00:41:39 +01:00
} , {
id : "swarm.heat" ,
label : "Set heat" ,
command : "set-heat" ,
writes : {
documentType : eveBindingDocumentType ,
key : providerId ,
field : "controlIntent.globalHeat" ,
} ,
2026-06-02 15:53:17 +01:00
} , {
id : "swarm.cadence" ,
label : "Set cadence" ,
command : "set-cadence-multiplier" ,
writes : {
documentType : eveBindingDocumentType ,
key : providerId ,
field : "controlIntent.cadenceMultiplier" ,
} ,
} , {
id : "swarm.force-turn" ,
label : "Pull Face forward" ,
command : "force-turn" ,
writes : {
documentType : eveBindingDocumentType ,
key : providerId ,
field : "controlIntent.manualTurnRequests" ,
} ,
} ] ,
rendererHints : {
preferredLowerings : [ "eve-native" , "nightwing-tui" , "browser" ] ,
viewportMode : "continuous-ops" ,
tileId : "voidbot-swarm" ,
minWidth : 112 ,
minHeight : 30 ,
preferredWidth : 156 ,
preferredHeight : 58 ,
priority : - 30 ,
density : "continuous" ,
} ,
lowerings : [ {
kind : "static-html" ,
role : "local-debug-artifact" ,
path : dashboardPath ,
} ] ,
} ;
}
function providerManifest ( ) {
return {
id : providerId ,
title : "VoidBot Swarm" ,
description : "Native Eve tab for VoidBot agent status, CTB order, selected Face state, and swarm controls." ,
version : "1" ,
endpoint : primaryCultMeshEndpoint ( ) ,
capabilities : [ "ctb" , "agent-status" , "state-tree" , "swarm-controls" , "cultmesh-snapshot" ] ,
usesCultMesh : true ,
transport : "CultMesh Eve interface binding." ,
} ;
}
function buildEveProviderState ( snapshot ) {
2026-07-15 02:41:54 +01:00
const operatorBinding = ( targetProp , pointerId ) => ( {
targetProp ,
pointerId ,
sourceId : "voidbot.swarm_operator_view:voidbot-swarm" ,
schemaId : "voidbot.swarm_operator_view.v1" ,
routeKind : "cultmesh-rudp" ,
routeDescription : swarmCultMeshRudpEndpoint ,
} ) ;
2026-06-02 15:53:17 +01:00
const summary = snapshot . summary ? ? { } ;
const participants = Array . isArray ( snapshot . participants ) ? snapshot . participants : [ ] ;
const upcoming = Array . isArray ( snapshot . upcomingTurns ) ? snapshot . upcomingTurns : [ ] ;
2026-07-03 01:57:11 +01:00
const activeTurns = Array . isArray ( snapshot . activeTurns ) ? snapshot . activeTurns : [ ] ;
const pendingMentions = Array . isArray ( snapshot . pendingMentions ) ? snapshot . pendingMentions : [ ] ;
2026-07-06 22:13:23 +01:00
const recentMentionActivity = Array . isArray ( snapshot . recentMentionActivity ) ? snapshot . recentMentionActivity : [ ] ;
2026-07-03 01:57:11 +01:00
const recentEvents = Array . isArray ( snapshot . recentEvents ) ? snapshot . recentEvents : [ ] ;
2026-06-02 15:53:17 +01:00
const orchestrator = snapshot . orchestrator ? ? { } ;
const organs = Array . isArray ( orchestrator . organs ) ? orchestrator . organs : [ ] ;
const watchdog = findSnapshotOrgan ( organs , "voidbot-operations-watchdog" ) ? ? findSnapshotOrgan ( organs , "watchdog" ) ;
2026-07-03 01:57:11 +01:00
const repoFaceOrgan = findSnapshotOrgan ( organs , "repo-face-heartbeats" ) ;
2026-07-05 19:58:59 +01:00
const swarmSurfaceOrgan = findSnapshotOrgan ( organs , "voidbot-swarm-surface" ) ;
2026-07-03 01:57:11 +01:00
const selected = selectDashboardParticipant ( snapshot , participants , upcoming ) ;
const selectedLeaf = findDashboardLeaf ( selected ) ;
const counts = selected ? . faceState ? . counts ? ? { } ;
const memoryCount = ( counts . shortTerm ? ? 0 ) + ( counts . memories ? ? 0 ) + ( counts . incubation ? ? 0 ) ;
2026-07-05 19:58:59 +01:00
const pressureCount = counts . pressures ? ? 0 ;
const highPressureFaces = [ ... participants ]
. sort ( compareOperatorPressure )
. slice ( 0 , 6 ) ;
const liveQueue = [
... activeTurns . map ( ( turn ) => ( { ... turn , operatorState : "active" } ) ) ,
... upcoming . filter ( ( turn ) => ( turn . nextTurnInMinutes ? ? 999999 ) <= 20 ) . map ( ( turn ) => ( {
... turn ,
operatorState : turn . nextTurnInMinutes <= 0 ? "ready" : "soon" ,
} ) ) ,
] . filter ( ( turn , index , all ) =>
index === all . findIndex ( ( entry ) => entry . identityId === turn . identityId )
) . slice ( 0 , 6 ) ;
const route = routeSummary ( snapshot , swarmSurfaceOrgan ) ;
const operatorAlerts = buildOperatorAlerts ( snapshot , {
watchdog ,
repoFaceOrgan ,
swarmSurfaceOrgan ,
pendingMentions ,
2026-07-06 22:13:23 +01:00
recentMentionActivity ,
2026-07-05 19:58:59 +01:00
activeTurns ,
} ) ;
2026-06-02 15:53:17 +01:00
const nodes = [
{
id : "voidbot-swarm" ,
label : ` VoidBot Swarm \n ${ summary . state ? ? "unknown" } ` ,
kind : "cultmesh-verse" ,
visible : true ,
health : summary . state ? ? "unknown" ,
detail : ` agents ${ summary . participantCount ? ? participants . length } ; next ${ summary . nextDisplayName ? ? "none" } ` ,
} ,
... participants . slice ( 0 , 24 ) . map ( ( participant , index ) => ( {
id : ` face- ${ participant . identityId } ` ,
label : ` ${ participant . displayName } \n ${ participant . repoName } ` ,
kind : "repo-face" ,
visible : true ,
x : - 0.9 + ( index % 6 ) * 0.36 ,
y : - 0.3 + Math . floor ( index / 6 ) * 0.22 ,
z : 0 ,
rotation : 0 ,
scale : 1 ,
width : 0.26 ,
height : 0.16 ,
health : participant . activeJobId ? "running" : participant . restState ? . isNapping ? "napping" : participant . status ,
detail : ` next ${ participant . nextTurnInMinutes ? ? "?" } m; heat ${ participant . heat ? ? "?" } ` ,
} ) ) ,
] ;
return {
type : "dashboard-state" ,
schema : "mimir.eve_dashboard_state.v1" ,
providerId ,
title : "VoidBot Swarm" ,
version : Math . floor ( Date . parse ( snapshot . generatedAt ? ? new Date ( ) . toISOString ( ) ) / 1000 ) ,
updatedAt : snapshot . generatedAt ,
2026-07-03 01:57:11 +01:00
selectedNodeId : "voidbot-swarm" ,
lutPreset : "terminal" ,
nodes ,
surface : {
schema : "gamecult.eve.surface.v1" ,
id : "voidbot.swarm.surface" ,
2026-06-02 15:53:17 +01:00
title : "VoidBot Swarm" ,
2026-07-03 01:57:11 +01:00
styles : {
tokens : {
colorBackground : "#03070d" ,
colorBackgroundTop : "#02060b" ,
colorBackgroundMid : "#06100f" ,
colorBackgroundBottom : "#08130f" ,
colorPanel : "rgba(6, 15, 19, 0.92)" ,
colorPanelAlt : "rgba(10, 36, 35, 0.96)" ,
colorPanelBorder : "rgba(142, 223, 176, 0.22)" ,
colorPanelBorderDeep : "rgba(142, 223, 176, 0.15)" ,
colorText : "#e8f3ee" ,
colorMuted : "#8fa79d" ,
colorAccent : "#ffae58" ,
colorAccentStrong : "#8efcff" ,
colorLink : "#8efcff" ,
fontMono : "\"Cascadia Mono\", Consolas, monospace" ,
} ,
} ,
root : eveNode ( "voidbot-cockpit" , "cockpit" , {
title : "VoidBot Swarm" ,
status : summary . state ? ? "unknown" ,
2026-06-02 15:53:17 +01:00
layout : {
direction : "vertical" ,
2026-07-13 00:41:39 +01:00
overflowX : "hidden" ,
overflowY : "auto" ,
2026-06-02 15:53:17 +01:00
gap : 8 ,
padding : 8 ,
grow : 5 ,
minWidth : 112 ,
minHeight : 30 ,
preferredWidth : 156 ,
preferredHeight : 58 ,
priority : - 30 ,
density : "continuous" ,
viewportMode : "continuous-ops" ,
} ,
2026-07-03 01:57:11 +01:00
} , [
2026-07-13 00:41:39 +01:00
eveNode ( "ctb-command-row" , "row" , {
layout : { direction : "horizontal" , gap : 8 , alignItems : "stretch" , overflowX : "hidden" } ,
} , [
eveNode ( "ctb-rail" , "rail" , {
title : "CTB order" ,
2026-07-13 01:02:17 +01:00
layout : { direction : "horizontal" , overflow : "hidden" , height : 96 , gap : 6 , padding : 6 , grow : 1 } ,
} , upcoming . slice ( 0 , 8 ) . map ( ( turn , index ) =>
2026-07-13 00:41:39 +01:00
eveNode ( ` turn- ${ stableId ( turn . identityId ) } - ${ index } ` , "avatar" , {
text : turn . displayName ,
assetUri : turn . avatarUrl ,
status : turnState ( turn ) ,
detail : ` ${ turn . repoName ? ? "repo" } / ${ minutesText ( turn . nextTurnInMinutes ) } ` ,
} ) ,
) ) ,
eveNode ( "swarm-heat-control" , "pane" , { title : "Heat" , density : "compact" , layout : { width : 220 , minWidth : 220 } } , [
eveNode ( "swarm-heat-value" , "text" , {
role : "mono" ,
2026-07-15 02:06:06 +01:00
text : "loading" ,
stateBindings : [ {
targetProp : "text" ,
pointerId : "globalHeat" ,
sourceId : "voidbot.swarm_control_state:voidbot-swarm" ,
schemaId : "voidbot.swarm_control_state.v1" ,
routeKind : "cultmesh-rudp" ,
routeDescription : swarmCultMeshRudpEndpoint ,
} ] ,
} ) ,
eveNode ( "swarm-heat-scale" , "text" , {
role : "caption" ,
text : "low 0.05 · nominal 1.00 · hot 2.00" ,
2026-07-13 00:41:39 +01:00
} ) ,
eveNode ( "swarm-heat-slider" , "control.slider" , {
label : "Swarm heat" ,
bind : "voidbot.swarm.globalHeat" ,
command : "swarm.set_heat" ,
transport : "cultmesh-binding" ,
providerId ,
min : 0.05 ,
max : 2 ,
step : 0.05 ,
2026-07-15 01:41:41 +01:00
stateBindings : [ {
targetProp : "value" ,
pointerId : "globalHeat" ,
sourceId : "voidbot.swarm_control_state:voidbot-swarm" ,
schemaId : "voidbot.swarm_control_state.v1" ,
routeKind : "cultmesh-rudp" ,
routeDescription : swarmCultMeshRudpEndpoint ,
} ] ,
2026-07-13 00:41:39 +01:00
} ) ,
] ) ,
] ) ,
2026-07-15 02:41:54 +01:00
eveNode ( "voidbot-status-metrics" , "row" , { layout : { direction : "horizontal" , gap : 8 } } , [
eveNode ( "metric-swarm-state" , "metric" , { label : "Swarm" , value : summary . state ? ? "unknown" , stateBindings : [ operatorBinding ( "value" , "summary.state" ) ] } ) ,
eveNode ( "metric-participants" , "metric" , { label : "Faces" , value : summary . participantCount ? ? participants . length , stateBindings : [ operatorBinding ( "value" , "summary.participantCount" ) ] } ) ,
eveNode ( "metric-active-turns" , "metric" , { label : "Active" , value : activeTurns . length || summary . activeTurnCount || 0 , stateBindings : [ operatorBinding ( "value" , "summary.activeTurnCount" ) ] } ) ,
eveNode ( "metric-ready-now" , "metric" , { label : "Ready" , value : summary . readyNowCount ? ? 0 , stateBindings : [ operatorBinding ( "value" , "summary.readyNowCount" ) ] } ) ,
eveNode ( "metric-pending-mentions" , "metric" , { label : "Mentions" , value : summary . pendingMentionCount ? ? 0 , stateBindings : [ operatorBinding ( "value" , "summary.pendingMentionCount" ) ] } ) ,
] ) ,
2026-07-05 19:58:59 +01:00
eveNode ( "voidbot-operator-deck" , "grid" , {
columns : "minmax(260px, 0.95fr) minmax(320px, 1.15fr) minmax(280px, 1fr) minmax(260px, 0.9fr)" ,
layout : { gap : 8 , alignItems : "stretch" } ,
2026-07-03 01:57:11 +01:00
} , [
2026-07-05 19:58:59 +01:00
eveNode ( "voidbot-inspector" , "pane" , { title : "Selected Face" , density : "compact" } , selected ? [
2026-07-03 01:57:11 +01:00
eveNode ( ` selected-avatar- ${ stableId ( selected . identityId ) } ` , "avatar" , {
text : selected . displayName ,
assetUri : selected . avatarUrl ,
status : selected . activeJobId ? "active" : selected . restState ? . isNapping ? "napping" : selected . status ,
detail : ` ${ selected . identityId } / ${ selected . repoName } ` ,
2026-07-15 02:41:54 +01:00
stateBindings : [
operatorBinding ( "text" , "selectedFace.displayName" ) ,
operatorBinding ( "assetUri" , "selectedFace.avatarUri" ) ,
operatorBinding ( "status" , "selectedFace.status" ) ,
operatorBinding ( "detail" , "selectedFace.repoName" ) ,
] ,
2026-07-03 01:57:11 +01:00
} ) ,
2026-07-15 02:41:54 +01:00
eveNode ( "metric-selected-turn" , "metric" , { label : "Turn (min)" , value : minutesText ( selected . nextTurnInMinutes ) , stateBindings : [ operatorBinding ( "value" , "selectedFace.nextTurnInMinutes" ) ] } ) ,
eveNode ( "metric-selected-memory" , "metric" , { label : "Memory" , value : String ( memoryCount ) , stateBindings : [ operatorBinding ( "value" , "selectedFace.memoryCount" ) ] } ) ,
eveNode ( "metric-selected-pressure" , "metric" , { label : "Pressure" , value : String ( pressureCount ) , stateBindings : [ operatorBinding ( "value" , "selectedFace.pressureCount" ) ] } ) ,
2026-07-03 01:57:11 +01:00
eveNode ( "selected-description" , "text" , {
role : "caption" ,
2026-07-05 19:58:59 +01:00
text : compactText ( selected . description ? ? "No Face description registered." , 210 ) ,
2026-07-15 02:41:54 +01:00
stateBindings : [ operatorBinding ( "text" , "selectedFace.description" ) ] ,
2026-07-03 01:57:11 +01:00
} ) ,
] : [
eveNode ( "selected-missing" , "text" , { text : "No selected Face." } ) ,
] ) ,
2026-07-05 19:58:59 +01:00
eveNode ( "voidbot-live-queue" , "pane" , { title : "Live Queue" , density : "compact" } , [
2026-07-15 02:41:54 +01:00
eveNode ( "live-queue-items" , "list" , { items : [ ] , stateBindings : [ operatorBinding ( "items" , "queue" ) ] } ) ,
2026-07-05 19:58:59 +01:00
] ) ,
eveNode ( "voidbot-route-pane" , "pane" , { title : "CultMesh Route" , density : "compact" } , [
2026-07-15 02:41:54 +01:00
eveNode ( "metric-route-store" , "metric" , { label : "Store" , value : snapshot . cultMesh ? . writeStatus ? ? "pending" , stateBindings : [ operatorBinding ( "value" , "route.storeWriteStatus" ) ] } ) ,
eveNode ( "metric-route-provider" , "metric" , { label : "Provider" , value : route . serverStatus , stateBindings : [ operatorBinding ( "value" , "route.providerStatus" ) ] } ) ,
eveNode ( "metric-route-odin" , "metric" , { label : "Odin" , value : route . odinStatus , stateBindings : [ operatorBinding ( "value" , "route.odinStatus" ) ] } ) ,
eveNode ( "route-alerts" , "list" , { items : [ ] , stateBindings : [ operatorBinding ( "items" , "route.alerts" ) ] } ) ,
2026-07-05 19:58:59 +01:00
] ) ,
eveNode ( "voidbot-controls" , "pane" , { title : "Controls" , density : "compact" } , [
2026-07-15 02:41:54 +01:00
eveNode ( "metric-swarm-brake" , "metric" , { label : "Brake" , value : summary . paused ? "paused" : "open" , stateBindings : [ operatorBinding ( "value" , "summary.paused" ) ] } ) ,
eveNode ( "metric-next-face" , "metric" , { label : "Next" , value : summary . nextDisplayName ? ? "none" , stateBindings : [ operatorBinding ( "value" , "summary.nextDisplayName" ) ] } ) ,
2026-07-05 19:58:59 +01:00
eveNode ( "swarm-command-surface" , "control.button" , {
label : summary . paused ? "Request unpause intent" : "Request pause intent" ,
command : summary . paused ? "swarm.unpause.intent" : "swarm.pause.intent" ,
transport : "cultmesh-binding" ,
providerId ,
} ) ,
eveNode ( "swarm-manual-turn" , "control.button" , {
label : ` Request ${ summary . nextDisplayName ? ? "next Face" } ` ,
command : "swarm.manual_turn.intent" ,
transport : "cultmesh-binding" ,
identityId : summary . nextIdentityId ? ? null ,
} ) ,
] ) ,
] ) ,
eveNode ( "voidbot-detail-deck" , "grid" , {
columns : "minmax(280px, 0.95fr) minmax(320px, 1.05fr) minmax(280px, 1fr) minmax(260px, 0.9fr)" ,
layout : { gap : 8 } ,
} , [
eveNode ( "voidbot-state" , "pane" , { title : "State Detail" , density : "compact" } , selectedLeaf ? [
2026-07-16 00:17:49 +01:00
eveNode ( "state-path" , "text" , { role : "mono" , text : selectedLeaf . path ? ? "state path" , stateBindings : [ operatorBinding ( "text" , "selectedFace.statePath" ) ] } ) ,
eveNode ( "state-preview" , "text" , { role : "mono" , text : compactText ( selectedLeaf . detail ? ? selectedLeaf . preview ? ? "" , 520 ) , stateBindings : [ operatorBinding ( "text" , "selectedFace.statePreview" ) ] } ) ,
2026-07-03 01:57:11 +01:00
] : [
2026-07-16 00:17:49 +01:00
eveNode ( "state-empty" , "text" , { text : selected ? . faceState ? . error ? ? "No readable Face state leaf." , stateBindings : [ operatorBinding ( "text" , "selectedFace.statePreview" ) ] } ) ,
2026-07-03 01:57:11 +01:00
] ) ,
2026-07-05 19:58:59 +01:00
eveNode ( "voidbot-watchdog-pane" , "pane" , { title : "Operations" , density : "compact" } , [
2026-06-02 15:53:17 +01:00
eveNode ( "watchdog-summary" , "text" , {
role : "mono" ,
2026-07-03 01:57:11 +01:00
text : ` orchestrator ${ orchestrator . state ? ? "unknown" } organs ${ organs . length } \n mesh ${ snapshot . cultMesh ? . writeStatus ? ? "pending" } ${ shortIso ( snapshot . cultMesh ? . writtenAt ? ? snapshot . generatedAt ) } ` ,
2026-07-16 00:17:49 +01:00
stateBindings : [ operatorBinding ( "text" , "operations.summary" ) ] ,
2026-06-02 15:53:17 +01:00
} ) ,
2026-07-16 00:17:49 +01:00
eveNode ( "operations-items" , "list" , { items : [ ] , stateBindings : [ operatorBinding ( "items" , "operations.items" ) ] } ) ,
] ) ,
eveNode ( "voidbot-pressure-pane" , "pane" , { title : "Pressure" , density : "compact" } , [
eveNode ( "pressure-items" , "list" , { items : [ ] , stateBindings : [ operatorBinding ( "items" , "pressure" ) ] } ) ,
2026-06-02 15:53:17 +01:00
] ) ,
2026-07-05 19:58:59 +01:00
eveNode ( "pending-mentions-pane" , "pane" , { title : "Mentions + Events" , density : "compact" } , [
2026-07-16 00:17:49 +01:00
eveNode ( "pending-mention-items" , "list" , { items : [ ] , stateBindings : [ operatorBinding ( "items" , "mentions" ) ] } ) ,
eveNode ( "recent-event-items" , "list" , { items : [ ] , stateBindings : [ operatorBinding ( "items" , "recentEvents" ) ] } ) ,
2026-07-05 19:58:59 +01:00
] ) ,
2026-06-02 15:53:17 +01:00
] ) ,
2026-07-13 00:41:39 +01:00
eveNode ( "voidbot-context" , "grid" , {
columns : "minmax(0, 1fr)" ,
layout : { gap : 8 , overflowX : "hidden" } ,
2026-06-02 15:53:17 +01:00
} , [
2026-07-16 00:17:49 +01:00
eveNode ( "selected-channels" , "pane" , { title : "Channels" , density : "compact" } , [
eveNode ( "selected-channel-items" , "list" , { items : [ ] , stateBindings : [ operatorBinding ( "items" , "selectedFace.channels" ) ] } ) ,
] ) ,
2026-06-02 15:53:17 +01:00
] ) ,
] ) ,
assets : participants
. filter ( ( participant ) => participant . avatarUrl )
. slice ( 0 , 32 )
. map ( ( participant ) => ( {
id : ` avatar- ${ participant . identityId } ` ,
kind : "image" ,
uri : participant . avatarUrl ,
} ) ) ,
} ,
} ;
}
2026-07-05 19:58:59 +01:00
function compareOperatorPressure ( left , right ) {
return ( faceOperatorScore ( right ) - faceOperatorScore ( left ) )
|| String ( left . displayName ? ? left . identityId ? ? "" ) . localeCompare ( String ( right . displayName ? ? right . identityId ? ? "" ) ) ;
}
function faceOperatorScore ( face ) {
const readyScore = typeof face ? . nextTurnInMinutes === "number" && face . nextTurnInMinutes <= 0 ? 25 : 0 ;
const activeScore = face ? . activeJobId ? 35 : 0 ;
return activeScore
+ readyScore
+ faceMemoryCount ( face ) * 2
+ facePressureCount ( face ) * 9
+ ( face ? . pendingMentionCount ? ? 0 ) * 18
+ ( face ? . queuedCount ? ? 0 ) * 4
+ ( face ? . heat ? ? 0 ) * 8 ;
}
function faceMemoryCount ( face ) {
const counts = face ? . faceState ? . counts ? ? { } ;
return ( counts . shortTerm ? ? 0 ) + ( counts . memories ? ? 0 ) + ( counts . incubation ? ? 0 ) ;
}
function facePressureCount ( face ) {
return face ? . faceState ? . counts ? . pressures ? ? 0 ;
}
function routeSummary ( snapshot , swarmSurfaceOrgan ) {
const server = swarmSurfaceOrgan ? . cultMeshServer ? ? { } ;
const serverStatus = server . status ? ? swarmSurfaceOrgan ? . lastStatus ? ? "missing" ;
const odinStatus = server . odinCultMeshUri || server . odinRudpEndpoint ? "ok" : "missing" ;
const lines = [
` store ${ snapshot . cultMesh ? . writeStatus ? ? "pending" } ${ shortIso ( snapshot . cultMesh ? . writtenAt ? ? snapshot . generatedAt ) } ` ,
` provider ${ serverStatus } ${ server . pid ? ` pid ${ server . pid } ` : "" } ` ,
` bind ${ server . bind ? ? "unknown" } ` ,
` odin ${ server . odinCultMeshUri ? ? "missing" } ` ,
` rudp ${ server . odinRudpEndpoint ? ? "missing" } ` ,
` cc ${ compactPath ( server . storePath ? ? snapshot . cultMesh ? . storePath ? ? "unknown" , 46 ) } ` ,
] ;
if ( server . error ) lines . push ( ` error ${ compactText ( server . error , 130 ) } ` ) ;
return {
serverStatus ,
odinStatus ,
text : lines . join ( "\n" ) ,
} ;
}
function buildOperatorAlerts ( snapshot , context ) {
const alerts = [ ] ;
if ( snapshot . cultMesh ? . writeStatus !== "ok" ) {
alerts . push ( ` Store write is ${ snapshot . cultMesh ? . writeStatus ? ? "unknown" } ; dashboard may be stale. ` ) ;
}
if ( ! context . swarmSurfaceOrgan ) {
alerts . push ( "voidbot-swarm-surface organ is missing from orchestrator state." ) ;
} else if ( ! [ "ok" , "ready" , "running" ] . includes ( String ( context . swarmSurfaceOrgan . lastStatus ? ? "" ) . toLowerCase ( ) ) ) {
alerts . push ( ` Eve surface organ reports ${ context . swarmSurfaceOrgan . lastStatus ? ? "unknown" } . ` ) ;
}
if ( ! context . swarmSurfaceOrgan ? . cultMeshServer ) {
alerts . push ( "CultMesh RUDP provider status is not projected yet." ) ;
} else if ( ! [ "already_running" , "started" , "running" , "ok" ] . includes ( String ( context . swarmSurfaceOrgan . cultMeshServer . status ? ? "" ) . toLowerCase ( ) ) ) {
alerts . push ( ` CultMesh RUDP provider is ${ context . swarmSurfaceOrgan . cultMeshServer . status ? ? "unknown" } . ` ) ;
}
if ( ! context . watchdog || ! [ "ok" , "ready" , "running" , "skipped_disabled" ] . includes ( String ( context . watchdog . lastStatus ? ? "" ) . toLowerCase ( ) ) ) {
alerts . push ( ` Watchdog is ${ context . watchdog ? . lastStatus ? ? "missing" } . ` ) ;
}
if ( ( context . pendingMentions ? . length ? ? 0 ) > 0 ) alerts . push ( ` ${ context . pendingMentions . length } pending mention(s) need routing. ` ) ;
2026-07-06 22:13:23 +01:00
else if ( ( context . recentMentionActivity ? . length ? ? 0 ) > 0 ) {
const latest = context . recentMentionActivity [ 0 ] ;
alerts . push ( ` Pending mentions are empty; latest mention activity was ${ latest . kind ? ? "seen" } for ${ latest . identityId ? ? "unknown" } at ${ shortIso ( latest . observedAt ) } . ` ) ;
}
2026-07-05 19:58:59 +01:00
if ( ( context . activeTurns ? . length ? ? 0 ) > 0 ) alerts . push ( ` ${ context . activeTurns . length } active turn(s) are running. ` ) ;
if ( ! alerts . length ) alerts . push ( "No immediate operator alerts." ) ;
return alerts ;
}
2026-07-06 22:13:23 +01:00
function mentionMetric ( summary , recentMentionActivity ) {
const pending = summary . pendingMentionCount ? ? 0 ;
if ( pending > 0 ) return ` ${ pending } pending ` ;
const latest = recentMentionActivity ? . [ 0 ] ? ? summary . lastMentionActivity ;
if ( ! latest ) return "0 pending" ;
const count = latest . mentionCount ? ? 1 ;
if ( latest . kind === "consumed" || latest . kind === "handled_job" ) {
return ` 0 pending / ${ count } handled ` ;
}
return ` 0 pending / ${ latest . kind ? ? "seen" } ` ;
}
function mentionEmptyText ( summary , recentMentionActivity ) {
const latest = recentMentionActivity ? . [ 0 ] ? ? summary . lastMentionActivity ;
if ( ! latest ) {
return "No pending mentions." ;
}
return ` No pending mentions. Recent activity: ${ mentionActivitySummary ( latest ) } . ` ;
}
function mentionActivityText ( activity ) {
return ` ${ mentionActivitySummary ( activity ) } \n ${ compactText ( activity . prompt || activity . mentions ? . [ 0 ] ? . prompt || activity . activeJobId || activity . requestMessageId || "" , 150 ) } ` ;
}
function mentionActivitySummary ( activity ) {
const label = activity . kind === "consumed"
? "consumed"
: activity . kind === "handled_job"
? "handled job"
: activity . kind === "duplicate_intake"
? "duplicate intake"
: activity . kind ? ? "activity" ;
const count = activity . mentionCount && activity . mentionCount > 1 ? ` x ${ activity . mentionCount } ` : "" ;
return ` ${ label } ${ count } ${ activity . identityId ? ? "face" } / ${ shortIso ( activity . observedAt ) } ` ;
}
2026-07-05 19:58:59 +01:00
function compactPath ( value , maxLength = 74 ) {
const text = String ( value ? ? "" ) ;
if ( text . length <= maxLength ) return text ;
const tail = text . slice ( Math . max ( 0 , text . length - maxLength + 3 ) ) ;
return ` ... ${ tail } ` ;
}
function compactText ( value , maxLength = 240 ) {
const text = String ( value ? ? "" ) . replace ( /\s+/g , " " ) . trim ( ) ;
if ( text . length <= maxLength ) return text ;
return ` ${ text . slice ( 0 , Math . max ( 0 , maxLength - 1 ) ) . trimEnd ( ) } ... ` ;
}
2026-07-03 01:57:11 +01:00
function eveMetric ( id , label , value ) {
return eveNode ( ` metric- ${ stableId ( id ) } ` , "metric" , {
label ,
value : String ( value ? ? "unknown" ) ,
} ) ;
}
function eveBar ( id , label , value , percent ) {
return eveNode ( ` bar- ${ stableId ( id ) } ` , "bar" , {
label ,
value : String ( value ? ? "unknown" ) ,
percent : clampPercent ( percent ) ,
} ) ;
}
function selectDashboardParticipant ( snapshot , participants , upcoming ) {
const preferredId = snapshot ? . summary ? . nextIdentityId ? ? upcoming [ 0 ] ? . identityId ? ? participants [ 0 ] ? . identityId ;
return participants . find ( ( participant ) => participant . identityId === preferredId ) ? ? participants [ 0 ] ? ? null ;
}
function findDashboardLeaf ( participant ) {
const leaves = flattenDashboardLeaves ( participant ? . faceState ? . tree ? ? [ ] ) ;
if ( ! leaves . length ) return null ;
return leaves . find ( ( leaf ) =>
leaf . label !== "empty" && (
String ( leaf . path ? ? "" ) . startsWith ( "thoughtMemory.shortTerm" ) ||
String ( leaf . path ? ? "" ) . startsWith ( "thoughtMemory.memories" ) ||
String ( leaf . path ? ? "" ) . startsWith ( "thoughtMemory.incubation" ) ||
String ( leaf . path ? ? "" ) . startsWith ( "agencyPressure.pressures" )
) ) ? ? leaves [ 0 ] ;
}
function flattenDashboardLeaves ( nodes ) {
const output = [ ] ;
const visit = ( node ) => {
if ( ! node ) return ;
if ( node . kind === "leaf" ) output . push ( node ) ;
for ( const child of node . children ? ? [ ] ) visit ( child ) ;
} ;
for ( const node of nodes ? ? [ ] ) visit ( node ) ;
return output ;
}
function turnPercent ( value ) {
if ( typeof value !== "number" ) return 0 ;
return value <= 0 ? 100 : clampPercent ( 100 - value * 5 ) ;
}
function statusFill ( value ) {
const state = String ( value || "missing" ) . toLowerCase ( ) ;
if ( state === "ok" || state === "ready" || state === "skipped_disabled" ) return 100 ;
if ( state === "running" ) return 82 ;
if ( state === "warning" || state === "paused" ) return 46 ;
return 12 ;
}
function clampPercent ( value ) {
const numeric = Number ( value ) ;
return Number . isFinite ( numeric ) ? Math . max ( 0 , Math . min ( 100 , numeric ) ) : 0 ;
}
2026-06-02 15:53:17 +01:00
function eveNode ( id , kind , props = { } , children = [ ] ) {
2026-07-15 01:41:41 +01:00
const { layout , style , stateBindings , ... nodeProps } = props ? ? { } ;
2026-07-05 19:58:59 +01:00
return {
id ,
kind ,
props : nodeProps ,
... ( layout && typeof layout === "object" ? { layout } : { } ) ,
... ( style && typeof style === "object" ? { style } : { } ) ,
2026-07-15 01:41:41 +01:00
... ( Array . isArray ( stateBindings ) && stateBindings . length > 0 ? { stateBindings } : { } ) ,
2026-07-05 19:58:59 +01:00
children ,
} ;
2026-06-02 15:53:17 +01:00
}
function stableId ( value ) {
return String ( value ? ? "id" )
. toLowerCase ( )
. replace ( /[^a-z0-9]+/g , "-" )
. replace ( /^-+|-+$/g , "" ) || "id" ;
}
function turnState ( turn ) {
if ( turn ? . activeJobId ) return "active" ;
if ( ( turn ? . pendingMentionCount ? ? 0 ) > 0 ) return "mention" ;
if ( turn ? . restState ? . isNapping ) return "nap" ;
return minutesText ( turn ? . nextTurnInMinutes ) ;
}
function minutesText ( value ) {
return typeof value === "number"
? value <= 0 ? "ready" : ` ${ value . toFixed ( value < 10 ? 1 : 0 ) } m `
: "unknown" ;
}
function formatNumber ( value , decimals ) {
return typeof value === "number" && Number . isFinite ( value ) ? value . toFixed ( decimals ) . replace ( /\.?0+$/ , "" ) : "?" ;
}
function shortIso ( value ) {
const timestamp = Date . parse ( value ? ? "" ) ;
if ( ! Number . isFinite ( timestamp ) ) return "unknown" ;
const date = new Date ( timestamp ) ;
return ` ${ String ( date . getMonth ( ) + 1 ) . padStart ( 2 , "0" ) } - ${ String ( date . getDate ( ) ) . padStart ( 2 , "0" ) } ${ String ( date . getHours ( ) ) . padStart ( 2 , "0" ) } : ${ String ( date . getMinutes ( ) ) . padStart ( 2 , "0" ) } ` ;
}
2026-07-06 22:13:23 +01:00
function timestampMs ( value ) {
const parsed = Date . parse ( value ? ? "" ) ;
return Number . isFinite ( parsed ) ? parsed : 0 ;
}
2026-06-02 15:53:17 +01:00
function findSnapshotOrgan ( organs , needle ) {
const lower = String ( needle ) . toLowerCase ( ) ;
return organs . find ( ( organ ) =>
String ( organ ? . id ? ? "" ) . toLowerCase ( ) . includes ( lower ) ||
String ( organ ? . label ? ? "" ) . toLowerCase ( ) . includes ( lower ) ) ;
}
function renderHtml ( snapshot ) {
return ` <!doctype html>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1, viewport-fit=cover" >
< title > VoidBot Swarm Control < / t i t l e >
< style >
@ import url ( "https://fonts.googleapis.com/css2?family=Montserrat:wght@100;300;500&family=Press+Start+2P&family=Ubuntu:wght@400;500;700&display=swap" ) ;
: root {
color - scheme : dark ;
-- bg : # 03070 d ;
-- panel : rgba ( 6 , 15 , 19 , 0.9 ) ;
-- panel - soft : rgba ( 142 , 223 , 176 , 0.07 ) ;
-- line : rgba ( 142 , 223 , 176 , 0.18 ) ;
-- line - strong : rgba ( 142 , 223 , 176 , 0.4 ) ;
-- text : # effcf8 ;
-- muted : rgba ( 239 , 252 , 248 , 0.66 ) ;
-- green : # 8 edfb0 ;
-- amber : # ffae58 ;
-- cyan : # 69e2 ef ;
-- coral : # ff7b72 ;
-- violet : # b99dff ;
-- rail : 124 px ;
-- font : "Ubuntu" , ui - sans - serif , system - ui , - apple - system , BlinkMacSystemFont , "Segoe UI" , sans - serif ;
-- display : "Montserrat" , "Ubuntu" , ui - sans - serif , system - ui , sans - serif ;
-- arcade : "Press Start 2P" , "VT323" , monospace ;
-- mono : "SFMono-Regular" , "Cascadia Mono" , Consolas , monospace ;
}
* { box - sizing : border - box ; }
html , body , # app { width : 100 % ; height : 100 % ; margin : 0 ; overflow : hidden ; }
html { height : - webkit - fill - available ; }
body {
background :
radial - gradient ( circle at 72 % 12 % , rgba ( 255 , 174 , 88 , 0.14 ) , transparent 24 % ) ,
radial - gradient ( circle at 10 % 18 % , rgba ( 142 , 223 , 176 , 0.14 ) , transparent 28 % ) ,
linear - gradient ( 180 deg , # 03070 d , # 07110 f 52 % , # 091712 ) ;
color : var ( -- text ) ;
font : 15 px / 1.45 var ( -- font ) ;
letter - spacing : 0 ;
}
h1 , h2 , h3 , p { margin : 0 ; }
h1 , h2 , h3 , . kicker , . badge , . metric strong , . turn - card strong , . state - leaf strong {
font - family : var ( -- display ) ;
font - weight : 100 ;
letter - spacing : 0 ;
}
button , select , input { font : inherit ; }
button , select {
min - height : 40 px ;
border : 1 px solid var ( -- line ) ;
border - radius : 8 px ;
background : rgba ( 142 , 223 , 176 , 0.09 ) ;
color : var ( -- text ) ;
font - weight : 760 ;
}
button { cursor : pointer ; padding : 0 12 px ; }
button : hover , select : hover { border - color : var ( -- amber ) ; }
select { min - width : 0 ; padding : 0 10 px ; }
input [ type = "range" ] { width : 100 % ; accent - color : var ( -- cyan ) ; }
. shell {
position : fixed ;
inset : 0 ;
width : 100 vw ;
height : var ( -- app - height , 100 vh ) ;
min - height : - webkit - fill - available ;
background : rgba ( 3 , 7 , 13 , 0.72 ) ;
overflow : hidden ;
}
. hud - canvas {
position : absolute ;
inset : 0 ;
z - index : 0 ;
width : 100 % ;
height : 100 % ;
pointer - events : none ;
}
. ctb - rail {
position : absolute ;
z - index : 3 ;
top : 0 ;
left : 0 ;
right : 0 ;
height : var ( -- rail ) ;
display : flex ;
gap : 8 px ;
padding : 10 px 274 px 10 px 10 px ;
border - color : var ( -- line ) ;
background : rgba ( 3 , 7 , 13 , 0.86 ) ;
backdrop - filter : blur ( 18 px ) ;
overflow : auto ;
min - width : 0 ;
- webkit - overflow - scrolling : touch ;
scrollbar - width : thin ;
scrollbar - color : rgba ( 142 , 223 , 176 , 0.58 ) rgba ( 3 , 7 , 13 , 0.32 ) ;
}
. turn - card {
flex : 0 0 auto ;
width : 72 px ;
height : 96 px ;
display : grid ;
justify - items : center ;
align - content : start ;
gap : 4 px ;
padding : 7 px 6 px ;
border : 1 px solid var ( -- line ) ;
border - radius : 8 px ;
background : rgba ( 8 , 19 , 24 , 0.9 ) ;
color : var ( -- text ) ;
text - align : center ;
}
. turn - card . active - turn { border - color : var ( -- cyan ) ; box - shadow : 0 0 24 px rgba ( 105 , 226 , 239 , 0.22 ) ; }
. turn - card . selected { border - color : var ( -- amber ) ; background : rgba ( 255 , 174 , 88 , 0.11 ) ; }
. turn - card . mention - turn { border - color : var ( -- amber ) ; }
. turn - card strong , . turn - card span {
width : 100 % ;
overflow : hidden ;
text - overflow : ellipsis ;
white - space : nowrap ;
}
. turn - card strong { font - size : 0.68 rem ; line - height : 1.05 ; }
. turn - card span { color : var ( -- muted ) ; font : 0.64 rem / 1.05 var ( -- mono ) ; }
. turn - card . turn - reason { color : var ( -- amber ) ; text - transform : uppercase ; }
. avatar {
display : grid ;
width : 42 px ;
height : 42 px ;
place - items : center ;
overflow : hidden ;
border : 2 px solid rgba ( 255 , 255 , 255 , 0.14 ) ;
border - radius : 999 px ;
background : linear - gradient ( 160 deg , # 69e2 ef , # c2f5f0 ) ;
color : # 08313 a ;
font - weight : 900 ;
line - height : 1 ;
}
. avatar img { width : 100 % ; height : 100 % ; object - fit : cover ; display : block ; }
. workspace {
position : absolute ;
z - index : 1 ;
top : var ( -- rail ) ;
left : 0 ;
right : 0 ;
bottom : 0 ;
overflow : hidden ;
}
. status - panel {
position : absolute ;
top : 14 px ;
right : 10 px ;
z - index : 4 ;
width : 250 px ;
height : 96 px ;
display : grid ;
grid - template - rows : auto minmax ( 0 , 1 fr ) ;
gap : 5 px ;
padding : 7 px ;
border : 1 px solid rgba ( 255 , 174 , 88 , 0.34 ) ;
border - radius : 8 px ;
background :
repeating - linear - gradient ( to bottom , rgba ( 0 , 0 , 0 , 0 ) 0 3 px , rgba ( 0 , 0 , 0 , 0.24 ) 3 px 4 px ) ,
linear - gradient ( 160 deg , rgba ( 255 , 174 , 88 , 0.12 ) , rgba ( 6 , 15 , 19 , 0.94 ) 34 % , rgba ( 105 , 226 , 239 , 0.08 ) ) ;
box - shadow : inset 0 0 0 1 px rgba ( 255 , 255 , 255 , 0.04 ) , 0 18 px 42 px rgba ( 0 , 0 , 0 , 0.32 ) ;
color : var ( -- text ) ;
font - family : var ( -- display ) ;
font - weight : 100 ;
overflow : hidden ;
}
. status - panel h2 {
display : flex ;
justify - content : space - between ;
gap : 6 px ;
font - size : 0.62 rem ;
line - height : 1 ;
color : var ( -- amber ) ;
font - family : var ( -- arcade ) ;
font - weight : 400 ;
}
. status - grid {
min - height : 0 ;
display : grid ;
grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ;
gap : 4 px 7 px ;
align - content : start ;
}
. hud - stat {
min - width : 0 ;
display : grid ;
gap : 3 px ;
}
. hud - label {
display : flex ;
justify - content : space - between ;
gap : 3 px ;
color : rgba ( 239 , 252 , 248 , 0.74 ) ;
font - size : 0.43 rem ;
line - height : 1 ;
text - transform : uppercase ;
white - space : nowrap ;
}
. hud - label span : first - child {
font - family : var ( -- arcade ) ;
font - weight : 400 ;
}
. hud - label span : last - child {
overflow : hidden ;
text - overflow : ellipsis ;
font - family : var ( -- display ) ;
font - weight : 100 ;
}
. hud - bar {
height : 4 px ;
overflow : hidden ;
border : 1 px solid rgba ( 239 , 252 , 248 , 0.16 ) ;
border - radius : 999 px ;
background : rgba ( 0 , 0 , 0 , 0.34 ) ;
}
. hud - fill {
display : block ;
height : 100 % ;
width : calc ( var ( -- fill , 0 ) * 1 % ) ;
max - width : 100 % ;
background : linear - gradient ( 90 deg , var ( -- green ) , var ( -- cyan ) ) ;
}
. hud - fill . warn { background : linear - gradient ( 90 deg , var ( -- amber ) , var ( -- coral ) ) ; }
. pane {
position : absolute ;
min - width : 0 ;
min - height : 0 ;
display : grid ;
gap : 12 px ;
padding : 14 px ;
border : 1 px solid var ( -- line ) ;
border - radius : 8 px ;
background : var ( -- panel ) ;
box - shadow : 0 24 px 80 px rgba ( 0 , 0 , 0 , 0.28 ) ;
overflow : hidden ;
}
. pane - scroll { overflow : auto ; }
. inspector - pane {
left : 12 px ;
top : 12 px ;
bottom : 12 px ;
width : calc ( 24 % - 15 px ) ;
grid - template - rows : auto auto auto minmax ( 0 , 1 fr ) ;
}
. tree - pane {
left : calc ( 24 % + 6 px ) ;
top : 12 px ;
bottom : 12 px ;
width : calc ( 34 % - 18 px ) ;
grid - template - rows : auto minmax ( 0 , 1 fr ) ;
}
. tree - pane . mono { overflow - wrap : anywhere ; }
. memory - pane {
left : calc ( 58 % + 6 px ) ;
top : 12 px ;
right : 12 px ;
bottom : 12 px ;
grid - template - rows : auto minmax ( 0 , 1 fr ) ;
}
. kicker { color : var ( -- green ) ; font - size : 0.74 rem ; text - transform : uppercase ; }
h1 { font - size : clamp ( 1.55 rem , 3.4 vw , 3 rem ) ; line - height : 0.98 ; }
h2 { font - size : 1 rem ; text - transform : uppercase ; }
. muted { color : var ( -- muted ) ; }
. mono { font - family : var ( -- mono ) ; }
. metrics { display : grid ; grid - template - columns : repeat ( 5 , minmax ( 0 , 1 fr ) ) ; gap : 8 px ; }
. metric , . fact , . agent - stat {
min - width : 0 ;
padding : 10 px ;
border : 1 px solid rgba ( 142 , 223 , 176 , 0.12 ) ;
border - radius : 8 px ;
background : var ( -- panel - soft ) ;
}
. metric span , . fact span { display : block ; color : var ( -- muted ) ; font - size : 0.68 rem ; font - weight : 800 ; text - transform : uppercase ; }
. metric strong { display : block ; overflow : hidden ; text - overflow : ellipsis ; white - space : nowrap ; font - size : 1.12 rem ; }
. fact strong { display : block ; overflow - wrap : anywhere ; font : 0.9 rem / 1.15 var ( -- mono ) ; }
. control - grid {
display : grid ;
gap : 8 px ;
align - content : start ;
padding : 10 px ;
border : 1 px solid rgba ( 105 , 226 , 239 , 0.16 ) ;
border - radius : 8 px ;
background : rgba ( 3 , 7 , 13 , 0.36 ) ;
}
. control - row { display : grid ; grid - template - columns : minmax ( 0 , 1 fr ) auto ; gap : 8 px ; align - items : center ; }
. force - row { display : grid ; grid - template - columns : minmax ( 0 , 1 fr ) auto ; gap : 8 px ; }
. inspector - hero {
display : grid ;
grid - template - columns : 64 px minmax ( 0 , 1 fr ) ;
gap : 12 px ;
align - items : center ;
}
. inspector - hero . avatar { width : 64 px ; height : 64 px ; }
. inspector - hero h1 , . inspector - hero p { overflow : hidden ; text - overflow : ellipsis ; white - space : nowrap ; }
. inspector - lore {
overflow : auto ;
- webkit - overflow - scrolling : touch ;
color : var ( -- muted ) ;
font - size : 0.83 rem ;
}
. agent - stats { display : grid ; gap : 8 px ; }
. agent - stat {
display : grid ;
gap : 6 px ;
padding : 8 px ;
}
. agent - stat - head {
display : flex ;
justify - content : space - between ;
gap : 10 px ;
color : rgba ( 239 , 252 , 248 , 0.88 ) ;
font : 0.72 rem / 1.1 var ( -- mono ) ;
text - transform : uppercase ;
}
. agent - stat - head span : first - child {
color : var ( -- muted ) ;
font - family : var ( -- display ) ;
font - weight : 300 ;
}
. agent - bar {
height : 8 px ;
overflow : hidden ;
border : 1 px solid rgba ( 239 , 252 , 248 , 0.16 ) ;
border - radius : 3 px ;
background : rgba ( 0 , 0 , 0 , 0.38 ) ;
box - shadow : inset 0 0 8 px rgba ( 0 , 0 , 0 , 0.34 ) ;
}
. agent - fill {
display : block ;
width : calc ( var ( -- fill , 0 ) * 1 % ) ;
max - width : 100 % ;
height : 100 % ;
background : linear - gradient ( 90 deg , var ( -- green ) , var ( -- cyan ) ) ;
box - shadow : 0 0 12 px rgba ( 105 , 226 , 239 , 0.28 ) ;
}
. agent - fill . hot { background : linear - gradient ( 90 deg , var ( -- amber ) , var ( -- coral ) ) ; }
. agent - fill . cool { background : linear - gradient ( 90 deg , var ( -- violet ) , var ( -- cyan ) ) ; }
. channel - list , . state - tree , . detail - body {
min - height : 0 ;
overflow : auto ;
- webkit - overflow - scrolling : touch ;
display : grid ;
align - content : start ;
gap : 8 px ;
}
. channel - chip {
display : grid ;
grid - template - columns : minmax ( 0 , 1 fr ) auto ;
gap : 8 px ;
align - items : center ;
padding : 8 px ;
border : 1 px solid var ( -- line ) ;
border - radius : 8 px ;
background : rgba ( 142 , 223 , 176 , 0.06 ) ;
font - size : 0.78 rem ;
}
. channel - chip strong , . channel - chip span { overflow : hidden ; text - overflow : ellipsis ; white - space : nowrap ; }
details . state - node {
border : 1 px solid rgba ( 142 , 223 , 176 , 0.12 ) ;
border - radius : 8 px ;
background : rgba ( 142 , 223 , 176 , 0.045 ) ;
overflow : hidden ;
}
details . state - node [ open ] { border - color : rgba ( 105 , 226 , 239 , 0.22 ) ; }
details . state - node > summary {
display : flex ;
justify - content : space - between ;
gap : 8 px ;
padding : 9 px 10 px ;
cursor : pointer ;
color : var ( -- text ) ;
font - family : var ( -- display ) ;
font - weight : 100 ;
}
. state - children {
display : grid ;
gap : 6 px ;
padding : 6 px 8 px 8 px 12 px ;
border - top : 1 px solid rgba ( 142 , 223 , 176 , 0.08 ) ;
}
. state - leaf {
min - width : 0 ;
display : grid ;
gap : 3 px ;
padding : 8 px ;
border : 1 px solid rgba ( 142 , 223 , 176 , 0.1 ) ;
border - radius : 8 px ;
background : rgba ( 3 , 7 , 13 , 0.34 ) ;
color : var ( -- text ) ;
text - align : left ;
}
. state - leaf : hover , . state - leaf . selected { border - color : var ( -- amber ) ; background : rgba ( 255 , 174 , 88 , 0.09 ) ; }
. state - leaf strong {
overflow : hidden ;
display : - webkit - box ;
- webkit - line - clamp : 2 ;
- webkit - box - orient : vertical ;
overflow - wrap : anywhere ;
}
. state - leaf span {
overflow : hidden ;
display : - webkit - box ;
- webkit - line - clamp : 2 ;
- webkit - box - orient : vertical ;
overflow - wrap : anywhere ;
}
. state - leaf span { color : var ( -- muted ) ; font : 0.72 rem / 1.15 var ( -- mono ) ; }
. facts { display : grid ; grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ; gap : 8 px ; }
. detail - card {
min - height : 0 ;
display : grid ;
gap : 10 px ;
align - content : start ;
padding : 12 px ;
border : 1 px solid rgba ( 105 , 226 , 239 , 0.16 ) ;
border - radius : 8 px ;
background : rgba ( 3 , 7 , 13 , 0.42 ) ;
}
. detail - card pre {
min - height : 0 ;
margin : 0 ;
overflow : auto ;
- webkit - overflow - scrolling : touch ;
white - space : pre - wrap ;
overflow - wrap : anywhere ;
color : rgba ( 239 , 252 , 248 , 0.88 ) ;
font : 0.84 rem / 1.35 var ( -- mono ) ;
}
. badge {
display : inline - flex ;
align - items : center ;
justify - content : center ;
min - height : 24 px ;
padding : 4 px 8 px ;
border - radius : 999 px ;
background : var ( -- green ) ;
color : # 06100 d ;
font - size : 0.7 rem ;
text - transform : uppercase ;
}
. badge . running , . badge . info { background : var ( -- cyan ) ; }
. badge . paused , . badge . warning { background : var ( -- amber ) ; }
. badge . failed , . badge . missing , . badge . error { background : var ( -- coral ) ; }
. badge . repo - face { background : var ( -- violet ) ; }
@ media ( orientation : landscape ) {
. ctb - rail {
flex - direction : row ;
align - items : center ;
border - bottom : 1 px solid var ( -- line ) ;
}
. turn - card { width : 76 px ; height : 96 px ; }
}
@ media ( orientation : portrait ) {
: root { -- rail : 94 px ; }
. ctb - rail {
top : 0 ;
left : 0 ;
right : auto ;
bottom : 0 ;
width : var ( -- rail ) ;
height : auto ;
padding : 10 px ;
flex - direction : column ;
align - items : center ;
border - right : 1 px solid var ( -- line ) ;
}
. workspace {
top : 0 ;
left : var ( -- rail ) ;
}
. inspector - pane {
left : 10 px ;
top : 10 px ;
right : 10 px ;
bottom : auto ;
width : auto ;
height : 34 % ;
padding - right : calc ( clamp ( 190 px , 22 vw , 230 px ) + 24 px ) ;
grid - template - columns : minmax ( 230 px , 0.9 fr ) minmax ( 180 px , 0.76 fr ) minmax ( 230 px , 1 fr ) ;
grid - template - rows : minmax ( 0 , 1 fr ) ;
align - items : stretch ;
}
. tree - pane {
left : 10 px ;
top : calc ( 34 % + 20 px ) ;
bottom : 10 px ;
width : calc ( 44 % - 16 px ) ;
}
. memory - pane {
left : calc ( 44 % + 4 px ) ;
top : calc ( 34 % + 20 px ) ;
right : 10 px ;
bottom : 10 px ;
}
. control - grid {
min - height : 0 ;
}
. inspector - hero {
align - self : start ;
}
. agent - stats {
min - height : 0 ;
grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ;
align - content : start ;
gap : 7 px ;
}
. agent - stat {
padding : 7 px ;
}
. agent - bar {
height : 7 px ;
}
. inspector - lore {
display : none ;
}
. turn - card { width : 72 px ; height : 96 px ; }
. status - panel {
position : fixed ;
top : 8 px ;
right : 8 px ;
bottom : auto ;
left : auto ;
width : clamp ( 190 px , 22 vw , 230 px ) ;
height : 88 px ;
}
}
@ media ( max - width : 760 px ) {
. pane { padding : 12 px ; }
. status - panel { width : 210 px ; }
}
@ media ( max - width : 850 px ) and ( orientation : portrait ) {
. inspector - pane {
height : 38 % ;
padding - right : 12 px ;
grid - template - columns : minmax ( 210 px , 1 fr ) minmax ( 170 px , 0.8 fr ) ;
}
. agent - stats {
grid - column : 1 / - 1 ;
grid - template - columns : repeat ( 3 , minmax ( 0 , 1 fr ) ) ;
}
. tree - pane {
top : calc ( 38 % + 20 px ) ;
}
. memory - pane {
top : calc ( 38 % + 20 px ) ;
}
. status - panel {
top : auto ;
right : 12 px ;
bottom : 12 px ;
width : 180 px ;
height : 84 px ;
}
}
@ media ( max - width : 980 px ) and ( orientation : landscape ) {
. inspector - pane { width : 25 % ; }
. tree - pane { left : calc ( 25 % + 18 px ) ; width : calc ( 34 % - 18 px ) ; }
. memory - pane { left : calc ( 59 % + 12 px ) ; }
. inspector - lore { display : none ; }
}
< / s t y l e >
< / h e a d >
< body >
< main id = "app" > < / m a i n >
< script id = "initial-snapshot" type = "application/json" > $ { escapeScriptJson ( JSON . stringify ( snapshot ) ) } < / s c r i p t >
< script >
const initialSnapshot = JSON . parse ( document . getElementById ( "initial-snapshot" ) . textContent ) ;
const app = document . getElementById ( "app" ) ;
let selectedIdentity = null ;
let selectedStatePath = null ;
const tone = ( value ) => String ( value || "unknown" ) . toLowerCase ( ) . replace ( /_/g , "-" ) ;
const text = ( value ) => value === null || value === undefined || value === "" ? "missing" : String ( value ) ;
const esc = ( value ) => text ( value ) . replace ( /&/g , "&" ) . replace ( /</g , "<" ) . replace ( />/g , ">" ) . replace ( /"/g , """ ) ;
const number = ( value ) => typeof value === "number" ? value . toLocaleString ( undefined , { maximumFractionDigits : 2 } ) : "missing" ;
const minutes = ( value , restState = null ) => restState ? . isNapping === true
? "napping"
: typeof value === "number"
? ( value <= 0 ? "ready" : value . toLocaleString ( undefined , { maximumFractionDigits : 1 } ) + "m" )
: "missing" ;
const relative = ( timestamp ) => {
if ( ! timestamp ) return "missing" ;
const time = Date . parse ( timestamp ) ;
if ( ! Number . isFinite ( time ) ) return timestamp ;
const seconds = Math . max ( 0 , Math . round ( ( Date . now ( ) - time ) / 1000 ) ) ;
if ( seconds < 60 ) return seconds + "s ago" ;
const mins = Math . round ( seconds / 60 ) ;
if ( mins < 60 ) return mins + "m ago" ;
const hours = Math . round ( mins / 60 ) ;
if ( hours < 48 ) return hours + "h ago" ;
return Math . round ( hours / 24 ) + "d ago" ;
} ;
const initials = ( value ) => text ( value ) . split ( /\\s+/ ) . map ( ( part ) => part [ 0 ] ) . join ( "" ) . slice ( 0 , 2 ) . toUpperCase ( ) || "?" ;
const badge = ( value , label = value ) => "<span class=\\" badge " + tone(value) + " \ \ ">" + esc ( String ( label ) . replace ( /_/g , " " ) ) + "</span>" ;
function render ( snapshot ) {
setAppHeight ( ) ;
const participants = sortedParticipants ( snapshot ) ;
if ( ! selectedIdentity || ! participants . some ( ( agent ) => agent . identityId === selectedIdentity ) ) {
selectedIdentity = ( snapshot . upcomingTurns || [ ] ) [ 0 ] ? . identityId || participants [ 0 ] ? . identityId || null ;
selectedStatePath = null ;
}
const selected = participants . find ( ( agent ) => agent . identityId === selectedIdentity ) || participants [ 0 ] || null ;
const selectedLeaf = findSelectedLeaf ( selected ) ;
if ( selectedLeaf ) selectedStatePath = selectedLeaf . path ;
app . innerHTML = [
"<div class=\\" shell \ \ ">" ,
"<canvas id=\\" hud - canvas \ \ " class=\\" hud - canvas \ \ "></canvas>" ,
renderCtb ( snapshot . upcomingTurns || [ ] ) ,
renderStatusPanel ( snapshot , selected ) ,
"<section class=\\" workspace \ \ " aria-label=\\" VoidBot swarm control \ \ ">" ,
renderInspector ( snapshot , participants , selected ) ,
renderStateTree ( selected ) ,
renderStateDetail ( selected , selectedLeaf ) ,
"</section>" ,
"</div>" ,
] . join ( "" ) ;
attachControls ( ) ;
attachSelection ( ) ;
attachStateSelection ( ) ;
requestAnimationFrame ( drawHudCanvas ) ;
}
function setAppHeight ( ) {
document . documentElement . style . setProperty ( "--app-height" , window . innerHeight + "px" ) ;
}
function sortedParticipants ( snapshot ) {
return [ ... ( snapshot . participants || [ ] ) ] . sort ( ( a , b ) => {
const active = Number ( Boolean ( b . activeJobId ) ) - Number ( Boolean ( a . activeJobId ) ) ;
if ( active ) return active ;
const mentions = ( b . pendingMentionCount || 0 ) - ( a . pendingMentionCount || 0 ) ;
if ( mentions ) return mentions ;
return ( a . nextTurnInMinutes ? ? 999999 ) - ( b . nextTurnInMinutes ? ? 999999 ) ;
} ) ;
}
function renderCtb ( turns ) {
return "<nav class=\\" ctb - rail \ \ " aria-label=\\" Upcoming CTB turns \ \ ">" + turns . map ( ( turn ) => {
const klass = [ "turn-card" , turn . identityId === selectedIdentity ? "selected" : "" , turn . activeJobId ? "active-turn" : "" , turn . pendingMentionCount > 0 ? "mention-turn" : "" ] . filter ( Boolean ) . join ( " " ) ;
return "<button class=\\" " + klass + " \ \ " type=\\" button \ \ " data-select=\\" " + esc(turn.identityId) + " \ \ " title=\\" " + esc(turn.displayName + " / " + minutes(turn.nextTurnInMinutes, turn.restState)) + " \ \ ">" + avatarHtml ( turn ) + "<strong>" + esc ( turn . displayName ) + "</strong><span>" + esc ( minutes ( turn . nextTurnInMinutes , turn . restState ) ) + "</span>" + ( turn . shuffleReason ? "<span class=\\" turn - reason \ \ ">" + esc ( turn . shuffleReason ) + "</span>" : "" ) + "</button>" ;
} ) . join ( "" ) + "</nav>" ;
}
function renderInspector ( snapshot , participants , agent ) {
if ( ! agent ) return "<section class=\\" pane inspector - pane \ \ "><p class=\\" kicker \ \ ">Face</p><p class=\\" muted \ \ ">No selected Face.</p></section>" ;
const counts = agent . faceState ? . counts || { } ;
const memoryCount = ( counts . shortTerm || 0 ) + ( counts . memories || 0 ) ;
return "<section class=\\" pane inspector - pane \ \ ">" + renderControls ( snapshot , participants ) + "<div class=\\" inspector - hero \ \ ">" + avatarHtml ( agent ) + "<div><p class=\\" kicker \ \ ">Selected Face</p><h1>" + esc ( agent . displayName ) + "</h1><p class=\\" muted mono \ \ ">" + esc ( agent . identityId ) + " / " + esc ( agent . repoName ) + "</p></div></div><div class=\\" agent - stats \ \ ">" +
statBar ( "Turn" , minutes ( agent . nextTurnInMinutes , agent . restState ) , turnPercent ( agent . nextTurnInMinutes ) , agent . restState ? . isNapping === true ? "warm" : "cool" ) +
statBar ( "Memory" , number ( memoryCount ) , Math . min ( 100 , memoryCount * 7 ) , "cool" ) +
statBar ( "Pressure" , number ( counts . pressures || 0 ) , Math . min ( 100 , ( counts . pressures || 0 ) * 14 ) , ( counts . pressures || 0 ) > 4 ? "hot" : "" ) +
statBar ( "Heat" , number ( agent . heat ) , Math . min ( 100 , ( agent . heat || 0 ) * 34 ) , ( agent . heat || 0 ) > 1.5 ? "hot" : "" ) +
2026-07-12 02:21:43 +01:00
statBar ( "Response" , number ( agent . responsePressure ) , Math . min ( 100 , ( agent . responsePressure || 0 ) * 100 ) , ( agent . responsePressure || 0 ) > 0.6 ? "hot" : "" ) +
statBar ( "Dynamic" , number ( agent . dynamicHeat ) , Math . min ( 100 , ( agent . dynamicHeat || 0 ) * 40 ) , ( agent . dynamicHeat || 0 ) > 1.5 ? "hot" : "" ) +
2026-06-02 15:53:17 +01:00
statBar ( "Load" , number ( agent . currentLoad ) , Math . min ( 100 , ( agent . currentLoad || 0 ) * 100 ) , ( agent . currentLoad || 0 ) > 0.7 ? "hot" : "" ) +
statBar ( "Speed" , number ( agent . effectiveSpeed ) , Math . min ( 100 , ( agent . effectiveSpeed || 0 ) * 34 ) , "" ) +
"</div><div class=\\" inspector - lore \ \ "><p>" + esc ( agent . description || "No Face description registered." ) + "</p><div class=\\" channel - list \ \ ">" + ( agent . channelPermissions || [ ] ) . map ( ( channel ) => "<div class=\\" channel - chip \ \ "><strong>" + esc ( channel . label || "channel" ) + "</strong><span>x" + esc ( number ( channel . speedMultiplier || 1 ) ) + "</span><span class=\\" muted \ \ ">" + esc ( channel . topic || "no topic" ) + "</span><span class=\\" mono muted \ \ ">" + esc ( channel . speechThreshold || "threshold" ) + "</span></div>" ) . join ( "" ) + "</div></div></section>" ;
}
function renderControls ( snapshot , participants ) {
const controls = snapshot . controls || { } ;
const latest = ( controls . manualTurnRequests || [ ] ) [ 0 ] ;
const paused = snapshot . summary ? . paused === true ;
const pauseReason = snapshot . summary ? . pauseReason
? "<div class=\\" muted small \ \ ">" + esc ( snapshot . summary . pauseReason ) + "</div>"
: "" ;
return "<div class=\\" control - grid \ \ "><p class=\\" kicker \ \ ">Controls</p>" +
"<div><div class=\\" muted \ \ ">Swarm brake</div><div class=\\" control - row \ \ "><span>" + badge ( paused ? "paused" : "running" , paused ? "Paused" : "Unpaused" ) + "</span></div>" + pauseReason + "</div>" +
"<div><div class=\\" muted \ \ ">Heartbeat cadence</div><div class=\\" control - row \ \ "><strong id=\\" cadence - value \ \ " class=\\" mono \ \ ">x" + esc ( number ( controls . cadenceMultiplier || 1 ) ) + "</strong></div></div>" +
"<div><div class=\\" muted \ \ ">Control surface</div><div class=\\" mono \ \ ">CultMesh Eve binding: gamecult.eve.interface_binding / voidbot.swarm</div></div>" +
"<div class=\\" mono muted \ \ ">Latest request: " + esc ( latest ? . identityId || "none" ) + " " + esc ( latest ? . status || "" ) + "</div>" +
"</div>" ;
}
function statBar ( label , value , fill , variant = "" ) {
return "<div class=\\" agent - stat \ \ "><div class=\\" agent - stat - head \ \ "><span>" + esc ( label ) + "</span><strong>" + esc ( value ) + "</strong></div><div class=\\" agent - bar \ \ "><span class=\\" agent - fill " + esc(variant) + " \ \ " style=\\" -- fill : " + esc(clampPercent(fill)) + " \ \ "></span></div></div>" ;
}
function turnPercent ( value ) {
if ( typeof value !== "number" ) return 0 ;
return value <= 0 ? 100 : clampPercent ( 100 - value * 5 ) ;
}
function renderStateTree ( agent ) {
const state = agent ? . faceState ;
if ( ! agent ) return "<section class=\\" pane tree - pane \ \ "><p class=\\" kicker \ \ ">State Graph</p><p class=\\" muted \ \ ">No Face selected.</p></section>" ;
if ( ! state ? . readable ) return "<section class=\\" pane tree - pane \ \ "><p class=\\" kicker \ \ ">State Graph</p><p class=\\" muted \ \ ">" + esc ( state ? . error || "Face state unreadable." ) + "</p></section>" ;
return "<section class=\\" pane tree - pane \ \ "><div><p class=\\" kicker \ \ ">State Graph</p><h2>" + esc ( agent . displayName ) + " memory tree</h2><p class=\\" muted mono \ \ ">" + esc ( state . path || "state path missing" ) + "</p></div><div class=\\" state - tree \ \ ">" + renderTreeNodes ( state . tree || [ ] , 0 ) + "</div></section>" ;
}
function renderTreeNodes ( nodes , depth = 0 ) {
return ( nodes || [ ] ) . map ( ( node ) => {
if ( node . kind === "branch" ) {
const open = depth === 0 || branchContainsSelection ( node ) ;
return "<details class=\\" state - node \ \ " " + ( open ? "open" : "" ) + "><summary><span>" + esc ( node . label ) + "</span><span class=\\" mono muted \ \ ">" + esc ( node . count || 0 ) + "</span></summary><div class=\\" state - children \ \ ">" + renderTreeNodes ( node . children || [ ] , depth + 1 ) + "</div></details>" ;
}
const klass = "state-leaf" + ( node . path === selectedStatePath ? " selected" : "" ) ;
return "<button class=\\" " + klass + " \ \ " type=\\" button \ \ " data-state-path=\\" " + esc(node.path) + " \ \ "><strong>" + esc ( node . label ) + "</strong><span>" + esc ( node . preview || "" ) + "</span></button>" ;
} ) . join ( "" ) ;
}
function renderStateDetail ( agent , leaf ) {
if ( ! agent ) return "<section class=\\" pane memory - pane \ \ "><p class=\\" kicker \ \ ">State Detail</p><p class=\\" muted \ \ ">No selected Face.</p></section>" ;
if ( ! agent . faceState ? . readable ) return "<section class=\\" pane memory - pane \ \ "><p class=\\" kicker \ \ ">State Detail</p><p class=\\" muted \ \ ">" + esc ( agent . faceState ? . error || "Face state unreadable." ) + "</p></section>" ;
const selected = leaf || firstLeaf ( agent . faceState . tree || [ ] ) ;
if ( ! selected ) return "<section class=\\" pane memory - pane \ \ "><p class=\\" kicker \ \ ">State Detail</p><p class=\\" muted \ \ ">No entries in this state file.</p></section>" ;
selectedStatePath = selected . path ;
return "<section class=\\" pane memory - pane \ \ "><div><p class=\\" kicker \ \ ">State Detail</p><h2>" + esc ( selected . title || selected . label ) + "</h2><p class=\\" muted mono \ \ ">" + esc ( selected . path ) + "</p></div><div class=\\" detail - body \ \ "><div class=\\" detail - card \ \ "><pre>" + esc ( selected . detail || selected . preview || "" ) + "</pre></div></div></section>" ;
}
function findSelectedLeaf ( agent ) {
const leaves = flattenLeaves ( agent ? . faceState ? . tree || [ ] ) ;
if ( ! leaves . length ) return null ;
if ( selectedStatePath ) {
const existing = leaves . find ( ( leaf ) => leaf . path === selectedStatePath ) ;
if ( existing ) return existing ;
}
const memory = leaves . find ( ( leaf ) =>
leaf . label !== "empty" && (
leaf . path . startsWith ( "thoughtMemory.shortTerm" ) ||
leaf . path . startsWith ( "thoughtMemory.memories" ) ||
leaf . path . startsWith ( "thoughtMemory.incubation" )
)
) ;
if ( memory ) return memory ;
return leaves [ 0 ] ;
}
function firstLeaf ( nodes ) {
return flattenLeaves ( nodes ) [ 0 ] || null ;
}
function flattenLeaves ( nodes ) {
const output = [ ] ;
const visit = ( node ) => {
if ( ! node ) return ;
if ( node . kind === "leaf" ) output . push ( node ) ;
for ( const child of node . children || [ ] ) visit ( child ) ;
} ;
for ( const node of nodes || [ ] ) visit ( node ) ;
return output ;
}
function branchContainsSelection ( node ) {
if ( ! selectedStatePath ) return false ;
if ( node . path && selectedStatePath . startsWith ( node . path ) ) return true ;
return ( node . children || [ ] ) . some ( ( child ) => child . kind === "branch" ? branchContainsSelection ( child ) : child . path === selectedStatePath ) ;
}
function renderStatusPanel ( snapshot , agent ) {
const summary = snapshot . summary || { } ;
const organs = snapshot . orchestrator ? . organs || [ ] ;
const watchdog = findOrgan ( organs , "watchdog" ) ;
const face = findOrgan ( organs , "repo-face-heartbeats" ) ;
const mood = findOrgan ( organs , "mood" ) ;
const rumination = findOrgan ( organs , "rumination" ) ;
const sourceFreshness = snapshot . sources ? . heartbeatStateUpdatedAt ? Math . max ( 0 , 100 - ( ( Date . now ( ) - Date . parse ( snapshot . sources . heartbeatStateUpdatedAt ) ) / 600 ) ) : 0 ;
const meshOk = snapshot . cultMesh ? . writeStatus === "ok" ? 100 : snapshot . cultMesh ? . writeStatus === "pending" ? 50 : 10 ;
const turn = agent ? . nextTurnInMinutes ? ? null ;
const turnFill = typeof turn === "number" ? clampPercent ( 100 - Math . max ( 0 , turn ) * 4 ) : 0 ;
const load = clampPercent ( ( agent ? . currentLoad || 0 ) * 100 ) ;
return "<aside class=\\" status - panel \ \ " aria-label=\\" Compact swarm status \ \ "><h2><span>VOID</span><span>" + esc ( String ( summary . state || "UNK" ) . slice ( 0 , 4 ) . toUpperCase ( ) ) + "</span></h2><div class=\\" status - grid \ \ ">" +
hud ( "WDOG" , organCode ( watchdog ) , organFill ( watchdog ) , organWarn ( watchdog ) ) +
hud ( "ORCH" , shortState ( snapshot . orchestrator ? . state ) , statusFill ( snapshot . orchestrator ? . state ) , statusWarn ( snapshot . orchestrator ? . state ) ) +
hud ( "FACE" , organCode ( face ) , organFill ( face ) , organWarn ( face ) ) +
hud ( "MOOD" , organCode ( mood ) , organFill ( mood ) , organWarn ( mood ) ) +
hud ( "RUM" , organCode ( rumination ) , organFill ( rumination ) , organWarn ( rumination ) ) +
hud ( "MESH" , shortState ( snapshot . cultMesh ? . writeStatus ) , meshOk , snapshot . cultMesh ? . writeStatus !== "ok" ) +
hud ( "AGE" , relative ( snapshot . sources ? . heartbeatStateUpdatedAt ) . replace ( / ago$/ , "" ) , sourceFreshness , sourceFreshness < 50 ) +
hud ( "TURN" , minutes ( turn ) , turnFill , load > 70 ) +
"</div></aside>" ;
}
function findOrgan ( organs , needle ) {
const lower = String ( needle ) . toLowerCase ( ) ;
return organs . find ( ( organ ) => String ( organ . id || "" ) . toLowerCase ( ) . includes ( lower ) || String ( organ . label || "" ) . toLowerCase ( ) . includes ( lower ) ) ;
}
function shortState ( value ) {
const state = String ( value || "missing" ) . toLowerCase ( ) ;
if ( state === "ok" ) return "OK" ;
if ( state === "ready" ) return "RDY" ;
if ( state === "running" ) return "RUN" ;
if ( state === "paused" ) return "PAUS" ;
if ( state === "warning" ) return "WARN" ;
if ( state === "skipped_disabled" ) return "SKIP" ;
if ( state === "missing" ) return "MISS" ;
if ( state === "failed" || state === "error" ) return "FAIL" ;
return state . slice ( 0 , 4 ) . toUpperCase ( ) ;
}
function organCode ( organ ) {
return organ ? shortState ( organ . lastStatus ) : "MISS" ;
}
function organFill ( organ ) {
return organ ? statusFill ( organ . lastStatus ) : 0 ;
}
function organWarn ( organ ) {
return ! organ || statusWarn ( organ . lastStatus ) ;
}
function statusFill ( value ) {
const state = String ( value || "missing" ) . toLowerCase ( ) ;
if ( state === "ok" || state === "ready" || state === "skipped_disabled" ) return 100 ;
if ( state === "running" ) return 82 ;
if ( state === "warning" || state === "paused" ) return 46 ;
return 12 ;
}
function statusWarn ( value ) {
const state = String ( value || "missing" ) . toLowerCase ( ) ;
return ! [ "ok" , "ready" , "running" , "skipped_disabled" ] . includes ( state ) ;
}
function hud ( label , value , fill , warn = false ) {
return "<div class=\\" hud - stat \ \ "><div class=\\" hud - label \ \ "><span>" + esc ( label ) + "</span><span>" + esc ( value ) + "</span></div><div class=\\" hud - bar \ \ "><span class=\\" hud - fill " + (warn ? " warn " : " ") + " \ \ " style=\\" -- fill : " + esc(clampPercent(fill)) + " \ \ "></span></div></div>" ;
}
function clampPercent ( value ) {
const numeric = Number ( value ) ;
return Number . isFinite ( numeric ) ? Math . max ( 0 , Math . min ( 100 , numeric ) ) : 0 ;
}
function metric ( label , value ) {
return "<div class=\\" metric \ \ "><span>" + esc ( label ) + "</span><strong>" + value + "</strong></div>" ;
}
function fact ( label , value ) {
return "<div class=\\" fact \ \ "><span>" + esc ( label ) + "</span><strong>" + esc ( value ) + "</strong></div>" ;
}
function avatarHtml ( agent ) {
return agent . avatarUrl
? "<span class=\\" avatar \ \ "><img src=\\" " + esc(agent.avatarUrl) + " \ \ " alt=\\" " + esc(agent.displayName) + " \ \ "></span>"
: "<span class=\\" avatar \ \ ">" + esc ( initials ( agent . displayName ) ) + "</span>" ;
}
function drawHudCanvas ( ) {
const canvas = document . getElementById ( "hud-canvas" ) ;
if ( ! canvas ) return ;
const rect = canvas . getBoundingClientRect ( ) ;
const ratio = Math . max ( 1 , Math . min ( 2 , window . devicePixelRatio || 1 ) ) ;
const width = Math . max ( 1 , Math . floor ( rect . width * ratio ) ) ;
const height = Math . max ( 1 , Math . floor ( rect . height * ratio ) ) ;
if ( canvas . width !== width || canvas . height !== height ) {
canvas . width = width ;
canvas . height = height ;
}
const ctx = canvas . getContext ( "2d" ) ;
ctx . setTransform ( ratio , 0 , 0 , ratio , 0 , 0 ) ;
ctx . clearRect ( 0 , 0 , rect . width , rect . height ) ;
const bg = ctx . createLinearGradient ( 0 , 0 , rect . width , rect . height ) ;
bg . addColorStop ( 0 , "#03070d" ) ;
bg . addColorStop ( 0.55 , "#07110f" ) ;
bg . addColorStop ( 1 , "#091712" ) ;
ctx . fillStyle = bg ;
ctx . fillRect ( 0 , 0 , rect . width , rect . height ) ;
ctx . globalAlpha = 0.26 ;
ctx . strokeStyle = "rgba(105,226,239,0.16)" ;
ctx . lineWidth = 1 ;
for ( let x = 0 ; x < rect . width ; x += 32 ) {
ctx . beginPath ( ) ;
ctx . moveTo ( x + 0.5 , 0 ) ;
ctx . lineTo ( x + 0.5 , rect . height ) ;
ctx . stroke ( ) ;
}
for ( let y = 0 ; y < rect . height ; y += 24 ) {
ctx . beginPath ( ) ;
ctx . moveTo ( 0 , y + 0.5 ) ;
ctx . lineTo ( rect . width , y + 0.5 ) ;
ctx . stroke ( ) ;
}
ctx . globalAlpha = 1 ;
document . querySelectorAll ( ".pane, .status-panel" ) . forEach ( ( panel ) => {
const r = panel . getBoundingClientRect ( ) ;
drawPanelChrome ( ctx , r . left , r . top , r . width , r . height ) ;
} ) ;
}
function drawPanelChrome ( ctx , x , y , width , height ) {
const radius = 8 ;
ctx . save ( ) ;
ctx . shadowColor = "rgba(0,0,0,0.45)" ;
ctx . shadowBlur = 22 ;
ctx . shadowOffsetY = 10 ;
roundedRect ( ctx , x , y , width , height , radius ) ;
ctx . fillStyle = "rgba(6,15,19,0.34)" ;
ctx . fill ( ) ;
ctx . shadowBlur = 0 ;
ctx . strokeStyle = "rgba(105,226,239,0.2)" ;
ctx . lineWidth = 1 ;
ctx . stroke ( ) ;
ctx . strokeStyle = "rgba(255,174,88,0.16)" ;
ctx . beginPath ( ) ;
ctx . moveTo ( x + 10 , y + 1.5 ) ;
ctx . lineTo ( x + Math . min ( width - 10 , 84 ) , y + 1.5 ) ;
ctx . stroke ( ) ;
ctx . restore ( ) ;
}
function roundedRect ( ctx , x , y , width , height , radius ) {
const r = Math . min ( radius , width / 2 , height / 2 ) ;
ctx . beginPath ( ) ;
ctx . moveTo ( x + r , y ) ;
ctx . lineTo ( x + width - r , y ) ;
ctx . quadraticCurveTo ( x + width , y , x + width , y + r ) ;
ctx . lineTo ( x + width , y + height - r ) ;
ctx . quadraticCurveTo ( x + width , y + height , x + width - r , y + height ) ;
ctx . lineTo ( x + r , y + height ) ;
ctx . quadraticCurveTo ( x , y + height , x , y + height - r ) ;
ctx . lineTo ( x , y + r ) ;
ctx . quadraticCurveTo ( x , y , x + r , y ) ;
}
function attachSelection ( ) {
document . querySelectorAll ( "[data-select]" ) . forEach ( ( element ) => {
element . addEventListener ( "click" , ( ) => {
selectedIdentity = element . getAttribute ( "data-select" ) ;
selectedStatePath = null ;
refresh ( ) ;
} ) ;
} ) ;
}
function attachStateSelection ( ) {
document . querySelectorAll ( "[data-state-path]" ) . forEach ( ( element ) => {
element . addEventListener ( "click" , ( ) => {
selectedStatePath = element . getAttribute ( "data-state-path" ) ;
refresh ( ) ;
} ) ;
} ) ;
}
function attachControls ( ) {
// Static HTML is a debug lowering only. Network controls live in the
// CultMesh Eve binding, not HTTP endpoints.
}
async function refresh ( ) {
try {
const response = await fetch ( "swarm-state.json?ts=" + Date . now ( ) , { cache : "no-store" } ) ;
if ( response . ok ) {
render ( await response . json ( ) ) ;
return ;
}
} catch { }
render ( initialSnapshot ) ;
}
render ( initialSnapshot ) ;
setInterval ( refresh , 10000 ) ;
window . addEventListener ( "orientationchange" , ( ) => setTimeout ( refresh , 180 ) ) ;
window . addEventListener ( "resize" , ( ) => window . requestAnimationFrame ( ( ) => {
setAppHeight ( ) ;
drawHudCanvas ( ) ;
} ) ) ;
refresh ( ) ;
< / s c r i p t >
< / b o d y >
< / h t m l >
` ;
}
function redactSnapshot ( snapshot ) {
const redacted = JSON . parse ( JSON . stringify ( snapshot ) ) ;
redacted . visibility = "public_redacted" ;
redacted . sources = {
heartbeatStateReadable : snapshot . sources ? . heartbeatStateReadable ? ? false ,
heartbeatStateUpdatedAt : snapshot . sources ? . heartbeatStateUpdatedAt ? ? null ,
orchestratorReadable : snapshot . sources ? . orchestratorReadable ? ? false ,
orchestratorUpdatedAt : snapshot . sources ? . orchestratorUpdatedAt ? ? null ,
pauseReadable : snapshot . sources ? . pauseReadable ? ? false ,
} ;
redacted . cultMesh = {
documentType : snapshot . cultMesh ? . documentType ,
schemaId : snapshot . cultMesh ? . schemaId ,
documentKey : snapshot . cultMesh ? . documentKey ,
writeStatus : snapshot . cultMesh ? . writeStatus ,
writtenAt : snapshot . cultMesh ? . writtenAt ,
note : "Public redacted snapshot. Local paths and job ids are withheld." ,
} ;
redacted . participants = redacted . participants . map ( ( participant ) => ( {
... participant ,
activeJobId : participant . activeJobId ? "active" : null ,
constraints : [ ] ,
2026-07-12 02:21:43 +01:00
responsePressureEvidence : [ ] ,
2026-06-02 15:53:17 +01:00
constraintCount : participant . constraintCount ,
description : participant . description ? truncate ( participant . description , 220 ) : null ,
faceStatePath : null ,
faceState : participant . faceState
? {
readable : participant . faceState . readable ,
counts : participant . faceState . counts ,
path : null ,
tree : [ ] ,
}
: undefined ,
} ) ) ;
redacted . activeTurns = redacted . activeTurns . map ( ( participant ) => ( {
... participant ,
activeJobId : participant . activeJobId ? "active" : null ,
constraints : [ ] ,
} ) ) ;
redacted . pendingMentions = redacted . pendingMentions . map ( ( mention ) => ( {
identityId : mention . identityId ,
createdAt : mention . createdAt ,
} ) ) ;
2026-07-06 22:13:23 +01:00
redacted . recentMentionActivity = redacted . recentMentionActivity . map ( ( activity ) => ( {
kind : activity . kind ,
identityId : activity . identityId ,
observedAt : activity . observedAt ,
mentionCount : activity . mentionCount ,
} ) ) ;
if ( redacted . summary ? . lastMentionActivity ) {
redacted . summary . lastMentionActivity = {
kind : redacted . summary . lastMentionActivity . kind ,
identityId : redacted . summary . lastMentionActivity . identityId ,
observedAt : redacted . summary . lastMentionActivity . observedAt ,
mentionCount : redacted . summary . lastMentionActivity . mentionCount ,
} ;
}
2026-06-02 15:53:17 +01:00
redacted . orchestrator . organs = redacted . orchestrator . organs . map ( ( organ ) => ( {
... organ ,
lastLogPath : null ,
} ) ) ;
redacted . recentEvents = redacted . recentEvents . map ( ( event ) => ( {
... event ,
activeJobId : event . activeJobId ? "active" : null ,
statusPath : null ,
} ) ) ;
return redacted ;
}
function primaryCultMeshEndpoint ( ) {
return ` cultmesh:// ${ verseId } /eve/providers/ ${ providerId } ` ;
}
2026-07-05 19:17:10 +01:00
function providerEndpoints ( ) {
return [
{
id : "voidbot.swarm.cultmesh" ,
transport : "cultmesh" ,
address : primaryCultMeshEndpoint ( ) ,
role : "provider-canonical" ,
schemaId : providerAdvertisementSchemaId ,
} ,
{
id : "voidbot.swarm.rudp.snapshot" ,
transport : "cultmesh-rudp" ,
address : swarmCultMeshRudpEndpoint ,
role : "provider-cultmesh-rudp snapshot" ,
schemaId : surfaceSchemaId ,
} ,
2026-07-13 01:02:17 +01:00
{
id : "voidbot.swarm.command" ,
transport : "cultmesh-rudp" ,
uri : "cultmesh://voidbot.local/commands/swarm" ,
address : swarmCultMeshRudpEndpoint . replace ( /^rudp:\/\// , "" ) ,
connectionId : 0x43554c54 ,
role : "provider-command" ,
tags : [ "command" , "swarm" ] ,
schemaId : "gamecult.eve.command.v1" ,
} ,
2026-07-05 19:17:10 +01:00
] ;
}
function providerRoutes ( ) {
return providerEndpoints ( ) ;
}
2026-06-02 15:53:17 +01:00
async function readJsonFile ( path ) {
try {
const raw = await readFile ( path , "utf8" ) ;
return { ok : true , value : JSON . parse ( stripBom ( raw ) ) } ;
} catch ( error ) {
return {
ok : false ,
value : null ,
error : error instanceof Error ? error . message : String ( error ) ,
} ;
}
}
async function getMtime ( path ) {
try {
return ( await stat ( path ) ) . mtime . toISOString ( ) ;
} catch {
return null ;
}
}
async function readDotEnv ( path ) {
const values = { } ;
try {
const raw = await readFile ( path , "utf8" ) ;
for ( const line of raw . split ( /\r?\n/u ) ) {
const trimmed = line . trim ( ) ;
if ( ! trimmed || trimmed . startsWith ( "#" ) ) continue ;
const separator = line . indexOf ( "=" ) ;
if ( separator < 1 ) continue ;
values [ line . slice ( 0 , separator ) . trim ( ) ] = line . slice ( separator + 1 ) ;
}
} catch { }
return values ;
}
2026-07-16 00:27:01 +01:00
function schedulerDebugProjectionPath ( value ) {
if ( ! value ) return value ;
const resolved = resolve ( value ) ;
if ( resolved . toLowerCase ( ) . endsWith ( ".cc" ) ) return ` ${ resolved . slice ( 0 , - 3 ) } .json ` ;
return resolved ;
}
2026-06-02 15:53:17 +01:00
function resolveConfigPath ( value , fallback ) {
const raw = typeof value === "string" && value . trim ( ) ? value . trim ( ) : fallback ;
return resolve ( repoRoot , raw ) ;
}
function parseArgs ( argv ) {
const parsed = { } ;
for ( let index = 0 ; index < argv . length ; index += 1 ) {
const arg = argv [ index ] ;
if ( arg === "--serve" ) parsed . serve = true ;
else if ( arg === "--open" ) parsed . open = true ;
else if ( arg . startsWith ( "--" ) ) {
const key = arg . slice ( 2 ) ;
const next = argv [ index + 1 ] ;
if ( next && ! next . startsWith ( "--" ) ) {
parsed [ key ] = next ;
index += 1 ;
} else {
parsed [ key ] = "true" ;
}
}
}
return parsed ;
}
function isFlagEnabled ( value ) {
return value === true || value === "true" || value === "1" || value === "yes" || value === "on" ;
}
function stripBom ( value ) {
return value . charCodeAt ( 0 ) === 0xfeff ? value . slice ( 1 ) : value ;
}
function numberOrNull ( value ) {
return typeof value === "number" && Number . isFinite ( value ) ? value : null ;
}
function stringOrNull ( value ) {
return typeof value === "string" && value . length > 0 ? value : null ;
}
function round ( value , places ) {
const factor = 10 * * places ;
return Math . round ( value * factor ) / factor ;
}
function truncate ( value , maxLength ) {
return value . length > maxLength ? ` ${ value . slice ( 0 , maxLength - 3 ) } ... ` : value ;
}
function escapeScriptJson ( value ) {
return value . replace ( /</g , "\\u003c" ) . replace ( />/g , "\\u003e" ) . replace ( /&/g , "\\u0026" ) ;
}