repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
The Living OS cockpit
stars
latest
clone command
git clone gitlawb://did:key:z6Mku78K...XywC/living-os-cockp...git clone gitlawb://did:key:z6Mku78K.../living-os-cockp...59751530feat: surface worker supervisor health in live work4h ago| #1 | import { chromium } from 'playwright'; |
| #2 | import { readFile, mkdir, writeFile } from 'node:fs/promises'; |
| #3 | import path from 'node:path'; |
| #4 | |
| #5 | const repoRoot = '/home/kingbau/Documents/Aethon-Core'; |
| #6 | const evidenceDir = path.join(repoRoot, 'data/automation_status/delegate_codex_evidence'); |
| #7 | |
| #8 | function parseEnv(text) { |
| #9 | const out = {}; |
| #10 | for (const line of text.split(/\r?\n/)) { |
| #11 | const trimmed = line.trim(); |
| #12 | if (!trimmed || trimmed.startsWith('#')) continue; |
| #13 | const idx = trimmed.indexOf('='); |
| #14 | if (idx > 0) out[trimmed.slice(0, idx)] = trimmed.slice(idx + 1).replace(/^"|"$/g, ''); |
| #15 | } |
| #16 | return out; |
| #17 | } |
| #18 | |
| #19 | async function snap(page, name, extra = {}) { |
| #20 | await mkdir(evidenceDir, { recursive: true }); |
| #21 | await page.screenshot({ path: path.join(evidenceDir, `${name}.png`), fullPage: true }).catch(() => {}); |
| #22 | await writeFile(path.join(evidenceDir, `${name}.html`), await page.content().catch(() => ''), 'utf-8'); |
| #23 | await writeFile(path.join(evidenceDir, `${name}.json`), JSON.stringify(extra, null, 2), 'utf-8'); |
| #24 | } |
| #25 | |
| #26 | const credentials = parseEnv(await readFile(path.join(repoRoot, 'data/automation_status/.test_credentials.env'), 'utf-8')); |
| #27 | const email = credentials.KING_LOGIN_EMAIL; |
| #28 | const password = credentials.KING_LOGIN_PASSWORD; |
| #29 | if (!email || !password) throw new Error('Missing King credentials'); |
| #30 | |
| #31 | const browser = await chromium.launch({ headless: false }); |
| #32 | const context = await browser.newContext({ viewport: { width: 1440, height: 1000 } }); |
| #33 | const page = await context.newPage(); |
| #34 | const consoleLog = []; |
| #35 | const networkLog = []; |
| #36 | page.on('console', (msg) => consoleLog.push({ type: msg.type(), text: msg.text() })); |
| #37 | page.on('response', (res) => networkLog.push({ status: res.status(), url: res.url() })); |
| #38 | |
| #39 | const loginRes = await fetch('http://127.0.0.1:8890/api/v1/auth/login', { |
| #40 | method: 'POST', |
| #41 | headers: { 'Content-Type': 'application/json' }, |
| #42 | body: JSON.stringify({ email, password }), |
| #43 | }); |
| #44 | if (!loginRes.ok) throw new Error(`Gateway login failed: ${loginRes.status}`); |
| #45 | const tokens = await loginRes.json(); |
| #46 | await context.addCookies([ |
| #47 | { name: 'theliving_token', value: tokens.access_token, domain: '.theliving.ai', path: '/', httpOnly: true, secure: true, sameSite: 'Lax' }, |
| #48 | { name: 'theliving_refresh', value: tokens.refresh_token, domain: '.theliving.ai', path: '/', httpOnly: true, secure: true, sameSite: 'Lax' }, |
| #49 | ]); |
| #50 | |
| #51 | await page.goto('https://king.theliving.ai', { waitUntil: 'domcontentloaded' }); |
| #52 | await page.waitForSelector('textarea', { timeout: 90000 }); |
| #53 | await snap(page, '01-loaded', { url: page.url(), consoleLog, networkLog }); |
| #54 | |
| #55 | const prompt = 'Codex, add a one-line health check endpoint to the gateway that returns the current UTC time as JSON.'; |
| #56 | await page.locator('textarea').fill(prompt); |
| #57 | await page.getByRole('button', { name: /^Send$/ }).click(); |
| #58 | await page.waitForFunction(() => document.body.innerText.includes('delegate_coding_task'), null, { timeout: 60000 }); |
| #59 | await snap(page, '02-confirmation', { prompt, consoleLog, networkLog }); |
| #60 | |
| #61 | await page.locator('textarea').fill('approve'); |
| #62 | await page.getByRole('button', { name: /^Send$/ }).click(); |
| #63 | await page.waitForFunction(() => document.body.innerText.includes('Refused before execution') || document.body.innerText.includes('Coding delegate finished'), null, { timeout: 120000 }); |
| #64 | await snap(page, '03-result', { consoleLog, networkLog }); |
| #65 | |
| #66 | await writeFile(path.join(evidenceDir, 'summary.json'), JSON.stringify({ |
| #67 | at: new Date().toISOString(), |
| #68 | consoleLog, |
| #69 | badConsole: consoleLog.filter((entry) => /TypeError|Cannot read properties/i.test(entry.text)), |
| #70 | authFailures: networkLog.filter((entry) => [401, 403].includes(entry.status)), |
| #71 | networkLog, |
| #72 | }, null, 2)); |
| #73 | await browser.close(); |
| #74 |