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 sources16d ago| #1 | /** |
| #2 | * HERMES x402 TUI — Header Panel |
| #3 | * |
| #4 | * Renders the neon pixel-art HERMES x402 branding banner. |
| #5 | */ |
| #6 | |
| #7 | import chalk from 'chalk'; |
| #8 | import type { DashboardState } from '../state.js'; |
| #9 | |
| #10 | const HERMES_ASCII = [ |
| #11 | ' ██╗ ██╗███████╗██████╗ ███╗ ███╗███████╗███████╗', |
| #12 | ' ██║ ██║██╔════╝██╔══██╗████╗ ████║██╔════╝██╔════╝', |
| #13 | ' ███████║█████╗ ██████╔╝██╔████╔██║█████╗ ███████╗', |
| #14 | ' ██╔══██║██╔══╝ ██╔══██╗██║╚██╔╝██║██╔══╝ ╚════██║', |
| #15 | ' ██║ ██║███████╗██║ ██║██║ ╚═╝ ██║███████╗███████║', |
| #16 | ]; |
| #17 | |
| #18 | const X402_BADGE = chalk.bgMagenta.white.bold(' x402 '); |
| #19 | const CLAWD_BADGE = chalk.bgCyan.black.bold(' $CLAWD '); |
| #20 | const PAYSH_BADGE = chalk.bgYellow.black.bold(' pay.sh '); |
| #21 | const packageBadge = (count: number): string => |
| #22 | chalk.bgBlue.white.bold(` PKG ${String(count).padStart(2, '0')} `); |
| #23 | const vaultBadge = (available: boolean, walletCount: number): string => |
| #24 | available |
| #25 | ? chalk.bgGreen.black.bold(` VAULT ${walletCount} `) |
| #26 | : chalk.bgRed.white.bold(' VAULT OFF '); |
| #27 | |
| #28 | export function renderHeader(state: DashboardState, width: number): string[] { |
| #29 | const lines: string[] = []; |
| #30 | const border = chalk.cyan('═'.repeat(width)); |
| #31 | |
| #32 | lines.push(chalk.cyan('╔') + border + chalk.cyan('╗')); |
| #33 | |
| #34 | // ASCII logo centered |
| #35 | for (const row of HERMES_ASCII) { |
| #36 | const colored = chalk.hex('#ff00ff').bold(row); |
| #37 | const padding = Math.max(0, Math.floor((width - stripLen(row)) / 2)); |
| #38 | const right = Math.max(0, width - stripLen(row) - padding); |
| #39 | lines.push( |
| #40 | chalk.cyan('║') + |
| #41 | ' '.repeat(padding) + |
| #42 | colored + |
| #43 | ' '.repeat(right) + |
| #44 | chalk.cyan('║'), |
| #45 | ); |
| #46 | } |
| #47 | |
| #48 | // x402 suffix + tagline |
| #49 | const tag = ` ${X402_BADGE} SOVEREIGN AI AGENT ON SOLANA ${CLAWD_BADGE}`; |
| #50 | const tagPlain = ' x402 SOVEREIGN AI AGENT ON SOLANA $CLAWD '; |
| #51 | const tagPad = Math.max(0, width - tagPlain.length); |
| #52 | lines.push( |
| #53 | chalk.cyan('║') + tag + ' '.repeat(tagPad) + chalk.cyan('║'), |
| #54 | ); |
| #55 | |
| #56 | // Sub-tag: self-sustaining loop |
| #57 | const loop = |
| #58 | chalk.yellow(' TRADE') + |
| #59 | chalk.white(' → ') + |
| #60 | chalk.green('EARN USDC') + |
| #61 | chalk.white(' → ') + |
| #62 | chalk.magenta('PAY x402') + |
| #63 | chalk.white(' → ') + |
| #64 | chalk.cyan('GET SMARTER') + |
| #65 | chalk.white(' → ') + |
| #66 | chalk.yellow('TRADE BETTER'); |
| #67 | const loopPlain = ' TRADE → EARN USDC → PAY x402 → GET SMARTER → TRADE BETTER'; |
| #68 | const loopPad = Math.max(0, width - loopPlain.length); |
| #69 | lines.push( |
| #70 | chalk.cyan('║') + loop + ' '.repeat(loopPad) + chalk.cyan('║'), |
| #71 | ); |
| #72 | |
| #73 | // Badges row |
| #74 | const badgeLine = ` ${PAYSH_BADGE} ${chalk.hex('#00eeff').bold('SOLANA')} ${chalk.hex('#ff00ff').bold('A2A')} ${chalk.hex('#00ff99').bold('MCP')} ${packageBadge(state.sdkPackageCount)} ${vaultBadge(state.walletVault.available, state.walletVault.walletCount)} `; |
| #75 | const badgePlain = ` pay.sh SOLANA A2A MCP PKG ${String(state.sdkPackageCount).padStart(2, '0')} VAULT ${state.walletVault.available ? String(state.walletVault.walletCount) : 'OFF'} `; |
| #76 | const badgePad = Math.max(0, width - badgePlain.length); |
| #77 | lines.push( |
| #78 | chalk.cyan('║') + badgeLine + ' '.repeat(badgePad) + chalk.cyan('║'), |
| #79 | ); |
| #80 | |
| #81 | lines.push(chalk.cyan('╠') + border + chalk.cyan('╣')); |
| #82 | |
| #83 | return lines; |
| #84 | } |
| #85 | |
| #86 | function stripLen(s: string): number { |
| #87 | // eslint-disable-next-line no-control-regex |
| #88 | return s.replace(/\x1b\[[0-9;]*m/g, '').length; |
| #89 | } |
| #90 |