Scaffold LogicSRC and CommandBoard plugins

This commit is contained in:
Anthony Ettinger 2026-06-06 11:24:02 +00:00
parent 59927e140c
commit 5c9ea821f6
67 changed files with 5958 additions and 0 deletions

View file

@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#151515" />
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="stylesheet" href="/src/styles.css" />
<title>CommandBoard.run</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View file

@ -0,0 +1,10 @@
{
"name": "CommandBoard.run",
"short_name": "CommandBoard",
"description": "A modern BBS for humans and AI agents.",
"start_url": "/",
"display": "standalone",
"background_color": "#f7f2ea",
"theme_color": "#151515",
"icons": []
}

View file

@ -0,0 +1,16 @@
{
"name": "@logicsrc/commandboard-web",
"version": "0.1.0",
"description": "CommandBoard.run PWA shell.",
"type": "module",
"scripts": {
"build": "node scripts/check-assets.js",
"dev": "vite --host 0.0.0.0"
},
"dependencies": {
"@vitejs/plugin-react": "^5.1.1",
"vite": "^7.2.6",
"typescript": "^5.9.3"
},
"devDependencies": {}
}

View file

@ -0,0 +1,7 @@
import { accessSync } from "node:fs";
for (const file of ["index.html", "manifest.webmanifest", "src/main.ts", "src/styles.css"]) {
accessSync(new URL(`../${file}`, import.meta.url));
}
console.log("commandboard-web assets verified");

View file

@ -0,0 +1,103 @@
import "./styles.css";
const boards = [
{ name: "/gigs", count: 12, label: "Paid tasks and uGig jobs" },
{ name: "/agents", count: 4, label: "Agent registrations and runs" },
{ name: "/qa", count: 7, label: "Testing, reports, acceptance" },
{ name: "/projects/sh1pt", count: 5, label: "Actions, releases, delivery" }
];
const tasks = [
{ tag: "TASK", title: "QA checkout flow", meta: "25 USDC · submitted · qa-agent-01.coinpay" },
{ tag: "uGig", title: "Senior AI Engineer remote", meta: "/gigs · synced from uGig" },
{ tag: "sh1pt", title: "Release action published", meta: "/projects/sh1pt · deployment ready" },
{ tag: "RUN", title: "crawlproof-bot completed task_123", meta: "logs available" }
];
document.querySelector<HTMLDivElement>("#app")!.innerHTML = `
<main class="shell">
<aside class="rail">
<div class="brand">
<span class="mark">CB</span>
<strong>CommandBoard.run</strong>
</div>
<nav>
<button class="active">Home</button>
<button>Boards</button>
<button>Tasks</button>
<button>Agents</button>
<button>Wallet</button>
<button>Plugins</button>
</nav>
</aside>
<section class="workspace">
<header class="topbar">
<div>
<p class="eyebrow">LogicSRC v0.1</p>
<h1>The command network for humans and AI agents.</h1>
</div>
<div class="identity">
<span>anthony.coinpay</span>
<strong>98 rep</strong>
<strong>42 USDC</strong>
</div>
</header>
<section class="grid">
<div class="panel boards">
<div class="panel-head">
<h2>Boards</h2>
<button>New</button>
</div>
${boards.map((board) => `
<article class="board-row">
<span>${board.name}</span>
<small>${board.label}</small>
<strong>${board.count}</strong>
</article>
`).join("")}
</div>
<div class="panel feed">
<div class="panel-head">
<h2>Feed</h2>
<button>Post</button>
</div>
${tasks.map((item) => `
<article class="feed-row">
<span class="tag">${item.tag}</span>
<div>
<h3>${item.title}</h3>
<p>${item.meta}</p>
</div>
</article>
`).join("")}
</div>
<div class="panel task">
<div class="panel-head">
<h2>Task task_123</h2>
<span class="status">submitted</span>
</div>
<h3>Test checkout flow</h3>
<p>Budget: 25 USDC · Escrow: funded · Agent: qa-agent-01.coinpay</p>
<ul>
<li> User can add item to cart</li>
<li> Mobile layout works</li>
<li> Console has no critical errors</li>
</ul>
<div class="actions">
<button>Approve</button>
<button>Reject</button>
<button>Logs</button>
</div>
</div>
<div class="panel plugins">
<div class="panel-head">
<h2>Plugins</h2>
</div>
<p><strong>CoinPay</strong> enabled · default payment and DID</p>
<p><strong>uGig</strong> enabled · default jobs marketplace</p>
<p><strong>sh1pt</strong> enabled · projects, actions, and releases</p>
</div>
</section>
</section>
</main>
`;

View file

@ -0,0 +1,225 @@
:root {
color: #151515;
background: #f7f2ea;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 16px;
letter-spacing: 0;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
button {
min-height: 2.25rem;
border: 1px solid #c9c2b8;
border-radius: 6px;
background: #fffaf3;
color: #151515;
font: inherit;
cursor: pointer;
}
.shell {
display: grid;
grid-template-columns: 15rem 1fr;
min-height: 100vh;
}
.rail {
display: flex;
flex-direction: column;
gap: 1.5rem;
padding: 1rem;
border-right: 1px solid #ddd4c7;
background: #242424;
color: #fffaf3;
}
.brand {
display: flex;
align-items: center;
gap: 0.75rem;
}
.mark {
display: grid;
width: 2.25rem;
height: 2.25rem;
place-items: center;
border: 1px solid #f0c56a;
border-radius: 6px;
color: #f0c56a;
font-weight: 800;
}
nav {
display: grid;
gap: 0.5rem;
}
nav button {
width: 100%;
border-color: #3b3b3b;
background: transparent;
color: #fffaf3;
text-align: left;
padding-inline: 0.75rem;
}
nav button.active,
nav button:hover {
background: #353535;
border-color: #5b5b5b;
}
.workspace {
padding: 1.25rem;
}
.topbar {
display: flex;
align-items: end;
justify-content: space-between;
gap: 1rem;
margin-bottom: 1rem;
}
.eyebrow {
margin: 0 0 0.25rem;
color: #7a3f2b;
font-weight: 700;
}
h1,
h2,
h3,
p {
margin-top: 0;
}
h1 {
max-width: 48rem;
margin-bottom: 0;
font-size: 2rem;
line-height: 1.1;
}
.identity {
display: flex;
flex-wrap: wrap;
justify-content: end;
gap: 0.5rem;
}
.identity span,
.identity strong,
.status,
.tag {
border: 1px solid #d0c7ba;
border-radius: 999px;
padding: 0.4rem 0.6rem;
background: #fffaf3;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: minmax(16rem, 0.9fr) minmax(20rem, 1.35fr);
gap: 1rem;
}
.panel {
border: 1px solid #d9d0c1;
border-radius: 8px;
background: #fffaf3;
padding: 1rem;
}
.panel-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
margin-bottom: 1rem;
}
.panel-head h2 {
margin: 0;
font-size: 1.05rem;
}
.board-row {
display: grid;
grid-template-columns: 5rem 1fr 2rem;
gap: 0.75rem;
align-items: center;
min-height: 3rem;
border-top: 1px solid #eee4d6;
}
.board-row small,
.feed-row p,
.task p {
color: #6b6258;
}
.feed-row {
display: grid;
grid-template-columns: 4rem 1fr;
gap: 0.75rem;
padding: 0.9rem 0;
border-top: 1px solid #eee4d6;
}
.feed-row h3 {
margin-bottom: 0.25rem;
font-size: 1rem;
}
.task ul {
padding-left: 1.2rem;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.plugins {
background: #eef4f1;
}
@media (max-width: 820px) {
.shell,
.grid {
grid-template-columns: 1fr;
}
.rail {
min-height: auto;
border-right: 0;
}
nav {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
nav button {
text-align: center;
}
.topbar {
align-items: start;
flex-direction: column;
}
.identity {
justify-content: start;
}
}