Skip to content

Commit d5b2e69

Browse files
authored
Merge pull request #43 from fulll/feat/vitepress-docs
Feat/vitepress docs
2 parents 37afdce + c111fb3 commit d5b2e69

43 files changed

Lines changed: 3453 additions & 506 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/instructions/bug-fixing.instructions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ Add a one-line comment above the fix if the root cause is non-obvious:
7575

7676
- Branch name: `fix/<short-description>` (e.g. `fix/exclude-repos-with-org-prefix`).
7777
- Commit message: imperative mood, e.g. `Fix --exclude-repositories ignoring org-prefixed names`.
78+
- **All commits must be signed** (GPG or SSH). Configure once with `git config --global commit.gpgsign true`.
79+
Commits pushed via the GitHub API (Copilot Coding Agent, MCP tools) are automatically Verified by GitHub.
7880
- PR description:
7981
- Root cause explanation.
8082
- Steps to reproduce (before the fix).
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
applyTo: "docs/**"
3+
---
4+
5+
# Documentation — instructions for Copilot coding agent
6+
7+
Follow these conventions when writing or editing pages in the `docs/` directory.
8+
9+
## 1. Tool & rendering pipeline
10+
11+
- **Generator**: [VitePress](https://vitepress.dev/) — pure Markdown/MDX, no Vue components needed.
12+
- **Build**: `bun run docs:build` → static output in `docs/.vitepress/dist/`
13+
- **Dev server**: `bun run docs:dev``http://localhost:5173/github-code-search/`
14+
- **Deploy**: GitHub Actions workflow `.github/workflows/docs.yml` → GitHub Pages.
15+
16+
## 2. Brand guidelines
17+
18+
### Typography
19+
20+
| Role | Font | Usage |
21+
| ------------------------------ | ------------------------------------------- | ---------------------------- |
22+
| Primary (headings, short text) | **Poppins** (Aestetico Informal substitute) | Titles, taglines, callouts |
23+
| Accompanying (body text) | **Poppins** | Paragraphs, tables, lists |
24+
| Monospace | VitePress default (`--vp-font-family-mono`) | All code blocks |
25+
| Bureautic fallback | **Arial** | Email / Office contexts only |
26+
27+
Poppins is loaded from Google Fonts in `docs/.vitepress/theme/custom.css`. Do not add additional font imports.
28+
29+
### Colour palette
30+
31+
| Name | Hex | Role |
32+
| ---------- | --------- | ------------------------------------------------------------- |
33+
| Violet | `#9933FF` | Primary — links, buttons, accents (9.1:1 on white ✓ WCAG AAA) |
34+
| Yellow | `#FFCC33` | Highlight / soft background tints |
35+
| Dark blue | `#0000CC` | Secondary / hover state |
36+
| Light blue | `#66CCFF` | Decorative only — **never for text** (insufficient contrast) |
37+
| Green | `#CCFF33` | Decorative only |
38+
| Orange | `#FF9933` | Decorative / warning callouts |
39+
40+
Only override CSS variables in `docs/.vitepress/theme/custom.css`. Do not hard-code colour values inside Markdown.
41+
42+
### Dark / light mode
43+
44+
`appearance: 'force-auto'` in the VitePress config means the site follows `prefers-color-scheme` by default; the user can toggle manually. All colour tokens have dark-mode variants defined in `custom.css`. Never use `@media (prefers-color-scheme)` directly — rely on the `.dark` class selector that VitePress manages.
45+
46+
## 3. File structure & naming
47+
48+
```
49+
docs/
50+
├── index.md # Landing page (layout: home)
51+
├── getting-started/ # Onboarding section
52+
├── usage/ # Use-case-driven guides
53+
├── reference/ # Reference tables (CLI, shortcuts, API, env)
54+
└── architecture/ # C4 diagrams (L1 → L3 in Mermaid)
55+
```
56+
57+
- Use **kebab-case** for file names: `team-grouping.md`, not `teamGrouping.md`.
58+
- Every section must have an `index.md` that serves as the landing page for that section.
59+
- All pages must have a `# Title` as the first heading — VitePress uses it for the sidebar and `<title>`.
60+
61+
## 4. Writing style
62+
63+
- Write in **English**.
64+
- Lead each page with a one-sentence description of what the feature does and **when to use it**.
65+
- Prefer **use-case-driven content**: show a realistic CLI example first, explain options after.
66+
- Every code block must declare its language: ` ```bash `, ` ```typescript `, ` ```json `, etc.
67+
- Use admonitions for important caveats:
68+
```markdown
69+
::: warning GitHub API limit
70+
Code search is capped at 1 000 results. See [GitHub API limits](/reference/github-api-limits).
71+
:::
72+
```
73+
- Cross-link liberally using root-relative paths: `[GitHub API limits](/reference/github-api-limits)`.
74+
75+
## 5. Mermaid / C4 diagrams
76+
77+
- Use `vitepress-plugin-mermaid` — wrap diagrams in ` ```mermaid ` fenced blocks.
78+
- C4 diagrams use `C4Context`, `C4Container`, `C4Component` diagram types.
79+
- Include a prose introduction **before** every diagram explaining what level it represents.
80+
- Keep diagrams self-contained: label every node and every arrow.
81+
- Do not add inline CSS to Mermaid diagrams — the plugin handles dark/light theming automatically via `mermaid.theme: 'default'` in the config.
82+
83+
## 6. Versioning
84+
85+
- `docs/public/versions.json` tracks published major versions.
86+
- Format: `[{ "text": "v1 (latest)", "link": "/" }]`
87+
- A new entry is appended automatically by CI when a `vX.0.0` tag is pushed.
88+
- Do **not** manually edit `versions.json` outside of the release workflow.
89+
- When updating docs for a new major version, update the nav `text` field in `docs/.vitepress/config.mts`.
90+
91+
## 7. Validation checklist
92+
93+
Before opening a PR for any docs change:
94+
95+
```bash
96+
bun run docs:build # must complete without errors
97+
bun run format:check # oxfmt — no formatting diff
98+
```
99+
100+
- All internal links must resolve (VitePress reports dead links on build).
101+
- No new `bun run knip` violations (docs/\*\* is excluded but `package.json` changes are not).

.github/instructions/implement-feature.instructions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@ bun run build.ts # binary compiles without errors
6666

6767
- Branch name: `feat/<short-description>` (e.g. `feat/json-output-type`).
6868
- Commit message: imperative mood, e.g. `Add --output-type flag for JSON format`.
69+
- **All commits must be signed** (GPG or SSH). Configure once with `git config --global commit.gpgsign true`.
70+
Commits pushed via the GitHub API (Copilot Coding Agent, MCP tools) are automatically Verified by GitHub.
6971
- PR description: motivation, what changed, how to test manually.

.github/instructions/refactoring.instructions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,6 @@ bun run build.ts # binary compiles without errors
7575

7676
- Branch name: `refactor/<short-description>` (e.g. `refactor/extract-filter-module`).
7777
- Commit message: imperative mood, e.g. `Extract FilterStats helpers into render/filter.ts`.
78+
- **All commits must be signed** (GPG or SSH). Configure once with `git config --global commit.gpgsign true`.
79+
Commits pushed via the GitHub API (Copilot Coding Agent, MCP tools) are automatically Verified by GitHub.
7880
- PR description: what was restructured, why, and a note confirming no behaviour change.

.github/workflows/docs.yml

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
name: Docs
2+
3+
# Triggers:
4+
# - push to main touching docs/** or this workflow → deploy latest to GitHub Pages
5+
# - push of a major release tag (v2.0.0, v3.0.0 …) → versioned snapshot
6+
# - workflow_dispatch → manual deploy of latest
7+
on:
8+
push:
9+
branches: [main]
10+
paths:
11+
- "docs/**"
12+
- ".github/workflows/docs.yml"
13+
tags:
14+
# Glob pattern (not regex): matches v1.0.0, v2.0.0, v10.0.0 …
15+
- "v[0-9]*.0.0"
16+
workflow_dispatch:
17+
18+
# Deployment strategy: GitHub Actions Pages source (actions/deploy-pages — official, no third party).
19+
# • gh-pages branch = versioned snapshot STORAGE only (not served directly by Pages)
20+
# • Every deploy job assembles a combined artifact:
21+
# - latest docs built from main at the artifact root
22+
# - each vX/ snapshot from the gh-pages branch merged in
23+
# → single artifact deployed via actions/deploy-pages
24+
# • Snapshot job stores the built snapshot in gh-pages branch via plain git,
25+
# then pushes the updated versions.json to main (no [skip ci]) which
26+
# re-triggers the deploy job to include the new snapshot immediately.
27+
# Requires: Settings → Pages → Source: GitHub Actions.
28+
permissions:
29+
contents: write
30+
pages: write
31+
id-token: write
32+
33+
# Only one concurrent deployment for the same ref; cancel outdated runs.
34+
concurrency:
35+
group: docs-${{ github.ref }}
36+
cancel-in-progress: true
37+
38+
jobs:
39+
# ── Deploy (latest) ─────────────────────────────────────────────────────────
40+
# Assembles a combined Pages artifact:
41+
# 1. Builds the latest docs (base: /github-code-search/)
42+
# 2. Merges existing versioned snapshots from the gh-pages storage branch
43+
# into the artifact (docs/.vitepress/dist/vX/ for each stored version)
44+
# 3. Uploads the artifact and deploys via actions/deploy-pages
45+
# Requires: Settings → Pages → Source: GitHub Actions.
46+
deploy:
47+
name: Build and deploy docs
48+
if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch'
49+
runs-on: ubuntu-latest
50+
permissions:
51+
contents: read
52+
pages: write
53+
id-token: write
54+
environment:
55+
name: github-pages
56+
url: ${{ steps.deploy.outputs.page_url }}
57+
58+
steps:
59+
- name: Checkout
60+
uses: actions/checkout@v4.2.2
61+
with:
62+
# Needed to fetch the gh-pages storage branch for versioned snapshots.
63+
fetch-depth: 0
64+
65+
- name: Setup Bun
66+
uses: oven-sh/setup-bun@v2.1.2
67+
with:
68+
bun-version: latest
69+
70+
- name: Install dependencies
71+
run: bun install --frozen-lockfile
72+
73+
- name: Build latest docs
74+
run: bun run docs:build
75+
# Base URL: /github-code-search/ (default in config.mts)
76+
77+
- name: Merge versioned snapshots from gh-pages storage
78+
run: |
79+
set -euo pipefail
80+
if git ls-remote --heads origin gh-pages | grep -q gh-pages; then
81+
git fetch origin gh-pages
82+
# List only top-level entries that match v<integer> (e.g. v1, v2).
83+
# Using a pathspec glob and a strict regex avoids iterating over
84+
# unrelated files (.nojekyll, README, etc.) at the branch root.
85+
for entry in $(git ls-tree --name-only origin/gh-pages -- 'v[0-9]*'); do
86+
if echo "$entry" | grep -qE '^v[0-9]+$'; then
87+
echo "Merging snapshot: $entry"
88+
mkdir -p "docs/.vitepress/dist/$entry"
89+
git archive origin/gh-pages "$entry" | tar -x -C docs/.vitepress/dist/
90+
# Validate: warn and remove if the extracted directory is empty.
91+
if [ -z "$(ls -A "docs/.vitepress/dist/$entry" 2>/dev/null)" ]; then
92+
echo "Warning: snapshot '$entry' is empty after extraction — removing."
93+
rmdir "docs/.vitepress/dist/$entry"
94+
fi
95+
fi
96+
done
97+
else
98+
echo "No gh-pages branch yet — skipping snapshot merge"
99+
fi
100+
101+
- name: Upload Pages artifact
102+
uses: actions/upload-pages-artifact@v3.0.1
103+
with:
104+
path: docs/.vitepress/dist
105+
106+
- name: Deploy to GitHub Pages
107+
id: deploy
108+
uses: actions/deploy-pages@v4.0.5
109+
110+
# ── Snapshot (versioned) ────────────────────────────────────────────────────
111+
# Triggered by a major release tag (e.g. v2.0.0).
112+
# 1. Builds docs with a versioned base URL (/github-code-search/v2/).
113+
# 2. Stores the output in the gh-pages branch under /v2/ using plain git
114+
# (no third-party action). The gh-pages branch is storage only — Pages
115+
# still points to GitHub Actions; the deploy job merges snapshots in.
116+
# 3. Prepends the entry to versions.json on main WITHOUT [skip ci], which
117+
# re-triggers the deploy job so the new snapshot is live immediately.
118+
#
119+
# Convention: only tags matching vX.0.0 (major bumps) trigger a snapshot.
120+
# Patch and minor releases update the main docs in-place via the deploy job.
121+
snapshot:
122+
name: Snapshot versioned docs
123+
if: startsWith(github.ref, 'refs/tags/')
124+
runs-on: ubuntu-latest
125+
permissions:
126+
contents: write
127+
128+
steps:
129+
- name: Checkout
130+
uses: actions/checkout@v4.2.2
131+
with:
132+
# Full history needed to push to gh-pages and commit versions.json to main.
133+
fetch-depth: 0
134+
135+
- name: Extract major version from tag
136+
id: ver
137+
run: |
138+
# Validate that the tag strictly matches vX.0.0 before proceeding.
139+
# The workflow trigger filter (v[0-9]*.0.0) is the primary guard, but
140+
# this ensures the script fails fast if triggered with an unexpected ref.
141+
if ! echo "$GITHUB_REF_NAME" | grep -Eq '^v[0-9]+\.0\.0$'; then
142+
echo "Error: '$GITHUB_REF_NAME' does not match expected pattern vX.0.0" >&2
143+
exit 1
144+
fi
145+
MAJOR="${GITHUB_REF_NAME%%.*}" # e.g. v2 from v2.0.0
146+
echo "major=$MAJOR" >> "$GITHUB_OUTPUT"
147+
148+
- name: Setup Bun
149+
uses: oven-sh/setup-bun@v2.1.2
150+
with:
151+
bun-version: latest
152+
153+
- name: Install dependencies
154+
run: bun install --frozen-lockfile
155+
156+
- name: Build versioned snapshot
157+
env:
158+
# config.mts reads VITEPRESS_BASE when set; falls back to /github-code-search/
159+
VITEPRESS_BASE: /github-code-search/${{ steps.ver.outputs.major }}/
160+
run: bun run docs:build
161+
162+
- name: Store snapshot in gh-pages branch
163+
run: |
164+
set -euo pipefail
165+
MAJOR="${{ steps.ver.outputs.major }}"
166+
git config user.name "github-actions[bot]"
167+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
168+
# Set up the gh-pages worktree (create orphan branch if it doesn't exist yet).
169+
if git ls-remote --heads origin gh-pages | grep -q gh-pages; then
170+
git fetch origin gh-pages
171+
git worktree add /tmp/gh-pages-storage origin/gh-pages
172+
else
173+
git worktree add --orphan -b gh-pages /tmp/gh-pages-storage
174+
touch /tmp/gh-pages-storage/.nojekyll # prevent Jekyll processing
175+
fi
176+
# Copy the built snapshot into its versioned directory.
177+
rm -rf "/tmp/gh-pages-storage/$MAJOR"
178+
cp -r docs/.vitepress/dist "/tmp/gh-pages-storage/$MAJOR"
179+
# Commit and push.
180+
cd /tmp/gh-pages-storage
181+
git add .
182+
git diff --staged --quiet || git commit -m "docs: store snapshot $MAJOR [skip ci]"
183+
git push origin gh-pages
184+
# Explicit cleanup — belt-and-suspenders even on ephemeral runners.
185+
git worktree remove /tmp/gh-pages-storage
186+
187+
- name: Prepend new version entry to versions.json
188+
run: |
189+
MAJOR="${{ steps.ver.outputs.major }}"
190+
LINK="/${MAJOR}/"
191+
# Idempotent — skip if the entry already exists.
192+
jq --arg text "$MAJOR" --arg link "$LINK" \
193+
'if any(.[]; .link == $link) then . else [{"text": $text, "link": $link}] + . end' \
194+
docs/public/versions.json > /tmp/versions_new.json
195+
mv /tmp/versions_new.json docs/public/versions.json
196+
197+
- name: Commit versions.json to main
198+
uses: stefanzweifel/git-auto-commit-action@v5.0.1
199+
with:
200+
# No [skip ci] — the push to main matches paths: docs/** and re-triggers
201+
# the deploy job, which merges the new snapshot into the Pages artifact.
202+
commit_message: "docs: add ${{ steps.ver.outputs.major }} to versions.json"
203+
file_pattern: docs/public/versions.json
204+
branch: main

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ dist/
33
coverage/
44
.env
55
*.local
6+
7+
# VitePress
8+
docs/.vitepress/cache
9+
docs/.vitepress/dist

AGENTS.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,49 @@ src/
112112
- When creating a new module that contains pure functions, create a companion `<module>.test.ts`.
113113
- Tests must be self-contained: no network calls, no filesystem side effects.
114114

115+
## Git conventions
116+
117+
### Signed commits (required)
118+
119+
All commits to this repository **must be cryptographically signed**. Unsigned commits will be rejected by branch protection rules.
120+
121+
**For local commits** — configure GPG or SSH signing once:
122+
123+
```bash
124+
# Recommended: sign every commit automatically
125+
git config --global commit.gpgsign true
126+
127+
# Or sign a single commit manually
128+
git commit -S -m "feat: my change"
129+
```
130+
131+
Verify your setup:
132+
133+
```bash
134+
git log --show-signature -1 # should show "Good signature from …"
135+
```
136+
137+
**For agent-created commits** — ensure the agent runs a local `git commit -S` so the local GPG/SSH key is used and the commit bears the developer's own verified signature. This is the **required approach** in this repository.
138+
139+
> ⚠️ **Do NOT use MCP REST API push tools** (`mcp_github_push_files`, `mcp_github_create_or_update_file`) to create commits in this repo.
140+
> Those tools push files via the GitHub REST API and create commits signed by GitHub's own key — not the developer's personal key. While GitHub marks them as "Verified", they do not carry the developer's identity.
141+
> **Always commit locally via `git commit -S` (or with `commit.gpgsign = true`)** and push with `git push`.
142+
143+
### Branch & commit conventions
144+
145+
| Branch type | Pattern | Example |
146+
| ------------- | ------------------------------ | ----------------------------------- |
147+
| Feature | `feat/<short-description>` | `feat/json-output-type` |
148+
| Bug fix | `fix/<short-description>` | `fix/exclude-repos-with-org-prefix` |
149+
| Refactoring | `refactor/<short-description>` | `refactor/extract-filter-module` |
150+
| Documentation | `docs/<short-description>` | `docs/25-init-vitepress` |
151+
152+
Commit messages use **imperative mood**: `Add …`, `Fix …`, `Extract …`, not `Added` or `Fixing`.
153+
154+
For epics spanning multiple PRs, create a long-lived **feature branch** (`feat/<epic-name>`) and merge each sub-issue PR into it. Open a final PR from the feature branch into `main` when the epic is complete.
155+
156+
---
157+
115158
## Development notes
116159

117160
- **TypeScript throughout** — no `.js` files in `src/`.

0 commit comments

Comments
 (0)