# docs-site/

Static GitHub Pages site for the ASB Skill Collections project. Pure HTML +
vanilla JS. No build step, no npm, no backend. Pages load no script, style or
font from another host: lunr.js is vendored under `vendor/` (MIT, licence in
`vendor/LICENSE-lunr.txt`) and the stylesheet uses locally installed or system
fonts.

## Pages

| File | What it shows |
| ---- | ------------- |
| `index.html` (+ `app.js`) | Catalogue of collections + new-release banner + ranked contributor leaderboard |
| `collections.html` (+ `collections.js`) | Browse a collection's skills, composite workflows (super-skills), and tools, with filters + per-item GitHub view/edit/suggest links |
| `corpus.html` (+ `corpus.js`) | Browse all source papers across collections, with filters |
| `paper.html` (+ `paper.js`) | Per-paper review: skills, tools, claims; verify/flag actions |
| `contribute.html` (+ `contribute.js`) | Package an anonymized skill/workflow improvement → pre-filled GitHub issue (mirrors `scripts/make_improvement_report.py`) |
| `propose.html` | Form to propose a new paper (submits via GitHub Issue URL params) |
| `search.html` (+ `search.js`) | Full-text search across papers / skills / tools (lunr.js) |

All write actions (verify, flag, propose, contribute) round-trip through GitHub
Issues or Pull Requests via prefilled URL params — no server.

`collections.html` reads each collection's machine indexes directly from GitHub
raw (`collections/<slug>/v<N>/skills_index.json`, `…/workflows/workflows_index.json`,
`…/tools_index.json`) — so it needs no build step and stays current with `main`.
`contribute.html` scrubs file paths, emails, IPs, and secrets in the browser
before building the issue body (same rules as the Python CLI).

## Search index

`search.html` performs client-side full-text search via
[lunr.js](https://lunrjs.com/) (2.3.9, vendored as `vendor/lunr-2.3.9.js`)
against a pre-built index at `docs-site/search_index.json`. The index is
checked into the repo so the site works offline / on Pages without any CI
step.

### Regenerating `search_index.json`

Run after any promote (i.e. anytime `collections/**` or `staged-collections/**`
changes in a way that affects papers, SKILL.md frontmatter, or tool YAMLs):

```bash
python3 docs-site/build_search_index.py
```

Requirements: Python 3.9+ and `PyYAML` (already pinned in `pyproject.toml`).
The script walks the local filesystem from the repo root — no network access
is needed.

Stdout prints a one-line summary like:

```
Indexed 5 papers, 106 skills, 38 tools across 1 collections. Wrote docs-site/search_index.json (327,303 bytes).
```

Commit the updated `search_index.json` alongside the content change.

The build records no timestamp and walks every tree in sorted path order, so
two builds of the same tree are byte-identical. The `search-index` job in
`.github/workflows/validate.yml` relies on that: it rebuilds the index with
`--output "$RUNNER_TEMP/search_index.json"` and fails when the result differs
from the committed file. To check locally without touching the committed file:

```bash
python docs-site/build_search_index.py --output /tmp/search_index.json
cmp /tmp/search_index.json docs-site/search_index.json
```

### Schema

The index is a single JSON object with the shape:

```json
{
  "schema_version": "0.1",
  "collections": ["metabolomics/v1", ...],
  "collection_status": {"metabolomics/v1": "staged", "metabolomics/v2": "released", ...},
  "papers": [{"doi": "...", "title": "...", "rationale": "...", "collection": "...",
              "status": "...", "access_type": "...", "derived_skills": N,
              "derived_tools": M, "search_text": "..."}, ...],
  "skills": [{"name": "...", "description": "...", "when_to_use_negative": "...",
              "edam_topics": [...], "collection": "...", "summary": "...",
              "source_dois": [...], "md_path": "...", "search_text": "..."}, ...],
  "tools":  [{"slug": "...", "name": "...", "source_paper_repos": [...],
              "license_spdx": "...", "evidence_text": "...", "collection": "...",
              "source_doi": "...", "yaml_path": "...", "search_text": "..."}, ...]
}
```

`collection_status` says which collections are released (served by the plugin
marketplace) and which are staged, with the rule `scripts/regen_catalogue.py`
applies to `catalogue.jsonld`; the search page labels results from staged
collections. `search_text` is the concatenated searchable text; all other fields are for
display. The lunr index itself is built client-side from this JSON on page
load (a few hundred ms for the current corpus).

## Local preview

```bash
cd docs-site
python3 -m http.server 8000
# open http://localhost:8000
```
