repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources15d ago| #1 | /** |
| #2 | * automaton-main/automation/runtime.ts — Leviathan runtime builder |
| #3 | * |
| #4 | * Orchestrates the full solana-clawd stack: |
| #5 | * 1. Verify environment (Node 20+, npm, optional Rust/Python) |
| #6 | * 2. Install deps |
| #7 | * 3. Build TypeScript dist |
| #8 | * 4. Spawn Leviathan identity (if not already spawned) |
| #9 | * 5. Optionally start brain, MCP, and HERMES |
| #10 | */ |
| #11 | |
| #12 | import { execSync, spawn } from 'node:child_process'; |
| #13 | import { existsSync } from 'node:fs'; |
| #14 | import { join } from 'node:path'; |
| #15 | import chalk from 'chalk'; |
| #16 | |
| #17 | const GREEN = chalk.hex('#14F195'); |
| #18 | const PURPLE = chalk.hex('#9945FF'); |
| #19 | const DIM = chalk.dim; |
| #20 | const REPO_ROOT = join(import.meta.dirname, '..', '..'); |
| #21 | |
| #22 | export interface RuntimeOptions { |
| #23 | install?: boolean; |
| #24 | build?: boolean; |
| #25 | spawn?: boolean; |
| #26 | brain?: boolean; |
| #27 | mcp?: boolean; |
| #28 | hermes?: boolean; |
| #29 | run?: boolean; |
| #30 | quiet?: boolean; |
| #31 | } |
| #32 | |
| #33 | function ok(msg: string) { console.log(` ${GREEN('✓')} ${msg}`); } |
| #34 | function warn(msg: string) { console.log(` ${chalk.yellow('!')} ${msg}`); } |
| #35 | function step(msg: string) { console.log(`\n${chalk.bold(PURPLE('▶'))} ${chalk.bold(msg)}`); } |
| #36 | |
| #37 | function run(cmd: string, opts: { silent?: boolean; cwd?: string } = {}): boolean { |
| #38 | try { |
| #39 | execSync(cmd, { |
| #40 | stdio: opts.silent ? 'pipe' : 'inherit', |
| #41 | encoding: 'utf8', |
| #42 | cwd: opts.cwd ?? REPO_ROOT, |
| #43 | }); |
| #44 | return true; |
| #45 | } catch { |
| #46 | return false; |
| #47 | } |
| #48 | } |
| #49 | |
| #50 | function nodeVersion(): number { |
| #51 | return Number(process.versions.node.split('.')[0]); |
| #52 | } |
| #53 | |
| #54 | export async function buildRuntime(opts: RuntimeOptions = {}): Promise<void> { |
| #55 | const { |
| #56 | install = true, |
| #57 | build = true, |
| #58 | spawn = false, |
| #59 | brain = false, |
| #60 | mcp = false, |
| #61 | hermes = false, |
| #62 | run: doRun = false, |
| #63 | quiet = false, |
| #64 | } = opts; |
| #65 | |
| #66 | if (!quiet) { |
| #67 | console.log(chalk.bold(PURPLE('\n LEVIATHAN RUNTIME :: automaton-main/automation/runtime.ts'))); |
| #68 | console.log(DIM(' curl -fsSL https://x402.wtf/automation/install.sh | bash\n')); |
| #69 | } |
| #70 | |
| #71 | // ── Environment ──────────────────────────────────────────────────────────── |
| #72 | step('Environment check'); |
| #73 | if (nodeVersion() < 20) { |
| #74 | console.error(chalk.red(`✗ Node >= 20 required (current: ${process.version})`)); |
| #75 | process.exit(1); |
| #76 | } |
| #77 | ok(`Node ${process.version}`); |
| #78 | |
| #79 | const repoRoot = REPO_ROOT; |
| #80 | |
| #81 | // ── Install ──────────────────────────────────────────────────────────────── |
| #82 | if (install) { |
| #83 | step('npm install'); |
| #84 | if (run('npm install --silent', { silent: true })) ok('Dependencies installed'); |
| #85 | else warn('npm install had warnings — check output'); |
| #86 | } |
| #87 | |
| #88 | // ── Build ────────────────────────────────────────────────────────────────── |
| #89 | if (build) { |
| #90 | step('Build TypeScript'); |
| #91 | if (run('npm run automaton:build', { silent: quiet })) ok('automaton-main build compiled'); |
| #92 | else warn('Build step failed — run npm run automaton:build manually'); |
| #93 | } |
| #94 | |
| #95 | // ── Spawn identity ───────────────────────────────────────────────────────── |
| #96 | if (spawn) { |
| #97 | const idFile = join(repoRoot, '.leviathan', 'identity.json'); |
| #98 | if (existsSync(idFile)) { |
| #99 | ok('Leviathan identity already exists (skip --spawn)'); |
| #100 | } else { |
| #101 | step('Spawn Leviathan identity'); |
| #102 | run('npm run leviathan:spawn'); |
| #103 | } |
| #104 | } |
| #105 | |
| #106 | // ── Brain ────────────────────────────────────────────────────────────────── |
| #107 | if (brain) { |
| #108 | step('Initialize Clawd memory (MemeBRain)'); |
| #109 | if (!run('npm run brain:init', { silent: quiet })) { |
| #110 | warn('brain:init skipped — Python / mnemosyne not installed'); |
| #111 | } else { |
| #112 | ok('Memory substrate ready'); |
| #113 | } |
| #114 | } |
| #115 | |
| #116 | // ── MCP ──────────────────────────────────────────────────────────────────── |
| #117 | if (mcp) { |
| #118 | step('Start MCP server'); |
| #119 | const child = spawn('npm', ['run', 'mcp:start'], { |
| #120 | detached: true, |
| #121 | stdio: 'ignore', |
| #122 | cwd: repoRoot, |
| #123 | }); |
| #124 | child.unref(); |
| #125 | ok(`MCP server started (PID ${child.pid})`); |
| #126 | } |
| #127 | |
| #128 | // ── HERMES / run ────────────────────────────────────────────────────────── |
| #129 | if (hermes) { |
| #130 | step('Launch HERMES x402 terminal'); |
| #131 | run('npm run hermes'); |
| #132 | } else if (doRun) { |
| #133 | step('Start Leviathan OODA loop'); |
| #134 | run('npm run leviathan'); |
| #135 | } |
| #136 | |
| #137 | ok(`Runtime ready :: ${GREEN('x402.wtf/automation')}`); |
| #138 | } |
| #139 |