From 1f0a4e0c7cd367b951aa9201b5018e7ad8233d60 Mon Sep 17 00:00:00 2001 From: Francois Lanusse Date: Tue, 29 Sep 2026 20:02:58 -0700 Subject: [PATCH 1/4] Serve the docs from the root, with a project selector The documentation now lives at the site root instead of /docs, and the empty landing page is gone: `/` is the stack's introduction. Content is organised as Fumadocs root folders, one per project, which Glass shows as a selector at the top of the sidebar: - Lightcone Stack (a `(stack)` folder group, so its pages sit at the root): stack-wide introduction, and later the quickstart and guides - Lightcone CLI, Agent Skills, Lightcone Lab and MySTRA: an overview of each component for now, linking to its current documentation until it is migrated here Each project names a Lucide icon in its meta.json, resolved by the loader's lucideIconsPlugin. The docs layout builds the tabs on the server, as fumadocs.dev does, because the default transform stretches icons to fill their box, which only suits the Docs layout. The ASTRA specification stays on astra-spec.org, linked from the stack's sidebar and introduction. The theming sample page is removed. Co-Authored-By: Claude Opus 5.5 --- app/{docs => (docs)}/[[...slug]]/page.tsx | 4 +- app/(docs)/layout.tsx | 18 ++++++ app/(home)/layout.tsx | 6 -- app/(home)/page.tsx | 16 ----- app/docs/layout.tsx | 11 ---- content/docs/(stack)/index.mdx | 38 ++++++++++++ content/docs/(stack)/meta.json | 7 +++ content/docs/agent-skills/index.mdx | 17 ++++++ content/docs/agent-skills/meta.json | 7 +++ content/docs/index.mdx | 13 ---- content/docs/lightcone-cli/index.mdx | 17 ++++++ content/docs/lightcone-cli/meta.json | 7 +++ content/docs/lightcone-lab/index.mdx | 16 +++++ content/docs/lightcone-lab/meta.json | 7 +++ content/docs/meta.json | 3 + content/docs/mystra/index.mdx | 14 +++++ content/docs/mystra/meta.json | 7 +++ content/docs/test.mdx | 72 ----------------------- lib/shared.ts | 2 +- lib/source.ts | 4 +- 20 files changed, 164 insertions(+), 122 deletions(-) rename app/{docs => (docs)}/[[...slug]]/page.tsx (91%) create mode 100644 app/(docs)/layout.tsx delete mode 100644 app/(home)/layout.tsx delete mode 100644 app/(home)/page.tsx delete mode 100644 app/docs/layout.tsx create mode 100644 content/docs/(stack)/index.mdx create mode 100644 content/docs/(stack)/meta.json create mode 100644 content/docs/agent-skills/index.mdx create mode 100644 content/docs/agent-skills/meta.json delete mode 100644 content/docs/index.mdx create mode 100644 content/docs/lightcone-cli/index.mdx create mode 100644 content/docs/lightcone-cli/meta.json create mode 100644 content/docs/lightcone-lab/index.mdx create mode 100644 content/docs/lightcone-lab/meta.json create mode 100644 content/docs/meta.json create mode 100644 content/docs/mystra/index.mdx create mode 100644 content/docs/mystra/meta.json delete mode 100644 content/docs/test.mdx diff --git a/app/docs/[[...slug]]/page.tsx b/app/(docs)/[[...slug]]/page.tsx similarity index 91% rename from app/docs/[[...slug]]/page.tsx rename to app/(docs)/[[...slug]]/page.tsx index da06a07..8789942 100644 --- a/app/docs/[[...slug]]/page.tsx +++ b/app/(docs)/[[...slug]]/page.tsx @@ -13,7 +13,7 @@ import type { Metadata } from 'next'; import { createRelativeLink } from 'fumadocs-ui/mdx'; import { getPageImageUrl, getPageMarkdownUrl, gitConfig } from '@/lib/shared'; -export default async function Page(props: PageProps<'/docs/[[...slug]]'>) { +export default async function Page(props: PageProps<'/[[...slug]]'>) { const params = await props.params; const page = source.getPage(params.slug); if (!page) notFound(); @@ -48,7 +48,7 @@ export async function generateStaticParams() { return source.generateParams(); } -export async function generateMetadata(props: PageProps<'/docs/[[...slug]]'>): Promise { +export async function generateMetadata(props: PageProps<'/[[...slug]]'>): Promise { const params = await props.params; const page = source.getPage(params.slug); if (!page) notFound(); diff --git a/app/(docs)/layout.tsx b/app/(docs)/layout.tsx new file mode 100644 index 0000000..7fe0883 --- /dev/null +++ b/app/(docs)/layout.tsx @@ -0,0 +1,18 @@ +import { source } from '@/lib/source'; +import { GlassLayout } from 'fumadocs-ui/layouts/glass'; +import { getLayoutTabs } from 'fumadocs-ui/layouts/shared'; +import { baseOptions } from '@/lib/layout.shared'; + +export default function Layout({ children }: LayoutProps<'/'>) { + const tree = source.getPageTree(); + // The project selector. The default transform stretches each icon to fill its + // box, which suits the Docs layout's tabs but not Glass's dropdown, so the + // icons are kept as the loader renders them (as fumadocs.dev does). + const tabs = getLayoutTabs(tree, { transform: (option) => option }); + + return ( + + {children} + + ); +} diff --git a/app/(home)/layout.tsx b/app/(home)/layout.tsx deleted file mode 100644 index 77379fa..0000000 --- a/app/(home)/layout.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { HomeLayout } from 'fumadocs-ui/layouts/home'; -import { baseOptions } from '@/lib/layout.shared'; - -export default function Layout({ children }: LayoutProps<'/'>) { - return {children}; -} diff --git a/app/(home)/page.tsx b/app/(home)/page.tsx deleted file mode 100644 index c936084..0000000 --- a/app/(home)/page.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import Link from 'next/link'; - -export default function HomePage() { - return ( -
-

Hello World

-

- You can open{' '} - - /docs - {' '} - and see the documentation. -

-
- ); -} diff --git a/app/docs/layout.tsx b/app/docs/layout.tsx deleted file mode 100644 index 3f821cd..0000000 --- a/app/docs/layout.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { source } from '@/lib/source'; -import { GlassLayout } from 'fumadocs-ui/layouts/glass'; -import { baseOptions } from '@/lib/layout.shared'; - -export default function Layout({ children }: LayoutProps<'/docs'>) { - return ( - - {children} - - ); -} diff --git a/content/docs/(stack)/index.mdx b/content/docs/(stack)/index.mdx new file mode 100644 index 0000000..9df0783 --- /dev/null +++ b/content/docs/(stack)/index.mdx @@ -0,0 +1,38 @@ +--- +title: Introduction +description: From research question to reproducible result. +--- + +import { Bot, FlaskConical, PenLine, Terminal } from 'lucide-react'; + +The Lightcone Research Stack is Lightcone Research's tooling for research analyses described +with [ASTRA](https://astra-spec.org/latest/). You describe an analysis in an `astra.yaml` +specification; the stack runs it, keeps every result tied to the choices that produced it, and +carries it through to a written report. + + + This site is being reorganised around the whole stack. A quickstart and guides are on their way; + until then, each component's section links to its current documentation. + + +## Components + +Choose a component from the selector at the top of the sidebar, or start here: + + + } title="Lightcone CLI" href="/lightcone-cli"> + The `lc` command: runs an analysis and records the provenance of every output. + + } title="Agent Skills" href="/agent-skills"> + Plugins that teach coding agents to scope, build and run ASTRA analyses. + + } title="Lightcone Lab" href="/lightcone-lab"> + A JupyterLab workbench for exploring an ASTRA project. + + } title="MySTRA" href="/mystra"> + Write reports that reference an analysis instead of copying its results. + + + +The ASTRA specification and the `astra` command have their own documentation at +[astra-spec.org](https://astra-spec.org/latest/). diff --git a/content/docs/(stack)/meta.json b/content/docs/(stack)/meta.json new file mode 100644 index 0000000..0fcddf0 --- /dev/null +++ b/content/docs/(stack)/meta.json @@ -0,0 +1,7 @@ +{ + "title": "Lightcone Stack", + "description": "Quickstart and guides for the whole stack", + "icon": "Layers", + "root": true, + "pages": ["index", "---Related---", "external:[ASTRA specification](https://astra-spec.org/latest/)"] +} diff --git a/content/docs/agent-skills/index.mdx b/content/docs/agent-skills/index.mdx new file mode 100644 index 0000000..f9f904a --- /dev/null +++ b/content/docs/agent-skills/index.mdx @@ -0,0 +1,17 @@ +--- +title: Overview +description: Plugins that teach coding agents to work with the Lightcone stack. +--- + +Agent Skills are plugins, in the open Agent Skills format, that teach coding agents such as +Claude Code and Codex to work with the stack. + +- The **astra** plugin covers writing `astra.yaml` specifications, and validates them as the agent + saves. +- The **lightcone** plugin includes astra, and adds guidance for scoping, running, reporting on + and publishing a Lightcone project. + + + This section is being migrated. Until then, see the current + [Agent Skills documentation](https://lightconeresearch.github.io/agent-skills/latest/). + diff --git a/content/docs/agent-skills/meta.json b/content/docs/agent-skills/meta.json new file mode 100644 index 0000000..d483d7d --- /dev/null +++ b/content/docs/agent-skills/meta.json @@ -0,0 +1,7 @@ +{ + "title": "Agent Skills", + "description": "Plugins that teach coding agents the stack", + "icon": "Bot", + "root": true, + "pages": ["index"] +} diff --git a/content/docs/index.mdx b/content/docs/index.mdx deleted file mode 100644 index 1ede18e..0000000 --- a/content/docs/index.mdx +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Hello World -description: Your first document ---- - -Welcome to the docs! You can start writing documents in `/content/docs`. - -## What is Next? - - - - - diff --git a/content/docs/lightcone-cli/index.mdx b/content/docs/lightcone-cli/index.mdx new file mode 100644 index 0000000..132500f --- /dev/null +++ b/content/docs/lightcone-cli/index.mdx @@ -0,0 +1,17 @@ +--- +title: Overview +description: The lc command runs an ASTRA analysis and records the provenance of every output. +--- + +The Lightcone CLI, `lc`, is the execution layer of the stack. It turns an `astra.yaml` +specification into outputs produced in a sandbox and committed with git and git-annex, with +provenance recorded for each one. It runs every variant of an analysis (its universes) and reuses +outputs that are already up to date. + +`lc` is built to be driven by people and coding agents alike: its commands never prompt, and most +of them report in JSON with `--json`. + + + This section is being migrated. Until then, see the current + [Lightcone CLI documentation](https://lightconeresearch.github.io/lightcone-cli/latest/). + diff --git a/content/docs/lightcone-cli/meta.json b/content/docs/lightcone-cli/meta.json new file mode 100644 index 0000000..a2363ad --- /dev/null +++ b/content/docs/lightcone-cli/meta.json @@ -0,0 +1,7 @@ +{ + "title": "Lightcone CLI", + "description": "The lc command: run analyses with provenance", + "icon": "Terminal", + "root": true, + "pages": ["index"] +} diff --git a/content/docs/lightcone-lab/index.mdx b/content/docs/lightcone-lab/index.mdx new file mode 100644 index 0000000..fc12a12 --- /dev/null +++ b/content/docs/lightcone-lab/index.mdx @@ -0,0 +1,16 @@ +--- +title: Overview +description: A JupyterLab workbench for exploring and working on ASTRA projects. +--- + +Lightcone Lab is a JupyterLab extension that turns JupyterLab into a workbench for ASTRA projects: +a project home, an inventory of the analysis and its pipeline, provenance and version comparison, +comments, project-aware agents, and a viewer for the project's MySTRA report. + +It runs as a browser-only workbench, or with its `full` extra for the features that need the +Jupyter server, such as running the Lightcone CLI and agents. + + + This section is being written. Until then, see the + [Lightcone Lab README](https://github.com/LightconeResearch/jupyterlab-lightcone). + diff --git a/content/docs/lightcone-lab/meta.json b/content/docs/lightcone-lab/meta.json new file mode 100644 index 0000000..7345319 --- /dev/null +++ b/content/docs/lightcone-lab/meta.json @@ -0,0 +1,7 @@ +{ + "title": "Lightcone Lab", + "description": "A JupyterLab workbench for ASTRA projects", + "icon": "FlaskConical", + "root": true, + "pages": ["index"] +} diff --git a/content/docs/meta.json b/content/docs/meta.json new file mode 100644 index 0000000..8c385b6 --- /dev/null +++ b/content/docs/meta.json @@ -0,0 +1,3 @@ +{ + "pages": ["(stack)", "lightcone-cli", "agent-skills", "lightcone-lab", "mystra"] +} diff --git a/content/docs/mystra/index.mdx b/content/docs/mystra/index.mdx new file mode 100644 index 0000000..f0b326b --- /dev/null +++ b/content/docs/mystra/index.mdx @@ -0,0 +1,14 @@ +--- +title: Overview +description: A MyST plugin for reports that reference an ASTRA analysis instead of copying it. +--- + +MySTRA is a plugin for [MyST](https://mystmd.org/) Markdown. A report written with it refers to +the parts of an ASTRA analysis, such as its decisions, results and values, by path instead of +copying them, so the report stays in step with the analysis. Projects created with `lc init` are +already set up to use it. + + + This section is being migrated. Until then, see the current + [MySTRA documentation](https://lightconeresearch.github.io/MySTRA/). + diff --git a/content/docs/mystra/meta.json b/content/docs/mystra/meta.json new file mode 100644 index 0000000..6447b2c --- /dev/null +++ b/content/docs/mystra/meta.json @@ -0,0 +1,7 @@ +{ + "title": "MySTRA", + "description": "Reference ASTRA analyses in MyST reports", + "icon": "PenLine", + "root": true, + "pages": ["index"] +} diff --git a/content/docs/test.mdx b/content/docs/test.mdx deleted file mode 100644 index 490c79e..0000000 --- a/content/docs/test.mdx +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Components -description: A sample of the elements documentation pages are built from. ---- - -Running prose sets the tone of every page. It carries [inline links](https://lightconeresearch.org), -`inline code`, **strong emphasis** and _italics_, so a long paragraph should read -comfortably from the first line to the last, with a measure that never gets too wide. - -## Lists - -- Describe the analysis in an `astra.yaml` specification. -- Validate it with the `astra` CLI. -- Run it with `lc run`, which records provenance as it goes. - -1. Install the stack. -2. Initialise a project. -3. Materialise the outputs. - -## Callouts - -A note, for context the reader may want. - -A warning, for something that can go wrong. - -An error, for something that will go wrong. - -A success, for confirming a result. - -## Code Block - -```python title="analysis.py" -from pathlib import Path - -def load(path: Path) -> list[str]: - """Read one record per line.""" - return path.read_text().splitlines() -``` - -```bash -lc init my-analysis -lc run --universe baseline -``` - -## Tabs - -```bash tab="uv" -uv tool install lightcone-cli -``` - -```bash tab="pip" -pip install lightcone-cli -``` - -## Table - -| Command | What it does | -| --- | --- | -| `lc init` | Scaffolds a project | -| `lc run` | Executes the analysis | -| `lc status` | Shows what is up to date | - -### A third-level heading - -Headings at every level use the brand's heading face. - -## Cards - - - - - diff --git a/lib/shared.ts b/lib/shared.ts index eb50276..55e57e5 100644 --- a/lib/shared.ts +++ b/lib/shared.ts @@ -1,7 +1,7 @@ import { createGetUrl } from 'fumadocs-core/source'; export const appName = 'Lightcone Research Stack'; -export const docsRoute = '/docs'; +export const docsRoute = '/'; export const docsImageRoute = '/og/docs'; export const docsContentRoute = '/llms.mdx/docs'; diff --git a/lib/source.ts b/lib/source.ts index 058f5b2..21b296c 100644 --- a/lib/source.ts +++ b/lib/source.ts @@ -1,4 +1,5 @@ import { llms, loader } from 'fumadocs-core/source'; +import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons'; import { docsContentRoute, docsImageRoute, docsRoute } from './shared'; import { defineDocs } from 'fumadocs-mdx/macro'; import { metaSchema, pageSchema } from 'fumadocs-core/source/schema'; @@ -20,7 +21,8 @@ const docs = defineDocs({ export const source = loader({ baseUrl: docsRoute, source: docs.toFumadocsSource(), - plugins: [], + // Resolves `icon` names in frontmatter and meta.json, such as each project's icon in the selector. + plugins: [lucideIconsPlugin()], }); export const docsLlms = llms(source, { From a72a2d11441de2f21742f06b9aaccaf21baf53f2 Mon Sep 17 00:00:00 2001 From: Francois Lanusse Date: Tue, 29 Sep 2026 20:07:25 -0700 Subject: [PATCH 2/4] Set page subtitles in Slate Blue The brand guidelines put a small-caps Slate Blue label under gold titles. Fumadocs colours the page description with its general muted colour, so the page's DocsDescription gets the brand's slate colour directly, leaving other secondary text unchanged. Co-Authored-By: Claude Opus 5.5 --- app/(docs)/[[...slug]]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/(docs)/[[...slug]]/page.tsx b/app/(docs)/[[...slug]]/page.tsx index 8789942..797d5f9 100644 --- a/app/(docs)/[[...slug]]/page.tsx +++ b/app/(docs)/[[...slug]]/page.tsx @@ -24,7 +24,7 @@ export default async function Page(props: PageProps<'/[[...slug]]'>) { return ( {page.data.title} - {page.data.description} + {page.data.description}
Date: Tue, 29 Sep 2026 20:09:06 -0700 Subject: [PATCH 3/4] Use Blue Ink for muted text Fumadocs' muted foreground (inactive sidebar links, callout and card text, descriptions, the search placeholder) now takes the brand's scheme-aware Blue Ink instead of its subtle mushroom tone. Co-Authored-By: Claude Opus 5.5 --- app/lightcone.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lightcone.css b/app/lightcone.css index fd2e45c..fe3d8e4 100644 --- a/app/lightcone.css +++ b/app/lightcone.css @@ -19,7 +19,7 @@ --color-fd-background: var(--lc-color-surface); --color-fd-foreground: var(--lc-color-text); --color-fd-muted: var(--lc-color-surface-muted); - --color-fd-muted-foreground: var(--lc-color-text-subtle); + --color-fd-muted-foreground: var(--lc-color-blue-ink); --color-fd-popover: var(--lc-color-canvas); --color-fd-popover-foreground: var(--lc-color-text); --color-fd-card: var(--lc-color-canvas); From a469af740b86824dcfb53a3f7b395fb3f77dc787 Mon Sep 17 00:00:00 2001 From: Francois Lanusse Date: Tue, 29 Sep 2026 20:11:27 -0700 Subject: [PATCH 4/4] Use the brand's muted text role for muted text The brand's --lc-color-text-muted is Blue Ink in the light scheme and a warm light grey in the dark scheme, so muted text follows the brand's own dark-scheme choice rather than a lightened Blue Ink. Co-Authored-By: Claude Opus 5.5 --- app/lightcone.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lightcone.css b/app/lightcone.css index fe3d8e4..731c9ce 100644 --- a/app/lightcone.css +++ b/app/lightcone.css @@ -19,7 +19,7 @@ --color-fd-background: var(--lc-color-surface); --color-fd-foreground: var(--lc-color-text); --color-fd-muted: var(--lc-color-surface-muted); - --color-fd-muted-foreground: var(--lc-color-blue-ink); + --color-fd-muted-foreground: var(--lc-color-text-muted); --color-fd-popover: var(--lc-color-canvas); --color-fd-popover-foreground: var(--lc-color-text); --color-fd-card: var(--lc-color-canvas);