A static, Astro-powered technology radar for publishing edition-based technology guidance to GitHub Pages.
The project has been simplified around a crisp static-site workflow: content lives in Astro content collections, the radar renders as a React/Visx island, and the site is built and deployed as static assets.
If you want the documentation front door first, start here:
The Flue docs use the Diátaxis model, with separate tutorial, how-to, reference, and explanation pages.
This repository currently focuses on:
- an Astro 6 web app in
apps/astro - MDX content for blips and editions
- edition-owned snapshot content in
apps/astro/src/content/editions/ - React 19 islands for interactive radar UI
- Visx-powered radar visualization
- Vanilla Extract styles
- fuzzy search with Fuse.js
- edition-aware static blip and quadrant routes
- snapshot-first related blip rendering on detail pages
- a Flue-powered edition and related-blips authoring package in
tooling/tech-radar-edition-agent - a draft related-blips GitHub Actions workflow for reviewable snapshot PRs
- GitHub Pages deployment
- Moon task orchestration
- Bun package management
Out of scope for the simplified version:
- legacy sidecar generators
- terminal UI tooling
- database-backed APIs
- server-side API endpoints for blips
- document freshness API endpoints
- full-stack intelligence services
For the full Flue docs map, start at the Flue landing page:
Direct links to the Flue doc set:
- Tutorial: Run your first local edition draft
- How to run the edition agent
- Flue reference
- Why the repo uses Flue this way
The Flue slice is intentionally narrow: it supports authoring reviewable edition drafts, provenance-aware narrative, and reviewable related-blip snapshot edits, while the published site remains static.
.
├── apps/
│ └── astro/ # Static Astro tech radar application
├── docs/
│ ├── README.md # Docs landing page
│ └── flue/ # Root-level Flue docs using Diátaxis
├── packages/
│ ├── biome-config/ # Shared Biome configuration package
│ └── tsconfig/ # Shared TypeScript configuration package
├── tooling/
│ └── tech-radar-edition-agent/
│ ├── .flue/ # Flue agents and roles for edition + relationship drafting
│ ├── .agents/ # Flue skill markdown
│ └── package.json # Flue tooling package scripts/deps
├── .github/workflows/ # GitHub Actions workflows
├── .make/ # Make target definitions
├── Makefile # Developer command shortcuts
├── package.json # Root Bun workspace configuration
└── README.md
The main app lives in apps/astro.
Important paths:
apps/astro/
├── src/
│ ├── components/ # Astro and React components
│ ├── content/ # Astro content collections
│ │ ├── blip/ # Technology blip MDX documents
│ │ └── editions/ # Edition-owned snapshot folders and blip state
│ ├── hooks/ # React hooks
│ ├── layouts/ # Astro layouts
│ ├── pages/ # Canonical and edition-scoped static routes
│ ├── stores/ # Nanostores state
│ ├── styles/ # Vanilla Extract styles
│ ├── types/ # Shared TypeScript domain types
│ └── utils/ # Build-time/content utilities and route helpers
├── astro.config.mts
├── content.config.ts
└── package.json
- Runtime/package manager: Bun
1.3.11 - Node.js:
22.12.0 - Monorepo tasks: Moon
- Framework: Astro
6 - UI islands: React
19 - Visualization: Visx
- Styling: Vanilla Extract
- State: Nanostores
- Search: Fuse.js
- Icons: Pixelarticons
- Validation/content schema: Astro content collections with Zod
- Tests: Vitest
- Deployment: GitHub Pages
Install:
- Node.js
22.12.0 - Bun
1.3.11
Then install dependencies:
bun installStart the Astro development server:
make astro-devOr run the Astro app directly:
cd apps/astro
bun run devmake help # Show available Make targets
make astro-dev # Start the Astro dev server
make astro-build # Build the Astro site through Moon
make check # Run Moon checks
make ci # Run Moon CI tasks
make test # Run Vitest once
make test-watch # Run Vitest in watch mode
make biome # Format the workspace with Biome
make commit # Create a Commitizen commit
make sherif # Run dependency/workspace checks with sherif
make code-owners # Sync CODEOWNERS from Moon metadatabun run moon:check
bun run moon:ci
bun run test
bun run test:watch
bun run prettier
bun run sherifFrom tooling/tech-radar-edition-agent:
bun run flue:dev # Start Flue local development mode with ../../.env
bun run flue:run # Run the edition agent once with the default local payload
bun run flue:run:relationships # Run the relationships agent once for the default edition payload
bun run generate:relationships # Execute the deterministic relationship-draft generator
bun run typecheck # Type-check the Flue tooling package
bun run test # Test deterministic relationship merge logicAt the workspace root, the Flue CLI is available through the installed dev dependency:
flue run edition --target node --id local-edition --payload '{}'
flue run relationships --target node --id local-related-blips --payload '{"editionId":"2026-05"}'From apps/astro:
bun run dev # Start Astro dev server
bun run build # Run astro check and astro build
bun run preview # Preview the static build
bun run test # Run Astro app testsThe radar is content-driven.
Blips live in:
apps/astro/src/content/blip/
Each blip is an MDX file with frontmatter such as:
---
id: "54"
name: "Azure"
ring: "Adopt"
quadrant: "Platforms"
tags: ["Cloud"]
authors: ["Author"]
hasAdr: false
description: "Cloud platform services from Microsoft."
created: "2023-01-02"
move:
- ["stay", "2025-04-09"]
---Today, ring and move still exist on canonical blips for compatibility with
blip detail/history views and canonical-route fallback when a blip is not
present in the latest edition snapshot. They are no longer the only source of
truth for the radar when edition snapshots are present.
Editions live in:
apps/astro/src/content/editions/
Each edition snapshot is represented by an index.mdx document with metadata
such as:
---
id: "2026-05"
number: 6
title: "Tech Radar Edition 6 - May 2026"
content: "Pilot edition snapshot used to derive movement from adjacent edition state."
date: "2026-05-05"
---Each edition snapshot folder contains:
- an
index.mdxdocument for edition metadata - a
blips/directory whose entries declare edition-owned ring/presence facts
Edition snapshot blips can also carry edition-local relatedBlips metadata for
the interactive radar. That keeps relationship hints aligned with the published
edition instead of treating them as globally timeless facts.
Current behavior:
- the radar homepage reads edition-owned snapshots from
src/content/editions/ - the edition landing pages under
/edition/[edition]read snapshotindex.mdxfiles only - the site generates both canonical routes and edition-specific routes for blips and quadrants
- canonical quadrant pages use the latest edition snapshot when one exists
- canonical blip pages use the latest edition snapshot when the requested blip exists there
- movement is derived by comparing adjacent edition snapshots
- some detail/history views still read legacy
ringandmovedata from the canonical blip model - related blips resolve from edition snapshot metadata first and fall back gracefully when absent
So the codebase is now partially aligned with the preferred edition model, but the migration is not fully complete yet.
The retired src/content/edition/ folder is no longer used by the app runtime
and can be deleted after content review.
The current direction for relatedBlips is:
- relationships shown on the radar should be edition-owned facts declared in
src/content/editions/*/blips/*.mdx - the published site should stay static; relationship inference happens during authoring, not at runtime
- humans remain the final reviewers of every relationship written to content
Implemented workflow:
- Flue reads the candidate edition blips, their rings, quadrants, ADR signals, notes, and any existing relationship graph.
- Flue proposes
relatedBlipsentries with:blipIdrelationshipType- a short
reason - optional
context - whether the link should be
bidirectional
- A deterministic merge layer validates ids, rejects duplicates, enforces confidence thresholds, and limits accepted relationships per source blip.
- Accepted proposals are written back as reviewable MDX changes inside the edition snapshot, not as hidden runtime state.
- Editors review, trim, rewrite, or reject those suggestions before publish.
- The GitHub Actions workflow at
.github/workflows/draft-related-blips.ymlcan upload review artifacts and open a draft PR automatically when changes exist.
Current repository entry points:
- local Flue run:
bun run flue:run:relationships - deterministic generator:
bun run generate:relationships - CI/draft PR automation:
.github/workflows/draft-related-blips.yml
Near-term roadmap:
- add consistency checks for missing reciprocal links and broken target IDs
- eventually let Flue refresh relationship drafts when a new edition is created or copied forward
The site deploys to GitHub Pages with .github/workflows/deploy.yml.
On pushes to main, the workflow:
- installs dependencies with Bun
- builds the Astro site from
apps/astro - uploads
apps/astro/dist - deploys the static artifact to GitHub Pages
Recommended pre-commit checks:
make check
make testFor focused Astro development, run from apps/astro:
bun run build
bun run testThe current direction is a static-only tech radar:
- content-first
- edition-oriented
- fast GitHub Pages deployment
- minimal runtime complexity
- no database or server API dependency
- no runtime sidecar services
- AI assistance limited to offline authoring/tooling where it produces reviewable artifacts
Future work should continue to simplify the domain model, especially edition movement. The preferred direction is:
A blip's ring and presence are edition-owned facts. Movement is derived by comparing adjacent edition snapshots.
That direction is already active in the radar edition pipeline, but not yet fully applied across every page and type in the app.
