From a404ccf2d947e827f538babd16c5f36dec8b11d8 Mon Sep 17 00:00:00 2001 From: Edward Twumasi Date: Sat, 3 Oct 2026 15:21:59 +0000 Subject: [PATCH 1/5] Align GroundControl marketing with Serendepify brand --- README.md | 6 +- SITE_REVIEW.md | 13 +- app/components/SiteChrome.tsx | 10 +- app/components/WorkloadModel.tsx | 2 +- app/globals.css | 314 ++++++++++++++++++++++++++----- app/layout.test.tsx | 5 +- app/layout.tsx | 28 +-- app/page.tsx | 167 ++++++++++------ 8 files changed, 421 insertions(+), 124 deletions(-) diff --git a/README.md b/README.md index b347af2..46d5c85 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ GroundControl itself is a self-hosted, single-tenant control plane. Each operato ## Current product story +“Keep your software running” connects GroundControl to Serendepify’s broader operational-intelligence story: understand the application, work from evidence, and retain control over agent access. The homepage uses the company site’s warm paper, ink, lime and coral palette, with Schibsted Grotesk headings, Hanken Grotesk body text and JetBrains Mono details. Fonts are self-hosted through Next.js. + +The product tour and dated deployment evidence describe available capabilities. The separate Autopilot section is explicitly marked **Product direction**; customer-journey testing and proactive recovery are not presented as available features. The installation guide remains the primary call to action. + GroundControl gives software agents bounded infrastructure capabilities through MCP + OAuth: - inspect deployments, runtime and health; @@ -89,4 +93,4 @@ The complete adoption path lives at `/docs`. Twelve guides cover the philosophy - Product screenshots open at full size and preserve their aspect ratio. - See `MEDIA_CAPTURE.md` for capture provenance, dates and claim boundaries. -Validate guide links/anchors, assets, endpoint formatting, clipboard behavior, product-tour keyboard navigation and checklist state with `npm test`. Review the actual rendered pages and capture any limits in `SITE_REVIEW.md`. The current browser runtime does not expose viewport emulation, so real phone testing remains outstanding. +Validate guide links/anchors, assets, endpoint formatting, clipboard behavior, product-tour keyboard navigation and checklist state with `npm test`. Review the actual rendered pages and capture any limits in `SITE_REVIEW.md`. Browser viewport testing covers desktop and narrow layouts; physical phone testing remains outstanding. diff --git a/SITE_REVIEW.md b/SITE_REVIEW.md index 890beae..3491e87 100644 --- a/SITE_REVIEW.md +++ b/SITE_REVIEW.md @@ -1,6 +1,15 @@ -# Public site review, 22 September 2026 +# Public site review + +## Serendepify brand alignment, 3 October 2026 + +The public marketing site adopts the company site's current visual language and outcome-focused messaging: “Keep your software running.” The new capability section explains application context, recorded evidence and scoped access. Warm paper, lime accents, an outlined headline and the company's font families connect the two sites without replacing GroundControl's identity or its real product screenshots. + +Available capabilities stay separate from the clearly labeled Autopilot product direction. The existing September evidence dates and provenance qualifications are preserved. Installation, native guides, product-tour behavior and operator-owned authentication boundaries are unchanged. No operator instance or deployment is part of this revision. + +Local lint, TypeScript, all nine tests and the static production build passed. Browser review covered the homepage at 1280 pixels, its tour selection, the installation link, and the installation guide's expandable documentation menu at 390 pixels. Font inspection confirmed Schibsted Grotesk headings and Hanken Grotesk body text. Neither the homepage nor the installation guide had horizontal document overflow at 390 pixels after constraining the installation panel's grid columns; long commands retain their own scroll area. Physical device testing remains outstanding. + +## Product journey revision, 22 September 2026 -## Product journey revision The homepage now has a four-part product tour using actual desktop captures, a post-install sequence, an illustrated workload model, inspectable deployment proof and direct learning paths. Twelve native guides cover the GroundControl philosophy, installation, next steps, publishing, discovery, enrollment, new template deployments, agent access, automation, maintenance, troubleshooting and evidence. diff --git a/app/components/SiteChrome.tsx b/app/components/SiteChrome.tsx index c782df5..3d269fa 100644 --- a/app/components/SiteChrome.tsx +++ b/app/components/SiteChrome.tsx @@ -55,8 +55,12 @@ export function Footer() { GroundControl

- Open-source operations for infrastructure you own. -
A Serendepify product. + Operational intelligence for infrastructure you own. +
Built by{" "} + + Serendepify + {" "} + in Accra, Ghana.

- Safe, smooth, observable, agentic. + Your infrastructure. Your final say. ); } diff --git a/app/components/WorkloadModel.tsx b/app/components/WorkloadModel.tsx index fc6a75b..696330b 100644 --- a/app/components/WorkloadModel.tsx +++ b/app/components/WorkloadModel.tsx @@ -10,7 +10,7 @@ export default function WorkloadModel() {
Project Weekend planner - Optional organization + Your application or product
diff --git a/app/globals.css b/app/globals.css index f323cb9..2653e46 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,18 +1,29 @@ @import "tailwindcss"; :root { - --paper: #f7f6f2; + /* Shared with Serendepify's v5 brand: warm paper, ink, lime, and coral. */ + --paper: #f1f0e8; + --paper-deep: #e8e7dc; + --lime: #c8ff3d; + --coral: #ff6846; + --grid-line: rgba(23, 24, 18, 0.055); + --lime-wash: rgba(200, 255, 61, 0.2); + --light-ink: #f1f0e8; + --dark-muted: #b6bbad; + --dark-active: #242a19; + --panel-line: #c8cabb; --surface: #ffffff; - --ink: #202923; - --muted: #626a64; - --line: #dcdfd8; - --dark: #141c18; - --dark-line: #38473e; - --green: #326349; - --soft-green: #eaf0e8; - --code: #e1eadd; - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); + --ink: #171812; + --muted: #606358; + --line: #d6d7cc; + --dark: #12140f; + --dark-line: #383d30; + --green: #475d1c; + --soft-green: #e8e7dc; + --code: #e5e8d7; + --font-sans: var(--font-brand-body); + --font-display: var(--font-brand-display); + --font-mono: var(--font-brand-mono); } * { box-sizing: border-box; @@ -56,7 +67,7 @@ pre:focus-visible, outline-offset: 5px; } ::selection { - background: #d5e6d6; + background: var(--lime); color: var(--ink); } h1, @@ -69,7 +80,8 @@ figure { h1, h2, h3 { - font-weight: 500; + font-family: var(--font-display), sans-serif; + font-weight: 600; } img { display: block; @@ -142,13 +154,16 @@ img { background: var(--ink); color: white; border: 1px solid var(--ink); - border-radius: 4px; + border-radius: 8px; font-size: 14px; - font-weight: 500; + font-weight: 600; transition: background 0.2s; } .button:hover { - background: var(--green); + background: var(--dark-active); +} +.button > span { + color: var(--lime); } .button.compact { min-height: 42px; @@ -173,7 +188,7 @@ img { align-items: center; } .site-header { - min-height: 82px; + min-height: 76px; padding: 0 max(32px, calc((100% - 1264px) / 2)); display: flex; justify-content: space-between; @@ -244,20 +259,22 @@ img { /* Product story */ .landing-hero { display: grid; - grid-template-columns: 1.15fr 1fr; + grid-template-columns: 1.12fr 1fr; gap: 8%; - padding-block: 78px 70px; + padding-block: 72px 60px; align-items: end; } .hero-heading h1 { - font-size: clamp(54px, 5.65vw, 79px); - line-height: 1.05; + font-size: clamp(72px, 7.6vw, 106px); + line-height: 0.96; + font-weight: 600; letter-spacing: -0.063em; margin-top: 25px; } .hero-heading em { font-style: normal; - color: var(--green); + color: transparent; + -webkit-text-stroke: 1.4px var(--ink); } .hero-intro { padding-bottom: 5px; @@ -312,7 +329,7 @@ img { border: 1px solid var(--dark-line); border-radius: 8px; background: var(--dark); - color: #edf1e8; + color: var(--light-ink); overflow: hidden; } .tour-tabs { @@ -327,7 +344,7 @@ img { align-items: center; gap: 17px; font-size: 15px; - color: #bec9be; + color: var(--dark-muted); border-bottom: 2px solid transparent; text-align: left; } @@ -337,7 +354,7 @@ img { .tour-tabs button > span:first-child { font-family: var(--font-mono); font-size: 10px; - color: #a0afa4; + color: var(--dark-muted); } .tour-tabs button > span:last-child { margin-left: auto; @@ -345,11 +362,11 @@ img { } .tour-tabs button[aria-selected="true"] { color: white; - background: #26372d; - border-bottom-color: #97bd9b; + background: var(--dark-active); + border-bottom-color: var(--lime); } .product-tour :focus-visible { - outline-color: #b5d2b5; + outline-color: var(--lime); outline-offset: -5px; } .tour-panel { @@ -361,7 +378,7 @@ img { min-height: 555px; } .tour-copy .eyebrow { - color: #a3b4a6; + color: var(--dark-muted); font-size: 10px; } .tour-copy h2 { @@ -374,7 +391,7 @@ img { font-size: 14px; line-height: 1.85; margin-top: 19px; - color: #bcc8bd; + color: var(--dark-muted); } .tour-copy .tour-fact { border-top: 1px solid var(--dark-line); @@ -386,7 +403,7 @@ img { display: inline-block; font-size: 13px; color: white; - border-bottom: 1px solid #64876a; + border-bottom: 1px solid var(--lime); padding: 12px 0 6px; margin-top: 12px; } @@ -487,8 +504,8 @@ img { color: var(--green); } .philosophy-band { - background: #e9eee7; - border-block: 1px solid #d4ded1; + background: var(--paper-deep); + border-block: 1px solid var(--line); padding-block: 75px; } .philosophy-grid { @@ -499,24 +516,24 @@ img { } .philosophy-grid > div > p:not(.eyebrow) { font-size: 15px; - color: #536151; + color: var(--muted); line-height: 1.85; margin-top: 22px; } .philosophy-grid .text-link { - border-color: #bdcbbc; + border-color: var(--panel-line); margin-top: 20px; } .workload-model { padding: 25px; - border: 1px solid #c7d4c5; + border: 1px solid var(--panel-line); border-radius: 5px; - background: #f7faf3; + background: var(--paper); } .workload-model figcaption { font-size: 11px; line-height: 1.6; - color: #52694f; + color: var(--muted); padding-bottom: 22px; } .model-row { @@ -525,13 +542,13 @@ img { gap: 7px 18px; padding: 17px; background: white; - border: 1px solid #d0dccb; + border: 1px solid var(--panel-line); align-items: center; } .model-row > span { font-size: 10px; font-family: var(--font-mono); - color: #63715e; + color: var(--muted); width: 80px; } .model-row strong { @@ -541,11 +558,11 @@ img { .model-row small { width: 100%; padding-left: 98px; - color: #687362; + color: var(--muted); font-size: 10px; } .model-deployment { - border-left: 1px solid #b6c8b2; + border-left: 1px solid var(--panel-line); margin: 0 0 0 15px; padding: 20px 0 0 17px; } @@ -556,17 +573,17 @@ img { padding: 13px 0; } .model-services > span { - border: 1px solid #d0dccb; + border: 1px solid var(--panel-line); padding: 13px; font-family: var(--font-mono); font-size: 12px; - background: #eaf1e4; + background: var(--paper-deep); } .model-services small { display: block; font-family: var(--font-sans); font-size: 10px; - color: #586b52; + color: var(--muted); margin-top: 7px; } .model-route { @@ -574,7 +591,7 @@ img { } .workload-model > p { font-size: 12px; - color: #52654b; + color: var(--muted); line-height: 1.8; margin-top: 20px; } @@ -688,10 +705,13 @@ img { } .start-grid { display: grid; - grid-template-columns: 1fr 1fr; + grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9%; align-items: center; } +.start-grid > div { + min-width: 0; +} .start-grid .eyebrow, .start-grid .small { color: #a5b5a7; @@ -1670,7 +1690,7 @@ tr:last-child td { gap: 35px; } .start-grid { - grid-template-columns: 1fr; + grid-template-columns: minmax(0, 1fr); gap: 35px; } .start-grid .code-block { @@ -2166,6 +2186,204 @@ tr:last-child td { font-size: 12px; } } +/* Brand story sections use Serendepify's visual language with real product evidence. */ +.hero-field { + background: radial-gradient(ellipse at 60% 24%, var(--lime-wash), transparent 40%), + repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 88px); +} +.hero-heading .eyebrow { + text-transform: uppercase; + letter-spacing: .12em; + font-size: 10px; +} +.hero-heading .status-dot { + background: var(--coral); + box-shadow: 0 0 0 4px color-mix(in srgb, var(--coral) 12%, transparent); +} +.hero-intro .lead { + font-size: clamp(24px, 2.25vw, 32px); + line-height: 1.25; + font-family: var(--font-display), sans-serif; + font-weight: 500; +} +.hero-intro > p + p { + font-size: 17px; + line-height: 1.65; +} +.button.secondary { + background: transparent; + color: var(--ink); + border-color: var(--panel-line); +} +.button.secondary > span { + color: var(--ink); +} +.button.secondary:hover { + background: var(--surface); +} +.hero-intro .returning-link { + margin-top: 15px; + border: 0; + color: var(--muted); +} +.hero-intro .returning-link:hover { + color: var(--ink); + text-decoration: underline; +} +.hero-spec { + border-top: 1px solid var(--line); + padding-top: 20px; +} +.hero-field .tour-section { + padding-bottom: 64px; +} +.product-tour { + border-radius: 12px; + box-shadow: 0 24px 50px color-mix(in srgb, var(--ink) 10%, transparent); +} +.tour-tabs button[aria-selected="true"] > span:first-child { + color: var(--lime); +} +.capability-story { + padding-block: 80px 92px; +} +.capability-story .section-heading h2 { + max-width: 13ch; +} +.capability-columns { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + border-top: 1px solid var(--line); +} +.capability-columns article { + padding: 28px 30px 0 0; +} +.capability-columns article + article { + border-left: 1px solid var(--line); + padding-left: 30px; +} +.capability-columns .mono { + color: var(--green); +} +.capability-columns h3 { + font-size: 23px; + letter-spacing: -.045em; + line-height: 1.2; + margin-top: 25px; +} +.capability-columns p { + color: var(--muted); + font-size: 16px; + line-height: 1.7; + margin-top: 15px; +} +.direction-section { + display: grid; + grid-template-columns: .65fr 1.35fr; + gap: 60px; + padding-block: 44px 54px; + border-block: 1px solid var(--line); +} +.direction-label { + display: flex; + align-items: flex-start; + flex-direction: column; + gap: 16px; +} +.direction-badge { + border: 1px solid var(--panel-line); + border-radius: 5px; + padding: 7px 10px; + font: 11px/1.4 var(--font-mono), monospace; + color: var(--green); +} +.direction-section h2 { + font-size: clamp(30px, 3vw, 42px); + line-height: 1.15; + letter-spacing: -.04em; +} +.direction-section p { + max-width: 640px; + color: var(--muted); + font-size: 16px; + line-height: 1.8; + margin-top: 20px; +} +.direction-section .text-link { + margin-top: 14px; +} +.company-link { + text-decoration: underline; + text-underline-offset: 3px; +} +.company-link:hover { + color: var(--ink); +} +.start-grid .button { + background: var(--lime); + color: var(--ink); + border-color: var(--lime); +} +.start-grid .button > span { + color: var(--ink); +} +.start-grid .button:hover { + background: var(--light-ink); + border-color: var(--light-ink); +} +@media (max-width: 950px) { + .direction-section { + grid-template-columns: 1fr; + gap: 28px; + } + .direction-label { + flex-direction: row; + align-items: center; + flex-wrap: wrap; + } +} +@media (max-width: 700px) { + .capability-story { + padding-block: 54px; + } + .capability-columns { + grid-template-columns: 1fr; + } + .capability-columns article { + padding: 24px 0; + } + .capability-columns article + article { + border-left: 0; + border-top: 1px solid var(--line); + padding-left: 0; + } + .capability-columns h3 { + margin-top: 12px; + } + .capability-columns p { + margin-top: 10px; + } + .hero-field .tour-section { + padding-bottom: 44px; + } + .direction-section { + padding-block: 32px; + gap: 24px; + } + .hero-intro .actions { + gap: 10px; + } + .hero-intro .actions .button { + flex: 1 1 180px; + } +} +@media (prefers-contrast: more), (forced-colors: active) { + .hero-heading em { + color: var(--ink); + -webkit-text-stroke: 0; + } +} + @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; diff --git a/app/layout.test.tsx b/app/layout.test.tsx index 60eb5df..e153951 100644 --- a/app/layout.test.tsx +++ b/app/layout.test.tsx @@ -1,8 +1,9 @@ import { beforeAll, describe, expect, it, vi } from "vitest"; vi.mock("next/font/google", () => ({ - Geist: () => ({ variable: "--font-geist-sans" }), - Geist_Mono: () => ({ variable: "--font-geist-mono" }), + Hanken_Grotesk: () => ({ variable: "--font-brand-body" }), + Schibsted_Grotesk: () => ({ variable: "--font-brand-display" }), + JetBrains_Mono: () => ({ variable: "--font-brand-mono" }), })); import { render, screen } from "@testing-library/react"; diff --git a/app/layout.tsx b/app/layout.tsx index 019ac32..1c2bc13 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,21 +1,26 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; +import { Hanken_Grotesk, JetBrains_Mono, Schibsted_Grotesk } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", +const bodyFont = Hanken_Grotesk({ + variable: "--font-brand-body", subsets: ["latin"], }); -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", +const displayFont = Schibsted_Grotesk({ + variable: "--font-brand-display", + subsets: ["latin"], +}); + +const monoFont = JetBrains_Mono({ + variable: "--font-brand-mono", subsets: ["latin"], }); export const metadata: Metadata = { - title: "GroundControl | Open-source agentic deployment with MCP + OAuth", + title: "GroundControl | Keep your software running", description: - "Open-source agentic deployment for Docker Compose infrastructure, with scoped OAuth and MCP access for software agents.", + "Understand your applications, operate with evidence, and stay in control. GroundControl brings self-hosted operations and scoped agent access to infrastructure you own. Built by Serendepify.", icons: { icon: "/favicon.svg", shortcut: "/favicon.svg", @@ -28,10 +33,11 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - - + + Skip to content diff --git a/app/page.tsx b/app/page.tsx index 20a088e..08f4521 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -8,60 +8,100 @@ export default function Home() { return ( <>
-
-
-
-

- - Open-source agentic deployment -

-

- Give your agents -
- the access to -
- follow through. -

-
-
-

- Discover your applications, choose what to manage, and let your - agents help operate them. -

-

- GroundControl is a self-hosted control plane for your VPS. It - gives agents controlled access through OAuth and MCP, so approved - work can move from a request to a verified result without repeated - access and credential handoffs. -

-
- - Install GroundControl - - - Already installed? Start here → +
+
+
+
+

+ + Operational intelligence, by Serendepify +

+

+ Keep your +
+ software +
+ running. +

+
+
+

+ For the teams who own the infrastructure—and the outcome. +

+

+ Understand what is running. Investigate what changed. Give your + team and your agents the context to act, with evidence to check + the result. GroundControl brings your applications, deployments, + and infrastructure into one place you control. +

+
+ + Install GroundControl + + + See how it works + +
+ + Already installed? Continue setup → +
+ Self-hosted + Docker Compose first + Open source +
-
- Docker Compose - Your VPS - MCP + OAuth +
+
+
+

Inside GroundControl

+ The product today · actual interface
-
-
-
-
-

- A working connection to your infrastructure + +

+
+
+
+
+

01 / Understand the whole system

+

Your VPS is a living system.

+
+

+ A running container is only part of the story. Bring the source, + services, configuration, and public address into the same view, + so the next decision starts with context.

- Explore the product
- +
+ {[ + [ + "01", + "See how it fits together.", + "Discover existing applications and inspect their source, runtime, and public route. Start with the infrastructure you already own.", + ], + [ + "02", + "Work from evidence.", + "Read deployment history, runtime checks, and endpoint results. Follow an operation to its recorded outcome, including what still needs attention.", + ], + [ + "03", + "Keep your final say.", + "Choose the deployments and capabilities an agent can access. GroundControl keeps infrastructure credentials behind that boundary.", + ], + ].map(([number, title, text]) => ( +
+ {number} +

{title}

+

{text}

+
+ ))} +
-

Installation is the beginning

+

02 / Start with what you have

You installed it.
@@ -116,16 +156,18 @@ export default function Home() {
-

The GroundControl approach

+

03 / Autonomy without surrender

- Your application is + Your infrastructure. +
+ Your agents.
- more than a container. + Your final say.

- GroundControl connects the source, runtime and public route to - one workload identity. Your team and your agents can work from - that shared context. + Keep the infrastructure you own and the workflows you know. + GroundControl gives your team and your agents a shared picture + of each application, without handing over unrestricted access.

You choose the scope. The control plane holds the infrastructure @@ -142,11 +184,11 @@ export default function Home() {

-

Used on a real VPS

+

04 / Evidence from a real VPS

- The work leaves + Proof you can
- something you can inspect. + open and inspect.

@@ -198,6 +240,19 @@ export default function Home() {

+
+
Where we’re goingProduct direction
+
+

From verified operations
to proactive recovery.

+

+ Serendepify’s vision is a system that understands service relationships, + tests affected customer journeys, and helps recover from regressions + within an operator’s policy. This is the direction for Autopilot, + not a promise of unattended recovery in today’s release. +

+ Explore the Serendepify vision +
+

The operator’s handbook

@@ -252,9 +307,9 @@ export default function Home() {

Start with one host and one application

- Make your infrastructure + Your next application.
- accessible to your agent. + Under your control.

Install privately, claim ownership, and choose the first From a700d698715bfe2136ba92b87ec37face36ec2a5 Mon Sep 17 00:00:00 2001 From: Edward Twumasi Date: Sat, 3 Oct 2026 16:27:49 +0000 Subject: [PATCH 2/5] Lead with agentic deployment on customer-owned infrastructure --- README.md | 4 +- SITE_REVIEW.md | 2 +- app/components/SiteChrome.tsx | 4 +- app/layout.tsx | 4 +- app/page.tsx | 102 +++++++++++++++++----------------- 5 files changed, 60 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 46d5c85..8a87d7f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ GroundControl itself is a self-hosted, single-tenant control plane. Each operato ## Current product story -“Keep your software running” connects GroundControl to Serendepify’s broader operational-intelligence story: understand the application, work from evidence, and retain control over agent access. The homepage uses the company site’s warm paper, ink, lime and coral palette, with Schibsted Grotesk headings, Hanken Grotesk body text and JetBrains Mono details. Fonts are self-hosted through Next.js. +“Put your agents to work” leads with GroundControl’s promise: deploy and operate applications with the agents you use, on infrastructure you own. The homepage brings the article’s operational context, MCP tools, OAuth access and durable execution into the product story. It explains what the connection enables: inspect application state, request supported deployments, and return to their recorded results. + +The homepage uses Serendepify’s warm paper, ink, lime and coral palette, with Schibsted Grotesk headings, Hanken Grotesk body text and JetBrains Mono details. Fonts are self-hosted through Next.js. The product tour and dated deployment evidence describe available capabilities. The separate Autopilot section is explicitly marked **Product direction**; customer-journey testing and proactive recovery are not presented as available features. The installation guide remains the primary call to action. diff --git a/SITE_REVIEW.md b/SITE_REVIEW.md index 3491e87..b318257 100644 --- a/SITE_REVIEW.md +++ b/SITE_REVIEW.md @@ -2,7 +2,7 @@ ## Serendepify brand alignment, 3 October 2026 -The public marketing site adopts the company site's current visual language and outcome-focused messaging: “Keep your software running.” The new capability section explains application context, recorded evidence and scoped access. Warm paper, lime accents, an outlined headline and the company's font families connect the two sites without replacing GroundControl's identity or its real product screenshots. +The public marketing site adopts the company site's current visual language while leading with GroundControl’s own promise: “Put your agents to work.” The opening explains agentic deployment on infrastructure the reader owns. The capability section brings forward the article’s application context, scoped execution and durable results, and links directly to the full story. The navigation now calls that article “Why GroundControl.” The proof section explains signed GitHub deployment automation and the agent’s access to recorded outcomes. Warm paper, lime accents, an outlined headline and the company's font families connect the two sites without replacing GroundControl's identity or its real product screenshots. Available capabilities stay separate from the clearly labeled Autopilot product direction. The existing September evidence dates and provenance qualifications are preserved. Installation, native guides, product-tour behavior and operator-owned authentication boundaries are unchanged. No operator instance or deployment is part of this revision. diff --git a/app/components/SiteChrome.tsx b/app/components/SiteChrome.tsx index 3d269fa..36d30db 100644 --- a/app/components/SiteChrome.tsx +++ b/app/components/SiteChrome.tsx @@ -38,7 +38,7 @@ export function Header() { Approach Docs - Field notes + Why GroundControl @@ -55,7 +55,7 @@ export function Footer() { GroundControl

- Operational intelligence for infrastructure you own. + Agentic deployment on infrastructure you own.
Built by{" "} Serendepify diff --git a/app/layout.tsx b/app/layout.tsx index 1c2bc13..3183a52 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -18,9 +18,9 @@ const monoFont = JetBrains_Mono({ }); export const metadata: Metadata = { - title: "GroundControl | Keep your software running", + title: "GroundControl | Agentic deployment on infrastructure you own", description: - "Understand your applications, operate with evidence, and stay in control. GroundControl brings self-hosted operations and scoped agent access to infrastructure you own. Built by Serendepify.", + "Connect your agents to your applications through MCP and OAuth. Inspect workloads, run supported deployments, and verify results on infrastructure you own. Open source and self-hosted.", icons: { icon: "/favicon.svg", shortcut: "/favicon.svg", diff --git a/app/page.tsx b/app/page.tsx index 08f4521..b69064b 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -14,32 +14,32 @@ export default function Home() {

-

Inside GroundControl

+

Connect your workloads. Put your agent to work.

The product today · actual interface
@@ -63,31 +63,32 @@ export default function Home() {
-

01 / Understand the whole system

-

Your VPS is a living system.

+

01 / From instruction to execution

+

Give agents the context to act.

- A running container is only part of the story. Bring the source, - services, configuration, and public address into the same view, - so the next decision starts with context. + GroundControl connects your application’s source, containers, + configuration, and public address. Your agent works from that + shared context, with tools to carry an authorized request through + to a result you can inspect.

{[ [ "01", - "See how it fits together.", - "Discover existing applications and inspect their source, runtime, and public route. Start with the infrastructure you already own.", + "Inspect real application state.", + "Ask your agent what is deployed, read the logs, and check service health. It works from your application’s state and deployment history.", ], [ "02", - "Work from evidence.", - "Read deployment history, runtime checks, and endpoint results. Follow an operation to its recorded outcome, including what still needs attention.", + "Let your agent take action.", + "Approve the capabilities and deployments it can use through OAuth. GroundControl executes supported deployment requests on your infrastructure while holding the credentials.", ], [ "03", - "Keep your final say.", - "Choose the deployments and capabilities an agent can access. GroundControl keeps infrastructure credentials behind that boundary.", + "Follow through to the result.", + "Get runtime checks and public endpoint evidence for the operation. A durable operation ID lets your agent return to the same work after a timeout or in a later conversation.", ], ].map(([number, title, text]) => (
@@ -97,6 +98,16 @@ export default function Home() {
))}
+ + Why GroundControl +

Your infrastructure, connected to the agents you use.

+ + Read the story + +
@@ -165,14 +176,15 @@ export default function Home() { Your final say.

- Keep the infrastructure you own and the workflows you know. - GroundControl gives your team and your agents a shared picture - of each application, without handing over unrestricted access. + Start with the applications already on your VPS, or launch a + new workload through Templates. Keep your existing files in + place and bring the applications you choose into GroundControl.

- You choose the scope. The control plane holds the infrastructure - credentials and records execution. Verification shows what - worked and what still needs attention. + MCP gives your agent the tools. OAuth defines its access. You + can work through the interface or your agent, using the same + application identity and recorded results. Review and revoke + access from the Agents workspace.

Read the philosophy and core concepts → @@ -186,15 +198,16 @@ export default function Home() {

04 / Evidence from a real VPS

- Proof you can + From GitHub push
- open and inspect. + to agent insight.

- GroundControl deployed RentAWeekend from a GitHub push. ChatGPT - connected through MCP to inspect its health and read the operation - record. + For managed workloads with merge automation enabled, a signed + GitHub push starts a deployment your agent can follow. In this + recorded example, GroundControl deployed RentAWeekend, and ChatGPT + inspected its health and operation record through MCP.

@@ -227,18 +240,6 @@ export default function Home() { Inspect the deployment record →
- - Engineering field notes -

- GroundControl: open-source agentic deployment with OAuth and MCP. -

- - Read the article - -
Where we’re goingProduct direction
@@ -307,13 +308,14 @@ export default function Home() {

Start with one host and one application

- Your next application. + Your infrastructure.
- Under your control. + Ready for your agent.

- Install privately, claim ownership, and choose the first - workload. + Install GroundControl, choose an application, and connect your + agent. Start with a health check, then explore the operations + your workload supports.

Follow the installation guide From e2033d2c8660e9e5da3c566ca956ef7d7e356445 Mon Sep 17 00:00:00 2001 From: Edward Twumasi Date: Tue, 20 Oct 2026 22:28:37 +0000 Subject: [PATCH 3/5] Present new setup and project flows in a dark public site --- MEDIA_CAPTURE.md | 4 + README.md | 18 +- SITE_REVIEW.md | 10 + .../page.tsx | 8 +- app/components/NextSteps.tsx | 6 +- app/components/ProductTour.tsx | 38 ++-- app/components/WorkloadModel.tsx | 11 +- app/docs/page.tsx | 6 +- app/globals.css | 99 ++++----- app/layout.tsx | 8 + app/opengraph-image.tsx | 26 +++ app/page.test.tsx | 12 +- app/page.tsx | 44 ++-- content/guide-index.ts | 16 +- content/guides.tsx | 198 +----------------- content/journey-guides.tsx | 49 +++-- content/setup-guides.tsx | 104 +++++++++ .../proof/project-deployments-2026-10-20.png | Bin 0 -> 40599 bytes public/proof/project-import-2026-10-20.png | Bin 0 -> 36998 bytes 19 files changed, 332 insertions(+), 325 deletions(-) create mode 100644 app/opengraph-image.tsx create mode 100644 content/setup-guides.tsx create mode 100644 public/proof/project-deployments-2026-10-20.png create mode 100644 public/proof/project-import-2026-10-20.png diff --git a/MEDIA_CAPTURE.md b/MEDIA_CAPTURE.md index 88918dc..b46212e 100644 --- a/MEDIA_CAPTURE.md +++ b/MEDIA_CAPTURE.md @@ -1,3 +1,7 @@ +# October 2026 distribution UI + +`project-import-2026-10-20.png` and `project-deployments-2026-10-20.png` are unaltered captures of the merged distribution UI, built from the product release branch on 20 October 2026. They use a disposable local Docker instance and a synthetic Weekend planner source folder. The folder contained a package.json and no Compose file; folder browsing, import and opening Add deployment were exercised through the UI. No production workload was changed. These are interface demonstrations, not deployment-success evidence. The tour captions distinguish them from the dated production evidence below. + # Public evidence captures The public site uses unaltered desktop captures from the operator's authenticated GroundControl interface, captured on 22 September 2026. No generated interface or chat image is presented as product evidence. diff --git a/README.md b/README.md index 8a87d7f..b5a3cbb 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ GroundControl itself is a self-hosted, single-tenant control plane. Each operato “Put your agents to work” leads with GroundControl’s promise: deploy and operate applications with the agents you use, on infrastructure you own. The homepage brings the article’s operational context, MCP tools, OAuth access and durable execution into the product story. It explains what the connection enables: inspect application state, request supported deployments, and return to their recorded results. -The homepage uses Serendepify’s warm paper, ink, lime and coral palette, with Schibsted Grotesk headings, Hanken Grotesk body text and JetBrains Mono details. Fonts are self-hosted through Next.js. +The homepage uses a dark theme with Serendepify’s lime and coral accents, with Schibsted Grotesk headings, Hanken Grotesk body text and JetBrains Mono details. Fonts are self-hosted through Next.js. The product tour and dated deployment evidence describe available capabilities. The separate Autopilot section is explicitly marked **Product direction**; customer-journey testing and proactive recovery are not presented as available features. The installation guide remains the primary call to action. @@ -21,7 +21,7 @@ GroundControl gives software agents bounded infrastructure capabilities through - use connector capability health for GitHub, GHCR and Daytona; - keep SSH keys, provider credentials and the human PTY outside the agent tool surface. -Fresh installs use the canonical on-host installer and a one-time human ownership claim. +Fresh installs start with the computer launcher: local Docker or a remote Linux server, followed by a one-time ownership claim. The canonical on-host installer remains available for server operators. ## Verified deployment proof @@ -40,13 +40,14 @@ The full deployment and Daytona contract is maintained in the main repository at ## Install -Human-readable: +On your computer (macOS / Linux, or Windows through WSL): ```bash -curl -fsSL https://raw.githubusercontent.com/teckedd-code2save/groundcontrol/main/scripts/install | sudo bash +curl -fsSL https://raw.githubusercontent.com/teckedd-code2save/groundcontrol/main/scripts/start -o groundcontrol-start +bash groundcontrol-start ``` -Agent-oriented JSON result: +Directly on a Linux server, with an agent-oriented JSON result: ```bash curl -fsSL https://raw.githubusercontent.com/teckedd-code2save/groundcontrol/main/scripts/install \ @@ -84,8 +85,9 @@ MIT ## Native documentation and public evidence -The complete adoption path lives at `/docs`. Twelve guides cover the philosophy and workload model, install/claim, next steps after installation, HTTPS publishing, host discovery, existing application enrollment, new template deployments, ChatGPT OAuth/MCP, deployment automation, maintenance, troubleshooting and evidence. No GitHub visit is required to follow a guide. +The complete adoption path lives at `/docs`. Thirteen guides cover projects and deployment instances, the philosophy and workload model, install/claim, next steps after installation, HTTPS publishing, host discovery, existing application enrollment, new template deployments, ChatGPT OAuth/MCP, deployment automation, maintenance, troubleshooting and evidence. No GitHub visit is required to follow a guide. +- `content/setup-guides.tsx` contains local/remote setup and the project/source/deployment model. - `content/guides.tsx` contains the guide sections, runnable examples and expected results. - `content/journey-guides.tsx` contains the philosophy, post-install, discovery and new-deployment guides. `content/guide-parts.tsx` supplies shared guide elements. - `content/guide-index.ts` defines sidebar order and search terms. @@ -96,3 +98,7 @@ The complete adoption path lives at `/docs`. Twelve guides cover the philosophy - See `MEDIA_CAPTURE.md` for capture provenance, dates and claim boundaries. Validate guide links/anchors, assets, endpoint formatting, clipboard behavior, product-tour keyboard navigation and checklist state with `npm test`. Review the actual rendered pages and capture any limits in `SITE_REVIEW.md`. Browser viewport testing covers desktop and narrow layouts; physical phone testing remains outstanding. + +## Sharing + +Share https://trygroundcontrol.serendepify.com/ or link directly to `/docs/getting-started`. The root metadata provides a dark Open Graph image and a large social card, generated at build time by `app/opengraph-image.tsx`. The install guide is self-contained; the public site does not collect credentials or expose an operator login. diff --git a/SITE_REVIEW.md b/SITE_REVIEW.md index b318257..a7ec021 100644 --- a/SITE_REVIEW.md +++ b/SITE_REVIEW.md @@ -1,3 +1,13 @@ +# Distribution release site review · 20 October 2026 + +The homepage, article and all thirteen handbook guides now share a dark theme with lime calls to action. The copy leads with agentic deployment on infrastructure the visitor owns, and explains the new local/remote computer launcher, folder/GitHub project import, and connect-existing/launch-new deployment paths. The project model separates application source from runtime instances. Desktop limits, WSL, AMD64 emulation and the server-only HTTPS/upgrade flows are explicit in the relevant guides. + +The first two walkthrough stages use fresh captures of the distribution UI with a disposable example project. The September OAuth and production-operation evidence keeps its original dates and qualifications. No production deployment was used or changed for the new captures. A static dark Open Graph image and large social card make the public URL ready to share. + +Validation: lint, TypeScript, all nine behavior/navigation tests and the production build passed. Browser review covered the homepage at 1280 and 390 pixels, walkthrough switching, the 390-pixel installation guide and expandable documentation navigation, image loading and the generated 1200×630 share card. No horizontal page overflow was observed. Actual physical-device testing remains unverified. + +## Earlier reviews + # Public site review ## Serendepify brand alignment, 3 October 2026 diff --git a/app/articles/agentic-deployment-with-oauth-and-mcp/page.tsx b/app/articles/agentic-deployment-with-oauth-and-mcp/page.tsx index 838884c..26cca27 100644 --- a/app/articles/agentic-deployment-with-oauth-and-mcp/page.tsx +++ b/app/articles/agentic-deployment-with-oauth-and-mcp/page.tsx @@ -45,7 +45,7 @@ export default function ArticlePage() { Connect an agent From merge to deployment The agent’s view - Use it on your VPS + Use your own infrastructure
@@ -183,9 +183,9 @@ export default function ArticlePage() {

Put it to work on your infrastructure.

- Install GroundControl, claim your instance and review the host - scan. Choose one application, confirm its identity and connect - your agent. A health check gives you a first result you can + Start GroundControl from your computer, locally or on a Linux + server. Add a project from a folder or GitHub, connect or launch + its deployment, and authorize your agent. A health check gives you a first result you can compare with the product interface. From there, follow the deployment guide for the operations your workload supports.

diff --git a/app/components/NextSteps.tsx b/app/components/NextSteps.tsx index 62d9da1..1788f57 100644 --- a/app/components/NextSteps.tsx +++ b/app/components/NextSteps.tsx @@ -19,10 +19,10 @@ const paths = [ { id: "new", title: "I want to deploy a new app", - intro: "Use a template to validate, create and enroll a new deployment.", + intro: "Add your project, then choose the launch path supported by its host.", steps: [ - ["Choose a template for your application", "new-deployment#choose"], - ["Connect and verify the source", "new-deployment#source"], + ["Add your project from a folder or GitHub", "projects#sources"], + ["Choose a host and deployment environment", "projects#deployments"], ["Configure and review the proposed deployment", "new-deployment#review"], ["Deploy and check the public result", "new-deployment#verify"], ["Grant your agent access to that workload", "agent-access#consent"], diff --git a/app/components/ProductTour.tsx b/app/components/ProductTour.tsx index 8b05600..8075ee6 100644 --- a/app/components/ProductTour.tsx +++ b/app/components/ProductTour.tsx @@ -6,24 +6,26 @@ import Capture from "./Capture"; const stages = [ { - title: "Discover", - heading: "Start with what is already running.", - text: "GroundControl reads the active host, finds Compose folders and containers, and presents candidates you can inspect.", - fact: "Review the candidates and choose which to enroll.", - file: "discovery-desktop.jpg", - alt: "GroundControl discovered workloads with source paths and Enrol deployment buttons", - href: "/docs/discovery", - link: "How discovery works", + title: "Project", + heading: "Start with the application you’re building.", + text: "Pick a folder from your computer or import a GitHub repository. Your project brings the source, purpose and deployment instances together.", + fact: "Add source first. Choose its deployments separately.", + file: "project-import-2026-10-20.png", + alt: "GroundControl Add project chooser with folder and GitHub import options", + caption: "Current interface · isolated demo · 20 October 2026", + href: "/docs/projects#sources", + link: "Add your first project", }, { - title: "Enrol", - heading: "Choose what belongs in GroundControl.", - text: "Enrol one candidate, keep its files where they are, and optionally group it into a project. Confirm its source, runtime and public address.", - fact: "Enrollment preserves the workload’s existing location.", - file: "enrollment-desktop.jpg", - alt: "GroundControl enrollment dialog showing optional project grouping", - href: "/docs/first-deployment", - link: "Follow the enrollment guide", + title: "Deploy", + heading: "Give each environment its own instance.", + text: "Connect an application already running on your host, or launch a new instance. Each deployment has its own environment, configuration and release history.", + fact: "Local Docker or your Linux server. Your infrastructure.", + file: "project-deployments-2026-10-20.png", + alt: "GroundControl Add deployment dialog offering connect existing or launch new", + caption: "Current interface · example project · 20 October 2026", + href: "/docs/projects#deployments", + link: "Choose a deployment path", }, { title: "Connect", @@ -31,6 +33,7 @@ const stages = [ text: "Add your instance’s MCP endpoint to a compatible client, sign in through OAuth and select the deployments it may access.", fact: "The grant names the capabilities and workloads.", file: "agents-desktop.jpg", + caption: "Operator interface · captured 22 September 2026", alt: "GroundControl Agents workspace showing a real active ChatGPT grant", href: "/docs/agent-access", link: "Connect your agent", @@ -41,6 +44,7 @@ const stages = [ text: "Read runtime checks and the public endpoint result. A durable operation ID lets your agent return to the same work after a timeout.", fact: "RentAWeekend recorded release · 21 September 2026.", file: "verification-desktop.jpg", + caption: "Recorded release · captured 22 September 2026", alt: "GroundControl runtime image verification and public endpoint evidence", href: "/docs/evidence", link: "Inspect the recorded evidence", @@ -109,7 +113,7 @@ export default function ProductTour() {
diff --git a/app/components/WorkloadModel.tsx b/app/components/WorkloadModel.tsx index 696330b..2f57b79 100644 --- a/app/components/WorkloadModel.tsx +++ b/app/components/WorkloadModel.tsx @@ -5,16 +5,21 @@ export default function WorkloadModel() { aria-label="Example of GroundControl entities and their relationships" >
- Example · one application, one deployment, several services + Example · one application, independent deployments
Project Weekend planner - Your application or product + Folder / GitHub repository +
+
+ Development + weekend-local + Docker on your computer
- Deployment + Production weekend-production On your VPS
diff --git a/app/docs/page.tsx b/app/docs/page.tsx index 1faaf5f..ec563d1 100644 --- a/app/docs/page.tsx +++ b/app/docs/page.tsx @@ -17,7 +17,7 @@ export default function DocsPage() {

The operator’s handbook

- From your first scan + From your first project
to a verified operation.

@@ -30,13 +30,13 @@ export default function DocsPage() { 01 / Start

I need to install it.

-

Install, claim and connect the local host.

+

Choose your computer or a server and open the setup link.

Installation guide → 02 / Continue

It’s installed. Now what?

-

Review discovery and choose your first application.

+

Add a project, then connect or launch a deployment.

Follow the next steps → diff --git a/app/globals.css b/app/globals.css index 2653e46..4ae1fd1 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,26 +1,28 @@ @import "tailwindcss"; :root { - /* Shared with Serendepify's v5 brand: warm paper, ink, lime, and coral. */ - --paper: #f1f0e8; - --paper-deep: #e8e7dc; + /* Serendepify's lime and coral on a dark, warm-neutral canvas. */ + --paper: #11130f; + --paper-deep: #171b14; --lime: #c8ff3d; - --coral: #ff6846; - --grid-line: rgba(23, 24, 18, 0.055); - --lime-wash: rgba(200, 255, 61, 0.2); - --light-ink: #f1f0e8; - --dark-muted: #b6bbad; - --dark-active: #242a19; - --panel-line: #c8cabb; - --surface: #ffffff; - --ink: #171812; - --muted: #606358; - --line: #d6d7cc; - --dark: #12140f; - --dark-line: #383d30; - --green: #475d1c; - --soft-green: #e8e7dc; - --code: #e5e8d7; + --coral: #ff8165; + --grid-line: rgba(225, 237, 203, 0.045); + --lime-wash: rgba(200, 255, 61, 0.08); + --light-ink: #f0f2e8; + --dark-muted: #b7bfab; + --dark-active: #252d1b; + --panel-line: #414a36; + --surface: #1c2118; + --ink: #f0f2e8; + --muted: #b7bfab; + --line: #353d2d; + --dark: #0b0e09; + --dark-line: #353d2d; + --green: #c8ff3d; + --soft-green: #232c18; + --code: #20271a; + --on-accent: #11160a; + --accent-hover: #daff84; --font-sans: var(--font-brand-body); --font-display: var(--font-brand-display); --font-mono: var(--font-brand-mono); @@ -29,6 +31,7 @@ box-sizing: border-box; } html { + color-scheme: dark; scroll-behavior: smooth; scroll-padding-top: 100px; } @@ -68,7 +71,7 @@ pre:focus-visible, } ::selection { background: var(--lime); - color: var(--ink); + color: var(--on-accent); } h1, h2, @@ -130,8 +133,8 @@ img { top: -100px; z-index: 99; padding: 14px 22px; - background: var(--ink); - color: white; + background: var(--lime); + color: var(--on-accent); } .skip-link:focus { top: 12px; @@ -151,19 +154,19 @@ img { gap: 30px; min-height: 48px; padding: 15px 21px; - background: var(--ink); - color: white; - border: 1px solid var(--ink); + background: var(--lime); + color: var(--on-accent); + border: 1px solid var(--lime); border-radius: 8px; font-size: 14px; font-weight: 600; transition: background 0.2s; } .button:hover { - background: var(--dark-active); + background: var(--accent-hover); } .button > span { - color: var(--lime); + color: inherit; } .button.compact { min-height: 42px; @@ -541,7 +544,7 @@ img { flex-wrap: wrap; gap: 7px 18px; padding: 17px; - background: white; + background: var(--surface); border: 1px solid var(--panel-line); align-items: center; } @@ -813,7 +816,7 @@ img { width: 100%; min-height: 48px; padding: 13px; - border: 1px solid #b6c0b5; + border: 1px solid var(--panel-line); border-radius: 3px; color: var(--ink); font-family: var(--font-mono); @@ -825,7 +828,7 @@ img { margin-top: 13px !important; } .endpoint-builder .input-error { - color: #a03f2e !important; + color: var(--coral) !important; } .endpoint-builder .code-block { margin-bottom: 13px; @@ -872,7 +875,7 @@ img { } .docs-sidebar nav a:hover { color: var(--ink); - background: #ecefe7; + background: var(--surface); } .docs-sidebar nav a.active { border-left-color: var(--green); @@ -886,7 +889,7 @@ img { .nav-group > p { font-size: 10px; font-family: var(--font-mono); - color: #737a72; + color: var(--muted); padding: 7px 12px 8px; } .sidebar-note { @@ -991,7 +994,7 @@ img { .prose li { font-size: 16px; line-height: 1.8; - color: #4c584e; + color: var(--muted); } .prose p + p { margin-top: 19px; @@ -1024,9 +1027,9 @@ img { .prose code { font-family: var(--font-mono); font-size: 0.82em; - background: #eaf0e5; - color: #375534; - border: 1px solid #dbe4d6; + background: var(--soft-green); + color: var(--ink); + border: 1px solid var(--line); padding: 2px 4px; border-radius: 3px; overflow-wrap: anywhere; @@ -1044,8 +1047,8 @@ img { } .callout { padding: 19px 21px; - border-left: 2px solid #adbda5; - background: #eff1e9; + border-left: 2px solid var(--panel-line); + background: var(--paper-deep); margin-block: 26px; } .callout > strong { @@ -1085,11 +1088,11 @@ td { } th { font-weight: 600; - background: #eaf0e5; - color: #42553d; + background: var(--soft-green); + color: var(--ink); } td { - color: #4f5c4c; + color: var(--muted); } td + td, th + th { @@ -1114,7 +1117,7 @@ tr:last-child td { flex-direction: column; gap: 10px; padding: 19px; - background: white; + background: var(--surface); } .scope-map > div + div { border-left: 1px solid var(--line); @@ -1172,7 +1175,7 @@ tr:last-child td { gap: 0; margin-block: 15px 27px; border: 1px solid var(--line); - background: white; + background: var(--surface); border-radius: 5px; } .docs-entrypoints > a { @@ -1284,7 +1287,7 @@ tr:last-child td { } .next-steps { border: 1px solid var(--line); - background: white; + background: var(--surface); border-radius: 5px; margin-block: 26px; overflow: hidden; @@ -1373,7 +1376,7 @@ tr:last-child td { margin: 0; padding: 16px 20px; font-size: 11px; - background: #f4f6f0; + background: var(--paper-deep); color: var(--muted); line-height: 1.7; } @@ -1475,7 +1478,7 @@ tr:last-child td { .operation-record { padding: 25px; background: var(--soft-green); - border: 1px solid #cedbc8; + border: 1px solid var(--line); margin-block: 25px; } .operation-record > code { @@ -1492,7 +1495,7 @@ tr:last-child td { .operation-record dl > div { display: flex; gap: 22px; - border-top: 1px solid #cdd9c8; + border-top: 1px solid var(--line); padding: 13px 0; font-size: 13px; } @@ -1974,7 +1977,7 @@ tr:last-child td { padding: 0; border: 1px solid var(--line); border-radius: 4px; - background: white; + background: var(--surface); } .docs-toggle { display: flex; diff --git a/app/layout.tsx b/app/layout.tsx index 3183a52..1967bd0 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -18,6 +18,14 @@ const monoFont = JetBrains_Mono({ }); export const metadata: Metadata = { + metadataBase: new URL("https://trygroundcontrol.serendepify.com"), + openGraph: { + type: "website", + siteName: "GroundControl", + title: "Put your agents to work | GroundControl", + description: "Deploy and operate on infrastructure you own. Start on your computer or a Linux server, bring a project from a folder or GitHub, and connect your agent.", + }, + twitter: { card: "summary_large_image" }, title: "GroundControl | Agentic deployment on infrastructure you own", description: "Connect your agents to your applications through MCP and OAuth. Inspect workloads, run supported deployments, and verify results on infrastructure you own. Open source and self-hosted.", diff --git a/app/opengraph-image.tsx b/app/opengraph-image.tsx new file mode 100644 index 0000000..ee75aa5 --- /dev/null +++ b/app/opengraph-image.tsx @@ -0,0 +1,26 @@ +import { ImageResponse } from "next/og"; + +export const alt = "GroundControl — Put your agents to work. Deploy and operate on infrastructure you own."; +export const size = { width: 1200, height: 630 }; +export const contentType = "image/png"; + +export default function Image() { + return new ImageResponse( +
+
+
GroundControl
+
Open source · Self-hosted · MCP + OAuth
+
+
+
+
Put your agents
to work.
+
+
Deploy and operate on infrastructure you own.
+
+
+
Your computer or your server.
trygroundcontrol.serendepify.com
+
+
, + size, + ); +} diff --git a/app/page.test.tsx b/app/page.test.tsx index fdce8c2..bc472cd 100644 --- a/app/page.test.tsx +++ b/app/page.test.tsx @@ -112,7 +112,7 @@ describe("The self-contained adoption journey", () => { it("replaces phone captures with current desktop evidence and clear provenance", () => { render(); expect( - screen.getByAltText(/GroundControl discovered workloads/), + screen.getByAltText(/GroundControl Add project chooser/), ).toBeInTheDocument(); fireEvent.click(screen.getByRole("tab", { name: /Connect/ })); expect( @@ -136,13 +136,13 @@ describe("The self-contained adoption journey", () => { }); it("lets readers navigate the product walkthrough using the keyboard", () => { render(); - const first = screen.getByRole("tab", { name: /Discover/ }); + const first = screen.getByRole("tab", { name: /Project/ }); fireEvent.keyDown(first, { key: "ArrowRight" }); - const enroll = screen.getByRole("tab", { name: /Enrol/ }); + const enroll = screen.getByRole("tab", { name: /Deploy/ }); expect(enroll).toHaveAttribute("aria-selected", "true"); expect(enroll).toHaveFocus(); expect(screen.getByRole("tabpanel")).toHaveTextContent( - "Choose what belongs", + "Give each environment", ); fireEvent.keyDown(enroll, { key: "End" }); expect(screen.getByRole("tab", { name: /Verify/ })).toHaveFocus(); @@ -159,8 +159,8 @@ describe("The self-contained adoption journey", () => { fireEvent.click(screen.getByRole("button", { name: /deploy a new app/ })); expect(screen.getByText("0 / 5 checked")).toBeInTheDocument(); expect( - screen.getByRole("link", { name: /Guide: Choose a template/ }), - ).toHaveAttribute("href", "/docs/new-deployment#choose"); + screen.getByRole("link", { name: /Guide: Add your project/ }), + ).toHaveAttribute("href", "/docs/projects#sources"); fireEvent.click( screen.getByRole("button", { name: /apps already run here/ }), ); diff --git a/app/page.tsx b/app/page.tsx index b69064b..e47aa3e 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -120,30 +120,30 @@ export default function Home() {

- The local host is connected. GroundControl can now help you - understand what is running and bring one application into its - control plane. + Start on your computer or connect an existing Linux server. + Add the application you’re building, then decide where and how + its deployments run.

{[ [ "01", - "Review what was found", - "Confirm the server, Compose folders, containers and proxy. Correct scan paths when something is missing.", - "discovery", + "Choose your starting point", + "Run the launcher on your computer. Choose local Docker or a remote Linux server and open your private setup link.", + "getting-started", ], [ "02", - "Choose your workload", - "Enrol an existing application in place, or use Templates to create and enroll a new deployment.", - "after-install#choose-path", + "Add your project", + "Pick a folder or a GitHub repository. Keep the source, context and deployments for your application together.", + "projects", ], [ "03", - "Establish its identity", - "Check the source, runtime, configuration and public address. Understand tracking and management mode.", - "first-deployment#management-mode", + "Connect or launch a deployment", + "Connect an app that already runs, or launch a new instance. Give each deployment its own environment and host.", + "projects#deployments", ], [ "04", @@ -176,9 +176,9 @@ export default function Home() { Your final say.

- Start with the applications already on your VPS, or launch a - new workload through Templates. Keep your existing files in - place and bring the applications you choose into GroundControl. + Bring a project from your computer or GitHub. Connect its + existing deployments or launch a new instance on your own + infrastructure. Keep your sources and environments together.

MCP gives your agent the tools. OAuth defines its access. You @@ -278,9 +278,9 @@ export default function Home() { "philosophy", ], [ - "Discovery & enrollment", - "Where the scanner looks and what enrollment changes.", - "discovery", + "Projects & deployments", + "Folder and GitHub imports, environments and running instances.", + "projects", ], [ "Connect your agent", @@ -323,13 +323,13 @@ export default function Home() {

- Linux · Docker · root or sudo + Choose this computer or a remote Linux server.
- Read the installation guide for prerequisites and host access. + macOS / Linux · Windows through WSL · Docker for local installs.

diff --git a/content/guide-index.ts b/content/guide-index.ts index 49e2d9a..52557ec 100644 --- a/content/guide-index.ts +++ b/content/guide-index.ts @@ -13,11 +13,11 @@ export const guideIndex = [ { slug: "getting-started", title: "Install & claim", - short: "Start on your VPS", + short: "Start on your computer", group: "Set up", description: - "Installation commands, SSH tunnel, ownership and host checks.", - keywords: "linux VPS docker bootstrap install claim setup", + "Choose local Docker or a remote Linux server and open your private setup link.", + keywords: "linux macOS Windows WSL desktop VPS docker bootstrap install claim setup", }, { slug: "after-install", @@ -28,6 +28,14 @@ export const guideIndex = [ "Review the host scan and follow a checklist for your first application.", keywords: "next onboarding first steps dashboard workflow", }, + { + slug: "projects", + title: "Projects & deployments", + short: "Bring your application together", + group: "Set up", + description: "Pick a folder or GitHub repository, then connect or launch deployment instances.", + keywords: "project folder picker GitHub source import environment deployment local desktop", + }, { slug: "publishing", title: "Publish over HTTPS", @@ -58,7 +66,7 @@ export const guideIndex = [ { slug: "new-deployment", title: "Deploy a new app", - short: "Create with Templates", + short: "Launch a new instance", group: "Set up", description: "Choose a template, verify source, review configuration and deploy.", diff --git a/content/guides.tsx b/content/guides.tsx index f89eeac..022d34b 100644 --- a/content/guides.tsx +++ b/content/guides.tsx @@ -1,5 +1,6 @@ import type { ReactNode } from "react"; import { Check, Note, Table } from "./guide-parts"; +import { setupGuides } from "./setup-guides"; import { journeyGuides } from "./journey-guides"; import Link from "next/link"; import CodeBlock from "@/app/components/CodeBlock"; @@ -15,175 +16,7 @@ const install = "https://raw.githubusercontent.com/teckedd-code2save/groundcontrol/main/scripts/install"; export const guides: Record = { ...journeyGuides, - "getting-started": { - title: "Install GroundControl and claim your instance", - description: - "Start on a Linux VPS, reach the private installer through an SSH tunnel, and create your administrator account.", - outcome: - "A claimed, healthy GroundControl instance with its local server enrolled.", - sections: [ - { - id: "before-you-start", - title: "What you need", - body: ( - <> - -

- GroundControl is a privileged host operations tool. Its canonical - Compose file mounts the Docker socket and host directories such as{" "} - /opt, /etc and /var/www. - Install it on a host you intend it to manage. The MCP grant later - exposes a much narrower set of operations to an agent. -

- - ), - }, - { - id: "install", - title: "1. Run the installer on the VPS", - body: ( - <> -

- SSH into your VPS, then run this there. The script downloads the - published image, writes installation files under{" "} - /opt/groundcontrol, creates persistent database - storage and starts the container on 127.0.0.1:3003. -

- -

For an agent or script that needs structured output, use:

- - -

- Look for claim_required, healthy container checks, - a claimUrl and its expiry. The claim is single-use - and lasts 30 minutes by default. Keep its token private. -

-
- - ), - }, - { - id: "tunnel", - title: "2. Open the private instance from your computer", - body: ( - <> -

- In a second terminal on your own computer, open a tunnel. Replace{" "} - YOUR_USER and YOUR_VPS_IP with the SSH - account and address you normally use. -

- -

- Leave that terminal running. Open the installer’s full{" "} - http://127.0.0.1:3003/claim#token=… URL in your - computer’s browser. The URL reaches the VPS through your tunnel; - it is not a public management endpoint. -

- -

- If local port 3003 is occupied, use{" "} - - ssh -N -L 13003:127.0.0.1:3003 YOUR_USER@YOUR_VPS_IP - {" "} - and change only the port in the claim URL to 13003. -

-
- - ), - }, - { - id: "claim", - title: "3. Create the owner account", - body: ( - <> -

- On Claim GroundControl, enter an administrator - username, a password and its confirmation. The password requires - at least 12 characters with upper and lower case letters, a number - and a symbol. The installing agent should not retain it. -

-

- The claim code is read from the URL fragment. Submit the form to - establish ownership. If the claim expired before you used it, - rerun the installer on that still-unclaimed instance for a new - claim; an already-claimed instance uses its existing login. -

- -

- Onboarding opens after claim. The local host should already be - enrolled. You do not need to paste its SSH private key back into - GroundControl. Additional remote servers can be added separately - through Add server. -

-
- - ), - }, - { - id: "verify", - title: "4. Verify the installation", - body: ( - <> -

- Run these read-only checks on the VPS. Replace the port if you - changed it during installation. -

- -
-

- Continue with{" "} - After installation to - review the host scan and choose your first application. Remote - agents need{" "} - a reachable HTTPS address;{" "} - for a private evaluation, keep using the tunnel. -

- - ), - }, - ], - }, + ...setupGuides, publishing: { title: "Give your instance a stable HTTPS address", description: @@ -198,7 +31,7 @@ export const guides: Record = { <>

After claim, continue to the onboarding step titled{" "} - Publish this GroundControl instance. Choose a + Publish this GroundControl instance on a Linux server installation. Desktop installations remain local; this publishing flow is for servers. Choose a method appropriate for the host and DNS you control.

= { }, { id: "project", - title: "2. Group it into a project, if useful", + title: "2. Connect it to your application’s project", body: ( <> -

- Enrol deployment adds the candidate without a - project group. To group it immediately, open its options menu and - choose Enrol into project or{" "} - Create project and enrol. Selecting a project - completes that enrollment; there is no separate final submit - button in the selection dialog. -

- -

- You can change this later with the enrolled workload’s{" "} - Move to project action. Several environments or - applications can share a group while retaining distinct deployment - identities. -

+

From a project, choose Add deployment → Connect existing, select the workload and confirm its name and environment. The project holds your application’s source and its deployment instances.

+

You can also enrol from discovery, then use Move to project to organize it later. Moving or registering a deployment does not relocate files or restart its runtime.

+

See Projects & deployments to add sources from the folder picker or GitHub and connect additional environments.

), }, @@ -1070,6 +887,7 @@ export const guides: Record = { title: "1. Preview the target version", body: ( <> +

This maintenance flow is for the canonical Linux server installation. Rerunning the computer launcher reconnects; it does not upgrade an existing desktop instance. Keep the desktop configuration folder and database volume together.

Run this on the VPS that already hosts GroundControl. Replace{" "} YOUR_TAG with the published version or image tag you diff --git a/content/journey-guides.tsx b/content/journey-guides.tsx index 5025de6..a87fd47 100644 --- a/content/journey-guides.tsx +++ b/content/journey-guides.tsx @@ -34,8 +34,8 @@ export const journeyGuides: Record = { confirmations and expired grants still need attention.

- The starting point is a founder or small team running applications - with Docker Compose on a VPS. GroundControl also has human + Start on your computer with Docker, or on a Linux server with + the applications you already operate. GroundControl also has human controls for runtime, logs, environment, proxy configuration and terminal access. You can begin using those before connecting an external agent. @@ -58,11 +58,11 @@ export const journeyGuides: Record = { ], [ "Project", - "An optional group of related deployments. Moving a deployment between project groups changes organization, not its files or runtime.", + "Your application or product, with folder or GitHub sources and deployment instances. Organizing deployments preserves their files and runtime.", ], [ "Deployment", - "The enrolled application identity: host, source or container, Compose identity, repository, public URL and recorded releases where available.", + "An instance of an application on a particular host and environment, with a Compose or container runtime identity, public URL and recorded releases where available.", ], [ "Service / container", @@ -236,15 +236,15 @@ export const journeyGuides: Record = { body: ( <>

- The canonical installer starts GroundControl privately, creates - persistent storage and connects the VPS it is running on as a - local host. Claim establishes your administrator account. You do + The launcher starts GroundControl privately, creates persistent + storage and connects the local Docker workspace or destination + Linux server. Claim establishes your administrator account. You do not need to add that same host again using SSH.

- After claim, onboarding asks how to publish the control plane. - Choose a stable HTTPS origin for remote MCP clients, or keep it - private while evaluating. On completion, GroundControl probes the + After claim, desktop onboarding verifies private local access. + On a Linux server, you can publish a stable HTTPS origin for + remote MCP clients or keep it private while evaluating. On completion, GroundControl probes the host and shows its findings.

= { <>

- For existing software, start in Deployments. For - a new workload, start in Templates. A template - deployment creates runtime resources and registers the result; - discovery and enrollment describe software already present. + Start in Projects → Add project and pick a folder + or GitHub repository. In that project, choose Add deployment + to connect an existing workload or launch a new instance. The + projects guide explains each path.

), @@ -333,7 +333,7 @@ export const journeyGuides: Record = { ], [ "Projects", - "Organize related deployments. Grouping does not relocate application files.", + "Add an application from a folder or GitHub and organize its deployment instances by host and environment.", ], [ "Runtime", @@ -401,7 +401,7 @@ export const journeyGuides: Record = { ], }, discovery: { - title: "Discover what is running on your VPS", + title: "Discover workloads on your host", description: "Understand where GroundControl looks, what a discovered candidate means, and how to resolve missing or unexpected results.", outcome: @@ -486,9 +486,11 @@ export const journeyGuides: Record = { ]} />

- Only enroll candidates you intend to track. A host can contain - temporary helper containers, old releases and infrastructure - services as well as customer applications. + Only enroll candidates you intend to track. Compose services from + the same stack are grouped together. Use Dismiss to hide a + suggestion, then Undo or Restore hidden to bring it back. This + does not stop or delete the workload. GroundControl excludes + its own helper containers.

), @@ -606,6 +608,15 @@ export const journeyGuides: Record = { outcome: "A new deployment with its runtime, source identity and public verification result recorded in GroundControl.", sections: [ + { + id: "host", + title: "Start with your project and host", + body: <> +

Open your project and choose Add deployment → Launch new. Select the host and environment for this instance.

+

On local Docker, the current flow launches a single container image using its default command without custom environment variables. It does not build arbitrary folder or repository source. On a Linux server, continue through the Templates steps below.

+

If you have not added your application yet, pick a folder or GitHub repository first.

+ , + }, { id: "choose", title: "1. Choose the deployment shape", diff --git a/content/setup-guides.tsx b/content/setup-guides.tsx new file mode 100644 index 0000000..9686ba8 --- /dev/null +++ b/content/setup-guides.tsx @@ -0,0 +1,104 @@ +import Link from "next/link"; +import type { Guide } from "./guides"; +import { Check, Note, Table } from "./guide-parts"; +import Capture from "@/app/components/Capture"; +import CodeBlock from "@/app/components/CodeBlock"; + +export const setupGuides: Record = { + "getting-started": { + title: "Start GroundControl from your computer", + description: "Choose this computer or an existing Linux server. The launcher prepares the instance and prints a private link for setup or login.", + outcome: "A private GroundControl workspace, your owner account and a clear next step for your first project.", + sections: [ + { id: "before-you-start", title: "Choose where it runs", body: <> +
+

Local GroundControl manages Docker workloads. It does not manage native Mac or Windows services. On a server, GroundControl is a privileged host operations tool; install it on infrastructure you intend it to manage.

+ }, + { id: "install", title: "1. Run the launcher on your computer", body: <> + +

Choose this computer or a remote server when prompted. Local setup uses Docker. Remote setup connects through SSH, installs GroundControl on the server and opens the private tunnel for you.

+

You can also choose the destination directly:

+ + +

The launcher prints a link on 127.0.0.1. A new instance opens setup; an instance you already own opens login. Local setup writes its configuration to .groundcontrol-desktop in the current folder by default. Retain that folder and the Docker database volume.

+ }, + { id: "tunnel", title: "2. Open your private setup link", body: <> +

Open the complete link printed by the launcher in your browser on the same computer. Its one-time claim token establishes ownership; keep the link private.

+
+

The remote server stays private unless you deliberately publish it. Rerunning the launcher reconnects to an existing installation; it does not upgrade it.

+ }, + { id: "claim", title: "3. Create your owner account", body: <> +

On Claim GroundControl, enter an administrator username and a password with at least 12 characters, upper and lower case letters, a number and a symbol. This account belongs to your own instance.

+

A claim link is single-use and expires after 30 minutes by default. Rerun the launcher for a fresh link if the unclaimed instance’s link expires. An already-claimed instance uses your existing login.

+

The local Docker workspace or destination Linux host is connected automatically. Continue setup to review it; you do not need to add that same host a second time.

+ }, + { id: "verify", title: "4. Verify and add your first project", body: <> +

Use the private verification step, then review the onboarding summary. On a desktop, the Linux environment belongs to the container; it is not the operating system of your Mac or Windows PC.

+

Open Projects → Add project. Pick a folder or a GitHub repository, then connect an existing deployment or launch a new one. Follow the projects and deployments guide.

+

A local-only address is for you on this computer. Remote MCP clients need a reachable HTTPS endpoint. The server installation supports publishing over HTTPS; desktop onboarding stays private.

+ }, + { id: "on-host", title: "Advanced: install directly on a Linux server", body: <> +

If you are already working in the destination server’s shell, use the canonical installer. Unlike the computer launcher, this command does not open an SSH tunnel on your computer.

+ +

Add -s -- --json after bash for structured installer output. From your computer, forward the default management port with:

+ +

Open the server installer’s complete claim link through that tunnel. Server installations live under /opt/groundcontrol by default and use persistent Docker database storage. See upgrade and recovery for maintenance.

+ }, + ], + }, + projects: { + title: "Your project, from source to deployments", + description: "Bring a folder or GitHub repository into GroundControl, then connect the instances of that application running on your infrastructure.", + outcome: "One project with its source and explicitly selected deployment instances, each with its own host and environment.", + sections: [ + { id: "model", title: "A project is the application you are building", body: <> +

A project gives your application or product a home. Its source can be a local folder or a GitHub repository. Its deployments are instances of that application—for example, development on your computer and production on a Linux server.

+
+

A project does not require a Compose file. Compose is one runtime method, alongside a standalone container. Registering source does not automatically build or start an application.

+ }, + { id: "sources", title: "1. Pick a folder or GitHub repository", body: <> + +
    +
  1. Open Projects → Add project.
  2. +
  3. Choose Folder to browse the host’s available locations and select your project folder. You do not need to type a path. For a local desktop install, use the Home, Workspace or Drives locations offered by the picker.
  4. +
  5. Or choose GitHub, select a repository and confirm the project details. Public repositories can be found by owner; private repositories require a GitHub connection with access. GroundControl retains the repository’s default branch.
  6. +
  7. Review the name and source, then add the project.
  8. +
+

Adding source records the project’s identity. It does not move your files or restart existing deployments. Removing a source link does not delete the original folder or repository.

+

The picker browses the selected host. A remote server’s filesystem is different from your computer’s. If Docker Desktop cannot read a local folder, allow that location in Docker Desktop’s file-sharing settings and select a smaller accessible folder. Windows users browse locations available to WSL and Docker.

+ }, + { id: "deployments", title: "2. Connect an existing app or launch an instance", body: <> + +

Open the project and select Add deployment. Choose the host, give the instance a useful name and set its environment.

+
+

Multiple instances may share source while running in different environments. A source folder alone is not a deployment and is not offered as a running workload to agents.

+

Follow existing app enrollment or new deployment setup for the remaining runtime-specific steps.

+ }, + { id: "discovery", title: "3. Keep discovery useful", body: <> +

Discovery suggests workloads on the selected host. Compose services from the same stack appear together, and GroundControl excludes its own helper containers.

+

Use Dismiss to hide a suggestion you do not want. Undo or Restore hidden brings it back. Dismissing a suggestion does not stop or remove the underlying workload.

+

Projects without Compose can still be added through the folder or GitHub flow. Their runtime becomes a deployment only when you explicitly connect or launch an instance.

+ }, + { id: "operate", title: "4. Work from a known deployment", body: <> +

Confirm the instance’s host, environment, services and public URL before operating it. Existing deployments, their configuration and their recorded history remain available when you organize them into projects.

+

For an external agent, authorize OAuth access to the specific deployments and capabilities it needs. Adding a project or connecting a runtime does not grant external-agent access on its own.

+ }, + ], + }, +}; diff --git a/public/proof/project-deployments-2026-10-20.png b/public/proof/project-deployments-2026-10-20.png new file mode 100644 index 0000000000000000000000000000000000000000..5b95702abf1d742dadb2bc1850395fe62415cb4f GIT binary patch literal 40599 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 s$41^Q-PRg@(G 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 literal 0 HcmV?d00001 From b50bef0bc1fbd9b7304eb4340192376d199cd2c7 Mon Sep 17 00:00:00 2001 From: Edward Twumasi Date: Tue, 20 Oct 2026 22:31:15 +0000 Subject: [PATCH 4/5] Show the revision date for updated distribution guides --- app/docs/[slug]/page.tsx | 2 +- content/guides.tsx | 7 ++++--- content/journey-guides.tsx | 4 ++++ content/setup-guides.tsx | 2 ++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/docs/[slug]/page.tsx b/app/docs/[slug]/page.tsx index 76f96cb..d137c6b 100644 --- a/app/docs/[slug]/page.tsx +++ b/app/docs/[slug]/page.tsx @@ -99,7 +99,7 @@ export default async function GuidePage({

Updated
- 22 September 2026 + {guide.updated ?? "22 September 2026"}

diff --git a/content/guides.tsx b/content/guides.tsx index 022d34b..526af79 100644 --- a/content/guides.tsx +++ b/content/guides.tsx @@ -7,6 +7,7 @@ import CodeBlock from "@/app/components/CodeBlock"; import Capture from "@/app/components/Capture"; import EndpointBuilder from "@/app/docs/_components/EndpointBuilder"; export type Guide = { + updated?: string; title: string; description: string; outcome: string; @@ -18,7 +19,7 @@ export const guides: Record = { ...journeyGuides, ...setupGuides, publishing: { - title: "Give your instance a stable HTTPS address", + updated: "20 October 2026", title: "Give your instance a stable HTTPS address", description: "Publish the control plane from onboarding, then verify the address your agent client will use for MCP and OAuth.", outcome: @@ -176,7 +177,7 @@ export const guides: Record = { ], }, "first-deployment": { - title: "Enrol an existing application", + updated: "20 October 2026", title: "Enrol an existing application", description: "Start with an existing Docker Compose application. Give GroundControl an explicit workload identity before granting an agent access.", outcome: @@ -876,7 +877,7 @@ export const guides: Record = { ], }, distribution: { - title: "Upgrade, recover and uninstall", + updated: "20 October 2026", title: "Upgrade, recover and uninstall", description: "Use the same installer for maintenance, with an explicit preview and a database/configuration backup before upgrade.", outcome: diff --git a/content/journey-guides.tsx b/content/journey-guides.tsx index a87fd47..2eda59c 100644 --- a/content/journey-guides.tsx +++ b/content/journey-guides.tsx @@ -8,6 +8,7 @@ import CodeBlock from "@/app/components/CodeBlock"; export const journeyGuides: Record = { philosophy: { + updated: "20 October 2026", title: "The GroundControl approach", description: "Understand the product, the things it manages, and how an agent gets a useful but bounded role in operating them.", @@ -224,6 +225,7 @@ export const journeyGuides: Record = { ], }, "after-install": { + updated: "20 October 2026", title: "GroundControl is installed. What next?", description: "Go from a claimed instance to one understood workload and a verified agent connection.", @@ -401,6 +403,7 @@ export const journeyGuides: Record = { ], }, discovery: { + updated: "20 October 2026", title: "Discover workloads on your host", description: "Understand where GroundControl looks, what a discovered candidate means, and how to resolve missing or unexpected results.", @@ -602,6 +605,7 @@ export const journeyGuides: Record = { ], }, "new-deployment": { + updated: "20 October 2026", title: "Deploy a new application from a template", description: "Use GroundControl’s Choose, Source, Config, Review and Deploy workflow to create and enroll a workload.", diff --git a/content/setup-guides.tsx b/content/setup-guides.tsx index 9686ba8..2ede14c 100644 --- a/content/setup-guides.tsx +++ b/content/setup-guides.tsx @@ -6,6 +6,7 @@ import CodeBlock from "@/app/components/CodeBlock"; export const setupGuides: Record = { "getting-started": { + updated: "20 October 2026", title: "Start GroundControl from your computer", description: "Choose this computer or an existing Linux server. The launcher prepares the instance and prints a private link for setup or login.", outcome: "A private GroundControl workspace, your owner account and a clear next step for your first project.", @@ -54,6 +55,7 @@ export const setupGuides: Record = { ], }, projects: { + updated: "20 October 2026", title: "Your project, from source to deployments", description: "Bring a folder or GitHub repository into GroundControl, then connect the instances of that application running on your infrastructure.", outcome: "One project with its source and explicitly selected deployment instances, each with its own host and environment.", From 9d4f86674f7e33732a306dd0e70122680b0cff28 Mon Sep 17 00:00:00 2001 From: Edward Twumasi Date: Tue, 20 Oct 2026 22:31:42 +0000 Subject: [PATCH 5/5] Continue setup into the projects guide --- app/docs/[slug]/page.tsx | 2 +- content/guides.tsx | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/docs/[slug]/page.tsx b/app/docs/[slug]/page.tsx index d137c6b..0b85d81 100644 --- a/app/docs/[slug]/page.tsx +++ b/app/docs/[slug]/page.tsx @@ -29,7 +29,7 @@ export default async function GuidePage({ if (!guide) notFound(); const index = guideIndex.findIndex((g) => g.slug === slug); const nextFor: Record = { - "after-install": "discovery", + "after-install": "projects", publishing: "discovery", "first-deployment": "agent-access", "new-deployment": "agent-access", diff --git a/content/guides.tsx b/content/guides.tsx index 526af79..f8f62b7 100644 --- a/content/guides.tsx +++ b/content/guides.tsx @@ -19,7 +19,8 @@ export const guides: Record = { ...journeyGuides, ...setupGuides, publishing: { - updated: "20 October 2026", title: "Give your instance a stable HTTPS address", + updated: "20 October 2026", + title: "Give your instance a stable HTTPS address", description: "Publish the control plane from onboarding, then verify the address your agent client will use for MCP and OAuth.", outcome: @@ -177,7 +178,8 @@ export const guides: Record = { ], }, "first-deployment": { - updated: "20 October 2026", title: "Enrol an existing application", + updated: "20 October 2026", + title: "Enrol an existing application", description: "Start with an existing Docker Compose application. Give GroundControl an explicit workload identity before granting an agent access.", outcome: @@ -877,7 +879,8 @@ export const guides: Record = { ], }, distribution: { - updated: "20 October 2026", title: "Upgrade, recover and uninstall", + updated: "20 October 2026", + title: "Upgrade, recover and uninstall", description: "Use the same installer for maintenance, with an explicit preview and a database/configuration backup before upgrade.", outcome: