Bring the terminal dev-tool/OSS-docs theme to full Wave A OVERRIDE-CONTRACT compliance. - 49 mandatory builtin overrides in templates/overrides/terminal/ (TTY chrome, re-skinned from the frozen builtin defaults; every content field, provider var, custom tag, data-bn-* attr and inline script preserved verbatim). - 7 page templates (default, full-width, landing, article, blog-index, contact, auth) with TTY-window chrome, man-page article layout, and theme_mode-driven light/dark switching. - GO BIG motion: dependency-free ASCII glyph-rain canvas on the hero override only (lazy-init, prefers-reduced-motion honored, static phosphor fallback). - 4 persona blocks (manpage_header, code_console, keybind_table, boot_log); ascii_header/toc/footer blocks retired in favour of overrides + template furniture. - 5 dual-mode presets (mode "both", all 19 tokens) with intentional paper-teletype light and phosphor dark sides. - Bundled OFL mono fonts (JetBrains Mono, IBM Plex Mono) with LICENSES record; all font-family via var(--font-heading|body|mono, fallback). - Themed email-safe wrapper (retained), master pages, and a seeded "grid" OSS dev-tool demo site (home, about, changelog + 3 posts, contact with row_inserted -> email-admins workflow, login). - Declared required_icon_packs = [lucide, simple-icons]. Verified: make build exit 0, make verify exit 0, check-safety exit 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
241 lines
13 KiB
JSON
241 lines
13 KiB
JSON
{
|
|
"demo": true,
|
|
"settings": {
|
|
"merge": {
|
|
"companyName": "grid",
|
|
"tagline": "A fast parallel task runner and build cache for the terminal."
|
|
}
|
|
},
|
|
"data_tables": [
|
|
{
|
|
"key": "contact_submissions",
|
|
"name": "Contact Enquiries",
|
|
"description": "Seeded contact-form submissions for the grid demo. A submission becomes a row here and emails the site admins.",
|
|
"columns": [
|
|
{ "key": "name", "label": "Name", "type": "text", "required": true },
|
|
{ "key": "email", "label": "Email", "type": "email", "required": true },
|
|
{ "key": "project", "label": "Project", "type": "text", "required": false },
|
|
{ "key": "message", "label": "Message", "type": "text", "required": true }
|
|
]
|
|
}
|
|
],
|
|
"pages": [
|
|
{
|
|
"slug": "/",
|
|
"title": "grid",
|
|
"template_key": "landing",
|
|
"blocks": [
|
|
{
|
|
"block_key": "hero",
|
|
"title": "Hero",
|
|
"slot": "main",
|
|
"sort_order": 1,
|
|
"content": {
|
|
"template": "centered",
|
|
"minHeight": "screen",
|
|
"eyebrow": "v1.4.0",
|
|
"headline": "Run every task in parallel",
|
|
"subheadline": "grid is a task runner and build cache for the terminal.",
|
|
"description": "Define tasks once. grid runs the ones that changed, in parallel, and caches the rest. No config server, no daemon.",
|
|
"ctaPrimary": { "text": "Install", "url": "/contact" },
|
|
"ctaSecondary": { "text": "Read the docs", "url": "/blog" }
|
|
}
|
|
},
|
|
{
|
|
"block_key": "feature-grid",
|
|
"title": "Features",
|
|
"slot": "main",
|
|
"sort_order": 2,
|
|
"content": {
|
|
"eyebrow": "What it does",
|
|
"heading": "One binary, three jobs",
|
|
"intro": "Runs tasks, caches output, and watches files. Nothing else to install.",
|
|
"layout": "card",
|
|
"columns": 3,
|
|
"items": [
|
|
{ "icon": "lucide:cpu", "title": "Parallel", "text": "Tasks that do not depend on each other run at the same time, up to your core count." },
|
|
{ "icon": "lucide:database", "title": "Cached", "text": "Every task output is keyed by its inputs. Unchanged inputs skip the work." },
|
|
{ "icon": "lucide:eye", "title": "Watch", "text": "Point grid at a file glob and it reruns the affected tasks on save." }
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"block_key": "terminal:code_console",
|
|
"title": "Install",
|
|
"slot": "main",
|
|
"sort_order": 3,
|
|
"content": {
|
|
"prompt": "$",
|
|
"language": "shell",
|
|
"command": "curl -fsSL https://grid.dev/install.sh | sh",
|
|
"output": "installing grid v1.4.0 ...\nok: /usr/local/bin/grid\nrun `grid init` in your project to get started"
|
|
}
|
|
},
|
|
{
|
|
"block_key": "terminal:boot_log",
|
|
"title": "Run log",
|
|
"slot": "main",
|
|
"sort_order": 4,
|
|
"content": {
|
|
"cursor": "block",
|
|
"lines": [
|
|
"grid run build test lint",
|
|
"build cached 0.00s",
|
|
"lint ok 0.31s",
|
|
"test ok 1.12s",
|
|
"3 tasks, 1 cached, 0 failed"
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"block_key": "cta",
|
|
"title": "CTA",
|
|
"slot": "main",
|
|
"sort_order": 5,
|
|
"content": {
|
|
"background": "band",
|
|
"heading": "Try it on your next build",
|
|
"text": "Install grid, run grid init, and watch your first cached run.",
|
|
"primaryLabel": "Install",
|
|
"primaryUrl": "/contact"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "/about",
|
|
"title": "About grid",
|
|
"template_key": "default",
|
|
"blocks": [
|
|
{ "block_key": "heading", "title": "Heading", "slot": "main", "sort_order": 1, "content": { "text": "About grid", "level": 1 } },
|
|
{ "block_key": "rich-text", "title": "Story", "slot": "main", "sort_order": 2, "content": { "html": "<p>grid started as a shell script that ran build steps in the background. The script grew until it needed a cache. Then it needed a dependency graph. At that point it became a real tool.</p><p>The goal has not changed. Run the work that changed, skip the work that did not, and stay out of the way. grid is open source and ships as a single static binary.</p>" } },
|
|
{
|
|
"block_key": "terminal:code_console",
|
|
"title": "Quickstart",
|
|
"slot": "main",
|
|
"sort_order": 3,
|
|
"content": { "prompt": "$", "language": "shell", "command": "grid init && grid run build", "output": "wrote grid.toml\nbuild ok 0.84s\n1 task, 0 cached, 0 failed" }
|
|
},
|
|
{
|
|
"block_key": "terminal:keybind_table",
|
|
"title": "Commands",
|
|
"slot": "main",
|
|
"sort_order": 4,
|
|
"content": {
|
|
"rows": [
|
|
{ "keys": "grid run", "action": "Run the named tasks and their dependencies" },
|
|
{ "keys": "grid watch", "action": "Rerun affected tasks when files change" },
|
|
{ "keys": "grid graph", "action": "Print the task dependency graph" },
|
|
{ "keys": "grid clean", "action": "Drop the local build cache" }
|
|
]
|
|
}
|
|
},
|
|
{ "block_key": "divider", "title": "Divider", "slot": "main", "sort_order": 5, "content": { "variant": "line", "weight": "medium" } },
|
|
{ "block_key": "quote", "title": "Quote", "slot": "main", "sort_order": 6, "content": { "style": "pull", "quote": "Do the work once. Cache the rest.", "attribution": "grid README" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/blog",
|
|
"title": "Changelog",
|
|
"template_key": "blog-index",
|
|
"blocks": [
|
|
{ "block_key": "heading", "title": "Heading", "slot": "main", "sort_order": 1, "content": { "text": "Changelog", "level": 1 } },
|
|
{ "block_key": "card", "title": "Post: Cache keys", "slot": "main", "sort_order": 2, "content": { "layout": "vertical", "title": "How grid keys the cache", "text": "<p>Every task output is keyed by its inputs. Here is how the hash is built and why it is stable across machines.</p>", "link": "/blog/cache-keys", "linkLabel": "Read on" } },
|
|
{ "block_key": "card", "title": "Post: Watch mode", "slot": "main", "sort_order": 3, "content": { "layout": "vertical", "title": "Watch mode without a daemon", "text": "<p>grid watch reruns affected tasks on save with no background process. This is how the file watcher stays cheap.</p>", "link": "/blog/watch-mode", "linkLabel": "Read on" } },
|
|
{ "block_key": "card", "title": "Post: Parallel", "slot": "main", "sort_order": 4, "content": { "layout": "vertical", "title": "Scheduling tasks in parallel", "text": "<p>Independent tasks run together, up to your core count. The scheduler is a topological sort with a worker pool.</p>", "link": "/blog/parallel-scheduling", "linkLabel": "Read on" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/blog/cache-keys",
|
|
"title": "How grid keys the cache",
|
|
"template_key": "article",
|
|
"parent_slug": "/blog",
|
|
"blocks": [
|
|
{ "block_key": "terminal:manpage_header", "title": "Man header", "slot": "main", "sort_order": 1, "content": { "name": "CACHE-KEYS", "section": 7, "version": "grid v1.4.0" } },
|
|
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 2, "content": { "text": "How grid keys the cache", "level": 1 } },
|
|
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 3, "content": { "html": "<p>A cache is only useful if the key is exact. grid hashes the task command, its input files, and the tool versions it declares. Same inputs, same key, cached output.</p><p>The key is content based, not time based. Two machines that check out the same commit build the same key. That makes the cache shareable across a team.</p>" } },
|
|
{ "block_key": "terminal:code_console", "title": "Example", "slot": "main", "sort_order": 4, "content": { "prompt": "$", "language": "shell", "command": "grid run build --explain", "output": "build key: sha256:9f2c...\ninputs: src/**, grid.toml, go 1.26\nresult: cache hit" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/blog/watch-mode",
|
|
"title": "Watch mode without a daemon",
|
|
"template_key": "article",
|
|
"parent_slug": "/blog",
|
|
"blocks": [
|
|
{ "block_key": "terminal:manpage_header", "title": "Man header", "slot": "main", "sort_order": 1, "content": { "name": "WATCH", "section": 1, "version": "grid v1.4.0" } },
|
|
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 2, "content": { "text": "Watch mode without a daemon", "level": 1 } },
|
|
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 3, "content": { "html": "<p>Most watchers run a background process that never exits. grid does not. grid watch runs in the foreground and exits when you press q.</p><p>On each save it maps the changed file back to the tasks that read it, then reruns only those. The rest stay cached.</p>" } },
|
|
{ "block_key": "terminal:code_console", "title": "Example", "slot": "main", "sort_order": 4, "content": { "prompt": "$", "language": "shell", "command": "grid watch 'src/**/*.go'", "output": "watching 42 files\nchanged: src/api/handler.go\ntest ok 0.90s" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/blog/parallel-scheduling",
|
|
"title": "Scheduling tasks in parallel",
|
|
"template_key": "article",
|
|
"parent_slug": "/blog",
|
|
"blocks": [
|
|
{ "block_key": "terminal:manpage_header", "title": "Man header", "slot": "main", "sort_order": 1, "content": { "name": "SCHEDULER", "section": 7, "version": "grid v1.4.0" } },
|
|
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 2, "content": { "text": "Scheduling tasks in parallel", "level": 1 } },
|
|
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 3, "content": { "html": "<p>grid builds a graph of tasks and their dependencies. It runs a task the moment its dependencies finish. Independent branches run at the same time.</p><p>The worker pool is sized to your core count by default. You can cap it with a flag when a task is memory heavy.</p>" } },
|
|
{ "block_key": "terminal:code_console", "title": "Example", "slot": "main", "sort_order": 4, "content": { "prompt": "$", "language": "shell", "command": "grid run all --jobs 4", "output": "scheduled 9 tasks across 4 workers\nall ok 2.03s" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/contact",
|
|
"title": "Contact",
|
|
"template_key": "contact",
|
|
"blocks": [
|
|
{
|
|
"block_key": "contact-form",
|
|
"title": "Contact form",
|
|
"slot": "main",
|
|
"sort_order": 1,
|
|
"content": {
|
|
"heading": "Get in touch",
|
|
"description": "Ask a question or report a bug. We reply within one business day.",
|
|
"submitLabel": "Send",
|
|
"successMessage": "Message received. We will reply within one business day.",
|
|
"fields": [
|
|
{ "name": "name", "label": "Your name", "type": "text", "required": true, "width": "half" },
|
|
{ "name": "email", "label": "Email", "type": "email", "required": true, "width": "half" },
|
|
{ "name": "project", "label": "Project", "type": "text", "required": false, "width": "full" },
|
|
{ "name": "message", "label": "Message", "type": "textarea", "required": true, "width": "full" }
|
|
],
|
|
"formConfig": { "enabled": true, "captchaEnabled": false, "targetTable": "contact_submissions" }
|
|
}
|
|
},
|
|
{
|
|
"block_key": "contact-card",
|
|
"title": "Reach us",
|
|
"slot": "main",
|
|
"sort_order": 2,
|
|
"content": {
|
|
"heading": "Other ways in",
|
|
"columns": 3,
|
|
"channels": [
|
|
{ "icon": "lucide:mail", "label": "Email", "value": "team@grid.dev", "link": "mailto:team@grid.dev" },
|
|
{ "icon": "simple-icons:github", "label": "Source", "value": "github.com/grid-dev/grid", "link": "https://github.com/grid-dev/grid" },
|
|
{ "icon": "lucide:message-square", "label": "Chat", "value": "Join the Discord", "link": "#" }
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "/login",
|
|
"title": "Sign in",
|
|
"template_key": "auth",
|
|
"blocks": [
|
|
{ "block_key": "auth-form", "title": "Sign in", "slot": "main", "sort_order": 1, "content": { "default_tab": "login", "show_social": false } }
|
|
]
|
|
}
|
|
],
|
|
"menu_items": [
|
|
{ "menu": "main", "label": "Home", "page_slug": "/", "sort_order": 1 },
|
|
{ "menu": "main", "label": "About", "page_slug": "/about", "sort_order": 2 },
|
|
{ "menu": "main", "label": "Docs", "page_slug": "/blog", "sort_order": 3 },
|
|
{ "menu": "main", "label": "Contact", "page_slug": "/contact", "sort_order": 4 }
|
|
]
|
|
}
|