SNAPKITTYWEST's picture
push from SNAPKITTYWEST/snapkitty-clojure-lisp-bridge
119e586 verified
Raw
History Blame Contribute Delete
3.39 kB
/**
* ABZU IDE Bridge β€” WebSocket push to Phoenix LiveView
*
* The ABZU Sovereign BEAM IDE (Phoenix LiveView, Elixir) receives live
* pipeline results via Phoenix channels. This bridge connects the Node.js
* GitLab connector to the ABZU IDE's WebSocket.
*
* ABZU channel: "sovereign:gitlab"
* Events pushed:
* "pipeline_result" β€” Frankenstein 4-step result with WORM seals
* "gitlab_event" β€” raw classified event (push/MR/pipeline)
* "worm_seal" β€” new chain entry notification
*
* The ABZU IDE renders:
* - Live Brain output (architect spec)
* - Live Legs code (Granite execution)
* - WORM chain visualisation
* - GitLab event feed
*/
import { createHash } from 'crypto'
const ABZU_URL = process.env.ABZU_URL || 'http://localhost:4000'
const ABZU_SECRET = process.env.ABZU_SECRET || 'sovereign-abzu-bridge'
// Phoenix channel HTTP push (via Phoenix.PubSub REST bridge on ABZU side)
// ABZU exposes POST /api/pipeline_event for server-to-server push
export async function pushToAbzu(payload) {
const ts = Date.now()
const sig = createHash('sha256')
.update(`${ABZU_SECRET}:${ts}:${JSON.stringify(payload)}`)
.digest('hex')
.slice(0, 16)
const body = {
channel: 'sovereign:gitlab',
event: 'pipeline_result',
payload,
ts,
sig,
worm_hash: payload.worm,
seal: '⬑ Ξ© β†Ί Ξ¨ Ξ” Ξ› Ξ£ Ξ¦ Ξ±',
}
try {
const res = await fetch(`${ABZU_URL}/api/pipeline_event`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Sovereign-Sig': sig,
'X-Sovereign-Ts': ts.toString(),
},
body: JSON.stringify(body),
signal: AbortSignal.timeout(5_000),
})
if (res.ok) {
console.log(`[ABZU] Pipeline result pushed β†’ ${ABZU_URL} βœ“`)
} else {
console.warn(`[ABZU] Push failed: HTTP ${res.status}`)
}
} catch (err) {
// ABZU IDE offline β€” log but don't fail the pipeline
console.warn(`[ABZU] IDE offline (${err.message}) β€” result logged to WORM only`)
}
}
// ── Format for ABZU LiveView rendering ───────────────────────────────────────
export function formatForAbzu(frankensteinResult, gitlabContext) {
const steps = frankensteinResult.steps || []
return {
pipeline_id: Date.now(),
event: gitlabContext,
brain: {
output: steps.find(s => s.step === 'BRAIN')?.output || '',
ms: steps.find(s => s.step === 'BRAIN')?.ms || 0,
worm: steps.find(s => s.step === 'BRAIN')?.worm || '',
},
hands: {
output: steps.find(s => s.step === 'HANDS')?.output || '',
ms: steps.find(s => s.step === 'HANDS')?.ms || 0,
},
legs: {
output: steps.find(s => s.step === 'LEGS')?.output || '',
ms: steps.find(s => s.step === 'LEGS')?.ms || 0,
worm: steps.find(s => s.step === 'LEGS')?.worm || '',
model: steps.find(s => s.step === 'LEGS')?.model || '',
},
review: {
output: frankensteinResult.final_out || '',
worm: steps.find(s => s.step === 'REVIEW')?.worm || '',
},
chain_hash: frankensteinResult.worm?.hash || '',
total_seals: frankensteinResult.worm?.seals || 0,
}
}