From da0317dda5ba6d96d85d6c28d5503b6cdc1b3757 Mon Sep 17 00:00:00 2001 From: Edward Twumasi <45181928+teckedd-code2save@users.noreply.github.com> Date: Tue, 22 Sep 2026 02:41:29 +0000 Subject: [PATCH] Rebuild product journey and document discovery, enrollment and next steps --- MEDIA_CAPTURE.md | 17 +- README.md | 7 +- SITE_REVIEW.md | 33 +- .../chatgpt-operated-my-deployment/page.tsx | 6 +- app/components/NextSteps.tsx | 97 + app/components/ProductTour.tsx | 118 + app/components/SiteChrome.tsx | 53 +- app/components/WorkloadModel.tsx | 47 + app/docs/[slug]/page.tsx | 10 +- app/docs/_components/DocsNav.tsx | 100 +- app/docs/_components/EndpointBuilder.tsx | 2 +- app/docs/page.tsx | 98 +- app/globals.css | 2121 +++++++++++------ app/layout.tsx | 2 +- app/page.test.tsx | 44 + app/page.tsx | 382 +-- content/guide-index.ts | 79 +- content/guide-parts.tsx | 47 + content/guides.tsx | 162 +- content/journey-guides.tsx | 738 ++++++ public/proof/discovery-desktop.jpg | Bin 0 -> 68482 bytes public/proof/enrollment-desktop.jpg | Bin 0 -> 39312 bytes public/proof/layout-desktop.jpg | Bin 0 -> 83987 bytes 23 files changed, 3032 insertions(+), 1131 deletions(-) create mode 100644 app/components/NextSteps.tsx create mode 100644 app/components/ProductTour.tsx create mode 100644 app/components/WorkloadModel.tsx create mode 100644 content/guide-parts.tsx create mode 100644 content/journey-guides.tsx create mode 100644 public/proof/discovery-desktop.jpg create mode 100644 public/proof/enrollment-desktop.jpg create mode 100644 public/proof/layout-desktop.jpg diff --git a/MEDIA_CAPTURE.md b/MEDIA_CAPTURE.md index 4149bf9..88918dc 100644 --- a/MEDIA_CAPTURE.md +++ b/MEDIA_CAPTURE.md @@ -2,11 +2,14 @@ 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. -| Asset | Product page | What it proves | -|---|---|---| -| `public/proof/agents-desktop.jpg` | Agents | MCP endpoint, active ChatGPT grant, five displayed scopes, eight allowed workloads | -| `public/proof/configure-desktop.jpg` | Deployments / RentAWeekend / Configure | Explicit repository, branch, recorded revision and enabled deployment-specific merge automation | +| Asset | Product page | What it proves | +| --------------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| `public/proof/agents-desktop.jpg` | Agents | MCP endpoint, active ChatGPT grant, five displayed scopes, eight allowed workloads | +| `public/proof/configure-desktop.jpg` | Deployments / RentAWeekend / Configure | Explicit repository, branch, recorded revision and enabled deployment-specific merge automation | | `public/proof/verification-desktop.jpg` | Deployments / RentAWeekend / Deploy / View evidence | Service image comparison, migration exit, public verification for the recorded 21 September release | +| `public/proof/discovery-desktop.jpg` | Deployments / Discovered on this host | Existing Compose candidates, paths and explicit enrollment controls | +| `public/proof/enrollment-desktop.jpg` | Deployments / Enrol into a project | Existing project choices and Create & link; the dialog was closed without enrolling anything | +| `public/proof/layout-desktop.jpg` | Settings / Layout / Deployment discovery | Separate discovery root and template deployment root, using the running instance's actual values | The public screenshot captions distinguish capture date from operation date. Images open full-size; their original aspect ratio is preserved. The previous mobile captures were removed. @@ -22,4 +25,8 @@ The public screenshot captions distinguish capture date from operation date. Ima ChatGPT's connection path was checked against https://developers.openai.com/plugins/deploy/connect-chatgpt on 22 September 2026. It currently describes Settings → Security and login → Developer mode, then Plugins → +. Older product copy refers to Apps / Connectors. Account and workspace availability can differ. -GroundControl setup labels, installer options, claim behavior, publishing paths, OAuth scopes and revocation behavior were checked against product main `68e2c23` and the running UI. Docs are rendered natively from `content/guides.tsx`; `content/guide-index.ts` drives the sidebar and guide navigation. +GroundControl setup labels, installer options, claim behavior, publishing paths, OAuth scopes and revocation behavior were checked against product main `68e2c23` and the running UI. The post-install follow-up also traced inventory discovery, enrollment defaults, project grouping, managed source-deploy guards and Templates. Discovery and enrollment captures did not start a deployment or change workload ownership. + +Docs are rendered natively from `content/guides.tsx` and `content/journey-guides.tsx`; `content/guide-index.ts` drives grouped navigation. The illustrated workload model is labeled as an example. The product-tour tabs display captured images, not a live connection to the reader's host. + +The documentation explicitly distinguishes tracking from managed deployment and from OAuth authorization. A newly discovered workload defaults to tracking, and the current UI has no general promotion control. Tracking is not documented as a universal read-only security boundary. diff --git a/README.md b/README.md index 7209a55..b347af2 100644 --- a/README.md +++ b/README.md @@ -78,12 +78,15 @@ MIT ## Native documentation and public evidence -The complete adoption path lives at `/docs`: install/claim, HTTPS publishing, deployment enrollment, ChatGPT OAuth/MCP connection, deployment automation, maintenance, troubleshooting and evidence. No GitHub visit is required to follow a guide. +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. - `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. +- `ProductTour` offers four views of the actual product with keyboard-accessible tabs. `NextSteps` provides separate session-only checklists for existing and new workloads; checking an item performs no host operation. +- `WorkloadModel` is a labeled conceptual illustration, not a screenshot or live status display. - `app/docs/_components/EndpointBuilder.tsx` formats the operator's HTTPS MCP URL entirely in the browser; it performs no network request. - 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 and clipboard behavior with `npm test`. Before publishing, inspect the hosted preview at desktop and narrow viewport widths, including copy actions and the ChatGPT setup guide. +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. diff --git a/SITE_REVIEW.md b/SITE_REVIEW.md index b84de0d..243123b 100644 --- a/SITE_REVIEW.md +++ b/SITE_REVIEW.md @@ -1,22 +1,27 @@ -# Public site review — 22 September 2026 +# Public site review, 22 September 2026 -## What changed +## Product journey revision -The adoption path now stays on the public site: eight guides cover installation, claim, HTTPS, workload enrollment, ChatGPT OAuth/MCP, operation tracking, maintenance, troubleshooting and evidence. The article and homepage use fresh desktop product captures; the previous phone images are removed. +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. -## Verification +The post-install guide offers separate checklists for existing and new applications. Checkmarks are session-only progress aids; they do not perform or verify any server operation. Documentation navigation is grouped into Understand, Set up and Operate, with an explicit expandable menu on narrow screens. -- Local lint, TypeScript, seven tests and production build passed. Tests validate all internal guide destinations, section anchors, image paths, connection instructions, endpoint validation and clipboard outcomes. -- PR #17 passed GitHub CI and Vercel deployment. Its merged production revision is `dcaa1dbf37fb7f2d5de6c8804c564b4b287e314e`. -- The public homepage and native OAuth guide were opened in the browser at 1363 CSS pixels. Both product images loaded; there was no horizontal document overflow. The guide's section links and search worked. -- Entering `https://gc.example.org` produced `https://gc.example.org/mcp`, and the browser clipboard contained that exact value after Copy. An HTTP address showed the HTTPS validation error. -- The guide's ChatGPT settings path was checked against OpenAI's current connection documentation. The GroundControl fields were checked against the product code and authenticated desktop UI. We did not create a separate new ChatGPT plugin or new VPS installation as part of this site review. -- Fresh MCP health and a retrieved, existing GitHub-triggered operation are published as separate evidence records. The article does not describe the existing operation as a new ChatGPT-issued deployment. +## Product verification -## Visual follow-up +- Installer, onboarding probe, inventory discovery, enrollment, project grouping, source deployment and Templates were traced against product main `68e2c23`. +- Live UI review confirmed Settings → Layout → Deployment discovery, the two root fields, Discovered on this host and the enrollment dialog. No workload was enrolled, deployed or restarted during those captures. +- The guides distinguish initial broad host probing from the inventory scan of configured roots. They explain Docker-label matching, conventional Compose names, bounded depth and common missing/duplicate candidate cases. +- Existing candidates default to tracking. New template deployments become managed. The current UI has no general tracking-to-managed promotion control. OAuth permissions are separate, and tracking is not a universal read-only security boundary. +- Loop, Daytona, public verification and source-to-image evidence limits remain explicit. -Browser review caught external-link arrows rendered as emoji tiles. Text-presentation selectors correct them. The article's visible title now names GroundControl and agentic deployment, and the hero explains the repeated access/credential friction directly. +## Automated verification -The available browser does not expose mobile viewport emulation. The 1200/900/700-pixel responsive rules were inspected in code, including horizontal table/code scrolling and mobile guide navigation. Actual phone-browser testing remains unverified; desktop review is not a substitute for it. +Local lint, TypeScript, nine tests and production build passed. Tests validate internal destinations and anchors across all twelve guides, image paths, OAuth connection instructions, endpoint validation, clipboard outcomes, product-tour keyboard navigation and independent checklist state. -Vercel preview required a separate sign-in, so visual verification used the public production pages after the authorized merge. +## Browser verification and limits + +The preceding public revision was reviewed at 1363 CSS pixels. The product images loaded, guide anchors and search worked, the endpoint builder produced the expected HTTPS MCP address and Copy placed it on the clipboard. There was no horizontal document overflow. The current journey revision requires a fresh public-page review after deployment; do not treat the preceding review as verification of this revision. + +The available browser does not expose mobile viewport emulation. Responsive rules at 1200, 950 and 700 pixels have been inspected, including local table/code scrolling, product-tour layout, accessible control sizes and collapsible guide navigation. Actual phone-browser testing remains unverified. + +Vercel preview requires a separate sign-in. Public production pages are available for visual verification after the authorized merge. This site revision does not establish that a separate fresh VPS installation or new ChatGPT plugin connection was completed. diff --git a/app/articles/chatgpt-operated-my-deployment/page.tsx b/app/articles/chatgpt-operated-my-deployment/page.tsx index 1a774cd..94a3c16 100644 --- a/app/articles/chatgpt-operated-my-deployment/page.tsx +++ b/app/articles/chatgpt-operated-my-deployment/page.tsx @@ -27,7 +27,7 @@ export default function ArticlePage() {

The useful moment was when the conversation could inspect my running application, retrieve its deployment evidence and check the public - result—all through a scoped connection. + result through a scoped connection.

Edward Kwabena Twumasi @@ -247,8 +247,8 @@ export default function ArticlePage() { Start the walkthrough ↗︎ - - Already installed? Connect ChatGPT → + + Already installed? Find your next step →
diff --git a/app/components/NextSteps.tsx b/app/components/NextSteps.tsx new file mode 100644 index 0000000..aedddef --- /dev/null +++ b/app/components/NextSteps.tsx @@ -0,0 +1,97 @@ +"use client"; +import Link from "next/link"; +import { useState } from "react"; + +const paths = [ + { + id: "existing", + title: "My apps already run here", + intro: + "Bring one existing workload into view before granting an agent access.", + steps: [ + ["Confirm the active host and scan paths", "discovery#locations"], + ["Scan and inspect the correct candidate", "discovery#scan"], + ["Enrol it and verify its runtime identity", "first-deployment#enroll"], + ["Add its repository and public URL", "first-deployment#source"], + ["Connect ChatGPT and make a read-only call", "agent-access#first-call"], + ], + }, + { + id: "new", + title: "I want to deploy a new app", + intro: "Use a template to validate, create and enroll a new deployment.", + steps: [ + ["Choose a template for your application", "new-deployment#choose"], + ["Connect and verify the source", "new-deployment#source"], + ["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"], + ], + }, +] as const; + +export default function NextSteps() { + const [path, setPath] = useState(0); + const [done, setDone] = useState([]); + const current = paths[path]; + const completed = current.steps.filter((_, index) => + done.includes(`${current.id}-${index}`), + ).length; + return ( +
+
+ {paths.map((item, i) => ( + + ))} +
+
+

{current.intro}

+ + {completed} / {current.steps.length} checked + +
+
    + {current.steps.map(([title, href], index) => { + const key = `${current.id}-${index}`; + return ( +
  1. + + + Guide + +
  2. + ); + })} +
+

+ Your checklist for this page session. Checking a box does not run an + action or verify a server. +

+
+ ); +} diff --git a/app/components/ProductTour.tsx b/app/components/ProductTour.tsx new file mode 100644 index 0000000..068373c --- /dev/null +++ b/app/components/ProductTour.tsx @@ -0,0 +1,118 @@ +"use client"; + +import { useRef, useState } from "react"; +import Link from "next/link"; +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: "A scan does not take ownership of a workload.", + file: "discovery-desktop.jpg", + alt: "GroundControl discovered workloads with source paths and Enrol deployment buttons", + href: "/docs/discovery", + link: "How discovery works", + }, + { + 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: "Tracking, managed deployment and agent permission are distinct.", + file: "enrollment-desktop.jpg", + alt: "GroundControl enrollment dialog showing optional project grouping", + href: "/docs/first-deployment", + link: "Follow the enrollment guide", + }, + { + title: "Connect", + heading: "Give your agent a scoped connection.", + text: "Add your instance’s MCP endpoint in ChatGPT, sign in through OAuth and select the deployments the client may access.", + fact: "The grant names the capabilities and workloads.", + file: "agents-desktop.jpg", + alt: "GroundControl Agents workspace showing a real active ChatGPT grant", + href: "/docs/agent-access", + link: "Connect ChatGPT", + }, + { + title: "Verify", + heading: "Follow the operation to its outcome.", + 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: "This capture shows a recorded release, not live status.", + file: "verification-desktop.jpg", + alt: "GroundControl runtime image verification and public endpoint evidence", + href: "/docs/evidence", + link: "Inspect the recorded evidence", + }, +] as const; + +export default function ProductTour() { + const [active, setActive] = useState(0); + const buttons = useRef<(HTMLButtonElement | null)[]>([]); + const stage = stages[active]; + return ( +
+
+ {stages.map((item, index) => ( + + ))} +
+
+
+

Inside GroundControl

+

{stage.heading}

+

{stage.text}

+

{stage.fact}

+ + {stage.link} + +
+ +
+
+ ); +} diff --git a/app/components/SiteChrome.tsx b/app/components/SiteChrome.tsx index 06c2de5..7bb5f07 100644 --- a/app/components/SiteChrome.tsx +++ b/app/components/SiteChrome.tsx @@ -4,20 +4,43 @@ export function Header() { return (
- + GroundControl - - Connect ChatGPT + + Get started
); @@ -30,18 +53,20 @@ export function Footer() { GroundControl

- A Serendepify product. -
- Open source. Self-hosted. Yours. + Open-source operations for infrastructure you own. +
A Serendepify product.

- Built for infrastructure you own. + Safe, smooth, observable, agentic. ); } diff --git a/app/components/WorkloadModel.tsx b/app/components/WorkloadModel.tsx new file mode 100644 index 0000000..fc6a75b --- /dev/null +++ b/app/components/WorkloadModel.tsx @@ -0,0 +1,47 @@ +export default function WorkloadModel() { + return ( +
+
+ Example · one application, one deployment, several services +
+
+ Project + Weekend planner + Optional organization +
+
+
+ Deployment + weekend-production + On your VPS +
+
+ + webPublic application + + + apiApplication service + + + postgresPersistent data + + + redisCache / queue + +
+
+ Public route + app.example.com → web + Verified separately +
+
+

+ An OAuth grant selects the deployment. Operations act on that identity + and record their results. +

+
+ ); +} diff --git a/app/docs/[slug]/page.tsx b/app/docs/[slug]/page.tsx index 316b84f..885ade4 100644 --- a/app/docs/[slug]/page.tsx +++ b/app/docs/[slug]/page.tsx @@ -28,7 +28,15 @@ export default async function GuidePage({ const guide = guides[slug]; if (!guide) notFound(); const index = guideIndex.findIndex((g) => g.slug === slug); - const next = guideIndex[index + 1]; + const nextFor: Record = { + "after-install": "discovery", + publishing: "discovery", + "first-deployment": "agent-access", + "new-deployment": "agent-access", + }; + const next = nextFor[slug] + ? guideIndex.find((item) => item.slug === nextFor[slug]) + : guideIndex[index + 1]; return ( <>
diff --git a/app/docs/_components/DocsNav.tsx b/app/docs/_components/DocsNav.tsx index 941ee5e..d475890 100644 --- a/app/docs/_components/DocsNav.tsx +++ b/app/docs/_components/DocsNav.tsx @@ -1,52 +1,80 @@ "use client"; import Link from "next/link"; import { useState } from "react"; -import { guideIndex } from "@/content/guide-index"; +import { guideGroups, guideIndex } from "@/content/guide-index"; export default function DocsNav({ current = "" }: { current?: string }) { const [query, setQuery] = useState(""); - const matches = guideIndex.filter((g) => - `${g.title} ${g.description} ${g.keywords}` + const [expanded, setExpanded] = useState(false); + const matches = guideIndex.filter((guide) => + `${guide.title} ${guide.description} ${guide.keywords}` .toLowerCase() .includes(query.toLowerCase()), ); return ( ); diff --git a/app/docs/_components/EndpointBuilder.tsx b/app/docs/_components/EndpointBuilder.tsx index 10b1539..9c16c03 100644 --- a/app/docs/_components/EndpointBuilder.tsx +++ b/app/docs/_components/EndpointBuilder.tsx @@ -44,7 +44,7 @@ export default function EndpointBuilder() { {origin ? "Copy this into the MCP server URL field in ChatGPT." - : "Example only — replace gc.example.com with your own hostname."} + : "Example only. Replace gc.example.com with your own hostname."} ); diff --git a/app/docs/page.tsx b/app/docs/page.tsx index f8a0de2..11a60b3 100644 --- a/app/docs/page.tsx +++ b/app/docs/page.tsx @@ -1,11 +1,11 @@ import Link from "next/link"; import { Header, Footer } from "@/app/components/SiteChrome"; import DocsNav from "./_components/DocsNav"; -import { guideIndex } from "@/content/guide-index"; +import { guideGroups, guideIndex } from "@/content/guide-index"; export const metadata = { - title: "GroundControl docs — From VPS to connected agent", + title: "GroundControl docs | Understand, set up and operate", description: - "Follow the complete GroundControl installation, HTTPS publishing, ChatGPT plugin, OAuth consent and first deployment walkthrough.", + "Understand GroundControl, install it, discover and enroll workloads, connect ChatGPT through OAuth and MCP, and verify operations.", }; export default function DocsPage() { return ( @@ -15,55 +15,69 @@ export default function DocsPage() {
-

GROUNDCONTROL DOCS

-

From your VPS to your first agent operation.

+

The operator’s handbook

+

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

- Install the control plane, connect a workload, and give ChatGPT a - verified path to operate it. Commands, expected results and - recovery steps are all here. + Learn how GroundControl thinks about your infrastructure, then + follow the path that matches where you are.

-
+
- START FROM SCRATCH -

I have a VPS.

-

Install, claim and publish GroundControl.

- Start installation → + 01 / Start +

I need to install it.

+

Install, claim and connect the local host.

+ Installation guide → + + + 02 / Continue +

It’s installed. Now what?

+

Review discovery and choose your first application.

+ Follow the next steps → - ALREADY INSTALLED? -

Connect ChatGPT.

-

Add the MCP plugin and complete OAuth.

- Open the connection guide → + 03 / Connect +

My workload is ready.

+

Add ChatGPT and approve its deployment scope.

+ Connect your agent →
-
-
-

The complete walkthrough

- SET UP → OPERATE → MAINTAIN + + Before the commands +
+

Understand the GroundControl approach.

+

+ What is a deployment? How is a project different? What does an + agent actually control? +

- {guideIndex.map((g, i) => ( - - - {String(i + 1).padStart(2, "0")} + + + {guideGroups.map((group) => ( +
+
+

{group}

+ + {guideIndex.filter((g) => g.group === group).length} guides -
-

{g.title}

-

{g.description}

-
- - - ))} -
-
- What is being installed? -

- GroundControl runs on your infrastructure. ChatGPT connects to - your instance through MCP and OAuth. The public product site hosts - these guides; each installation has its own login, credentials and - grants. -

-
+
+ {guideIndex + .filter((g) => g.group === group) + .map((g) => ( + +
+

{g.title}

+

{g.description}

+
+ + + ))} +
+ ))}