oxedyne/daimond/dev/keeper.mjs
3.6 KiB, 1 run
created by r2519314175:23, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | // A long-lived HEADED browser on the user's screen (:0), launched by Playwright |
| 2 | // (which gets the sandbox flags right) and left alive with CDP exposed so other |
| 3 | // scripts can attach and drive it. Real Fireworks key, from the gitignored |
| 4 | // testcfg. Signs in (skips the passphrase), connects the value model, and then |
| 5 | // waits — the user can watch, and grant a real folder when asked. |
| 6 | import fs from 'node:fs'; |
| 7 | import os from 'node:os'; |
| 8 | import path from 'node:path'; |
| 9 | import { fileURLToPath, pathToFileURL } from 'node:url'; |
| 10 | |
| 11 | // Chromium's ozone platform is chosen by autodetection and prefers Wayland whenever |
| 12 | // `WAYLAND_DISPLAY` is set -- which it is in every rc session on argonaut -- so a headed |
| 13 | // run under `xvfb-run` still went to the compositor and opened a window on the owner's |
| 14 | // desktop. Importing this strips the two variables from `process.env`, which is all a |
| 15 | // launcher that spreads `process.env` needs. See dev/display.mjs. |
| 16 | import './display.mjs'; |
| 17 | const HERE = path.dirname(fileURLToPath(import.meta.url)); |
| 18 | const PW = path.join(os.homedir(), '.red-pw/node_modules/playwright-core/index.mjs'); |
| 19 | const { chromium } = await import(pathToFileURL(PW).href); |
| 20 | const CHROME = `${os.homedir()}/.cache/ms-playwright/chromium-1229/chrome-linux64/chrome`; |
| 21 | const cfg = JSON.parse(fs.readFileSync(path.join(HERE, '.secrets/testcfg.json'), 'utf8')); |
| 22 | const MODEL = cfg.models.value; |
| 23 | const CDP_PORT = 9223; |
| 24 | // The world's dev server -- see dev/world.sh. Kept inline rather than imported, |
| 25 | // so this stays standalone and does not load the harness. |
| 26 | const APP = process.env.DAIMOND_APP || `http://localhost:${process.env.DAIMOND_PORT || 8777}`; |
| 27 | |
| 28 | // Not /tmp -- see the SCRATCH note in harness.mjs. Kept inline rather than |
| 29 | // imported, so this stays standalone and does not load the harness. |
| 30 | const SCRATCH = process.env.DAIMOND_SCRATCH || path.join(os.homedir(), '.cache/daimond'); |
| 31 | fs.mkdirSync(SCRATCH, { recursive: true }); |
| 32 | |
| 33 | const browser = await chromium.launchPersistentContext(path.join(SCRATCH, 'real-profile'), { |
| 34 | executablePath: CHROME, |
| 35 | headless: false, |
| 36 | args: [ |
| 37 | '--no-sandbox', '--disable-gpu', '--disable-dev-shm-usage', |
| 38 | `--remote-debugging-port=${CDP_PORT}`, |
| 39 | '--window-size=1600,1000', '--window-position=40,40', |
| 40 | ], |
| 41 | viewport: null, |
| 42 | }); |
| 43 | const page = browser.pages()[0] || await browser.newPage(); |
| 44 | page.on('console', m => { if (m.type() === 'error') console.log('PAGEERR:', m.text().slice(0, 200)); }); |
| 45 | |
| 46 | await page.goto(APP, { waitUntil: 'domcontentloaded' }); |
| 47 | await page.waitForSelector('#id-primary', { timeout: 20000 }); |
| 48 | |
| 49 | // Skip the passphrase (browser-only mode) so the key is simply set; a throwaway |
| 50 | // test profile, so plaintext-in-localStorage is fine here. |
| 51 | const skip = await page.$('#id-skip'); |
| 52 | if (skip && await skip.isVisible()) await skip.click(); |
| 53 | await page.waitForTimeout(800); |
| 54 | |
| 55 | // Set the real provider config directly, then reload so the app adopts it. |
| 56 | await page.evaluate((c) => { |
| 57 | localStorage.setItem('daimond-byok', JSON.stringify({ |
| 58 | baseUrl: c.baseUrl, apiKey: c.apiKey, apiKeyEnc: '', model: c.model, maxTokens: 4096, tools: true, |
| 59 | })); |
| 60 | }, { baseUrl: cfg.baseUrl, apiKey: cfg.apiKey, model: MODEL }); |
| 61 | await page.reload({ waitUntil: 'domcontentloaded' }); |
| 62 | await page.waitForTimeout(1500); |
| 63 | |
| 64 | const ready = await page.evaluate(() => { |
| 65 | try { const j = JSON.parse(localStorage.getItem('daimond-byok') || '{}'); |
| 66 | return { model: j.model, hasKey: !!j.apiKey, base: j.baseUrl }; } catch { return null; } |
| 67 | }); |
| 68 | console.log('KEEPER READY on :0 — CDP on', CDP_PORT, '— cfg:', JSON.stringify(ready)); |
| 69 | console.log('Attach with: connectOverCDP("http://localhost:' + CDP_PORT + '")'); |
| 70 | |
| 71 | // Stay alive. Other scripts attach over CDP and drive this same browser. |
| 72 | await new Promise(() => {}); |