Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions .github/workflows/techdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: TechDocs

# Keeps the Backstage TechDocs corpus in sync with the GitHub docs.
#
# How the sync works end to end:
# 1. catalog-info.yaml registers skill-pool in Backstage; the System carries
# `backstage.io/techdocs-ref: dir:.`, so Backstage builds TechDocs from
# ./mkdocs.yml on its own refresh schedule (builder: local) — no push
# needed from here.
# 2. docs/index.md is generated from README.md by scripts/sync-techdocs.py so
# the GitHub landing page and the TechDocs home never drift.
# 3. This workflow guarantees `main` always holds a buildable, in-sync docs
# tree (PR gate below), and can optionally pre-publish a built site to a
# TechDocs external storage bucket when one is configured.

on:
push:
branches: [main]
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'README.md'
- 'openapi.yaml'
- 'catalog-info.yaml'
- 'scripts/sync-techdocs.py'
- '.github/workflows/techdocs.yml'
pull_request:
branches: [main]
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'README.md'
- 'openapi.yaml'
- 'catalog-info.yaml'
- 'scripts/sync-techdocs.py'
- '.github/workflows/techdocs.yml'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
# ---------------------------------------------------------------------------
# Validate: README↔index sync + a real mkdocs build. Runs on PRs and main.
# No cloud credentials required.
# ---------------------------------------------------------------------------
build:
name: Build TechDocs
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install TechDocs MkDocs toolchain
run: pip install --disable-pip-version-check mkdocs-techdocs-core

- name: Verify docs/index.md is in sync with README.md
run: python3 scripts/sync-techdocs.py --check

- name: Build TechDocs site
run: mkdocs build --site-dir techdocs-site

- name: Upload built site
uses: actions/upload-artifact@v4
with:
name: techdocs-site
path: techdocs-site
retention-days: 14

# ---------------------------------------------------------------------------
# Publish: only on main, and only when an external TechDocs publisher is
# configured (set repo variable TECHDOCS_PUBLISH=true and the AWS bits below).
# A no-op otherwise — Backstage's local builder already serves from the repo.
# ---------------------------------------------------------------------------
publish:
name: Publish to TechDocs storage
needs: build
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' && vars.TECHDOCS_PUBLISH == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
id-token: write # for AWS OIDC, mirrors the deploy workflow
env:
ENTITY_NAMESPACE: default
ENTITY_KIND: system
ENTITY_NAME: skill-pool
TECHDOCS_S3_BUCKET_NAME: ${{ vars.TECHDOCS_S3_BUCKET_NAME }}
AWS_REGION: ${{ vars.AWS_REGION }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install toolchains
run: |
pip install --disable-pip-version-check mkdocs-techdocs-core
npm install -g @techdocs/cli

- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ vars.TECHDOCS_PUBLISH_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}

- name: Generate + publish TechDocs
run: |
techdocs-cli generate --no-docker --verbose
techdocs-cli publish \
--publisher-type awsS3 \
--storage-name "$TECHDOCS_S3_BUCKET_NAME" \
--entity "$ENTITY_NAMESPACE/$ENTITY_KIND/$ENTITY_NAME"
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,19 @@ Full subcommand list: `init`, `login`, `ensure`, `add` / `add-agent` / `add-comm
- **[`docs/lifecycle.md`](docs/lifecycle.md)** — embeddings, dependency resolution, decay
- **[`docs/tenancy.md`](docs/tenancy.md)** · **[`docs/sso.md`](docs/sso.md)** · **[`docs/scim.md`](docs/scim.md)** · **[`docs/theming.md`](docs/theming.md)** · **[`docs/enterprise.md`](docs/enterprise.md)**

### Backstage

This repo is annotated for [Backstage](https://backstage.io/): the Software
Catalog descriptor lives in [`catalog-info.yaml`](catalog-info.yaml) (a
`skill-pool` System with the server/web/cli Components, the REST `API`, and the
db/object-store/cache Resources), and the full `docs/` tree is published as
[TechDocs](https://backstage.io/docs/features/techdocs/) via
[`mkdocs.yml`](mkdocs.yml). The TechDocs home is generated from this README by
[`scripts/sync-techdocs.py`](scripts/sync-techdocs.py), and the
[`TechDocs` workflow](.github/workflows/techdocs.yml) keeps the two in sync on
every push. See [`docs/backstage.md`](docs/backstage.md) for the catalog model
and sync details.

## Bundled demo content

This portal ships ready to seed with 120+ curated skills, agents, and commands from [borghei/Claude-Skills](https://github.com/borghei/Claude-Skills) (License: MIT + Commons Clause — attribution preserved in each item's frontmatter). The set spans `code-reviewer`, `design-auditor`, `api-design-reviewer`, `rag-architect`, `ci-cd-pipeline-builder`, `terraform-patterns`, and dozens more. See the [Bundled Skills page](./docs/wiki/Bundled-Skills.md) for the full list.
Expand Down
163 changes: 154 additions & 9 deletions catalog-info.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,162 @@
# Auto-generated by olafkfreund/backstage catalog-onboard workflow.
# Hand-edit at will — the bot only fires for repos that lack this
# file entirely.
# Backstage Software Catalog descriptor for skill-pool.
# Registered as a Location pointing at this file on the default branch; the
# Backstage GitHub provider re-reads it on a schedule. TechDocs are built from
# ./mkdocs.yml (see the System entity's backstage.io/techdocs-ref annotation).
apiVersion: backstage.io/v1alpha1
kind: Component
kind: System
metadata:
name: skill_pool
description: "Self-hosted Claude Code skill/agent/command registry for teams — CLI, web UI, auto-bootstrap, retrospective capture."
name: skill-pool
title: skill-pool
description: Self-hosted, multi-tenant Claude Code skill/agent/command/plugin registry for teams.
annotations:
github.com/project-slug: olafkfreund/skill_pool
backstage.io/techdocs-ref: dir:.
backstage.io/source-location: url:https://github.com/olafkfreund/skill_pool/tree/main/
links:
- url: https://github.com/olafkfreund/skill_pool
title: Repository
icon: github
- url: https://github.com/olafkfreund/skill_pool/tree/main/docs/wiki
title: Wiki
icon: docs
tags:
- rust
- claude-code
- registry
- multi-tenant
spec:
owner: group:default/olafkfreund
domain: public

---
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: skill-pool-server
title: skill-pool server
description: Rust + Axum API server — REST surface, MCP JSON-RPC transport, plugin git endpoints, and the retrospective-capture daemon.
annotations:
github.com/project-slug: olafkfreund/skill_pool
tags: []
backstage.io/techdocs-ref: dir:.
backstage.io/source-location: url:https://github.com/olafkfreund/skill_pool/tree/main/server/
tags:
- rust
- axum
- sqlx
- tokio
spec:
type: service
lifecycle: production
owner: olafkfreund
domain: public
owner: group:default/olafkfreund
system: skill-pool
providesApis:
- skill-pool-api
dependsOn:
- resource:default/skill-pool-db
- resource:default/skill-pool-object-store
- resource:default/skill-pool-cache

---
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: skill-pool-web
title: skill-pool web portal
description: SvelteKit 2 + Svelte 5 web portal — catalog browse, Monaco editor, version history, drafts inbox, per-tenant theming, RBAC.
annotations:
github.com/project-slug: olafkfreund/skill_pool
backstage.io/source-location: url:https://github.com/olafkfreund/skill_pool/tree/main/web/
tags:
- sveltekit
- svelte
- tailwindcss
- typescript
spec:
type: website
lifecycle: production
owner: group:default/olafkfreund
system: skill-pool
consumesApis:
- skill-pool-api

---
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: skill-pool-cli
title: skill-pool CLI
description: Rust CLI (clap + reqwest) — detect/bootstrap, publish/install, capture, doctor, direnv + Claude Code hook installation.
annotations:
github.com/project-slug: olafkfreund/skill_pool
backstage.io/source-location: url:https://github.com/olafkfreund/skill_pool/tree/main/cli/
tags:
- rust
- clap
- cli
spec:
type: library
lifecycle: production
owner: group:default/olafkfreund
system: skill-pool
consumesApis:
- skill-pool-api

---
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: skill-pool-api
title: skill-pool REST API
description: Tenant-scoped REST + MCP + plugin-marketplace/git surface served by the skill-pool server.
annotations:
github.com/project-slug: olafkfreund/skill_pool
backstage.io/source-location: url:https://github.com/olafkfreund/skill_pool/tree/main/openapi.yaml
tags:
- rest
- openapi
spec:
type: openapi
lifecycle: production
owner: group:default/olafkfreund
system: skill-pool
definition:
$text: ./openapi.yaml

---
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: skill-pool-db
title: skill-pool database
description: Postgres 17 + pgvector 0.7 — catalog rows, tenancy, audit log, usage events, and description embeddings.
spec:
type: database
lifecycle: production
owner: group:default/olafkfreund
system: skill-pool

---
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: skill-pool-object-store
title: skill-pool object storage
description: opendal-backed bundle storage — S3 / GCS / Azure Blob / MinIO / filesystem from one DSN-style config.
spec:
type: object-storage
lifecycle: production
owner: group:default/olafkfreund
system: skill-pool

---
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: skill-pool-cache
title: skill-pool queue + cache
description: Optional Redis — async job queue with DLQ and read-through auth/marketplace cache. Fail-open; server stays up if Redis is down.
spec:
type: cache
lifecycle: production
owner: group:default/olafkfreund
system: skill-pool
66 changes: 66 additions & 0 deletions docs/backstage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Backstage integration

skill-pool is registered in the [Backstage](https://backstage.io/) Software
Catalog and ships its documentation as [TechDocs](https://backstage.io/docs/features/techdocs/)
built straight from this repository. This page describes the catalog model and
how the docs stay in sync.

## Catalog model

The catalog descriptor lives at [`catalog-info.yaml`](https://github.com/olafkfreund/skill_pool/blob/main/catalog-info.yaml)
in the repo root. It declares one `System` and the entities that make it up:

| Entity | Kind | Notes |
| --- | --- | --- |
| `skill-pool` | System | Umbrella; owns the TechDocs (`backstage.io/techdocs-ref: dir:.`), domain `public`. |
| `skill-pool-server` | Component (`service`) | Rust + Axum API; **provides** `skill-pool-api`; **depends on** the db, object store, and cache. |
| `skill-pool-web` | Component (`website`) | SvelteKit portal; **consumes** `skill-pool-api`. |
| `skill-pool-cli` | Component (`library`) | Rust CLI; **consumes** `skill-pool-api`. |
| `skill-pool-api` | API (`openapi`) | Definition tracked in [`openapi.yaml`](https://github.com/olafkfreund/skill_pool/blob/main/openapi.yaml). |
| `skill-pool-db` | Resource (`database`) | Postgres 17 + pgvector. |
| `skill-pool-object-store` | Resource (`object-storage`) | opendal bundle storage (S3/GCS/Azure/MinIO/fs). |
| `skill-pool-cache` | Resource (`cache`) | Optional Redis queue + cache. |

All entities are owned by `group:default/olafkfreund` and grouped under the
`skill-pool` system, so Backstage renders the full provides/consumes/depends-on
graph on the system page.

## How docs stay in sync

There are three moving parts, and together they make the sync hands-off:

1. **Registration + local builder.** Once `catalog-info.yaml` is registered as a
Location, Backstage re-reads it on a schedule. Because the System carries
`backstage.io/techdocs-ref: dir:.`, the TechDocs *local builder* rebuilds the
site from [`mkdocs.yml`](https://github.com/olafkfreund/skill_pool/blob/main/mkdocs.yml)
on `main` — no push from CI required.

2. **README → TechDocs home.** `README.md` is the single source of truth for the
project overview. [`scripts/sync-techdocs.py`](https://github.com/olafkfreund/skill_pool/blob/main/scripts/sync-techdocs.py)
regenerates `docs/index.md` from it, rewriting links for the TechDocs context
(repo-relative `docs/...` links are stripped; links to code outside `docs/`
become absolute GitHub URLs). Run it after editing the README:

```bash
python3 scripts/sync-techdocs.py # regenerate docs/index.md
python3 scripts/sync-techdocs.py --check # CI gate: fail if drifted
```

3. **CI gate + optional publish.** The
[`TechDocs` workflow](https://github.com/olafkfreund/skill_pool/blob/main/.github/workflows/techdocs.yml)
runs on every PR and on `main`: it checks the README↔index sync and does a
real `mkdocs build`, so broken docs never reach `main`. An optional
`publish` job pushes a pre-built site to an external TechDocs bucket (AWS S3)
when the repo variable `TECHDOCS_PUBLISH=true` and the publisher settings are
present; otherwise Backstage's local builder serves the docs directly.

## Building the docs locally

```bash
python3 -m venv .venv && . .venv/bin/activate
pip install mkdocs-techdocs-core
mkdocs serve # live preview on http://127.0.0.1:8000
mkdocs build # one-shot build into ./site
```

This mirrors exactly what the Backstage TechDocs builder runs.
Loading
Loading